Skip to content

Commit

Permalink
Fix for longjmp(.., 0) under wasm EH
Browse files Browse the repository at this point in the history
Fixes: #21486
  • Loading branch information
sbc100 committed Mar 8, 2024
1 parent cf81dbe commit 1ca5f72
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 0 deletions.
8 changes: 8 additions & 0 deletions system/lib/compiler-rt/emscripten_setjmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,14 @@ thread_local struct __WasmLongjmpArgs __wasm_longjmp_args;
// TODO Consider switching to throwing two values at the same time later.
void __wasm_longjmp(void *env, int val) {
__wasm_longjmp_args.env = env;
/*
 * C standard:
 * The longjmp function cannot cause the setjmp macro to return
 * the value 0; if val is 0, the setjmp macro returns the value 1.
 */
if (val == 0) {
val = 1;
}
__wasm_longjmp_args.val = val;
__builtin_wasm_throw(C_LONGJMP, &__wasm_longjmp_args);
}
Expand Down
27 changes: 27 additions & 0 deletions test/core/test_longjmp_zero.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright 2016 The Emscripten Authors. All rights reserved.
* Emscripten is available under two separate licenses, the MIT license and the
* University of Illinois/NCSA Open Source License. Both these licenses can be
* found in the LICENSE file.
*/

#include <stdio.h>
#include <setjmp.h>

int main() {
printf("start\n");
jmp_buf b1;
int val = setjmp(b1);
if (val) {
printf("success\n");
return 0;
}
/*
* C standard:
* > The longjmp function cannot cause the setjmp macro to return
* > the value 0; if val is 0, the setjmp macro returns the value 1.
*/
longjmp(b1, 0);
__builtin_trap();
return 0;
}
2 changes: 2 additions & 0 deletions test/core/test_longjmp_zero.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
start
success
4 changes: 4 additions & 0 deletions test/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,10 @@ def test_longjmp_standalone(self):
def test_longjmp(self):
self.do_core_test('test_longjmp.c')

@with_both_sjlj
def test_longjmp_zero(self):
self.do_core_test('test_longjmp_zero.c')

def test_longjmp_with_and_without_exceptions(self):
# Emscripten SjLj with and without Emscripten EH support
self.set_setting('SUPPORT_LONGJMP', 'emscripten')
Expand Down

0 comments on commit 1ca5f72

Please sign in to comment.