diff options
-rw-r--r-- | AUTHORS | 12 | ||||
-rw-r--r-- | src/library.js | 16 | ||||
-rw-r--r-- | src/postamble.js | 12 | ||||
-rw-r--r-- | src/settings.js | 4 | ||||
-rw-r--r-- | tests/runner.py | 13 | ||||
-rw-r--r-- | tools/shared.py | 2 |
6 files changed, 46 insertions, 13 deletions
@@ -9,14 +9,4 @@ under the licensing terms detailed in LICENSE. * Benoit Tremblay <benoit.tremblay@frimastudio.com> * Andreas Bergmeier <andreas.bergmeier@gmx.net> * Ben Schwartz <bens@alum.mit.edu> - - - - - - - - - - - +* David Claughton <dave@eclecticdave.com> diff --git a/src/library.js b/src/library.js index 113c955c..1f63e6d0 100644 --- a/src/library.js +++ b/src/library.js @@ -1752,9 +1752,25 @@ LibraryManager.library = { _exit: function(status) { // void _exit(int status); // http://pubs.opengroup.org/onlinepubs/000095399/functions/exit.html + +#if CATCH_EXIT_CODE + function ExitStatus() { + this.name = "ExitStatus"; + this.message = "Program terminated with exit(" + status + ")"; + this.status = status; + }; + ExitStatus.prototype = new Error(); + ExitStatus.prototype.constructor = ExitStatus; +#endif + __shutdownRuntime__(); ABORT = true; + +#if CATCH_EXIT_CODE + throw new ExitStatus(); +#else throw 'exit(' + status + ') called, at ' + new Error().stack; +#endif }, fork__deps: ['__setErrNo', '$ERRNO_CODES'], fork: function() { diff --git a/src/postamble.js b/src/postamble.js index c8fd44bd..51ffc6ee 100644 --- a/src/postamble.js +++ b/src/postamble.js @@ -17,7 +17,14 @@ Module.callMain = function callMain(args) { argv.push(0); argv = allocate(argv, 'i32', ALLOC_STATIC); +#if CATCH_EXIT_CODE + try { + return _main(argc, argv, 0); + } + catch(e) { if (e.name == "ExitStatus") return e.status; throw e; } +#else return _main(argc, argv, 0); +#endif } {{GLOBAL_VARS}} @@ -49,7 +56,10 @@ Module['noInitialRun'] = true; #endif if (!Module['noInitialRun']) { - run(); + var ret = run(); +#if CATCH_EXIT_CODE + print('Exit Status: ' + ret); +#endif } // {{POST_RUN_ADDITIONS}} diff --git a/src/settings.js b/src/settings.js index bcda4757..66762298 100644 --- a/src/settings.js +++ b/src/settings.js @@ -77,6 +77,10 @@ var CLOSURE_INLINE_PREVENTION_LINES = 50; // Functions of this number of lines o // code generated that tells the closure compiler not to // inline them. This is useful to prevent the generation of // overly large functions. +var CATCH_EXIT_CODE = 0; // If set, causes exit() to throw an exception object which is caught + // in a try..catch block and results in the exit status being + // returned from run(). If zero (the default), the program is just + // terminated with an error message. // Generated code debugging options var SAFE_HEAP = 0; // Check each write to the heap against a list of blocked addresses diff --git a/tests/runner.py b/tests/runner.py index ea2025b7..bd01d6d2 100644 --- a/tests/runner.py +++ b/tests/runner.py @@ -4533,6 +4533,19 @@ Child2:9 except: pass + def test_exit_status(self): + Settings.CATCH_EXIT_CODE = 1 + + src = ''' + #include <stdio.h> + #include <stdlib.h> + int main() + { + printf("hello, world!\\n"); + exit(118); // Unusual exit status to make sure it's working! + } + ''' + self.do_run(src, 'hello, world!\nExit Status: 118') # Generate tests for all our compilers def make_run(name, compiler, llvm_opts, embetter, quantum_size, typed_arrays): diff --git a/tools/shared.py b/tools/shared.py index 06c69f83..f6a03c6c 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -275,7 +275,7 @@ class Building: # Run Emscripten exported_settings = {} - for setting in ['QUANTUM_SIZE', 'RELOOP', 'MICRO_OPTS', 'ASSERTIONS', 'USE_TYPED_ARRAYS', 'SAFE_HEAP', 'CHECK_OVERFLOWS', 'CORRECT_OVERFLOWS', 'CORRECT_SIGNS', 'CHECK_SIGNS', 'CORRECT_OVERFLOWS_LINES', 'CORRECT_SIGNS_LINES', 'CORRECT_ROUNDINGS', 'CORRECT_ROUNDINGS_LINES', 'INVOKE_RUN', 'SAFE_HEAP_LINES', 'INIT_STACK', 'PGO', 'EXPORTED_FUNCTIONS', 'EXPORTED_GLOBALS', 'BUILD_AS_SHARED_LIB', 'INCLUDE_FULL_LIBRARY', 'RUNTIME_TYPE_INFO', 'DISABLE_EXCEPTION_CATCHING', 'TOTAL_MEMORY', 'FAST_MEMORY', 'EXCEPTION_DEBUG', 'PROFILE', 'I64_MODE', 'EMULATE_UNALIGNED_ACCESSES']: + for setting in ['QUANTUM_SIZE', 'RELOOP', 'MICRO_OPTS', 'ASSERTIONS', 'USE_TYPED_ARRAYS', 'SAFE_HEAP', 'CHECK_OVERFLOWS', 'CORRECT_OVERFLOWS', 'CORRECT_SIGNS', 'CHECK_SIGNS', 'CORRECT_OVERFLOWS_LINES', 'CORRECT_SIGNS_LINES', 'CORRECT_ROUNDINGS', 'CORRECT_ROUNDINGS_LINES', 'INVOKE_RUN', 'SAFE_HEAP_LINES', 'INIT_STACK', 'PGO', 'EXPORTED_FUNCTIONS', 'EXPORTED_GLOBALS', 'BUILD_AS_SHARED_LIB', 'INCLUDE_FULL_LIBRARY', 'RUNTIME_TYPE_INFO', 'DISABLE_EXCEPTION_CATCHING', 'TOTAL_MEMORY', 'FAST_MEMORY', 'EXCEPTION_DEBUG', 'PROFILE', 'I64_MODE', 'EMULATE_UNALIGNED_ACCESSES', 'CATCH_EXIT_CODE']: try: value = eval('Settings.' + setting) if value is not None: |