diff options
author | Alon Zakai <alonzakai@gmail.com> | 2011-12-07 11:24:09 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2011-12-07 11:24:09 -0800 |
commit | ac5c48218d97222a6e18aa3341f16507766596bd (patch) | |
tree | 8f583cf3778b7792eed9de0353f12f3c58ac7e1f /src | |
parent | e702f719f832582fb6b1864115bb7a8526148574 (diff) |
parseInt test is problematic, mark it as such, and fix some i64 issues with rounding (but not all)
Diffstat (limited to 'src')
-rw-r--r-- | src/parseTools.js | 10 | ||||
-rw-r--r-- | src/runtime.js | 2 |
2 files changed, 8 insertions, 4 deletions
diff --git a/src/parseTools.js b/src/parseTools.js index 86bd6bc1..f8a67ae5 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -577,19 +577,21 @@ function makeI64(low, high) { // Will suffer from rounding. margeI64 does the opposite. // TODO: optimize I64 calcs. For example, saving their parts as signed 32 as opposed to unsigned would help function splitI64(value) { - assert(I64_MODE == 1); - return makeInlineCalculation(makeI64('VALUE>>>0', 'Math.floor(VALUE/4294967296)'), value, 'tempBigInt'); + // We need to min here, since our input might be a double, and large values are rounded, so they can + // be slightly higher than expected. And if we get 4294967296, that will turn into a 0 if put into a + // HEAP32 or |0'd, etc. + return makeInlineCalculation(makeI64('VALUE>>>0', 'Math.min(Math.floor(VALUE/4294967296), 4294967295)'), value, 'tempBigInt'); } function mergeI64(value) { assert(I64_MODE == 1); - return '(tempI64=' + value + ',tempI64[0]+tempI64[1]*4294967296)'; + return makeInlineCalculation('VALUE[0]+VALUE[1]*4294967296', value, 'tempI64'); } // Takes an i64 value and changes it into the [low, high] form used in i64 mode 1. In that // mode, this is a no-op function ensureI64_1(value) { if (I64_MODE == 1) return value; - return makeInlineCalculation('[VALUE>>>0, Math.floor(VALUE/4294967296)]', value, 'tempBigInt'); + return splitI64(value, 1); } function makeCopyI64(value) { diff --git a/src/runtime.js b/src/runtime.js index 637632f8..0b36f967 100644 --- a/src/runtime.js +++ b/src/runtime.js @@ -305,6 +305,8 @@ function reSign(value, bits, ignore, sig) { var noted = false; #endif if (value >= half && (bits <= 32 || value > half)) { // for huge values, we can hit the precision limit and always get true here. so don't do that + // but, in general there is no perfect solution here. With 64-bit ints, we get rounding and errors + // TODO: In i64 mode 1, resign the two parts separately and safely #if CHECK_SIGNS if (!ignore) { CorrectionsMonitor.note('ReSign', 0, sig); |