Skip to content

Commit a866e7a

Browse files
committed
Fix for longjmp(.., 0) under wasm EH
Fixes: emscripten-core#21486
1 parent 34d8a98 commit a866e7a

File tree

4 files changed

+43
-0
lines changed

4 files changed

+43
-0
lines changed

system/lib/compiler-rt/emscripten_setjmp.c

+8
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,14 @@ thread_local struct __WasmLongjmpArgs __wasm_longjmp_args;
9090
// TODO Consider switching to throwing two values at the same time later.
9191
void __wasm_longjmp(void *env, int val) {
9292
__wasm_longjmp_args.env = env;
93+
/*
94+
 * C standard:
95+
 * The longjmp function cannot cause the setjmp macro to return
96+
 * the value 0; if val is 0, the setjmp macro returns the value 1.
97+
 */
98+
if (val == 0) {
99+
val = 1;
100+
}
93101
__wasm_longjmp_args.val = val;
94102
__builtin_wasm_throw(C_LONGJMP, &__wasm_longjmp_args);
95103
}

test/core/test_longjmp_zero.c

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright 2016 The Emscripten Authors. All rights reserved.
3+
* Emscripten is available under two separate licenses, the MIT license and the
4+
* University of Illinois/NCSA Open Source License. Both these licenses can be
5+
* found in the LICENSE file.
6+
*/
7+
8+
#include <stdio.h>
9+
#include <setjmp.h>
10+
11+
int main() {
12+
printf("start\n");
13+
jmp_buf b1;
14+
int val = setjmp(b1);
15+
if (val) {
16+
printf("success\n");
17+
return 0;
18+
}
19+
/*
20+
* C standard:
21+
* > The longjmp function cannot cause the setjmp macro to return
22+
* > the value 0; if val is 0, the setjmp macro returns the value 1.
23+
*/
24+
printf("longjmp\n");
25+
longjmp(b1, 0);
26+
__builtin_trap();
27+
return 0;
28+
}

test/core/test_longjmp_zero.out

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
start
2+
longjmp
3+
success

test/test_core.py

+4
Original file line numberDiff line numberDiff line change
@@ -892,6 +892,10 @@ def test_longjmp_standalone(self):
892892
def test_longjmp(self):
893893
self.do_core_test('test_longjmp.c')
894894

895+
@with_both_sjlj
896+
def test_longjmp_zero(self):
897+
self.do_core_test('test_longjmp_zero.c')
898+
895899
def test_longjmp_with_and_without_exceptions(self):
896900
# Emscripten SjLj with and without Emscripten EH support
897901
self.set_setting('SUPPORT_LONGJMP', 'emscripten')

0 commit comments

Comments
 (0)