Skip to content

Commit a2d4949

Browse files
authored
Improve SUPPORT_LONGJMP=0 (#12394)
Don't run the backend pass if longjmp support is disabled. This allows setting the flag at compile time to disable invoke generation for longjmps, when that is not desired. Also, before this change, the error would just be "undefined symbol: longjmp" which is not that clear, and worse, if errors on undefined symbols were disabled, it would just be a warning. This emits a clear error at link time if the flag is set to not support longjmp but the code requires it.
1 parent f4cf8bb commit a2d4949

File tree

5 files changed

+33
-4
lines changed

5 files changed

+33
-4
lines changed

ChangeLog.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ See docs/process.md for how version tagging works.
1717

1818
Current Trunk
1919
-------------
20+
- When `-s SUPPORT_LONGJMP=0` is passed to disable longjmp, do not run the LLVM
21+
wasm backend path that handles longjmp. Before this only affected linking, and
22+
now the flag gives you the ability to affect codegen at compile time too. This
23+
is necessary if one does not want any invokes generated for longjmp at all.
24+
(#12394)
2025

2126
2.0.6: 10/02/2020
2227
-----------------

src/library.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1766,19 +1766,27 @@ LibraryManager.library = {
17661766
// setjmp.h
17671767
// ==========================================================================
17681768

1769-
#if SUPPORT_LONGJMP
17701769
longjmp__sig: 'vii',
1770+
#if SUPPORT_LONGJMP
17711771
longjmp: function(env, value) {
17721772
_setThrew(env, value || 1);
17731773
throw 'longjmp';
17741774
},
1775+
#else
1776+
longjmp__deps: [function() {
1777+
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)');
1778+
}],
1779+
// will never be emitted, as the dep errors at compile time
1780+
longjmp: function() {
1781+
abort('longjmp not supported');
1782+
},
1783+
#endif
17751784
// TODO: remove these aliases if/when the LLVM backend can stop emitting them
17761785
// (it emits them atm as they are generated by an IR pass, at at that time
17771786
// they each have a different signature - it is only at the wasm level that
17781787
// they become identical).
17791788
emscripten_longjmp: 'longjmp',
17801789
emscripten_longjmp_jmpbuf: 'longjmp',
1781-
#endif
17821790

17831791
// ==========================================================================
17841792
// sys/wait.h

src/settings.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1497,6 +1497,9 @@ var RUNTIME_FUNCS_TO_IMPORT = ['abort', 'setTempRet0', 'getTempRet0']
14971497
// not available. If you are using C++ exceptions, but do not need
14981498
// setjmp()+longjmp() API, then you can set this to 0 to save a little bit of
14991499
// code size and performance when catching exceptions.
1500+
// [compile+link] - at compile time this enables the transformations needed for
1501+
// longjmp support at codegen time, while at link it allows linking in the
1502+
// library support.
15001503
var SUPPORT_LONGJMP = 1;
15011504

15021505
// If set to 1, disables old deprecated HTML5 API event target lookup behavior.

tests/test_other.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9407,3 +9407,15 @@ def test_SYSCALL_DEBUG(self):
94079407
def test_LIBRARY_DEBUG(self):
94089408
self.set_setting('LIBRARY_DEBUG')
94099409
self.do_runf(path_from_root('tests', 'hello_world.c'), '[library call:_fd_write: 0x1')
9410+
9411+
def test_SUPPORT_LONGJMP_executable(self):
9412+
stderr = self.run_process([EMCC, path_from_root('tests', 'core', 'test_longjmp.c'), '-s', 'SUPPORT_LONGJMP=0'], stderr=PIPE, check=False).stderr
9413+
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)',
9414+
stderr)
9415+
9416+
def test_SUPPORT_LONGJMP_object(self):
9417+
# compile the object *with* support, but link without
9418+
self.run_process([EMCC, path_from_root('tests', 'core', 'test_longjmp.c'), '-c', '-s', 'SUPPORT_LONGJMP=1', '-o', 'a.o'])
9419+
stderr = self.run_process([EMCC, 'a.o', '-s', 'SUPPORT_LONGJMP=0'], stderr=PIPE, check=False).stderr
9420+
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)',
9421+
stderr)

tools/building.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -438,8 +438,9 @@ def llvm_backend_args():
438438
allowed = ','.join(Settings.EXCEPTION_CATCHING_ALLOWED or ['__fake'])
439439
args += ['-emscripten-cxx-exceptions-allowed=' + allowed]
440440

441-
# asm.js-style setjmp/longjmp handling
442-
args += ['-enable-emscripten-sjlj']
441+
if Settings.SUPPORT_LONGJMP:
442+
# asm.js-style setjmp/longjmp handling
443+
args += ['-enable-emscripten-sjlj']
443444

444445
# better (smaller, sometimes faster) codegen, see binaryen#1054
445446
# and https://bugs.llvm.org/show_bug.cgi?id=39488

0 commit comments

Comments
 (0)