diff options
author | Alon Zakai <azakai@mozilla.com> | 2011-01-01 16:56:22 -0800 |
---|---|---|
committer | Alon Zakai <azakai@mozilla.com> | 2011-01-01 16:56:22 -0800 |
commit | 785e01b0d00125bbf9b1d32ecfd98af311f4e985 (patch) | |
tree | 13d8f13d47189d41778d65a593a96d8be42e2b1a /src | |
parent | 0a2735ebc744bb877b20ff4b9669ab55b8e5100b (diff) |
CORRECT_OVERFLOWS option; strengthening of various tests, and fixes a bug in python with typed arrays
Diffstat (limited to 'src')
-rw-r--r-- | src/jsifier.js | 26 | ||||
-rw-r--r-- | src/preamble.js | 13 | ||||
-rw-r--r-- | src/settings.js | 5 |
3 files changed, 31 insertions, 13 deletions
diff --git a/src/jsifier.js b/src/jsifier.js index af8d19ab..a753fd05 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -742,36 +742,46 @@ function JSify(data, functionsOnly, givenTypes, givenFunctions, givenGlobalVaria ident2 = makeUnSign(ident2, type); } } - function checkOverflow(text) { + var bits = null; + if (item.type[0] === 'i') { + bits = parseInt(item.type.substr(1)); + } + function handleOverflow(text) { + if (!bits) return text; + if (CORRECT_OVERFLOWS && bits <= 32) text = '(' + text + ')&' + (Math.pow(2, bits) - 1); if (!CHECK_OVERFLOWS) return text; - if (item.type[0] !== 'i') return text; - var bits = item.type.substr(1); return 'CHECK_OVERFLOW(' + text + ', ' + bits + ')'; } switch (op) { - case 'add': return checkOverflow(ident1 + ' + ' + ident2); - case 'sub': return checkOverflow(ident1 + ' - ' + ident2); - case 'sdiv': case 'udiv': return checkOverflow('Math.floor(' + ident1 + ' / ' + ident2 + ')'); - case 'mul': return checkOverflow(ident1 + ' * ' + ident2); + // basic integer ops + case 'add': return handleOverflow(ident1 + ' + ' + ident2); + case 'sub': return handleOverflow(ident1 + ' - ' + ident2); + case 'sdiv': case 'udiv': return 'Math.floor(' + ident1 + ' / ' + ident2 + ')'; + case 'mul': return handleOverflow(ident1 + ' * ' + ident2); case 'urem': case 'srem': return 'Math.floor(' + ident1 + ' % ' + ident2 + ')'; case 'or': return ident1 + ' | ' + ident2; // TODO this forces into a 32-bit int - add overflow-style checks? also other bitops below us case 'and': return ident1 + ' & ' + ident2; case 'xor': return ident1 + ' ^ ' + ident2; - case 'shl': return ident1 + ' << ' + ident2; + case 'shl': return handleOverflow(ident1 + ' << ' + ident2); case 'ashr': return ident1 + ' >> ' + ident2; case 'lshr': return ident1 + ' >>> ' + ident2; + // basic float ops case 'fadd': return ident1 + ' + ' + ident2; case 'fsub': return ident1 + ' - ' + ident2; case 'fdiv': return ident1 + ' / ' + ident2; case 'fmul': return ident1 + ' * ' + ident2; case 'uitofp': case 'sitofp': return ident1; case 'fptoui': case 'fptosi': return 'Math.floor(' + ident1 + ')'; + + // TODO: We sometimes generate false instead of 0, etc., in the *cmps. It seemed slightly faster before, but worth rechecking + // Note that with typed arrays, these become 0 when written. So that is a potential difference with non-typed array runs. case 'icmp': { switch (variant) { case 'uge': case 'sge': return ident1 + ' >= ' + ident2; case 'ule': case 'sle': return ident1 + ' <= ' + ident2; case 'ugt': case 'sgt': return ident1 + ' > ' + ident2; case 'ult': case 'slt': return ident1 + ' < ' + ident2; + // We use loose comparisons, which allows false == 0 to be true, etc. Ditto in fcmp case 'ne': case 'une': return ident1 + ' != ' + ident2; case 'eq': return ident1 + ' == ' + ident2; default: throw 'Unknown icmp variant: ' + variant; diff --git a/src/preamble.js b/src/preamble.js index 181a3340..2bf7c17e 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -25,7 +25,7 @@ var SAFE_HEAP_ERRORS = 0; var ACCEPTABLE_SAFE_HEAP_ERRORS = 0; function SAFE_HEAP_ACCESS(dest, type, store) { #if SAFE_HEAP_LOG - //if (dest === A_NUMBER) print (new Error().stack); // Something like this may be useful, in debugging + //if (dest === A_NUMBER) print ([dest, type, store] + ' ' + new Error().stack); // Something like this may be useful, in debugging #endif if (type && type[type.length-1] == '*') type = 'i32'; // pointers are ints, for our purposes here // Note that this will pass even with unions: You can store X, load X, then store Y and load Y. @@ -77,13 +77,16 @@ function SAFE_HEAP_STORE(dest, value, type) { } } function SAFE_HEAP_LOAD(dest, type) { -#if SAFE_HEAP_LOG - print('load : ' + dest + ' [' + type + '] |' + JSON.stringify([IHEAP[dest],FHEAP[dest]]) + '|'); -#endif SAFE_HEAP_ACCESS(dest, type); if (type in Runtime.FLOAT_TYPES) { +#if SAFE_HEAP_LOG + print('load : ' + dest + ' [' + type + '] |' + FHEAP[dest] + '|'); +#endif return FHEAP[dest]; } else { +#if SAFE_HEAP_LOG + print('load : ' + dest + ' [' + type + '] |' + IHEAP[dest] + '|'); +#endif return IHEAP[dest]; } } @@ -99,7 +102,7 @@ function __Z18UNPROTECT_HEAPADDRPv(dest) { #if CHECK_OVERFLOWS function CHECK_OVERFLOW(value, bits) { assert(value !== Infinity && value !== -Infinity, 'Infinity!'); - assert(Math.abs(value) < Math.pow(2, bits-1), 'Overflow!'); + assert(Math.abs(value) < Math.pow(2, bits), 'Overflow!'); return value; } #endif diff --git a/src/settings.js b/src/settings.js index 79b4e6fa..0bc6c88d 100644 --- a/src/settings.js +++ b/src/settings.js @@ -43,6 +43,11 @@ CHECK_OVERFLOWS = 0; // Add code that checks for overflows in integer math opera // some factor, in order to get 'random' hash values - by taking // that |value & hash_table_size| - then multiplying enough times will overflow. // But instead, you can do |value = value & 30_BITS| in each iteration. +CORRECT_OVERFLOWS = 1; // Experimental code that tries to prevent unexpected JS overflows in integer + // mathops, by doing controlled overflows (sort of parallel to a CPU). + // Note that as mentioned above in CHECK_OVERFLOWS, the best thing is to + // not rely on overflows in your C/C++ code, as even if this option works, + // it slows things down. // Compiler debugging options DEBUG_TAGS_SHOWING = []; |