diff options
author | Anthony Pesch <inolen@gmail.com> | 2013-07-29 16:03:01 -0700 |
---|---|---|
committer | Anthony Pesch <inolen@gmail.com> | 2013-07-29 21:35:02 -0700 |
commit | 908e87a0a6fa87c03108b627ee85592922b778fa (patch) | |
tree | 734d00002b2bc9ff9b34fca2abe550700906fa3d | |
parent | 9987b9a039052cb84f33127e5b2c3df58f349d7c (diff) |
- remove code that attempts to propogate _main's exit status through returns. we can't rely on that, the status must be signaled through an event to support both sync / async applications.
- consolidate exit functionality
- moved exitRuntime to callMain
-rw-r--r-- | src/library.js | 18 | ||||
-rw-r--r-- | src/postamble.js | 67 | ||||
-rw-r--r-- | src/preamble.js | 6 |
3 files changed, 53 insertions, 38 deletions
diff --git a/src/library.js b/src/library.js index e650a545..895b5d55 100644 --- a/src/library.js +++ b/src/library.js @@ -2144,20 +2144,7 @@ LibraryManager.library = { _exit: function(status) { // void _exit(int status); // http://pubs.opengroup.org/onlinepubs/000095399/functions/exit.html - - function ExitStatus() { - this.name = "ExitStatus"; - this.message = "Program terminated with exit(" + status + ")"; - this.status = status; - Module.print('Exit Status: ' + status); - }; - ExitStatus.prototype = new Error(); - ExitStatus.prototype.constructor = ExitStatus; - - exitRuntime(); - ABORT = true; - - throw new ExitStatus(); + Module['exit'](status); }, fork__deps: ['__setErrNo', '$ERRNO_CODES'], fork: function() { @@ -3922,8 +3909,7 @@ LibraryManager.library = { __cxa_atexit: 'atexit', abort: function() { - ABORT = true; - throw 'abort() at ' + (new Error().stack); + Module['abort'](); }, bsearch: function(key, base, num, size, compar) { diff --git a/src/postamble.js b/src/postamble.js index 49fd9b3e..2a6885d4 100644 --- a/src/postamble.js +++ b/src/postamble.js @@ -1,6 +1,9 @@ // === Auto-generated postamble setup entry stuff === +var initialStackTop; +var inMain; + 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'); @@ -28,29 +31,36 @@ 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 == 'Exited') { + // 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; } 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,7 +70,7 @@ function run(args) { if (runDependencies > 0) { Module.printErr('run() called, but dependencies remain, so not running'); - return 0; + return; } if (Module['preRun']) { @@ -72,7 +82,7 @@ function run(args) { } if (runDependencies > 0) { // a preRun added a dependency, run will be called later - return 0; + return; } } @@ -81,13 +91,9 @@ function run(args) { preMain(); - var ret = 0; calledRun = true; if (Module['_main'] && shouldRunNow) { - ret = Module['callMain'](args); - if (!Module['noExitRuntime']) { - exitRuntime(); - } + Module['callMain'](args); } if (Module['postRun']) { if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']]; @@ -95,7 +101,6 @@ function run(args) { Module['postRun'].pop()(); } } - return ret; } if (Module['setStatus']) { @@ -106,13 +111,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 'Exited'; + } +} +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']) { diff --git a/src/preamble.js b/src/preamble.js index 218e0388..f1a0de4c 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -242,12 +242,6 @@ var tempI64, tempI64b; var tempRet0, tempRet1, tempRet2, tempRet3, tempRet4, tempRet5, tempRet6, tempRet7, tempRet8, tempRet9; #endif -function abort(text) { - Module.print(text + ':\n' + (new Error).stack); - ABORT = true; - throw "Assertion: " + text; -} - function assert(condition, text) { if (!condition) { abort('Assertion failed: ' + text); |