diff options
Diffstat (limited to 'src/preamble.js')
-rw-r--r-- | src/preamble.js | 101 |
1 files changed, 43 insertions, 58 deletions
diff --git a/src/preamble.js b/src/preamble.js index db092045..ae00b796 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -76,7 +76,7 @@ function SAFE_HEAP_STORE(dest, value, type, ignore) { Module.print('SAFE_HEAP store: ' + [dest, type, value, ignore]); #endif - if (!ignore && !value && value !== 0 && value !== false && !isNaN(value)) { // false can be the result of a mathop comparator; NaN can be the result of a math function + if (!ignore && !value && (value === null || value === undefined)) { throw('Warning: Writing an invalid value of ' + JSON.stringify(value) + ' at ' + dest + ' :: ' + new Error().stack + '\n'); } SAFE_HEAP_ACCESS(dest, type, true, ignore); @@ -104,7 +104,7 @@ function SAFE_HEAP_STORE(dest, value, type, ignore) { } function SAFE_HEAP_LOAD(dest, type, unsigned, ignore) { - SAFE_HEAP_ACCESS(dest, type, ignore); + SAFE_HEAP_ACCESS(dest, type, false, ignore); #if SAFE_HEAP_LOG Module.print('SAFE_HEAP load: ' + [dest, type, getValue(dest, type, 1), ignore]); @@ -315,18 +315,27 @@ var globalScope = this; // -s EXPORTED_FUNCTIONS='["_func1","_func2"]' // // @param ident The name of the C function (note that C++ functions will be name-mangled - use extern "C") -// @param returnType The return type of the function, one of the JS types 'number' or 'string' (use 'number' for any C pointer). -// @param argTypes An array of the types of arguments for the function (if there are no arguments, this can be ommitted). Types are as in returnType. +// @param returnType The return type of the function, one of the JS types 'number', 'string' or 'array' (use 'number' for any C pointer, and +// 'array' for JavaScript arrays and typed arrays). +// @param argTypes An array of the types of arguments for the function (if there are no arguments, this can be ommitted). Types are as in returnType, +// except that 'array' is not possible (there is no way for us to know the length of the array) // @param args An array of the arguments to the function, as native JS values (as in returnType) // Note that string arguments will be stored on the stack (the JS string will become a C string on the stack). // @return The return value, as a native JS value (as in returnType) function ccall(ident, returnType, argTypes, args) { + var stack = 0; function toC(value, type) { if (type == 'string') { - var ret = STACKTOP; - Runtime.stackAlloc(value.length+1); + if (value === null || value === undefined || value === 0) return 0; // null string + if (!stack) stack = Runtime.stackSave(); + var ret = Runtime.stackAlloc(value.length+1); writeStringToMemory(value, ret); return ret; + } else if (type == 'array') { + if (!stack) stack = Runtime.stackSave(); + var ret = Runtime.stackAlloc(value.length); + writeArrayToMemory(value, ret); + return ret; } return value; } @@ -334,6 +343,7 @@ function ccall(ident, returnType, argTypes, args) { if (type == 'string') { return Pointer_stringify(value); } + assert(type != 'array'); return value; } try { @@ -348,7 +358,9 @@ function ccall(ident, returnType, argTypes, args) { var cArgs = args ? args.map(function(arg) { return toC(arg, argTypes[i++]); }) : []; - return fromC(func.apply(null, cArgs), returnType); + var ret = fromC(func.apply(null, cArgs), returnType); + if (stack) Runtime.stackRestore(stack); + return ret; } Module["ccall"] = ccall; @@ -365,6 +377,7 @@ function cwrap(ident, returnType, argTypes) { return ccall(ident, returnType, argTypes, Array.prototype.slice.call(arguments)); } } +Module["cwrap"] = cwrap; // Sets a value in memory in a dynamic way at run-time. Uses the // type data. This is the same as makeSetValue, except that @@ -693,12 +706,15 @@ function callRuntimeCallbacks(callbacks) { } var __ATINIT__ = []; // functions called during startup +var __ATMAIN__ = []; // functions called when main() is to be run var __ATEXIT__ = []; // functions called during shutdown function initRuntime() { callRuntimeCallbacks(__ATINIT__); } - +function preMain() { + callRuntimeCallbacks(__ATMAIN__); +} function exitRuntime() { callRuntimeCallbacks(__ATEXIT__); @@ -706,37 +722,6 @@ function exitRuntime() { CorrectionsMonitor.print(); } - -// Copies a list of num items on the HEAP into a -// a normal JavaScript array of numbers -function Array_copy(ptr, num) { -#if USE_TYPED_ARRAYS == 1 - // TODO: In the SAFE_HEAP case, do some reading here, for debugging purposes - currently this is an 'unnoticed read'. - return Array.prototype.slice.call(IHEAP.subarray(ptr, ptr+num)); // Make a normal array out of the typed 'view' - // Consider making a typed array here, for speed? -#endif -#if USE_TYPED_ARRAYS == 2 - return Array.prototype.slice.call(HEAP8.subarray(ptr, ptr+num)); // Make a normal array out of the typed 'view' - // Consider making a typed array here, for speed? -#endif - return HEAP.slice(ptr, ptr+num); -} -Module['Array_copy'] = Array_copy; - -#if USE_TYPED_ARRAYS -// Copies a list of num items on the HEAP into a -// JavaScript typed array. -function TypedArray_copy(ptr, num) { - // TODO: optimize this! - var arr = new Uint8Array(num); - for (var i = 0; i < num; ++i) { - arr[i] = {{{ makeGetValue('ptr', 'i', 'i8') }}}; - } - return arr.buffer; -} -Module['TypedArray_copy'] = TypedArray_copy; -#endif - function String_len(ptr) { var i = 0; while ({{{ makeGetValue('ptr', 'i', 'i8') }}}) i++; // Note: should be |!= 0|, technically. But this helps catch bugs with undefineds @@ -744,26 +729,18 @@ function String_len(ptr) { } Module['String_len'] = String_len; -// Copies a C-style string, terminated by a zero, from the HEAP into -// a normal JavaScript array of numbers -function String_copy(ptr, addZero) { - var len = String_len(ptr); - if (addZero) len++; - var ret = Array_copy(ptr, len); - if (addZero) ret[len-1] = 0; - return ret; -} -Module['String_copy'] = String_copy; - // Tools // This processes a JS string into a C-line array of numbers, 0-terminated. // For LLVM-originating strings, see parser.js:parseLLVMString function -function intArrayFromString(stringy, dontAddNull) { +function intArrayFromString(stringy, dontAddNull, length /* optional */) { var ret = []; var t; var i = 0; - while (i < stringy.length) { + if (length === undefined) { + length = stringy.length; + } + while (i < length) { var chr = stringy.charCodeAt(i); if (chr > 0xFF) { #if ASSERTIONS @@ -817,6 +794,13 @@ function writeStringToMemory(string, buffer, dontAddNull) { } Module['writeStringToMemory'] = writeStringToMemory; +function writeArrayToMemory(array, buffer) { + for (var i = 0; i < array.length; i++) { + {{{ makeSetValue('buffer', 'i', 'array[i]', 'i8') }}}; + } +} +Module['writeArrayToMemory'] = writeArrayToMemory; + var STRING_TABLE = []; {{{ unSign }}} @@ -824,8 +808,11 @@ var STRING_TABLE = []; // A counter of dependencies for calling run(). If we need to // do asynchronous work before running, increment this and -// decrement it. Incrementing must happen in Module.preRun -// or PRE_RUN_ADDITIONS (used by emcc to add file preloading). +// decrement it. Incrementing must happen in a place like +// PRE_RUN_ADDITIONS (used by emcc to add file preloading). +// Note that you can add dependencies in preRun, even though +// it happens right before run - run will be postponed until +// the dependencies are met. var runDependencies = 0; function addRunDependency() { runDependencies++; @@ -833,6 +820,7 @@ function addRunDependency() { Module['monitorRunDependencies'](runDependencies); } } +Module['addRunDependency'] = addRunDependency; function removeRunDependency() { runDependencies--; if (Module['monitorRunDependencies']) { @@ -840,10 +828,7 @@ function removeRunDependency() { } if (runDependencies == 0) run(); } - -// Preloading - -var preloadedImages = {}; // maps url to image data +Module['removeRunDependency'] = removeRunDependency; // === Body === |