aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2011-12-07 11:24:09 -0800
committerAlon Zakai <alonzakai@gmail.com>2011-12-07 11:24:09 -0800
commitac5c48218d97222a6e18aa3341f16507766596bd (patch)
tree8f583cf3778b7792eed9de0353f12f3c58ac7e1f /src
parente702f719f832582fb6b1864115bb7a8526148574 (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.js10
-rw-r--r--src/runtime.js2
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);