aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-04-02 13:20:20 -0700
committerAlon Zakai <alonzakai@gmail.com>2012-04-02 13:20:20 -0700
commitd061071c37db687389e2f8aad64741d1ce9a2ad0 (patch)
tree9d075504e06bb0bbc539b96aa4b2b39251408604
parent1823aaf13bfbbc3cbbe6c8dc9ff153361f0bcf4a (diff)
only include i64 precise code if it will actually be used
-rw-r--r--src/jsifier.js7
-rw-r--r--src/library.js4
-rw-r--r--src/parseTools.js3
-rwxr-xr-xtests/runner.py31
-rw-r--r--tools/shared.py1
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