From 878a2f1306e25cce0c1627ef5c06e9f60d85df80 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Wed, 2 Jun 2021 18:48:53 -0700 Subject: [PATCH] Support Emscripten EH/SjLj in Wasm64 This mostly changes some `uint32_t`s to `uintptr_t` in libraries for EH and SjLj to support wasm64. More details in case you are interested: 1. I described in https://reviews.llvm.org/D101985 how changing the first argument of `emscripten_longjmp` in turn changed `testSetjmp`'s first argument to `uintptr_t`. 2. `testSetjmp`'s first argument `id` is compared with the local variable `curr`. So it's `uintptr_t` now: [Link](https://github.com/emscripten-core/emscripten/blob/aa2bad5d6a0de5b175688fc8ead46f70a1b43a0d/system/lib/compiler-rt/emscripten_setjmp.c#L53) 3. That `curr` is set from `table[i].id`, which is `TableEntry.id`. So `id` in `TableEntry` here is now `uintptr_t`: [Link](https://github.com/emscripten-core/emscripten/blob/aa2bad5d6a0de5b175688fc8ead46f70a1b43a0d/system/lib/compiler-rt/emscripten_setjmp.c#L51) 4. Because `table[i].id` is set from `setjmpId`, `setjmpId` needs to be `uintptr_t` too: [Link](https://github.com/emscripten-core/emscripten/blob/aa2bad5d6a0de5b175688fc8ead46f70a1b43a0d/system/lib/compiler-rt/emscripten_setjmp.c#L31) 5. Because `setjmpId` is stored in `env` (first parameter) in `saveSetjmp`, `saveSetjmp`'s first argument has to change to `uintptr_t`: [Link](https://github.com/emscripten-core/emscripten/blob/aa2bad5d6a0de5b175688fc8ead46f70a1b43a0d/system/lib/compiler-rt/emscripten_setjmp.c#L28) Not sure how to add tests for this given that wasm64 support is not ready yet. Existing tests run fine. --- .../compiler-rt/emscripten_exception_builtins.c | 5 +++-- system/lib/compiler-rt/emscripten_setjmp.c | 16 ++++++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) 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 5be8554ea19e3..756a82f7240e8 100644 --- a/system/lib/compiler-rt/emscripten_setjmp.c +++ b/system/lib/compiler-rt/emscripten_setjmp.c @@ -9,17 +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. @@ -45,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;