diff options
-rw-r--r-- | src/library.js | 22 | ||||
-rw-r--r-- | src/parseTools.js | 7 | ||||
-rw-r--r-- | tests/parseInt/output_i64mode1.txt | 134 | ||||
-rw-r--r-- | tests/runner.py | 5 |
4 files changed, 159 insertions, 9 deletions
diff --git a/src/library.js b/src/library.js index 624e8550..2158e803 100644 --- a/src/library.js +++ b/src/library.js @@ -2209,7 +2209,7 @@ LibraryManager.library = { } else if (type == 'i64') { ret = [{{{ makeGetValue('varargs', 'argIndex', 'i32', undefined, undefined, true) }}}, {{{ makeGetValue('varargs', 'argIndex+4', 'i32', undefined, undefined, true) }}}]; - ret = unSign(ret[0], 32) + unSign(ret[1], 32)*Math.pow(2, 32); // XXX - loss of precision + ret = unSign(ret[0], 32) + unSign(ret[1], 32)*Math.pow(2, 32); // Unsigned in this notation. Signed later if needed. // XXX - loss of precision #endif } else { ret = {{{ makeGetValue('varargs', 'argIndex', 'i32', undefined, undefined, true) }}}; @@ -3274,7 +3274,7 @@ LibraryManager.library = { }, _parseInt__deps: ['isspace', '__setErrNo', '$ERRNO_CODES'], - _parseInt: function(str, endptr, base, min, max, unsignBits) { + _parseInt: function(str, endptr, base, min, max, bits, unsign) { // Skip space. while (_isspace({{{ makeGetValue('str', 0, 'i8') }}})) str++; @@ -3325,12 +3325,12 @@ LibraryManager.library = { } // Unsign if needed. - if (unsignBits) { + if (unsign) { if (Math.abs(ret) > max) { ret = max; ___setErrNo(ERRNO_CODES.ERANGE); } else { - ret = unSign(ret, unsignBits); + ret = unSign(ret, bits); } } @@ -3340,23 +3340,29 @@ LibraryManager.library = { ___setErrNo(ERRNO_CODES.ERANGE); } +#if I64_MODE == 1 + if (bits == 64) { + ret = {{{ splitI64('ret') }}}; + } +#endif + return ret; }, strtoll__deps: ['_parseInt'], strtoll: function(str, endptr, base) { - return __parseInt(str, endptr, base, -9223372036854775808, 9223372036854775807); // LLONG_MIN, LLONG_MAX; imprecise. + return __parseInt(str, endptr, base, -9223372036854775808, 9223372036854775807, 64); // LLONG_MIN, LLONG_MAX; imprecise. }, strtol__deps: ['_parseInt'], strtol: function(str, endptr, base) { - return __parseInt(str, endptr, base, -2147483648, 2147483647); // LONG_MIN, LONG_MAX. + return __parseInt(str, endptr, base, -2147483648, 2147483647, 32); // LONG_MIN, LONG_MAX. }, strtoul__deps: ['_parseInt'], strtoul: function(str, endptr, base) { - return __parseInt(str, endptr, base, 0, 4294967295, 32); // ULONG_MAX. + return __parseInt(str, endptr, base, 0, 4294967295, 32, true); // ULONG_MAX. }, strtoull__deps: ['_parseInt'], strtoull: function(str, endptr, base) { - return __parseInt(str, endptr, base, 0, 18446744073709551615, 64); // ULONG_MAX; imprecise. + return __parseInt(str, endptr, base, 0, 18446744073709551615, 64, true); // ULONG_MAX; imprecise. }, qsort__deps: ['memcpy'], diff --git a/src/parseTools.js b/src/parseTools.js index 67d87a76..fad414ed 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -533,12 +533,19 @@ function IEEEUnHex(stringy) { function makeI64(low, high) { if (I64_MODE == 1) { return '[' + low + ',' + (high || '0') + ']'; + // FIXME with this? return '[unSign(' + low + ',32),' + (high ? ('unSign(' + high + ',32)') : '0') + ']'; } else { assert(!high); return low; } } +// Splits a number (an integer in a double, possibly > 32 bits) into an I64_MODE 1 i64 value +function splitI64(value) { + assert(I64_MODE == 1); + return makeI64(value + '|0', 'Math.floor(' + value + '/4294967296)'); +} + function makeCopyI64(value) { assert(I64_MODE == 1); diff --git a/tests/parseInt/output_i64mode1.txt b/tests/parseInt/output_i64mode1.txt new file mode 100644 index 00000000..649500b0 --- /dev/null +++ b/tests/parseInt/output_i64mode1.txt @@ -0,0 +1,134 @@ +strtol("-9223372036854775809") = -2147483648 +ERR 34 +strtoll("-9223372036854775809") = 9223372036854776000 +ERR 34 +strtoul("-9223372036854775809") = 4294967295 +ERR 34 +strtoull("-9223372036854775809") = 9223372036854774000 + +strtol("-9223372036854775808") = -2147483648 +ERR 34 +strtoll("-9223372036854775808") = 9223372036854776000 +ERR 34 +strtoul("-9223372036854775808") = 4294967295 +ERR 34 +strtoull("-9223372036854775808") = 9223372036854774000 + +strtol("-9223372036854775807") = -2147483648 +ERR 34 +strtoll("-9223372036854775807") = 9223372036854776000 +ERR 34 +strtoul("-9223372036854775807") = 4294967295 +ERR 34 +strtoull("-9223372036854775807") = 9223372036854774000 + +strtol("-2147483649") = -2147483648 +ERR 34 +strtoll("-2147483649") = -2147483648 +strtoul("-2147483649") = 2147483647 +strtoull("-2147483649") = 18446744071562068000 + +strtol("-2147483648") = -2147483648 +strtoll("-2147483648") = -2147483648 +strtoul("-2147483648") = 2147483648 +strtoull("-2147483648") = 18446744071562068000 + +strtol("-2147483647") = -2147483647 +strtoll("-2147483647") = -2147483648 +strtoul("-2147483647") = 2147483649 +strtoull("-2147483647") = 18446744071562068000 + +strtol("-5") = -5 +strtoll("-5") = 0 +strtoul("-5") = 4294967291 +strtoull("-5") = 18446744073709552000 + +strtol("-1") = -1 +strtoll("-1") = 0 +strtoul("-1") = 4294967295 +strtoull("-1") = 18446744073709552000 + +strtol("0") = 0 +strtoll("0") = 0 +strtoul("0") = 0 +strtoull("0") = 0 + +strtol("1") = 1 +strtoll("1") = 1 +strtoul("1") = 1 +strtoull("1") = 1 + +strtol("5") = 5 +strtoll("5") = 5 +strtoul("5") = 5 +strtoull("5") = 5 + +strtol("2147483646") = 2147483646 +strtoll("2147483646") = 2147483646 +strtoul("2147483646") = 2147483646 +strtoull("2147483646") = 2147483646 + +strtol("2147483647") = 2147483647 +strtoll("2147483647") = 2147483647 +strtoul("2147483647") = 2147483647 +strtoull("2147483647") = 2147483647 + +strtol("2147483648") = 2147483647 +ERR 34 +strtoll("2147483648") = 2147483648 +strtoul("2147483648") = 2147483648 +strtoull("2147483648") = 2147483648 + +strtol("4294967294") = 2147483647 +ERR 34 +strtoll("4294967294") = 4294967294 +strtoul("4294967294") = 4294967294 +strtoull("4294967294") = 4294967294 + +strtol("4294967295") = 2147483647 +ERR 34 +strtoll("4294967295") = 4294967295 +strtoul("4294967295") = 4294967295 +strtoull("4294967295") = 4294967295 + +strtol("4294967296") = 2147483647 +ERR 34 +strtoll("4294967296") = 4294967296 +strtoul("4294967296") = 4294967295 +ERR 34 +strtoull("4294967296") = 4294967296 + +strtol("18446744073709551614") = 2147483647 +ERR 34 +strtoll("18446744073709551614") = 9223372036854776000 +ERR 34 +strtoul("18446744073709551614") = 4294967295 +ERR 34 +strtoull("18446744073709551614") = 18446744073709552000 + +strtol("18446744073709551615") = 2147483647 +ERR 34 +strtoll("18446744073709551615") = 9223372036854776000 +ERR 34 +strtoul("18446744073709551615") = 4294967295 +ERR 34 +strtoull("18446744073709551615") = 18446744073709552000 + +strtol("18446744073709551616") = 2147483647 +ERR 34 +strtoll("18446744073709551616") = 9223372036854776000 +ERR 34 +strtoul("18446744073709551616") = 4294967295 +ERR 34 +strtoull("18446744073709551616") = 18446744073709552000 + +strtol("0x12", 0, 0) = 18 +strtol("0x12", 0, 10) = 0 +strtol("012", 0, 0) = 10 +strtol("012", 0, 10) = 12 +strtol("0y12", 0, 0) = 0 +strtol("hello", 0, 30) = 14167554 +strtol("hello", 0, 10) = 0 +strtol("not-a-number") = 0 +strtol(" 0x12end") = 302 +endptr - str = 7 diff --git a/tests/runner.py b/tests/runner.py index 2748d6a1..4587d0b7 100644 --- a/tests/runner.py +++ b/tests/runner.py @@ -2385,7 +2385,10 @@ if 'benchmark' not in str(sys.argv): def test_parseInt(self): if Settings.USE_TYPED_ARRAYS != 0: return self.skip('Typed arrays truncate i64') src = open(path_from_root('tests', 'parseInt', 'src.c'), 'r').read() - expected = open(path_from_root('tests', 'parseInt', 'output.txt'), 'r').read() + if Settings.I64_MODE == 0: + expected = open(path_from_root('tests', 'parseInt', 'output.txt'), 'r').read() + else: + expected = open(path_from_root('tests', 'parseInt', 'output_i64mode1.txt'), 'r').read() # some rounding issues, etc. self.do_run(src, expected) def test_printf(self): |