diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-12-07 18:42:02 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-12-07 18:42:02 -0800 |
commit | 2699ec8dbdb8a8a681c4f5b1ad5314debd6dd2d0 (patch) | |
tree | 50f4e8bcb7fcd1bfbc938468eafc85f85fa093ee | |
parent | ab399ca532fb1deb7607f6cc2feb01186d75ec2b (diff) |
clear setjmped when handling a longjmp, so we can proceed to longjmp later correctly; fixes #747
-rw-r--r-- | src/jsifier.js | 2 | ||||
-rwxr-xr-x | tests/runner.py | 52 |
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") |