diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/jsifier.js | 25 | ||||
-rw-r--r-- | src/preamble.js | 4 | ||||
-rw-r--r-- | src/settings.js | 18 |
3 files changed, 36 insertions, 11 deletions
diff --git a/src/jsifier.js b/src/jsifier.js index 67c6ac06..a6ce4c6a 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -758,9 +758,17 @@ function JSify(data, functionsOnly, givenTypes, givenFunctions, givenGlobalVaria function makeSignOp(value, type, op) { // TODO: If value isNumber, do this at compile time if (!value) return value; - if (!GUARD_SIGNS) return value; + if (!CORRECT_SIGNS && !CHECK_SIGNS) return value; if (type in Runtime.INT_TYPES) { var bits = parseInt(type.substr(1)); + // shortcuts for 32-bit case + if (bits === 32 && !CHECK_SIGNS) { + if (op === 're') { + return '((' + value + ')|0)'; + } else { + // TODO: figure out something here along the lines of return '(' + Math.pow(2, 32) + '+((' + value + ')|0))'; + } + } return op + 'Sign(' + value + ', ' + bits + ')'; } else { return value; @@ -806,7 +814,20 @@ function JSify(data, functionsOnly, givenTypes, givenFunctions, givenGlobalVaria 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 handleOverflow(ident1 + ' << ' + ident2, bits); + case 'shl': { + // Note: Increases in size may reach the 32-bit limit... where our sign can flip. But this may be expected by the code... + /* + if (bits >= 32) { + if (CHECK_SIGNS && !CORRECT_SIGNS) return 'shlSignCheck(' + ident1 + ', ' + ident2 + ')'; + if (CORRECT_SIGNS) { + var mul = 'Math.pow(2, ' + ident2 + ')'; + if (isNumber(ident2)) mul = eval(mul); + return ident1 + ' * ' + mul; + } + } + */ + return ident1 + ' << ' + ident2; + } case 'ashr': return ident1 + ' >> ' + ident2; case 'lshr': return ident1 + ' >>> ' + ident2; // basic float ops diff --git a/src/preamble.js b/src/preamble.js index c2941902..b471da92 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -373,7 +373,7 @@ function intArrayToString(array) { function unSign(value, bits) { if (value >= 0) return value; #if CHECK_SIGNS - print('WARNING: unSign needed, ' + [value, bits] + ' at ' + new Error().stack); + abort('unSign needed, data: ' + [value, bits]); #endif return bits <= 32 ? 2*Math.abs(1 << (bits-1)) + value // Need some trickery, since if bits == 32, we are right at the limit of the bits JS uses in bitshifts : Math.pow(2, bits) + value; @@ -388,7 +388,7 @@ function reSign(value, bits) { : Math.pow(2, bits-1); if (value >= half) { #if CHECK_SIGNS - print('WARNING: reSign needed, ' + [value, bits] + ' at ' + new Error().stack); + abort('reSign needed, data: ' + [value, bits]); #endif value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts } diff --git a/src/settings.js b/src/settings.js index c4335838..4eb6b6a4 100644 --- a/src/settings.js +++ b/src/settings.js @@ -13,13 +13,13 @@ QUANTUM_SIZE = 4; // This is the size of an individual field in a structure. 1 w // TODO: Cleverly analyze malloc, memset, memcpy etc. operations in // llvm, and replace with the proper values for us -GUARD_SIGNS = 1; // Whether we make sure to convert unsigned values to signed values. - // Decreases performance with additional runtime checks. Might not be - // needed in some kinds of code. -CHECK_SIGNS = 0; // Runtime warning for signing issues that need correcting. Note: - // *requires* GUARD_SIGNS to work. It is recommended to use this in - // order to find if your code needs GUARD_SIGNS. If you can get your - // code to run without GUARD_SIGNS, it will run much faster +CORRECT_SIGNS = 1; // Whether we make sure to convert unsigned values to signed values. + // Decreases performance with additional runtime checks. Might not be + // needed in some kinds of code. +CHECK_SIGNS = 0; // Runtime errors for signing issues that need correcting. + // It is recommended to use this in + // order to find if your code needs CORRECT_SIGNS. If you can get your + // code to run without CORRECT_SIGNS, it will run much faster GUARD_LABELS = 0; // Whether we should throw if we encounter a bad __label__, i.e., // if code flow runs into a fault @@ -55,6 +55,10 @@ CORRECT_OVERFLOWS = 1; // Experimental code that tries to prevent unexpected JS // 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. + // + // NOTE: You can introduce signing issues by using this option. If you + // take a large enough 32-bit value, and correct it for overflows, + // you may get a negative number, as JS & operations are signed. SHOW_LABELS = 0; // Show labels in the generated code |