diff options
author | Alon Zakai <azakai@mozilla.com> | 2011-01-27 21:31:20 -0800 |
---|---|---|
committer | Alon Zakai <azakai@mozilla.com> | 2011-01-27 21:31:20 -0800 |
commit | 5958a6a754324de9eeff39fe1f21ba2b7042f833 (patch) | |
tree | b9a5f9929c3cbe64f9b45ae7be4b6037f2b7b33d /src | |
parent | 8e51dd91884b48f9c59fed12e995ed9fdbdcd5f8 (diff) |
reSign parallel to unSign to fix rare signing issues; CHECK_SIGNS option
Diffstat (limited to 'src')
-rw-r--r-- | src/jsifier.js | 12 | ||||
-rw-r--r-- | src/preamble.js | 22 | ||||
-rw-r--r-- | src/settings.js | 5 |
3 files changed, 34 insertions, 5 deletions
diff --git a/src/jsifier.js b/src/jsifier.js index c64c2ced..3f3c4161 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -752,9 +752,10 @@ function JSify(data, functionsOnly, givenTypes, givenFunctions, givenGlobalVaria return makeOne(0); }); - function makeUnSign(value, type) { + function makeSignOp(value, type, op) { if (type in Runtime.INT_TYPES) { - return 'unSign(' + value + ', ' + type.substr(1) + ')'; + var bits = parseInt(type.substr(1)); + return op + 'Sign(' + value + ', ' + type.substr(1) + ')'; } else { return value; } @@ -768,8 +769,11 @@ function JSify(data, functionsOnly, givenTypes, givenFunctions, givenGlobalVaria } if (GUARD_SIGNS) { if (op[0] == 'u' || (variant && variant[0] == 'u')) { - ident1 = makeUnSign(ident1, type); - ident2 = makeUnSign(ident2, type); + ident1 = makeSignOp(ident1, type, 'un'); + ident2 = makeSignOp(ident2, type, 'un'); + } else if (op[0] == 's' || (variant && variant[0] == 's')) { + ident1 = makeSignOp(ident1, type, 're'); + ident2 = makeSignOp(ident2, type, 're'); } } var bits = null; diff --git a/src/preamble.js b/src/preamble.js index e375b90a..ade02496 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -349,7 +349,27 @@ function intArrayToString(array) { // example, -1 in int32 would be a very large number as unsigned. function unSign(value, bits) { if (value >= 0) return value; - return 2*Math.abs(1 << (bits-1)) + value; +#if CHECK_SIGNS + print('WARNING: unSign needed, ' + [value, bits] + ' at ' + new Error().stack); +#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; + // TODO: clean up previous line +} + +// Converts a value we have as unsigned, into a signed value. For +// example, 200 in a uint8 would be a negative number. +function reSign(value, bits) { + if (value <= 0) return value; + var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32 + : Math.pow(2, bits-1); + if (value >= half) { +#if CHECK_SIGNS + print('WARNING: reSign needed, ' + [value, bits] + ' at ' + new Error().stack); +#endif + value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts + } + return value; } // === Body === diff --git a/src/settings.js b/src/settings.js index 1b0b2bce..c4335838 100644 --- a/src/settings.js +++ b/src/settings.js @@ -16,6 +16,11 @@ QUANTUM_SIZE = 4; // This is the size of an individual field in a structure. 1 w 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 + GUARD_LABELS = 0; // Whether we should throw if we encounter a bad __label__, i.e., // if code flow runs into a fault GUARD_MEMORY = 1; // Whether we should check that each allocation to the stack does not |