Skip to content

Commit cf2e64c

Browse files
authored
[SjLj] Enable Wasm SjLj with -sSUPPORT_LONGJMP=wasm (#16111)
Because currently `DISABLE_EXCEPTION_THROWING` is 0 by default, which enables Emscripten EH exception throwing, to use Wasm SjLj, you need to specify both options, which is inconvenient and unintuitive: ``` emcc -sSUPPORT_LONGJMP=wasm -sDISABLE_EXCEPTION_THROWING=1 test.c ``` So far we've errored out when `SUPPORT_LONGJMP=wasm` was given with either `DISABLE_EXCEPTION_CATCHING=0` or `DISABLE_EXCEPTION_THROWING=0`. But unlike `DISABLE_EXCEPTION_CATCHING`, which is 1 by default and you have to explicitly disable it to make it 0, `DISABLE_EXCEPTION_THROWING` is 0 by default so you always have to turn it off when we use Wasm SjLj, which is very inconvenient. This PR automatically sets `DISABLE_EXCEPTION_THROWING` to 1 when `SUPPORT_LONGJMP` is `wasm`.
1 parent df352fc commit cf2e64c

File tree

3 files changed

+34
-19
lines changed

3 files changed

+34
-19
lines changed

emcc.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,10 +1441,17 @@ def default_setting(name, new_default):
14411441

14421442
# Wasm SjLj cannot be used with Emscripten EH
14431443
if settings.SUPPORT_LONGJMP == 'wasm':
1444+
# DISABLE_EXCEPTION_THROWING is 0 by default for Emscripten EH throwing, but
1445+
# Wasm SjLj cannot be used with Emscripten EH. We error out if
1446+
# DISABLE_EXCEPTION_THROWING=0 is explicitly requested by the user;
1447+
# otherwise we disable it here.
1448+
default_setting('DISABLE_EXCEPTION_THROWING', 1)
1449+
if not settings.DISABLE_EXCEPTION_THROWING:
1450+
exit_with_error('SUPPORT_LONGJMP=wasm cannot be used with DISABLE_EXCEPTION_CATCHING=0')
1451+
# We error out for DISABLE_EXCEPTION_CATCHING=0, because it is 1 by default
1452+
# and this can be 0 only if the user specifies so.
14441453
if not settings.DISABLE_EXCEPTION_CATCHING:
14451454
exit_with_error('SUPPORT_LONGJMP=wasm cannot be used with DISABLE_EXCEPTION_CATCHING=0')
1446-
if not settings.DISABLE_EXCEPTION_THROWING:
1447-
exit_with_error('SUPPORT_LONGJMP=wasm cannot be used with DISABLE_EXCEPTION_THROWING=0')
14481455

14491456
return (newargs, input_files)
14501457

src/settings.js

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -655,8 +655,10 @@ var ENVIRONMENT = 'web,webview,worker,node';
655655
var LZ4 = 0;
656656

657657
// Emscripten exception handling options.
658-
// These options only pertain to Emscripten exception handling and do not
659-
// control the experimental native wasm exception handling option.
658+
// The three options below (DISABLE_EXCEPTION_CATCHING,
659+
// EXCEPTION_CATCHING_ALLOWED, and DISABLE_EXCEPTION_THROWING) only pertain to
660+
// Emscripten exception handling and do not control the experimental native wasm
661+
// exception handling option (EXCEPTION_HANDLING).
660662

661663
// Disables generating code to actually catch exceptions. This disabling is on
662664
// by default as the overhead of exceptions is quite high in size and speed
@@ -683,6 +685,21 @@ var DISABLE_EXCEPTION_CATCHING = 1;
683685
// [compile+link] - affects user code at compile and system libraries at link
684686
var EXCEPTION_CATCHING_ALLOWED = [];
685687

688+
// Internal: Tracks whether Emscripten should link in exception throwing (C++
689+
// 'throw') support library. This does not need to be set directly, but pass
690+
// -fno-exceptions to the build disable exceptions support. (This is basically
691+
// -fno-exceptions, but checked at final link time instead of individual .cpp
692+
// file compile time) If the program *does* contain throwing code (some source
693+
// files were not compiled with `-fno-exceptions`), and this flag is set at link
694+
// time, then you will get errors on undefined symbols, as the exception
695+
// throwing code is not linked in. If so you should either unset the option (if
696+
// you do want exceptions) or fix the compilation of the source files so that
697+
// indeed no exceptions are used).
698+
// TODO(sbc): Move to settings_internal (current blocked due to use in test
699+
// code).
700+
// [link]
701+
var DISABLE_EXCEPTION_THROWING = 0;
702+
686703
// By default we handle exit() in node, by catching the Exit exception. However,
687704
// this means we catch all process exceptions. If you disable this, then we no
688705
// longer do that, and exceptions work normally, which can be useful for libraries
@@ -1817,21 +1834,6 @@ var MAYBE_WASM2JS = 0;
18171834
// [link]
18181835
var ASAN_SHADOW_SIZE = -1
18191836

1820-
// Internal: Tracks whether Emscripten should link in exception throwing (C++
1821-
// 'throw') support library. This does not need to be set directly, but pass
1822-
// -fno-exceptions to the build disable exceptions support. (This is basically
1823-
// -fno-exceptions, but checked at final link time instead of individual .cpp
1824-
// file compile time) If the program *does* contain throwing code (some source
1825-
// files were not compiled with `-fno-exceptions`), and this flag is set at link
1826-
// time, then you will get errors on undefined symbols, as the exception
1827-
// throwing code is not linked in. If so you should either unset the option (if
1828-
// you do want exceptions) or fix the compilation of the source files so that
1829-
// indeed no exceptions are used).
1830-
// TODO(sbc): Move to settings_internal (current blocked due to use in test
1831-
// code).
1832-
// [link]
1833-
var DISABLE_EXCEPTION_THROWING = 0;
1834-
18351837
// Whether we should use the offset converter. This is needed for older
18361838
// versions of v8 (<7.7) that does not give the hex module offset into wasm
18371839
// binary in stack traces, as well as for avoiding using source map entries

tests/test_other.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10505,6 +10505,12 @@ def test_SUPPORT_LONGJMP_object(self):
1050510505
self.assertContained('error: longjmp support was disabled (SUPPORT_LONGJMP=0), but it is required by the code (either set SUPPORT_LONGJMP=1, or remove uses of it in the project)',
1050610506
stderr)
1050710507

10508+
def test_SUPPORT_LONGJMP_wasm(self):
10509+
# Tests if -sSUPPORT_LONGJMP=wasm alone is enough to use Wasm SjLj, i.e., it
10510+
# automatically sets DISABLE_EXCEPTION_THROWING to 1, which is 0 by default,
10511+
# because Emscripten EH and Wasm SjLj cannot be used at the same time.
10512+
self.run_process([EMCC, test_file('core/test_longjmp.c'), '-c', '-sSUPPORT_LONGJMP=wasm', '-o', 'a.o'])
10513+
1050810514
def test_pthread_MODULARIZE(self):
1050910515
stderr = self.run_process([EMCC, test_file('hello_world.c'), '-pthread', '-sMODULARIZE'], stderr=PIPE, check=False).stderr
1051010516
self.assertContained('pthreads + MODULARIZE currently require you to set -s EXPORT_NAME=Something (see settings.js) to Something != Module, so that the .worker.js file can work',

0 commit comments

Comments
 (0)