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..ba55adcc73459 100644 --- a/src/library_signals.js +++ b/src/library_signals.js @@ -138,20 +138,16 @@ var funs = { return -1; }, #if SUPPORT_LONGJMP -#if ASSERTIONS - siglongjmp__deps: ['longjmp'], siglongjmp: function(env, value) { +#if ASSERTIONS // 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 + _emscripten_longjmp(env, value); + }, #endif sigpending: function(set) { diff --git a/system/lib/compiler-rt/emscripten_exception_builtins.c b/system/lib/compiler-rt/emscripten_exception_builtins.c index 0c29c243f4818..97fcb87b73c3a 100644 --- a/system/lib/compiler-rt/emscripten_exception_builtins.c +++ b/system/lib/compiler-rt/emscripten_exception_builtins.c @@ -9,12 +9,13 @@ * See: https://llvm.org/doxygen/WebAssemblyLowerEmscriptenEHSjLj_8cpp.html */ +#include #include -thread_local int __THREW__ = 0; +thread_local uintptr_t __THREW__ = 0; thread_local int __threwValue = 0; -void setThrew(int threw, int value) { +void setThrew(uintptr_t threw, int value) { if (__THREW__ == 0) { __THREW__ = threw; __threwValue = value; diff --git a/system/lib/compiler-rt/emscripten_setjmp.c b/system/lib/compiler-rt/emscripten_setjmp.c index e9bf41f136668..756a82f7240e8 100644 --- a/system/lib/compiler-rt/emscripten_setjmp.c +++ b/system/lib/compiler-rt/emscripten_setjmp.c @@ -9,15 +9,21 @@ #include #include -static uint32_t setjmpId = 0; +// 0 - Nothing thrown +// 1 - Exception thrown +// Other values - jmpbuf pointer in the case that longjmp was thrown +static uintptr_t setjmpId = 0; typedef struct TableEntry { - uint32_t id, label; + uintptr_t id; + uint32_t label; } 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) { +TableEntry* saveSetjmp(uintptr_t* env, uint32_t label, TableEntry* table, uint32_t size) { // Not particularly fast: slow table lookup of setjmpId to label. But setjmp // prevents relooping anyhow, so slowness is to be expected. And typical case // is 1 setjmp per invocation, or less. @@ -43,10 +49,10 @@ TableEntry* saveSetjmp(uint32_t* env, uint32_t label, TableEntry* table, uint32_ return table; } -uint32_t testSetjmp(uint32_t id, TableEntry* table, uint32_t size) { - uint32_t i = 0, curr; +uint32_t testSetjmp(uintptr_t id, TableEntry* table, uint32_t size) { + uint32_t i = 0; while (i < size) { - uint32_t curr = table[i].id; + uintptr_t curr = table[i].id; if (curr == 0) break; if (curr == id) { return table[i].label; @@ -55,3 +61,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/tools/deps_info.py b/tools/deps_info.py index eaa96cb5ceba2..5f2f58376097b 100644 --- a/tools/deps_info.py +++ b/tools/deps_info.py @@ -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'], @@ -181,7 +180,7 @@ 'setjmp': ['saveSetjmp'], 'setprotoent': ['malloc'], 'setgroups': ['sysconf'], - 'siglongjmp': ['setThrew'], + 'siglongjmp': ['emscripten_longjmp', 'setThrew'], 'syslog': ['malloc', 'ntohs'], 'timegm': ['_get_tzname', '_get_daylight', '_get_timezone', 'malloc'], 'times': ['memset'],