diff options
Diffstat (limited to 'src/postamble.js')
-rw-r--r-- | src/postamble.js | 94 |
1 files changed, 60 insertions, 34 deletions
diff --git a/src/postamble.js b/src/postamble.js index 49fd9b3e..25a50bfc 100644 --- a/src/postamble.js +++ b/src/postamble.js @@ -1,9 +1,12 @@ // === Auto-generated postamble setup entry stuff === -Module['callMain'] = function callMain(args) { +var initialStackTop; +var inMain; + +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 || []; @@ -28,29 +31,37 @@ Module['callMain'] = function callMain(args) { var start = Date.now(); #endif - var ret; + initialStackTop = STACKTOP; + inMain = true; - var initialStackTop = STACKTOP; + var ret; try { ret = Module['_main'](argc, argv, 0); } catch(e) { - if (e.name == 'ExitStatus') { - return e.status; + if (e && typeof e == 'object' && e.type == 'ExitStatus') { + // exit() throws this once it's done to make sure execution + // has been stopped completely + Module.print('Exit Status: ' + e.value); + return e.value; } else if (e == 'SimulateInfiniteLoop') { + // running an evented main loop, don't immediately exit Module['noExitRuntime'] = true; } else { throw e; } } finally { - STACKTOP = initialStackTop; + inMain = false; } #if BENCHMARK Module.realPrint('main() took ' + (Date.now() - start) + ' milliseconds'); #endif - return ret; + // if we're not running an evented main loop, it's time to exit + if (!Module['noExitRuntime']) { + exit(ret); + } } {{GLOBAL_VARS}} @@ -60,20 +71,14 @@ function run(args) { 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) { + // a preRun added a dependency, run will be called later + return; } function doRun() { @@ -81,21 +86,12 @@ function run(args) { 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 +102,43 @@ function run(args) { }, 1); if (!ABORT) doRun(); }, 1); - return 0; } else { - return doRun(); + doRun(); } } Module['run'] = Module.run = run; +function exit(status) { + ABORT = true; + STACKTOP = initialStackTop; + + // TODO call externally added 'exit' callbacks with the status code. + // It'd be nice to provide the same interface for all Module events (e.g. + // prerun, premain, postmain). Perhaps an EventEmitter so we can do: + // Module.on('exit', function (status) {}); + + // exit the runtime + exitRuntime(); + + if (inMain) { + // if we're still inside the callMain's try/catch, we need to throw an + // exception in order to immediately terminate execution. + throw { type: 'ExitStatus', value: status }; + } +} +Module['exit'] = Module.exit = exit; + +function abort(text) { + if (text) { + Module.print(text); + } + + ABORT = true; + + throw 'abort() at ' + (new Error().stack); +} +Module['abort'] = Module.abort = abort; + // {{PRE_RUN_ADDITIONS}} if (Module['preInit']) { |