aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-05-21 15:41:23 -0700
committerAlon Zakai <alonzakai@gmail.com>2013-05-21 15:41:23 -0700
commitbf07641793f10e7c6a003cb8ab4918c4472975a1 (patch)
tree5b07b59aab4f28d01b6bf3953462230f9beace39
parent7102046e02fdc97ce7197302b20d50497b3980f0 (diff)
parent91a245c47ea0c371aa19b8a7c1f2904bd75d5c6c (diff)
Merge pull request #1195 from inolen/longjmp_signed
trigger setjmp on negative values
-rw-r--r--src/jsifier.js2
-rwxr-xr-xtests/runner.py24
2 files changed, 16 insertions, 10 deletions
diff --git a/src/jsifier.js b/src/jsifier.js
index 3f52337f..c1bf1e1a 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -1489,7 +1489,7 @@ function JSify(data, functionsOnly, givenFunctions) {
if (ASM_JS && funcData.setjmpTable) {
// check if a longjmp was done. If a setjmp happened, check if ours. If ours, go to -111 to handle it.
// otherwise, just return - the call to us must also have been an invoke, so the setjmp propagates that way
- ret += '; if (((__THREW__|0) != 0) & ((threwValue|0) > 0)) { setjmpLabel = ' + asmCoercion('_testSetjmp(' + makeGetValue('__THREW__', 0, 'i32') + ', setjmpTable)', 'i32') + '; if ((setjmpLabel|0) > 0) { label = -1111; break } else return ' + (funcData.returnType != 'void' ? asmCoercion('0', funcData.returnType) : '') + ' } __THREW__ = threwValue = 0;\n';
+ ret += '; if (((__THREW__|0) != 0) & ((threwValue|0) !== 0)) { setjmpLabel = ' + asmCoercion('_testSetjmp(' + makeGetValue('__THREW__', 0, 'i32') + ', setjmpTable)', 'i32') + '; if ((setjmpLabel|0) > 0) { label = -1111; break } else return ' + (funcData.returnType != 'void' ? asmCoercion('0', funcData.returnType) : '') + ' } __THREW__ = threwValue = 0;\n';
}
return ret;
diff --git a/tests/runner.py b/tests/runner.py
index 37fb2bbb..9ec2f57d 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -2452,28 +2452,34 @@ returned |umber one top notchfi FI FO FUM WHEN WHERE WHY HOW WHO|''', ['wowie',
static jmp_buf buf;
void second(void) {
- printf("second\n"); // prints
- longjmp(buf,1); // jumps back to where setjmp was called - making setjmp now return 1
+ printf("second\n");
+ longjmp(buf,-1);
}
void first(void) {
- second();
- printf("first\n"); // does not print
+ printf("first\n"); // prints
+ longjmp(buf,1); // jumps back to where setjmp was called - making setjmp now return 1
}
int main() {
volatile int x = 0;
- if ( ! setjmp(buf) ) {
+ int jmpval = setjmp(buf);
+ if (!jmpval) {
+ x++; // should be properly restored once longjmp jumps back
+ first(); // when executed, setjmp returns 1
+ printf("skipped\n"); // does not print
+ } else if (jmpval == 1) { // when first() jumps back, setjmp returns 1
+ printf("result: %d %d\n", x, jmpval); // prints
x++;
- first(); // when executed, setjmp returns 0
- } else { // when longjmp jumps back, setjmp returns 1
- printf("main: %d\n", x); // prints
+ second(); // when executed, setjmp returns -1
+ } else if (jmpval == -1) { // when second() jumps back, setjmp returns -1
+ printf("result: %d %d\n", x, jmpval); // prints
}
return 0;
}
'''
- self.do_run(src, 'second\nmain: 1\n')
+ self.do_run(src, 'first\nresult: 1 1\nsecond\nresult: 2 -1')
def test_longjmp2(self):
src = r'''