diff options
-rw-r--r-- | src/jsifier.js | 7 | ||||
-rw-r--r-- | src/library.js | 4 | ||||
-rw-r--r-- | src/parseTools.js | 3 | ||||
-rwxr-xr-x | tests/runner.py | 31 | ||||
-rw-r--r-- | tools/shared.py | 1 |
5 files changed, 42 insertions, 4 deletions
diff --git a/src/jsifier.js b/src/jsifier.js index dcc853f2..8caab6e2 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -38,7 +38,6 @@ function JSify(data, functionsOnly, givenFunctions) { var preFile = BUILD_AS_SHARED_LIB ? 'preamble_sharedlib.js' : 'preamble.js'; var pre = processMacros(preprocess(read(preFile).replace('{{RUNTIME}}', getRuntime()))); print(pre); - if (PRECISE_I64_MATH) print(read('long.js')); Functions.implementedFunctions = set(data.unparsedFunctions.map(function(func) { return func.ident })); } @@ -1200,6 +1199,12 @@ function JSify(data, functionsOnly, givenFunctions) { // This is the main pass. Print out the generated code that we have here, together with the // rest of the output that we started to print out earlier (see comment on the // "Final shape that will be created"). + if (PRECISE_I64_MATH && preciseI64MathUsed) { + print(read('long.js')); + } else { + print('// Warning: printing of i64 values may be slightly rounded! No deep i64 math used, so precise i64 code not included'); + print('var i64Math = null;'); + } var generated = itemsDict.functionStub.concat(itemsDict.GlobalVariablePostSet); generated.forEach(function(item) { print(indentify(item.JS || '', 2)); }); if (RUNTIME_TYPE_INFO) { diff --git a/src/library.js b/src/library.js index f49a8a58..be5e48d7 100644 --- a/src/library.js +++ b/src/library.js @@ -2507,12 +2507,12 @@ LibraryManager.library = { var prefix = ''; if (next == 'd'.charCodeAt(0) || next == 'i'.charCodeAt(0)) { #if PRECISE_I64_MATH == 1 - if (argSize == 8) argText = i64Math.stringify(origArg[0], origArg[1]); else + if (argSize == 8 && i64Math) argText = i64Math.stringify(origArg[0], origArg[1]); else #endif argText = reSign(currArg, 8 * argSize, 1).toString(10); } else if (next == 'u'.charCodeAt(0)) { #if PRECISE_I64_MATH == 1 - if (argSize == 8) argText = i64Math.stringify(origArg[0], origArg[1], true); else + if (argSize == 8 && i64Math) argText = i64Math.stringify(origArg[0], origArg[1], true); else #endif argText = unSign(currArg, 8 * argSize, 1).toString(10); currArg = Math.abs(currArg); diff --git a/src/parseTools.js b/src/parseTools.js index 5ec3b4ed..22f38207 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -1560,6 +1560,8 @@ function isSignedOp(op, variant) { } var legalizedI64s = USE_TYPED_ARRAYS == 2; // We do not legalize globals, but do legalize function lines. This will be true in the latter case +var preciseI64MathUsed = false; // Set to true if we actually use precise i64 math: If PRECISE_I64_MATH is set, and also such math is actually + // needed (+,-,*,/,% - we do not need it for bitops) function processMathop(item) { var op = item.op; @@ -1617,6 +1619,7 @@ function processMathop(item) { } } function i64PreciseOp(type, lastArg) { + preciseI64MathUsed = true; return finish(['(i64Math.' + type + '(' + low1 + ',' + high1 + ',' + low2 + ',' + high2 + (lastArg ? ',' + lastArg : '') + '),i64Math.result[0])', 'i64Math.result[1]']); } diff --git a/tests/runner.py b/tests/runner.py index 62d09ee9..42cb211f 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -860,8 +860,37 @@ m_divisor is 1091269979 ''' self.do_run(src, open(path_from_root('tests', 'i64_precise.txt')).read()) + # Verify that without precision, we do not include the precision code + Settings.PRECISE_I64_MATH = 0 + self.do_run(src, 'unsigned') + code = open(os.path.join(self.get_dir(), 'src.cpp.o.js')).read() + assert 'goog.math.Long' not in code and 'jsbn' not in code, 'i64 precise math should not have been included if not asked for' + + # Verify that even if we ask for precision, if it is not needed it is not included + Settings.PRECISE_I64_MATH = 1 + src = ''' + #include <inttypes.h> + #include <stdio.h> + + int main(int argc, char **argv) { + uint64_t x = 2125299906845564, y = 1225891506842664; + if (argc == 12) { + x = x >> 1; + y = y >> 1; + } + x = x & 12ULL; + y = y | 12ULL; + x = x ^ y; + x <<= 2; + y >>= 3; + printf("*%llu, %llu*\\n", x, y); + } + ''' + self.do_run(src, '*4903566027370624, 153236438355333*') + code = open(os.path.join(self.get_dir(), 'src.cpp.o.js')).read() + assert 'goog.math.Long' not in code and 'jsbn' not in code, 'i64 precise math should not have been included if not actually used' + print 'TODO: make precise the default, and imprecise in -O3. Remove precise setting in this test and cube2hash' - print 'TODO: only include this code when needed' #1/0. def test_cube2hash(self): diff --git a/tools/shared.py b/tools/shared.py index 4e5f3d6a..17887afe 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -344,6 +344,7 @@ class Settings: Settings.CORRECT_OVERFLOWS = 0 Settings.CORRECT_ROUNDINGS = 0 Settings.DOUBLE_MODE = 0 + Settings.PRECISE_I64_MATH = 0 if noisy: print >> sys.stderr, 'Warning: Applying some potentially unsafe optimizations! (Use -O2 if this fails.)' global Settings |