aboutsummaryrefslogtreecommitdiff
path: root/src/postamble.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/postamble.js')
-rw-r--r--src/postamble.js162
1 files changed, 118 insertions, 44 deletions
diff --git a/src/postamble.js b/src/postamble.js
index 49fd9b3e..382d3117 100644
--- a/src/postamble.js
+++ b/src/postamble.js
@@ -1,12 +1,55 @@
// === Auto-generated postamble setup entry stuff ===
-Module['callMain'] = function callMain(args) {
+if (memoryInitializer) {
+ function applyData(data) {
+#if USE_TYPED_ARRAYS == 2
+ HEAPU8.set(data, STATIC_BASE);
+#else
+ allocate(data, 'i8', ALLOC_NONE, STATIC_BASE);
+#endif
+ }
+ if (ENVIRONMENT_IS_NODE || ENVIRONMENT_IS_SHELL) {
+ applyData(Module['readBinary'](memoryInitializer));
+ } else {
+ addRunDependency('memory initializer');
+ Browser.asyncLoad(memoryInitializer, function(data) {
+ applyData(data);
+ removeRunDependency('memory initializer');
+ }, function(data) {
+ throw 'could not load memory initializer ' + memoryInitializer;
+ });
+ }
+}
+
+function ExitStatus(status) {
+ this.name = "ExitStatus";
+ this.message = "Program terminated with exit(" + status + ")";
+ this.status = status;
+};
+ExitStatus.prototype = new Error();
+ExitStatus.prototype.constructor = ExitStatus;
+
+var initialStackTop;
+var preloadStartTime = null;
+var calledMain = false;
+
+dependenciesFulfilled = function runCaller() {
+ // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
+ if (!Module['calledRun'] && shouldRunNow) run();
+ if (!Module['calledRun']) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
+}
+
+Module['callMain'] = Module.callMain = function callMain(args) {
assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on __ATMAIN__)');
- assert(!Module['preRun'] || Module['preRun'].length == 0, 'cannot call main when preRun functions remain to be called');
+ assert(__ATPRERUN__.length == 0, 'cannot call main when preRun functions remain to be called');
args = args || [];
+ if (ENVIRONMENT_IS_WEB && preloadStartTime !== null) {
+ Module.printErr('preload time: ' + (Date.now() - preloadStartTime) + ' ms');
+ }
+
ensureInitRuntime();
var argc = args.length+1;
@@ -24,33 +67,40 @@ Module['callMain'] = function callMain(args) {
argv.push(0);
argv = allocate(argv, 'i32', ALLOC_NORMAL);
+ initialStackTop = STACKTOP;
+
+ try {
#if BENCHMARK
- var start = Date.now();
+ var start = Date.now();
#endif
- var ret;
+ var ret = Module['_main'](argc, argv, 0);
- var initialStackTop = STACKTOP;
- try {
- ret = Module['_main'](argc, argv, 0);
+#if BENCHMARK
+ Module.realPrint('main() took ' + (Date.now() - start) + ' milliseconds');
+#endif
+
+ // if we're not running an evented main loop, it's time to exit
+ if (!Module['noExitRuntime']) {
+ exit(ret);
+ }
}
catch(e) {
- if (e.name == 'ExitStatus') {
- return e.status;
+ if (e instanceof ExitStatus) {
+ // exit() throws this once it's done to make sure execution
+ // has been stopped completely
+ return;
} else if (e == 'SimulateInfiniteLoop') {
+ // running an evented main loop, don't immediately exit
Module['noExitRuntime'] = true;
+ return;
} else {
+ if (e && typeof e === 'object' && e.stack) Module.printErr('exception thrown: ' + [e, e.stack]);
throw e;
}
} finally {
- STACKTOP = initialStackTop;
+ calledMain = true;
}
-
-#if BENCHMARK
- Module.realPrint('main() took ' + (Date.now() - start) + ' milliseconds');
-#endif
-
- return ret;
}
{{GLOBAL_VARS}}
@@ -58,44 +108,31 @@ Module['callMain'] = function callMain(args) {
function run(args) {
args = args || Module['arguments'];
+ if (preloadStartTime === null) preloadStartTime = Date.now();
+
if (runDependencies > 0) {
Module.printErr('run() called, but dependencies remain, so not running');
- return 0;
+ return;
}
- if (Module['preRun']) {
- if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];
- var toRun = Module['preRun'];
- Module['preRun'] = [];
- for (var i = toRun.length-1; i >= 0; i--) {
- toRun[i]();
- }
- if (runDependencies > 0) {
- // a preRun added a dependency, run will be called later
- return 0;
- }
- }
+ preRun();
+
+ if (runDependencies > 0) return; // a preRun added a dependency, run will be called later
+ if (Module['calledRun']) return; // run may have just been called through dependencies being fulfilled just in this very frame
function doRun() {
+ if (Module['calledRun']) return; // run may have just been called while the async setStatus time below was happening
+ Module['calledRun'] = true;
+
ensureInitRuntime();
preMain();
- var ret = 0;
- calledRun = true;
if (Module['_main'] && shouldRunNow) {
- ret = Module['callMain'](args);
- if (!Module['noExitRuntime']) {
- exitRuntime();
- }
- }
- if (Module['postRun']) {
- if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']];
- while (Module['postRun'].length > 0) {
- Module['postRun'].pop()();
- }
+ Module['callMain'](args);
}
- return ret;
+
+ postRun();
}
if (Module['setStatus']) {
@@ -106,13 +143,46 @@ function run(args) {
}, 1);
if (!ABORT) doRun();
}, 1);
- return 0;
} else {
- return doRun();
+ doRun();
}
}
Module['run'] = Module.run = run;
+function exit(status) {
+ ABORT = true;
+ EXITSTATUS = status;
+ STACKTOP = initialStackTop;
+
+ // exit the runtime
+ exitRuntime();
+
+ // TODO We should handle this differently based on environment.
+ // In the browser, the best we can do is throw an exception
+ // to halt execution, but in node we could process.exit and
+ // I'd imagine SM shell would have something equivalent.
+ // This would let us set a proper exit status (which
+ // would be great for checking test exit statuses).
+ // https://github.com/kripken/emscripten/issues/1371
+
+ // throw an exception to halt the current execution
+ throw new ExitStatus(status);
+}
+Module['exit'] = Module.exit = exit;
+
+function abort(text) {
+ if (text) {
+ Module.print(text);
+ Module.printErr(text);
+ }
+
+ ABORT = true;
+ EXITSTATUS = 1;
+
+ throw 'abort() at ' + stackTrace();
+}
+Module['abort'] = Module.abort = abort;
+
// {{PRE_RUN_ADDITIONS}}
if (Module['preInit']) {
@@ -132,6 +202,10 @@ if (Module['noInitialRun']) {
shouldRunNow = false;
}
+#if NO_EXIT_RUNTIME
+Module["noExitRuntime"] = true;
+#endif
+
run();
// {{POST_RUN_ADDITIONS}}