-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Support Emscripten EH/SjLj in Wasm64 #14108
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -138,20 +138,16 @@ var funs = { | |
| return -1; | ||
| }, | ||
| #if SUPPORT_LONGJMP | ||
| #if ASSERTIONS | ||
| siglongjmp__deps: ['longjmp'], | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is this |
||
| 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', | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I first tried to change this to siglongjmp: '_emscripten_longjmp'But then
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should probable move this alias into native code alongsize longjmp. If its really just an alias you can use
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That sounds better. I'll split this PR into two as you suggested and do it there. |
||
| #endif | ||
| _emscripten_longjmp(env, value); | ||
| }, | ||
| #endif | ||
|
|
||
| sigpending: function(set) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,15 +9,21 @@ | |
| #include <stdlib.h> | ||
| #include <setjmp.h> | ||
|
|
||
| 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; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like this is an auto-incrementing counter.. set from the
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's tricky... It looks I need to turn even more variables into
5 was missing in this PR so I added it too. Not sure if this propagation of |
||
| 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) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cool... I tried this but I got some odd crashed in the compiler.. but if this works that is great! |
||
| setThrew(env, val); | ||
| _emscripten_throw_longjmp(); | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.