diff options
Diffstat (limited to 'src/postamble.js')
-rw-r--r-- | src/postamble.js | 162 |
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}} |