aboutsummaryrefslogtreecommitdiff
path: root/src/preamble.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/preamble.js')
-rw-r--r--src/preamble.js101
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 ===