diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-12-30 11:07:01 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-12-30 11:07:01 -0800 |
commit | d4562d82ed21a1c4fab4b4ef9d98d24a097dada4 (patch) | |
tree | ca5f4f78aa654502f992c86fb20baac43aa1949e /src | |
parent | ea655d0482618759fc08ca681083ad86f9a6c28b (diff) |
use precise 64-bit parsing for parseInt, add bswap64 test, fixes #768
Diffstat (limited to 'src')
-rw-r--r-- | src/library.js | 70 |
1 files changed, 66 insertions, 4 deletions
diff --git a/src/library.js b/src/library.js index 4dfd9438..30ad1128 100644 --- a/src/library.js +++ b/src/library.js @@ -3837,9 +3837,71 @@ LibraryManager.library = { return ret; }, - strtoll__deps: ['_parseInt'], +#if USE_TYPED_ARRAYS == 2 + _parseInt64__deps: ['isspace', '__setErrNo', '$ERRNO_CODES', function() { Types.preciseI64MathUsed = 1 }], + _parseInt64: function(str, endptr, base, min, max, unsign) { + var start = str; + + // Skip space. + while (_isspace({{{ makeGetValue('str', 0, 'i8') }}})) str++; + + // Check for a plus/minus sign. + if ({{{ makeGetValue('str', 0, 'i8') }}} == '-'.charCodeAt(0)) { + str++; + } else if ({{{ makeGetValue('str', 0, 'i8') }}} == '+'.charCodeAt(0)) { + str++; + } + + // Find base. + var finalBase = base; + if (!finalBase) { + if ({{{ makeGetValue('str', 0, 'i8') }}} == '0'.charCodeAt(0)) { + if ({{{ makeGetValue('str+1', 0, 'i8') }}} == 'x'.charCodeAt(0) || + {{{ makeGetValue('str+1', 0, 'i8') }}} == 'X'.charCodeAt(0)) { + finalBase = 16; + str += 2; + } else { + finalBase = 8; + str++; + } + } + } + if (!finalBase) finalBase = 10; + + // Get digits. + var chr; + var ok = false; + while ((chr = {{{ makeGetValue('str', 0, 'i8') }}}) != 0) { + var digit = parseInt(String.fromCharCode(chr), finalBase); + if (isNaN(digit)) { + break; + } else { + ok = true; + str++; + } + } + + try { + i64Math.fromString(Pointer_stringify(start, str - start), finalBase, min, max, unsign); + } catch(e) { + ___setErrNo(ERRNO_CODES.ERANGE); // not quite correct + } + + // Set end pointer. + if (endptr) { + {{{ makeSetValue('endptr', 0, 'str', '*') }}} + } + + // Unsign if needed. XXX + + ret = i64Math.result.slice(0); + + return ret; + }, +#endif + strtoll__deps: ['_parseInt64'], strtoll: function(str, endptr, base) { - return __parseInt(str, endptr, base, -9223372036854775200, 9223372036854775200, 64); // LLONG_MIN, LLONG_MAX; imprecise. + return __parseInt64(str, endptr, base, '-9223372036854775808', '9223372036854775807'); // LLONG_MIN, LLONG_MAX. }, strtoll_l: 'strtoll', // no locale support yet strtol__deps: ['_parseInt'], @@ -3852,9 +3914,9 @@ LibraryManager.library = { return __parseInt(str, endptr, base, 0, 4294967295, 32, true); // ULONG_MAX. }, strtoul_l: 'strtoul', // no locale support yet - strtoull__deps: ['_parseInt'], + strtoull__deps: ['_parseInt64'], strtoull: function(str, endptr, base) { - return __parseInt(str, endptr, base, 0, 18446744073709551615, 64, true); // ULONG_MAX; imprecise. + return __parseInt64(str, endptr, base, 0, '18446744073709551615', true); // ULONG_MAX. }, strtoull_l: 'strtoull', // no locale support yet |