aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-12-08 14:37:51 -0800
committerAlon Zakai <alonzakai@gmail.com>2012-12-08 14:37:51 -0800
commit037e8d20c096ccacbfb7d3a2d7a243bc9e11081d (patch)
tree1b0038077cbea88457122dc2230ee4ddb42b6a7c
parentb1da8a876bd06aa8409d8dcb5a325267ca63b9c3 (diff)
properly use identifier given to resume instruction, avoids issues with cxa_catch cleaning it up; fixes test_multiexception, the exception-handling part of #747
-rw-r--r--src/intertyper.js1
-rw-r--r--src/jsifier.js6
-rwxr-xr-xtests/runner.py2
3 files changed, 8 insertions, 1 deletions
diff --git a/src/intertyper.js b/src/intertyper.js
index 7db1a2fe..1d18c3cf 100644
--- a/src/intertyper.js
+++ b/src/intertyper.js
@@ -919,6 +919,7 @@ function intertyper(data, sidePass, baseLineNums) {
processItem: function(item) {
return [{
intertype: 'resume',
+ ident: toNiceIdent(item.tokens[2].text),
lineNum: item.lineNum
}];
}
diff --git a/src/jsifier.js b/src/jsifier.js
index 8b3c9683..47118d76 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -1036,8 +1036,12 @@ function JSify(data, functionsOnly, givenFunctions) {
return ret + ';';
});
makeFuncLineActor('resume', function(item) {
+ // exception pointer is from the ident (we can't reuse it from the original exception since cxa_end_catch might clean it up);
+ // type and destructor can be reused.
return (EXCEPTION_DEBUG ? 'Module.print("Resuming exception");' : '') +
- 'throw ' + makeGetValue('_llvm_eh_exception.buf', '0', 'void*') + ';';
+ '___cxa_throw(' + item.ident + '.f0, ' +
+ makeGetValue('_llvm_eh_exception.buf', Runtime.QUANTUM_SIZE, 'void*') + ',' +
+ makeGetValue('_llvm_eh_exception.buf', Runtime.QUANTUM_SIZE*2, 'void*') + ');';
});
makeFuncLineActor('invoke', function(item) {
// Wrapping in a function lets us easily return values if we are
diff --git a/tests/runner.py b/tests/runner.py
index 1f40ed70..723356c0 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -2377,8 +2377,10 @@ int main(int argc, char *argv[]) {
self.do_run(src, '''setjmp normal execution path, level: 0, prev_jmp: -1
setjmp normal execution path, level: 1, prev_jmp: 0
level is 2, perform longjmp!
+caught 1
setjmp exception execution path, level: 1, prev_jmp: 0
prev_jmp is not empty, continue with longjmp!
+caught 0
setjmp exception execution path, level: 0, prev_jmp: -1
Exiting setjmp function, level: 0, prev_jmp: -1
''')