diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler.js | 4 | ||||
-rw-r--r-- | src/jsifier.js | 11 | ||||
-rw-r--r-- | src/preamble.js | 41 | ||||
-rw-r--r-- | src/settings.js | 3 |
4 files changed, 40 insertions, 19 deletions
diff --git a/src/compiler.js b/src/compiler.js index c0cdff19..b4e9530a 100644 --- a/src/compiler.js +++ b/src/compiler.js @@ -28,10 +28,6 @@ load('analyzer.js'); load('jsifier.js'); load('runtime.js'); -// Sanity checks - -assert(!(USE_TYPED_ARRAYS && SAFE_HEAP)); - //=============================== // Main //=============================== diff --git a/src/jsifier.js b/src/jsifier.js index 7e824286..af8d19ab 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -149,10 +149,13 @@ function JSify(data, functionsOnly, givenTypes, givenFunctions, givenGlobalVaria } function makeCopyValue(dest, destPos, src, srcPos, type, modifier) { - var types = (type !== 'null' || !USE_TYPED_ARRAYS) ? [type] : ['i32', 'double']; - return types.map(function(currType) { - return makeSetValue(dest, destPos, makeGetValue(src, srcPos, currType) + (modifier || ''), currType); - }).join(' '); + if (type !== 'null') { + return makeSetValue(dest, destPos, makeGetValue(src, srcPos, type) + (modifier || ''), type); + } + // Null is special-cased: We copy over all heaps + return 'IHEAP[' + dest + '+' + destPos + '] = IHEAP[' + src + '+' + srcPos + ']; ' + + 'FHEAP[' + dest + '+' + destPos + '] = FHEAP[' + src + '+' + srcPos + ']; ' + + (SAFE_HEAP ? 'SAFE_HEAP_ACCESS(' + dest + ' + ' + destPos + ', null, true)' : ''); } function makeEmptyStruct(type) { diff --git a/src/preamble.js b/src/preamble.js index 11ef2085..181a3340 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -24,6 +24,9 @@ function SAFE_HEAP_CLEAR(dest) { 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 +#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. // You cannot, however, do the nonportable act of store X and load Y! @@ -36,8 +39,8 @@ function SAFE_HEAP_ACCESS(dest, type, store) { if (type === null) return; var history = HEAP_HISTORY[dest]; if (history === null) return; - assert(history, 'Must have a history for a safe heap load!'); // Warning - bit fields in C structs cause loads+stores for each store, so - // they will show up here... + assert(history, 'Must have a history for a safe heap load! ' + dest + ':' + type); // Warning - bit fields in C structs cause loads+stores for each store, so + // they will show up here... // assert((history && history[0]) /* || HEAP[dest] === 0 */, "Loading from where there was no store! " + dest + ',' + HEAP[dest] + ',' + type + ', \n\n' + new Error().stack + '\n'); // if (history[0].type !== type) { if (history !== type) { @@ -53,6 +56,9 @@ function SAFE_HEAP_ACCESS(dest, type, store) { } } function SAFE_HEAP_STORE(dest, value, type) { +#if SAFE_HEAP_LOG + print('store: ' + dest + ' [' + type + '] |' + value + '|'); +#endif if (!value && value !== 0 && value !== false) { // false can be the result of a mathop comparator throw('Warning: Writing an invalid value of ' + JSON.stringify(value) + ' at ' + dest + ' :: ' + new Error().stack + '\n'); } @@ -61,11 +67,25 @@ function SAFE_HEAP_STORE(dest, value, type) { print((new Error()).stack); throw "Bad store!" + dest; } - HEAP[dest] = value; + if (type === null) { + IHEAP[dest] = value; + FHEAP[dest] = value; + } else if (type in Runtime.FLOAT_TYPES) { + FHEAP[dest] = value; + } else { + IHEAP[dest] = value; + } } 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); - return HEAP[dest]; + if (type in Runtime.FLOAT_TYPES) { + return FHEAP[dest]; + } else { + return IHEAP[dest]; + } } function __Z16PROTECT_HEAPADDRPv(dest) { HEAP_WATCHED[dest] = true; @@ -196,12 +216,12 @@ function __initializeRuntime__() { var FAST_MEMORY = TOTAL_MEMORY/32; IHEAP = FHEAP = HEAP = new Array(FAST_MEMORY); for (var i = 0; i < FAST_MEMORY; i++) { - {{{ makeSetValue(0, 'i', 0, 'null') }}} + IHEAP[i] = FHEAP[i] = 0; // We do *not* use {{{ makeSetValue(0, 'i', 0, 'null') }}} here, since this is done just to optimize runtime speed } } - var base = intArrayFromString('(null)'); // So printing %s of NULL gives '(null)' - // Also this ensures we leave 0 as an invalid address, 'NULL' + var base = intArrayFromString('(null)').concat(0); // So printing %s of NULL gives '(null)' + // Also this ensures we leave 0 as an invalid address, 'NULL' for (var i = 0; i < base.length; i++) { {{{ makeSetValue(0, 'i', 'base[i]', 'i8') }}} } @@ -261,9 +281,10 @@ function __formatString() { } var ret = []; - var curr = -1, next, currArg; - while (curr) { // Note: should be curr != 0, technically. But this helps catch bugs with undefineds + var curr, next, currArg; + while(1) { curr = {{{ makeGetValue(0, 'textIndex', 'i8') }}}; + if (curr === 0) break; next = {{{ makeGetValue(0, 'textIndex+1', 'i8') }}}; if (curr == '%'.charCodeAt(0)) { // Handle very very simply formatting, namely only %.X[f|d|u|etc.] @@ -333,7 +354,7 @@ function __formatString() { textIndex += 1; } } - return Pointer_make(ret, 0, ALLOC_STACK); // NB: Stored on the stack + return Pointer_make(ret.concat(0), 0, ALLOC_STACK); // NB: Stored on the stack } // Copies a list of num items on the HEAP into a diff --git a/src/settings.js b/src/settings.js index 62143fa9..79b4e6fa 100644 --- a/src/settings.js +++ b/src/settings.js @@ -31,8 +31,9 @@ USE_TYPED_ARRAYS = 0; // Try to use typed arrays for the heap // Generated code debugging options SAFE_HEAP = 0; // Check each write to the heap against a list of blocked addresses +SAFE_HEAP_LOG = 0; // Print out every single heap read and write (LOTS of output) LABEL_DEBUG = 0; // Print out labels and functions as we enter them -EXCEPTION_DEBUG = 0; // Print out exceptions in emscriptened code +EXCEPTION_DEBUG = 1; // Print out exceptions in emscriptened code EXECUTION_TIMEOUT = -1; // Throw an exception after X seconds - useful to debug infinite loops CHECK_OVERFLOWS = 0; // Add code that checks for overflows in integer math operations. // There is currently not much to do to handle overflows if they occur. |