diff options
-rw-r--r-- | src/postamble.js | 4 | ||||
-rw-r--r-- | src/settings.js | 4 | ||||
-rwxr-xr-x | tests/runner.py | 47 |
3 files changed, 54 insertions, 1 deletions
diff --git a/src/postamble.js b/src/postamble.js index 83a4daa6..5f541733 100644 --- a/src/postamble.js +++ b/src/postamble.js @@ -18,10 +18,14 @@ Module.callMain = function callMain(args) { argv = allocate(argv, 'i32', ALLOC_STATIC); #if CATCH_EXIT_CODE + var initialStackTop = STACKTOP; try { return Module['_main'](argc, argv, 0); } catch(e) { if (e.name == "ExitStatus") return e.status; throw e; } + finally { + STACKTOP = initialStackTop; + } #else return Module['_main'](argc, argv, 0); #endif diff --git a/src/settings.js b/src/settings.js index 84d64167..11af4692 100644 --- a/src/settings.js +++ b/src/settings.js @@ -118,7 +118,9 @@ var INLINING_LIMIT = 50; // A limit on inlining. If 0, we will inline normally i 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. + // terminated with an error message, that is, the exception thrown + // by exit() is not handled in any way (in particular, the stack + // position will not be reset). // Generated code debugging options var SAFE_HEAP = 0; // Check each write to the heap, for example, this will give a clear diff --git a/tests/runner.py b/tests/runner.py index e55a3f60..742ddf1f 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -2471,6 +2471,53 @@ setjmp exception execution path, level: 0, prev_jmp: -1 Exiting setjmp function, level: 0, prev_jmp: -1 ''') + def test_exit_stack(self): + if self.emcc_args is None: return self.skip('requires emcc') + if Settings.ASM_JS: return self.skip('uses report_stack without exporting') + + Settings.CATCH_EXIT_CODE = 1 + + src = r''' + #include <stdio.h> + #include <stdlib.h> + + extern "C" { + extern void report_stack(int x); + } + + char moar() { + char temp[125]; + for (int i = 0; i < 125; i++) temp[i] = i*i; + for (int i = 1; i < 125; i++) temp[i] += temp[i-1]/2; + if (temp[100] != 99) exit(1); + return temp[120]; + } + + int main(int argc, char *argv[]) { + report_stack((int)alloca(4)); + printf("*%d*\n", moar()); + return 0; + } + ''' + + open(os.path.join(self.get_dir(), 'pre.js'), 'w').write(''' + var initialStack = -1; + var _report_stack = function(x) { + Module.print('reported'); + initialStack = x; + } + var Module = { + postRun: function() { + Module.print('postRun'); + assert(initialStack == STACKTOP, [initialStack, STACKTOP]); + Module.print('ok.'); + } + }; + ''') + + self.emcc_args += ['--pre-js', 'pre.js'] + self.do_run(src, '''reported\npostRun\nok.\nExit Status: 1\n''') + def test_class(self): src = ''' #include <stdio.h> |