From 70555a2ead1a0ed834c3cb4ad9e080fb5eebcbea Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Fri, 14 May 2021 00:56:15 -0700 Subject: [PATCH 01/12] Move longjmp into native code This moves `longjmp` and `siglongjmp` into native code and leaves only the throwing stub in JS code, which cannot be moved. This currently fails a wasm2c test in `test_longjmp_standalone`. I don't know enough about wasm2c but it looks wasm2c has its own support in tools/wasm2c.py and tools/wasm2c/base.c. Any starting point on how to fix that part? --- emcc.py | 11 +++++++---- src/library.js | 16 +++------------- src/library_signals.js | 16 ---------------- system/lib/compiler-rt/emscripten_setjmp.c | 7 +++++++ system/lib/libc/musl/include/setjmp.h | 3 ++- tools/deps_info.py | 3 --- tools/shared.py | 1 + 7 files changed, 20 insertions(+), 37 deletions(-) diff --git a/emcc.py b/emcc.py index 688b9cc6f22bc..5d135f7b982b0 100755 --- a/emcc.py +++ b/emcc.py @@ -2190,10 +2190,13 @@ def check_memory_setting(setting): # LTO these symbols don't exist prior the linking. '___cxa_is_pointer_type', '___cxa_can_catch', - - # Emscripten exception handling can generate invoke calls, and they call - # setThrew(). We cannot handle this using deps_info as the invokes are not - # emitted because of library function usage, but by codegen itself. + ] + if not settings.DISABLE_EXCEPTION_CATCHING or settings.SUPPORT_LONGJMP: + settings.EXPORTED_FUNCTIONS += [ + # Emscripten exception handling and setjmp/longjmp handling can generate + # invoke calls, and they call setThrew(). We cannot handle this using + # deps_info as the invokes are not emitted because of library function + # usage, but by codegen itself. '_setThrew', ] diff --git a/src/library.js b/src/library.js index 01aef041221ab..977a8375a15b6 100644 --- a/src/library.js +++ b/src/library.js @@ -1524,13 +1524,9 @@ LibraryManager.library = { // setjmp.h // ========================================================================== - longjmp__sig: 'vii', -#if SUPPORT_LONGJMP - longjmp: function(env, value) { - _setThrew(env, value || 1); - throw 'longjmp'; - }, -#else + _emscripten_throw_longjmp__sig: 'v', + _emscripten_throw_longjmp: function() { throw 'longjmp'; }, +#if !SUPPORT_LONGJMP longjmp__deps: [function() { 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)'); }], @@ -1539,12 +1535,6 @@ LibraryManager.library = { abort('longjmp not supported'); }, #endif - // TODO: remove these aliases if/when the LLVM backend can stop emitting them - // (it emits them atm as they are generated by an IR pass, at at that time - // they each have a different signature - it is only at the wasm level that - // they become identical). - emscripten_longjmp__sig: 'vii', - emscripten_longjmp: 'longjmp', // ========================================================================== // sys/wait.h diff --git a/src/library_signals.js b/src/library_signals.js index 65f00be95a930..408459b7bd71c 100644 --- a/src/library_signals.js +++ b/src/library_signals.js @@ -137,22 +137,6 @@ var funs = { setErrNo(ERRNO_CODES.EINTR); return -1; }, -#if SUPPORT_LONGJMP -#if ASSERTIONS - siglongjmp__deps: ['longjmp'], - siglongjmp: function(env, value) { - // We cannot wrap the sigsetjmp, but I hope that - // in most cases siglongjmp will be called later. - - // siglongjmp can be called very many times, so don't flood the stderr. - warnOnce("Calling longjmp() instead of siglongjmp()"); - _longjmp(env, value); - }, -#else - siglongjmp__sig: 'vii', - siglongjmp: 'longjmp', -#endif -#endif sigpending: function(set) { {{{ makeSetValue('set', 0, 0, 'i32') }}}; diff --git a/system/lib/compiler-rt/emscripten_setjmp.c b/system/lib/compiler-rt/emscripten_setjmp.c index e9bf41f136668..5be8554ea19e3 100644 --- a/system/lib/compiler-rt/emscripten_setjmp.c +++ b/system/lib/compiler-rt/emscripten_setjmp.c @@ -16,6 +16,8 @@ typedef struct TableEntry { } TableEntry; extern void setTempRet0(uint32_t value); +extern void setThrew(uintptr_t threw, int value); +extern void _emscripten_throw_longjmp(); // defined in src/library.js TableEntry* saveSetjmp(uint32_t* env, uint32_t label, TableEntry* table, uint32_t size) { // Not particularly fast: slow table lookup of setjmpId to label. But setjmp @@ -55,3 +57,8 @@ uint32_t testSetjmp(uint32_t id, TableEntry* table, uint32_t size) { } return 0; } + +void emscripten_longjmp(uintptr_t env, int val) { + setThrew(env, val); + _emscripten_throw_longjmp(); +} diff --git a/system/lib/libc/musl/include/setjmp.h b/system/lib/libc/musl/include/setjmp.h index fac697fc4a3aa..5bbf2b2fd70a1 100644 --- a/system/lib/libc/musl/include/setjmp.h +++ b/system/lib/libc/musl/include/setjmp.h @@ -22,10 +22,11 @@ typedef jmp_buf sigjmp_buf; /* XXX EMSCRIPTEN: No signals support, alias sigsetjmp and siglongjmp to their non-signals counterparts. */ #if __EMSCRIPTEN__ #define sigsetjmp(buf, x) setjmp((buf)) +#define siglongjmp(buf, val) longjmp(buf, val) #else int sigsetjmp (sigjmp_buf, int); +int siglongjmp (sigjmp_buf, int); #endif -_Noreturn void siglongjmp (sigjmp_buf, int); #endif #if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \ diff --git a/tools/deps_info.py b/tools/deps_info.py index eaa96cb5ceba2..654cd79c8d296 100644 --- a/tools/deps_info.py +++ b/tools/deps_info.py @@ -93,7 +93,6 @@ 'emscripten_idb_load': ['malloc', 'free'], 'emscripten_init_websocket_to_posix_socket_bridge': ['malloc', 'free'], 'emscripten_log': ['strlen'], - 'emscripten_longjmp': ['setThrew'], 'emscripten_pc_get_file': ['emscripten_builtin_malloc', 'emscripten_builtin_free', 'emscripten_builtin_memalign', 'malloc', 'free'], 'emscripten_pc_get_function': ['emscripten_builtin_malloc', 'emscripten_builtin_free', 'emscripten_builtin_memalign', 'malloc', 'free'], 'emscripten_run_preload_plugins_data': ['malloc'], @@ -167,7 +166,6 @@ 'gmtime_r': ['malloc'], 'localtime': ['_get_tzname', '_get_daylight', '_get_timezone', 'malloc'], 'localtime_r': ['_get_tzname', '_get_daylight', '_get_timezone', 'malloc'], - 'longjmp': ['setThrew'], 'mktime': ['_get_tzname', '_get_daylight', '_get_timezone', 'malloc'], 'mmap': ['memalign', 'memset', 'malloc'], 'munmap': ['malloc', 'free'], @@ -181,7 +179,6 @@ 'setjmp': ['saveSetjmp'], 'setprotoent': ['malloc'], 'setgroups': ['sysconf'], - 'siglongjmp': ['setThrew'], 'syslog': ['malloc', 'ntohs'], 'timegm': ['_get_tzname', '_get_daylight', '_get_timezone', 'malloc'], 'times': ['memset'], diff --git a/tools/shared.py b/tools/shared.py index 833a8741bd342..b54696af0dd75 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -682,6 +682,7 @@ def make_dynCall(sig, args): @staticmethod def make_invoke(sig, named=True): + assert('_setThrew' in settings.EXPORTED_FUNCTIONS) legal_sig = JS.legalize_sig(sig) # TODO: do this in extcall, jscall? args = ['index'] + ['a' + str(i) for i in range(1, len(legal_sig))] ret = 'return ' if sig[0] != 'v' else '' From b281cdb7cd3ee828ab52f04bc3e90ccc08bdbf07 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Thu, 20 May 2021 23:24:33 -0700 Subject: [PATCH 02/12] Address comments --- system/lib/libc/musl/include/setjmp.h | 2 +- tools/shared.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/system/lib/libc/musl/include/setjmp.h b/system/lib/libc/musl/include/setjmp.h index 5bbf2b2fd70a1..a9d3d85c42b97 100644 --- a/system/lib/libc/musl/include/setjmp.h +++ b/system/lib/libc/musl/include/setjmp.h @@ -25,7 +25,7 @@ typedef jmp_buf sigjmp_buf; #define siglongjmp(buf, val) longjmp(buf, val) #else int sigsetjmp (sigjmp_buf, int); -int siglongjmp (sigjmp_buf, int); +_Noreturn int siglongjmp (sigjmp_buf, int); #endif #endif diff --git a/tools/shared.py b/tools/shared.py index b54696af0dd75..833a8741bd342 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -682,7 +682,6 @@ def make_dynCall(sig, args): @staticmethod def make_invoke(sig, named=True): - assert('_setThrew' in settings.EXPORTED_FUNCTIONS) legal_sig = JS.legalize_sig(sig) # TODO: do this in extcall, jscall? args = ['index'] + ['a' + str(i) for i in range(1, len(legal_sig))] ret = 'return ' if sig[0] != 'v' else '' From 2b3f6905fb7729ef52b8fbad1dc552a1af9da7a0 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Fri, 21 May 2021 00:03:19 -0700 Subject: [PATCH 03/12] wasm2c support --- tools/wasm2c/base.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/tools/wasm2c/base.c b/tools/wasm2c/base.c index bb5db047895be..0b7aea1d7d08f 100644 --- a/tools/wasm2c/base.c +++ b/tools/wasm2c/base.c @@ -113,21 +113,10 @@ static jmp_buf setjmp_stack[MAX_SETJMP_STACK]; static u32 next_setjmp = 0; -// Declare an export that may be needed and may not be. For example if longjmp -// is included then we need setThrew, but we must declare setThrew so that -// the C compiler can build us without error if longjmp is not actually used. - -#define DECLARE_WEAK_EXPORT(ret, name, args) \ -__attribute__((weak)) \ -ret (*WASM_RT_ADD_PREFIX(name)) args = NULL; - -DECLARE_WEAK_EXPORT(void, Z_setThrewZ_vii, (u32, u32)); - -IMPORT_IMPL(void, Z_envZ_emscripten_longjmpZ_vii, (u32 buf, u32 value), { +IMPORT_IMPL(void, Z_envZ__emscripten_throw_longjmpZ_vv, (), { if (next_setjmp == 0) { abort_with_message("longjmp without setjmp"); } - WASM_RT_ADD_PREFIX(Z_setThrewZ_vii)(buf, value ? value : 1); longjmp(setjmp_stack[next_setjmp - 1], 1); }); From 53659cc6861f0bfbb562b02c3ecf433a27b266bf Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Sun, 23 May 2021 22:06:05 -0700 Subject: [PATCH 04/12] Don't include `setThrew` unconditionally --- emcc.py | 11 ++++------- tools/deps_info.py | 1 + 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/emcc.py b/emcc.py index cd501adf51bd7..a03039205dace 100755 --- a/emcc.py +++ b/emcc.py @@ -2207,13 +2207,10 @@ def check_memory_setting(setting): # so we include then unconditionally when exceptions are enabled. '___cxa_is_pointer_type', '___cxa_can_catch', - ] - if not settings.DISABLE_EXCEPTION_CATCHING or settings.SUPPORT_LONGJMP: - settings.EXPORTED_FUNCTIONS += [ - # Emscripten exception handling and setjmp/longjmp handling can generate - # invoke calls, and they call setThrew(). We cannot handle this using - # deps_info as the invokes are not emitted because of library function - # usage, but by codegen itself. + + # Emscripten exception handling can generate invoke calls, and they call + # setThrew(). We cannot handle this using deps_info as the invokes are not + # emitted because of library function usage, but by codegen itself. '_setThrew', ] diff --git a/tools/deps_info.py b/tools/deps_info.py index 4133564dff1d3..1fcdcf5ce7392 100644 --- a/tools/deps_info.py +++ b/tools/deps_info.py @@ -93,6 +93,7 @@ 'emscripten_idb_load': ['malloc', 'free'], 'emscripten_init_websocket_to_posix_socket_bridge': ['malloc', 'free'], 'emscripten_log': ['strlen'], + 'emscripten_longjmp': ['setThrew'], 'emscripten_pc_get_file': ['emscripten_builtin_malloc', 'emscripten_builtin_free', 'emscripten_builtin_memalign', 'malloc', 'free'], 'emscripten_pc_get_function': ['emscripten_builtin_malloc', 'emscripten_builtin_free', 'emscripten_builtin_memalign', 'malloc', 'free'], 'emscripten_run_preload_plugins_data': ['malloc'], From 83a86f715ec708c06fbe2f17a290b7993c12a886 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Tue, 25 May 2021 02:34:04 -0700 Subject: [PATCH 05/12] Fix --- tools/deps_info.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/deps_info.py b/tools/deps_info.py index 1fcdcf5ce7392..f71b2bd0c7eb2 100644 --- a/tools/deps_info.py +++ b/tools/deps_info.py @@ -93,7 +93,7 @@ 'emscripten_idb_load': ['malloc', 'free'], 'emscripten_init_websocket_to_posix_socket_bridge': ['malloc', 'free'], 'emscripten_log': ['strlen'], - 'emscripten_longjmp': ['setThrew'], + 'emscripten_longjmp': ['malloc', 'free', 'setThrew'], 'emscripten_pc_get_file': ['emscripten_builtin_malloc', 'emscripten_builtin_free', 'emscripten_builtin_memalign', 'malloc', 'free'], 'emscripten_pc_get_function': ['emscripten_builtin_malloc', 'emscripten_builtin_free', 'emscripten_builtin_memalign', 'malloc', 'free'], 'emscripten_run_preload_plugins_data': ['malloc'], @@ -167,6 +167,7 @@ 'gmtime_r': ['malloc'], 'localtime': ['_get_tzname', '_get_daylight', '_get_timezone', 'malloc'], 'localtime_r': ['_get_tzname', '_get_daylight', '_get_timezone', 'malloc'], + 'longjmp': ['malloc', 'free', 'setThrew'], 'mktime': ['_get_tzname', '_get_daylight', '_get_timezone', 'malloc'], 'mmap': ['memalign', 'memset', 'malloc'], 'munmap': ['malloc', 'free'], @@ -177,7 +178,7 @@ 'accept': ['htons'], 'recvfrom': ['htons'], 'send': ['ntohs'], - 'setjmp': ['saveSetjmp'], + 'setjmp': ['malloc', 'free', 'saveSetjmp'], 'setprotoent': ['malloc'], 'setgroups': ['sysconf'], 'syslog': ['malloc', 'ntohs'], From 05a3094ead926e789c92d8161c79ff5a6b6fd10b Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Tue, 25 May 2021 03:15:39 -0700 Subject: [PATCH 06/12] temp --- tests/test_other.py | 5 +++-- tools/deps_info.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/test_other.py b/tests/test_other.py index 72f47438a1641..fb08f2c38515e 100644 --- a/tests/test_other.py +++ b/tests/test_other.py @@ -10349,7 +10349,7 @@ def test_deps_info(self): # When debugging set this valud to the function that you want to start # with. All symbols prior will be skipped over. - start_at = None + start_at = 'longjmp' assert not start_at or start_at in deps_info.get_deps_info() for function, deps in deps_info.get_deps_info().items(): if start_at: @@ -10402,7 +10402,8 @@ def test_deps_info(self): if function.startswith('__cxa_'): cmd.append('-fexceptions') # Causes WebAssemblyLowerEmscriptenEHSjLj pass in llvm to crash - if function == 'setjmp': + # TODO + if function in ['emscripten_longjmp', 'longjmp', 'setjmp']: continue print(shared.shlex_join(cmd)) self.run_process(cmd) diff --git a/tools/deps_info.py b/tools/deps_info.py index f71b2bd0c7eb2..b7a4bba50ca56 100644 --- a/tools/deps_info.py +++ b/tools/deps_info.py @@ -178,7 +178,7 @@ 'accept': ['htons'], 'recvfrom': ['htons'], 'send': ['ntohs'], - 'setjmp': ['malloc', 'free', 'saveSetjmp'], + #'setjmp': ['malloc', 'free', 'saveSetjmp'], 'setprotoent': ['malloc'], 'setgroups': ['sysconf'], 'syslog': ['malloc', 'ntohs'], From b17ebbf26cc6c15c36877020d5469f11d6f40d37 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Tue, 1 Jun 2021 17:13:35 -0700 Subject: [PATCH 07/12] attempt --- tools/deps_info.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/deps_info.py b/tools/deps_info.py index b7a4bba50ca56..dfcd16d65de2f 100644 --- a/tools/deps_info.py +++ b/tools/deps_info.py @@ -93,7 +93,7 @@ 'emscripten_idb_load': ['malloc', 'free'], 'emscripten_init_websocket_to_posix_socket_bridge': ['malloc', 'free'], 'emscripten_log': ['strlen'], - 'emscripten_longjmp': ['malloc', 'free', 'setThrew'], + 'emscripten_longjmp': ['setThrew'], 'emscripten_pc_get_file': ['emscripten_builtin_malloc', 'emscripten_builtin_free', 'emscripten_builtin_memalign', 'malloc', 'free'], 'emscripten_pc_get_function': ['emscripten_builtin_malloc', 'emscripten_builtin_free', 'emscripten_builtin_memalign', 'malloc', 'free'], 'emscripten_run_preload_plugins_data': ['malloc'], @@ -167,7 +167,7 @@ 'gmtime_r': ['malloc'], 'localtime': ['_get_tzname', '_get_daylight', '_get_timezone', 'malloc'], 'localtime_r': ['_get_tzname', '_get_daylight', '_get_timezone', 'malloc'], - 'longjmp': ['malloc', 'free', 'setThrew'], + #'longjmp': ['setThrew'], 'mktime': ['_get_tzname', '_get_daylight', '_get_timezone', 'malloc'], 'mmap': ['memalign', 'memset', 'malloc'], 'munmap': ['malloc', 'free'], @@ -178,7 +178,7 @@ 'accept': ['htons'], 'recvfrom': ['htons'], 'send': ['ntohs'], - #'setjmp': ['malloc', 'free', 'saveSetjmp'], + #'setjmp': ['malloc', 'free', 'saveSetjmp', 'setThrew'], 'setprotoent': ['malloc'], 'setgroups': ['sysconf'], 'syslog': ['malloc', 'ntohs'], From 8144a290b4f8192bd5d4fc46aab678075a41ca3e Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Wed, 2 Jun 2021 02:21:31 -0700 Subject: [PATCH 08/12] fix --- tests/test_other.py | 15 +++++++++++---- tools/deps_info.py | 5 ++--- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/tests/test_other.py b/tests/test_other.py index 6fac5b86d7493..e97eabd5f8e8a 100644 --- a/tests/test_other.py +++ b/tests/test_other.py @@ -10381,7 +10381,7 @@ def test_deps_info(self): # When debugging set this valud to the function that you want to start # with. All symbols prior will be skipped over. - start_at = 'longjmp' + start_at = None assert not start_at or start_at in deps_info.get_deps_info() for function, deps in deps_info.get_deps_info().items(): if start_at: @@ -10433,9 +10433,16 @@ def test_deps_info(self): cmd.append('-sUSE_WEBGPU') if function.startswith('__cxa_'): cmd.append('-fexceptions') - # Causes WebAssemblyLowerEmscriptenEHSjLj pass in llvm to crash - # TODO - if function in ['emscripten_longjmp', 'longjmp', 'setjmp']: + # In WebAssemblyLowerEmscriptenEHSjLj pass in the LLVM backend, function + # calls that exist in the same function with setjmp are converted to some + # code sequence that includes malloc, free, and emscripten_longjmp. + # emscripten_longjmp is included in deps_info.py because in non-LTO build + # setjmp does not exist anymore in the final object file. So the mere + # indirect reference of setjmp or emscripten_longjmp does not generate + # calls to malloc/free/saveSetjmp, which are specified in deps_info.py. + # Also Emscripten EH has a known restriction that setjmp cannot be called + # or referenced indirectly anyway. + if function in ['emscripten_longjmp', 'setjmp']: continue print(shared.shlex_join(cmd)) self.run_process(cmd) diff --git a/tools/deps_info.py b/tools/deps_info.py index dfcd16d65de2f..d57fd1a816b0b 100644 --- a/tools/deps_info.py +++ b/tools/deps_info.py @@ -93,7 +93,7 @@ 'emscripten_idb_load': ['malloc', 'free'], 'emscripten_init_websocket_to_posix_socket_bridge': ['malloc', 'free'], 'emscripten_log': ['strlen'], - 'emscripten_longjmp': ['setThrew'], + 'emscripten_longjmp': ['malloc', 'free', 'saveSetjmp', 'setThrew'], 'emscripten_pc_get_file': ['emscripten_builtin_malloc', 'emscripten_builtin_free', 'emscripten_builtin_memalign', 'malloc', 'free'], 'emscripten_pc_get_function': ['emscripten_builtin_malloc', 'emscripten_builtin_free', 'emscripten_builtin_memalign', 'malloc', 'free'], 'emscripten_run_preload_plugins_data': ['malloc'], @@ -167,7 +167,6 @@ 'gmtime_r': ['malloc'], 'localtime': ['_get_tzname', '_get_daylight', '_get_timezone', 'malloc'], 'localtime_r': ['_get_tzname', '_get_daylight', '_get_timezone', 'malloc'], - #'longjmp': ['setThrew'], 'mktime': ['_get_tzname', '_get_daylight', '_get_timezone', 'malloc'], 'mmap': ['memalign', 'memset', 'malloc'], 'munmap': ['malloc', 'free'], @@ -178,7 +177,7 @@ 'accept': ['htons'], 'recvfrom': ['htons'], 'send': ['ntohs'], - #'setjmp': ['malloc', 'free', 'saveSetjmp', 'setThrew'], + 'setjmp': ['malloc', 'free', 'saveSetjmp', 'setThrew'], 'setprotoent': ['malloc'], 'setgroups': ['sysconf'], 'syslog': ['malloc', 'ntohs'], From 106b03ef17fb41b3c9af6eeb23313f67a50fd40b Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Wed, 2 Jun 2021 11:29:35 -0700 Subject: [PATCH 09/12] work --- src/library.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/library.js b/src/library.js index c2a5a68201aa9..f9766159366ee 100644 --- a/src/library.js +++ b/src/library.js @@ -1534,6 +1534,11 @@ LibraryManager.library = { longjmp: function(env, value) { abort('longjmp not supported'); }, + setjmp: function(env, value) { + abort('setjmp not supported'); + }, + //_emscripten_throw_longjmp__deps: longjmp__deps, + _emscripten_throw_longjmp__deps: longjmp__deps, #endif // ========================================================================== From 37c0f36907cf1c1582dd5f06d9ac24dfb48e97eb Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Wed, 2 Jun 2021 14:27:26 -0700 Subject: [PATCH 10/12] comment --- src/library.js | 2 -- tests/test_other.py | 13 ++++++------- tools/deps_info.py | 11 +++++++++++ 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/library.js b/src/library.js index f9766159366ee..535756f753956 100644 --- a/src/library.js +++ b/src/library.js @@ -1537,8 +1537,6 @@ LibraryManager.library = { setjmp: function(env, value) { abort('setjmp not supported'); }, - //_emscripten_throw_longjmp__deps: longjmp__deps, - _emscripten_throw_longjmp__deps: longjmp__deps, #endif // ========================================================================== diff --git a/tests/test_other.py b/tests/test_other.py index e97eabd5f8e8a..79f08bec5378c 100644 --- a/tests/test_other.py +++ b/tests/test_other.py @@ -10435,13 +10435,12 @@ def test_deps_info(self): cmd.append('-fexceptions') # In WebAssemblyLowerEmscriptenEHSjLj pass in the LLVM backend, function # calls that exist in the same function with setjmp are converted to some - # code sequence that includes malloc, free, and emscripten_longjmp. - # emscripten_longjmp is included in deps_info.py because in non-LTO build - # setjmp does not exist anymore in the final object file. So the mere - # indirect reference of setjmp or emscripten_longjmp does not generate - # calls to malloc/free/saveSetjmp, which are specified in deps_info.py. - # Also Emscripten EH has a known restriction that setjmp cannot be called - # or referenced indirectly anyway. + # code sequence that includes emscripten_longjmp. emscripten_longjmp is + # included in deps_info.py because in non-LTO builds setjmp does not exist + # anymore in the object files. So the mere indirect reference of setjmp or + # emscripten_longjmp does not generate calls to its dependencies specified + # in deps_info.py. Also Emscripten EH has a known restriction that setjmp + # cannot be called or referenced indirectly anyway. if function in ['emscripten_longjmp', 'setjmp']: continue print(shared.shlex_join(cmd)) diff --git a/tools/deps_info.py b/tools/deps_info.py index d57fd1a816b0b..1f576a7f756f1 100644 --- a/tools/deps_info.py +++ b/tools/deps_info.py @@ -93,6 +93,11 @@ 'emscripten_idb_load': ['malloc', 'free'], 'emscripten_init_websocket_to_posix_socket_bridge': ['malloc', 'free'], 'emscripten_log': ['strlen'], + # This list is the same as setjmp's dependencies. In non-LTO builds, setjmp + # does not exist in the object files; it is converted into a code sequence + # that includes several functions, one of which is emscripten_longjmp. This is + # a trick to includes these dependencies for setjmp even when setjmp does not + # exist. Refer to setjmp's entry for more details. 'emscripten_longjmp': ['malloc', 'free', 'saveSetjmp', 'setThrew'], 'emscripten_pc_get_file': ['emscripten_builtin_malloc', 'emscripten_builtin_free', 'emscripten_builtin_memalign', 'malloc', 'free'], 'emscripten_pc_get_function': ['emscripten_builtin_malloc', 'emscripten_builtin_free', 'emscripten_builtin_memalign', 'malloc', 'free'], @@ -177,6 +182,12 @@ 'accept': ['htons'], 'recvfrom': ['htons'], 'send': ['ntohs'], + # In WebAssemblyLowerEmscriptenEHSjLj pass in the LLVM backend, function calls + # that exist in the same function with setjmp are converted to some code + # sequence that includes invokes, malloc, free, saveSetjmp, and + # emscripten_longjmp. setThrew is called from invokes, but there's no way to + # directly include invokes in deps_info.py, so we list it as setjmp's + # dependency. 'setjmp': ['malloc', 'free', 'saveSetjmp', 'setThrew'], 'setprotoent': ['malloc'], 'setgroups': ['sysconf'], From 213d507fe1ddae78f5a86725079c508128570eb7 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Wed, 2 Jun 2021 14:52:53 -0700 Subject: [PATCH 11/12] Done? --- src/library.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/library.js b/src/library.js index 535756f753956..da3580ab6ea84 100644 --- a/src/library.js +++ b/src/library.js @@ -1527,9 +1527,22 @@ LibraryManager.library = { _emscripten_throw_longjmp__sig: 'v', _emscripten_throw_longjmp: function() { throw 'longjmp'; }, #if !SUPPORT_LONGJMP + // These are in order to print helpful error messages when either longjmp of + // setjmp is used. longjmp__deps: [function() { 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)'); }], + get setjmp__deps() { + return this.longjmp__deps; + }, + // This is to print the correct error message when a program is built with + // SUPPORT_LONGJMP=1 but linked with SUPPORT_LONGJMP=0. When a program is + // built with SUPPORT_LONGJMP=1, the object file contains references of not + // longjmp but _emscripten_throw_longjmp, which is called from + // emscripten_longjmp. + get _emscripten_throw_longjmp__deps() { + return this.longjmp__deps; + }, // will never be emitted, as the dep errors at compile time longjmp: function(env, value) { abort('longjmp not supported'); From 84e92b398c39539e04a92445a496fe1b00e098ac Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Wed, 2 Jun 2021 17:01:02 -0700 Subject: [PATCH 12/12] Typo fixes in comments --- tools/deps_info.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/deps_info.py b/tools/deps_info.py index 1f576a7f756f1..ddb504ea12654 100644 --- a/tools/deps_info.py +++ b/tools/deps_info.py @@ -96,7 +96,7 @@ # This list is the same as setjmp's dependencies. In non-LTO builds, setjmp # does not exist in the object files; it is converted into a code sequence # that includes several functions, one of which is emscripten_longjmp. This is - # a trick to includes these dependencies for setjmp even when setjmp does not + # a trick to include these dependencies for setjmp even when setjmp does not # exist. Refer to setjmp's entry for more details. 'emscripten_longjmp': ['malloc', 'free', 'saveSetjmp', 'setThrew'], 'emscripten_pc_get_file': ['emscripten_builtin_malloc', 'emscripten_builtin_free', 'emscripten_builtin_memalign', 'malloc', 'free'], @@ -186,7 +186,7 @@ # that exist in the same function with setjmp are converted to some code # sequence that includes invokes, malloc, free, saveSetjmp, and # emscripten_longjmp. setThrew is called from invokes, but there's no way to - # directly include invokes in deps_info.py, so we list it as setjmp's + # directly include invokes in deps_info.py, so we list it as a setjmp's # dependency. 'setjmp': ['malloc', 'free', 'saveSetjmp', 'setThrew'], 'setprotoent': ['malloc'],