// === Auto-generated preamble library stuff ===
//========================================
// Runtime code shared with compiler
//========================================
{{RUNTIME}}
#if ASM_JS
#if RESERVED_FUNCTION_POINTERS
function jsCall() {
var args = Array.prototype.slice.call(arguments);
return Runtime.functionPointers[args[0]].apply(null, args.slice(1));
}
#endif
#endif
#if BENCHMARK
Module.realPrint = Module.print;
Module.print = Module.printErr = function(){};
#endif
#if SAFE_HEAP
//========================================
// Debugging tools - Heap
//========================================
var HEAP_WATCHED = [];
var HEAP_HISTORY = [];
function SAFE_HEAP_CLEAR(dest) {
#if SAFE_HEAP_LOG
Module.print('SAFE_HEAP clear: ' + dest);
#endif
HEAP_HISTORY[dest] = undefined;
}
var SAFE_HEAP_ERRORS = 0;
var ACCEPTABLE_SAFE_HEAP_ERRORS = 0;
function SAFE_HEAP_ACCESS(dest, type, store, ignore, storeValue) {
//if (dest === A_NUMBER) Module.print ([dest, type, store, ignore, storeValue] + ' ' + new Error().stack); // Something like this may be useful, in debugging
assert(dest > 0, 'segmentation fault');
#if USE_TYPED_ARRAYS
// When using typed arrays, reads over the top of TOTAL_MEMORY will fail silently, so we must
// correct that by growing TOTAL_MEMORY as needed. Without typed arrays, memory is a normal
// JS array so it will work (potentially slowly, depending on the engine).
assert(ignore || dest < Math.max(DYNAMICTOP, STATICTOP));
assert(ignore || DYNAMICTOP <= TOTAL_MEMORY);
#endif
#if USE_TYPED_ARRAYS == 2
return; // It is legitimate to violate the load-store assumption in this case
#endif
if (type && type.charAt(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!
if (store) {
HEAP_HISTORY[dest] = ignore ? null : type;
} else {
#if USE_TYPED_ARRAYS == 0
if (!HEAP[dest] && HEAP[dest] !== 0 && HEAP[dest] !== false && !ignore) { // false can be the result of a mathop comparator
var error = true;
try {
if (HEAP[dest].toString() === 'NaN') error = false; // NaN is acceptable, as a double value
} catch(e){}
if (error) throw('Warning: Reading an invalid value at ' + dest + ' :: ' + new Error().stack + '\n');
}
#endif
if (type === null) return;
var history = HEAP_HISTORY[dest];
if (history === null) return;
if (!ignore)
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 && !ignore) {
Module.print('Load-store consistency assumption failure! ' + dest);
Module.print('\n');
Module.print(JSON.stringify(history));
Module.print('\n');
Module.print('LOAD: ' + type + ', ' + new Error().stack);
Module.print('\n');
SAFE_HEAP_ERRORS++;
assert(SAFE_HEAP_ERRORS <= ACCEPTABLE_SAFE_HEAP_ERRORS, 'Load-store consistency assumption failure!');
}
}
}
function SAFE_HEAP_STORE(dest, value, type, ignore) {
#if SAFE_HEAP_LOG
Module.print('SAFE_HEAP store: ' + [dest, type, value, ignore]);
#endif
if (!ignore && !value && (value === null || value === undefined)) {
throw('Warning: Writing an invalid value of ' + JSON.stringify(value) + ' at ' + dest + ' :: ' + new Error().stack + '\n');
}
//if (!ignore && (value === Infinity || value === -Infinity || isNaN(value))) throw [value, typeof value, new Error().stack];
SAFE_HEAP_ACCESS(dest, type, true, ignore, value);
if (dest in HEAP_WATCHED) {
Module.print((new Error()).stack);
throw "Bad store!"