aboutsummaryrefslogtreecommitdiff
path: root/src/preamble.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/preamble.js')
-rw-r--r--src/preamble.js167
1 files changed, 83 insertions, 84 deletions
diff --git a/src/preamble.js b/src/preamble.js
index 98d12a43..986592ee 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -14,7 +14,7 @@ var HEAP_WATCHED = [];
var HEAP_HISTORY = [];
function SAFE_HEAP_CLEAR(dest) {
#if SAFE_HEAP_LOG
- print('SAFE_HEAP clear: ' + dest);
+ Module.print('SAFE_HEAP clear: ' + dest);
#endif
HEAP_HISTORY[dest] = [];
}
@@ -22,7 +22,7 @@ var SAFE_HEAP_ERRORS = 0;
var ACCEPTABLE_SAFE_HEAP_ERRORS = 0;
function SAFE_HEAP_ACCESS(dest, type, store, ignore) {
- //if (dest === A_NUMBER) print ([dest, type, store] + ' ' + new Error().stack); // Something like this may be useful, in debugging
+ //if (dest === A_NUMBER) Module.print ([dest, type, store] + ' ' + new Error().stack); // Something like this may be useful, in debugging
#if USE_TYPED_ARRAYS
// When using typed arrays, reads over the top of TOTAL_MEMORY will fail silently, so we must
@@ -59,12 +59,12 @@ function SAFE_HEAP_ACCESS(dest, type, store, ignore) {
// 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) {
- print('Load-store consistency assumption failure! ' + dest);
- print('\n');
- print(JSON.stringify(history));
- print('\n');
- print('LOAD: ' + type + ', ' + new Error().stack);
- print('\n');
+ 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!');
}
@@ -73,15 +73,15 @@ function SAFE_HEAP_ACCESS(dest, type, store, ignore) {
function SAFE_HEAP_STORE(dest, value, type, ignore) {
#if SAFE_HEAP_LOG
- print('SAFE_HEAP store: ' + [dest, type, value, 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);
if (dest in HEAP_WATCHED) {
- print((new Error()).stack);
+ Module.print((new Error()).stack);
throw "Bad store!" + dest;
}
@@ -104,10 +104,10 @@ 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
- print('SAFE_HEAP load: ' + [dest, type, getValue(dest, type, 1), ignore]);
+ Module.print('SAFE_HEAP load: ' + [dest, type, getValue(dest, type, 1), ignore]);
#endif
#if USE_TYPED_ARRAYS == 2
@@ -132,7 +132,7 @@ function SAFE_HEAP_LOAD(dest, type, unsigned, ignore) {
function SAFE_HEAP_COPY_HISTORY(dest, src) {
#if SAFE_HEAP_LOG
- print('SAFE_HEAP copy: ' + [dest, src]);
+ Module.print('SAFE_HEAP copy: ' + [dest, src]);
#endif
HEAP_HISTORY[dest] = HEAP_HISTORY[src];
SAFE_HEAP_ACCESS(dest, HEAP_HISTORY[dest] || null, true, false);
@@ -160,7 +160,7 @@ var CorrectionsMonitor = {
sig = (new Error().stack).toString().split('\n')[2].split(':').slice(-1)[0]; // Spidermonkey-specific FIXME
sig = type + '|' + sig;
if (!this.sigs[sig]) {
- //print('Correction: ' + sig);
+ //Module.print('Correction: ' + sig);
this.sigs[sig] = [0, 0]; // fail, succeed
}
this.sigs[sig][succeed ? 1 : 0]++;
@@ -181,7 +181,7 @@ var CorrectionsMonitor = {
items.sort(function(x, y) { return y.total - x.total; });
for (var i = 0; i < items.length; i++) {
var item = items[i];
- print(item.sig + ' : ' + item.total + ' hits, %' + (Math.ceil(100*item.fails/item.total)) + ' failures');
+ Module.print(item.sig + ' : ' + item.total + ' hits, %' + (Math.ceil(100*item.fails/item.total)) + ' failures');
}
#endif
}
@@ -253,7 +253,7 @@ Module['stopProfiling'] = stopProfiling;
function printProfiling() {
function dumpData(name_, node, indent) {
- print(indent + ('________' + node.time).substr(-8) + ': ' + name_ + ' (' + node.calls + ')');
+ Module.print(indent + ('________' + node.time).substr(-8) + ': ' + name_ + ' (' + node.calls + ')');
var children = [];
for (var child in node.children) {
children.push(node.children[child]);
@@ -265,57 +265,6 @@ function printProfiling() {
dumpData('root', PROFILING_ROOT, ' ');
}
Module['printProfiling'] = printProfiling;
-
-function printXULProfiling() {
- function dumpData(name_, node, indent) {
- var children = [];
- for (var child in node.children) {
- children.push(node.children[child]);
- children[children.length-1].name_ = child;
- }
- print('<treeitem' + (children.length > 0 ? ' container="true"' : '') + '>');
- print(' <treerow>');
- print(' <treecell label="' + name_ + '"/>');
- print(' <treecell label="' + node.time + '"/>');
- print(' <treecell label="' + node.calls + '"/>');
- print(' </treerow>');
-
- if (children.length > 0) {
- print(' <treechildren>');
- children.sort(function(x, y) { return y.time - x.time });
- children.forEach(function(child) { dumpData(child.name_, child, indent + ' ') });
- print(' </treechildren>');
- }
-
- print('</treeitem>');
- }
-
- print('<?xml version="1.0"?>');
- print('<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> ');
- print('<?xml-stylesheet href="file://C:/main.css" type="text/css"?> ');
- print('<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> ');
- print('<tree id="myTree" flex="1" hidecolumnpicker="false" seltype="single" class="tree"');
- print(' rows="5">');
- print(' <treecols id="myTree2-treeCols">');
- print(' <treecol id="myTree2-treeCol0" primary="true" flex="2" label="Name"');
- print(' persist="width" ordinal="1"/>');
- print(' <splitter class="tree-splitter" ordinal="2"/>');
- print(' <treecol id="myTree2-treeCol1" flex="1" label="Milliseconds"');
- print(' persist="width" ordinal="3"/>');
- print(' <treecol id="myTree2-treeCol2" flex="1" label="Calls"');
- print(' persist="width" ordinal="4"/>');
- print(' </treecols>');
- print(' <treechildren>');
-
- dumpData('root', PROFILING_ROOT, ' ');
-
- print(' </treechildren>');
- print('</tree>');
- print('</window>');
-
- // This requires dom.allow_XUL_XBL_for_file
-}
-Module['printXULProfiling'] = printXULProfiling;
#endif
//========================================
@@ -335,7 +284,7 @@ var tempI64, tempI64b;
#endif
function abort(text) {
- print(text + ':\n' + (new Error).stack);
+ Module.print(text + ':\n' + (new Error).stack);
ABORT = true;
throw "Assertion: " + text;
}
@@ -366,18 +315,26 @@ 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 (!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;
}
@@ -385,6 +342,7 @@ function ccall(ident, returnType, argTypes, args) {
if (type == 'string') {
return Pointer_stringify(value);
}
+ assert(type != 'array');
return value;
}
try {
@@ -399,7 +357,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;
@@ -416,6 +376,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
@@ -594,7 +555,7 @@ var FHEAP;
#endif
#endif
#if USE_TYPED_ARRAYS == 2
-var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32;
+var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64;
#endif
var STACK_ROOT, STACKTOP, STACK_MAX;
@@ -603,7 +564,7 @@ var STATICTOP;
function enlargeMemory() {
// TOTAL_MEMORY is the current size of the actual array, and STATICTOP is the new top.
#if ASSERTIONS
- printErr('Warning: Enlarging memory arrays, this is not fast! ' + [STATICTOP, TOTAL_MEMORY]);
+ Module.printErr('Warning: Enlarging memory arrays, this is not fast! ' + [STATICTOP, TOTAL_MEMORY]);
assert(STATICTOP >= TOTAL_MEMORY);
assert(TOTAL_MEMORY > 4); // So the loop below will not be infinite
#endif
@@ -631,6 +592,7 @@ function enlargeMemory() {
HEAPU16 = new Uint16Array(buffer);
HEAPU32 = new Uint32Array(buffer);
HEAPF32 = new Float32Array(buffer);
+ HEAPF64 = new Float64Array(buffer);
HEAP8.set(oldHEAP8);
#endif
}
@@ -662,6 +624,7 @@ var FAST_MEMORY = Module['FAST_MEMORY'] || {{{ FAST_MEMORY }}};
HEAPU16 = new Uint16Array(buffer);
HEAPU32 = new Uint32Array(buffer);
HEAPF32 = new Float32Array(buffer);
+ HEAPF64 = new Float64Array(buffer);
// Endianness check (note: assumes compiler arch was little-endian)
HEAP32[0] = 255;
@@ -697,6 +660,7 @@ Module['HEAPU8'] = HEAPU8;
Module['HEAPU16'] = HEAPU16;
Module['HEAPU32'] = HEAPU32;
Module['HEAPF32'] = HEAPF32;
+Module['HEAPF64'] = HEAPF64;
#endif
STACK_ROOT = STACKTOP = Runtime.alignMemory(STATICTOP);
@@ -707,7 +671,7 @@ var tempDoublePtr = Runtime.alignMemory(STACK_MAX, 8);
var tempDoubleI8 = HEAP8.subarray(tempDoublePtr);
var tempDoubleI32 = HEAP32.subarray(tempDoublePtr >> 2);
var tempDoubleF32 = HEAPF32.subarray(tempDoublePtr >> 2);
-var tempDoubleF64 = new Float64Array(HEAP8.buffer).subarray(tempDoublePtr >> 3);
+var tempDoubleF64 = HEAPF64.subarray(tempDoublePtr >> 3);
function copyTempFloat(ptr) { // functions, because inlining this code is increases code size too much
tempDoubleI8[0] = HEAP8[ptr];
tempDoubleI8[1] = HEAP8[ptr+1];
@@ -741,12 +705,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__);
@@ -774,11 +741,14 @@ 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) {
+function TypedArray_copy(ptr, num, offset /*optional*/) {
// TODO: optimize this!
- var arr = new Uint8Array(num);
- for (var i = 0; i < num; ++i) {
- arr[i] = {{{ makeGetValue('ptr', 'i', 'i8') }}};
+ if (offset === undefined) {
+ offset = 0;
+ }
+ var arr = new Uint8Array(num - offset);
+ for (var i = offset; i < num; ++i) {
+ arr[i - offset] = {{{ makeGetValue('ptr', 'i', 'i8') }}};
}
return arr.buffer;
}
@@ -807,11 +777,14 @@ Module['String_copy'] = String_copy;
// 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
@@ -865,10 +838,36 @@ 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 }}}
{{{ reSign }}}
+// 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).
+var runDependencies = 0;
+function addRunDependency() {
+ runDependencies++;
+ if (Module['monitorRunDependencies']) {
+ Module['monitorRunDependencies'](runDependencies);
+ }
+}
+function removeRunDependency() {
+ runDependencies--;
+ if (Module['monitorRunDependencies']) {
+ Module['monitorRunDependencies'](runDependencies);
+ }
+ if (runDependencies == 0) run();
+}
+
// === Body ===