aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-12-07 18:42:02 -0800
committerAlon Zakai <alonzakai@gmail.com>2012-12-07 18:42:02 -0800
commit2699ec8dbdb8a8a681c4f5b1ad5314debd6dd2d0 (patch)
tree50f4e8bcb7fcd1bfbc938468eafc85f85fa093ee
parentab399ca532fb1deb7607f6cc2feb01186d75ec2b (diff)
clear setjmped when handling a longjmp, so we can proceed to longjmp later correctly; fixes #747
-rw-r--r--src/jsifier.js2
-rwxr-xr-xtests/runner.py52
2 files changed, 53 insertions, 1 deletions
diff --git a/src/jsifier.js b/src/jsifier.js
index ce094e1e..d4d60cee 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -639,7 +639,7 @@ function JSify(data, functionsOnly, givenFunctions) {
}).join('\n');
ret += '\n' + indent + ' default: assert(0, "bad label: " + label);\n' + indent + '}';
if (func.setjmpTable) {
- ret += ' } catch(e) { if (!setjmped) throw(e); if (!e.longjmp) throw(e); setjmpTable[e.label](e.value) }';
+ ret += ' } catch(e) { if (!setjmped) throw(e); setjmped = false; if (!e.longjmp) throw(e); setjmpTable[e.label](e.value) }';
}
} else {
ret += (SHOW_LABELS ? indent + '/* ' + block.entries[0] + ' */' : '') + '\n' + getLabelLines(block.labels[0], indent);
diff --git a/tests/runner.py b/tests/runner.py
index 1480afe7..a3197bc7 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -2078,6 +2078,58 @@ Setjmp error execution path, level: 0
Exiting stack_manipulate_func, level: 0
''')
+ def test_longjmp3(self):
+ src = r'''
+ #include <setjmp.h>
+ #include <stdio.h>
+
+ typedef struct {
+ jmp_buf* jmp;
+ } jmp_state;
+
+ void setjmp_func(jmp_state* s, int level) {
+ jmp_buf* prev_jmp = s->jmp;
+ jmp_buf c_jmp;
+
+ if (level == 2) {
+ printf("level is 2, perform longjmp!\n");
+ longjmp(*(s->jmp), 1);
+ }
+
+ if (setjmp(c_jmp) == 0) {
+ printf("setjmp normal execution path, level: %d\n", level);
+ s->jmp = &c_jmp;
+ setjmp_func(s, level + 1);
+ } else {
+ printf("setjmp exception execution path, level: %d\n", level);
+ if (prev_jmp) {
+ printf("prev_jmp is not empty, continue with longjmp!\n");
+ s->jmp = prev_jmp;
+ longjmp(*(s->jmp), 1);
+ }
+ }
+
+ printf("Exiting setjmp function, level: %d\n", level);
+ }
+
+ int main(int argc, char *argv[]) {
+ jmp_state s;
+ s.jmp = NULL;
+
+ setjmp_func(&s, 0);
+
+ return 0;
+ }
+ '''
+ self.do_run(src, '''setjmp normal execution path, level: 0
+setjmp normal execution path, level: 1
+level is 2, perform longjmp!
+setjmp exception execution path, level: 1
+prev_jmp is not empty, continue with longjmp!
+setjmp exception execution path, level: 0
+Exiting setjmp function, level: 0
+''')
+
def test_exceptions(self):
if Settings.QUANTUM_SIZE == 1: return self.skip("we don't support libcxx in q1")