-
Notifications
You must be signed in to change notification settings - Fork 3.5k
[EH] Make getCppExceptionThrownValue return thrown value #17157
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 |
|---|---|---|
|
|
@@ -398,29 +398,32 @@ var LibraryExceptions = { | |
| return Module['asm']['__cpp_exception']; | ||
| }, | ||
|
|
||
| $getCppExceptionThrownValue__deps: ['$getCppExceptionTag'], | ||
| $getCppExceptionThrownValue__deps: ['$getCppExceptionTag', '__thrown_object_from_unwind_exception'], | ||
| $getCppExceptionThrownValue: function(ex) { | ||
| return ex.getArg(getCppExceptionTag(), 0); | ||
| // In Wasm EH, the value extracted from WebAssembly.Exception is a pointer | ||
| // to the unwind header. Convert it to the actual thrown value. | ||
| var unwind_ex = ex.getArg(getCppExceptionTag(), 0); | ||
| return ___thrown_object_from_unwind_exception(unwind_ex); | ||
| }, | ||
|
|
||
| $incrementExceptionRefcount__deps: ['__increment_wasm_exception_refcount', '$getCppExceptionThrownValue'], | ||
| $incrementExceptionRefcount__deps: ['__cxa_increment_exception_refcount', '$getCppExceptionThrownValue'], | ||
| $incrementExceptionRefcount: function(obj) { | ||
| var ptr = getCppExceptionThrownValue(obj); | ||
| ___increment_wasm_exception_refcount(ptr); | ||
| ___cxa_increment_exception_refcount(ptr); | ||
| }, | ||
|
|
||
| $decrementExceptionRefcount__deps: ['__decrement_wasm_exception_refcount', '$getCppExceptionThrownValue'], | ||
| $decrementExceptionRefcount__deps: ['__cxa_decrement_exception_refcount', '$getCppExceptionThrownValue'], | ||
| $decrementExceptionRefcount: function(obj) { | ||
| var ptr = getCppExceptionThrownValue(obj); | ||
| ___decrement_wasm_exception_refcount(ptr); | ||
| ___cxa_decrement_exception_refcount(ptr); | ||
| }, | ||
|
|
||
| $getExceptionMessage__deps: ['__get_exception_message', 'free', '$getCppExceptionThrownValue'], | ||
| $getExceptionMessage: function(ptr) { | ||
| $getExceptionMessage: function(obj) { | ||
|
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. Drive-by fix: the variable names ( |
||
| // In Wasm EH, the thrown object is a WebAssembly.Exception. Extract the | ||
| // thrown value from it. | ||
| var obj = getCppExceptionThrownValue(ptr); | ||
| var utf8_addr = ___get_exception_message(obj); | ||
| var ptr = getCppExceptionThrownValue(obj); | ||
| var utf8_addr = ___get_exception_message(ptr); | ||
| var result = UTF8ToString(utf8_addr); | ||
| _free(utf8_addr); | ||
| return result; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,27 +33,26 @@ thrown_object_from_cxa_exception(__cxa_exception* exception_header) { | |
| // Get the exception object from the unwind pointer. | ||
| // Relies on the structure layout, where the unwind pointer is right in | ||
| // front of the user's exception object | ||
| static inline __cxa_exception* cxa_exception_from_exception_unwind_exception( | ||
| static inline __cxa_exception* cxa_exception_from_unwind_exception( | ||
|
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. This was named
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. If this is more correct we should maybe propose this as an upstream change? I do think there is some value in matching these names with the upstream ones... but I don't feel strongly about it. |
||
| _Unwind_Exception* unwind_exception) { | ||
| return cxa_exception_from_thrown_object(unwind_exception + 1); | ||
| } | ||
|
|
||
| static inline void* thrown_object_from_exception_unwind_exception( | ||
| static inline void* thrown_object_from_unwind_exception( | ||
| _Unwind_Exception* unwind_exception) { | ||
| __cxa_exception* exception_header = | ||
| cxa_exception_from_exception_unwind_exception(unwind_exception); | ||
| cxa_exception_from_unwind_exception(unwind_exception); | ||
| return thrown_object_from_cxa_exception(exception_header); | ||
| } | ||
|
|
||
| extern "C" { | ||
|
|
||
| void* __thrown_object_from_unwind_exception( | ||
| _Unwind_Exception* unwind_exception) { | ||
| return thrown_object_from_unwind_exception(unwind_exception); | ||
| } | ||
|
|
||
| char* __get_exception_message(void* thrown_object, bool terminate=false) { | ||
| #if __USING_WASM_EXCEPTIONS__ | ||
| // In Wasm EH, the thrown value is 'unwindHeader' field of __cxa_exception. So | ||
| // we need to get the real pointer thrown by user. | ||
| thrown_object = thrown_object_from_exception_unwind_exception( | ||
| static_cast<_Unwind_Exception*>(thrown_object)); | ||
| #endif | ||
| __cxa_exception* exception_header = | ||
| cxa_exception_from_thrown_object(thrown_object); | ||
| const __shim_type_info* thrown_type = | ||
|
|
@@ -95,34 +94,6 @@ char* __get_exception_terminate_message(void *thrown_object) { | |
| return __get_exception_message(thrown_object, true); | ||
| } | ||
|
|
||
| #if __USING_WASM_EXCEPTIONS__ | ||
| void __cxa_increment_exception_refcount(void* thrown_object) _NOEXCEPT; | ||
| void __cxa_decrement_exception_refcount(void* thrown_object) _NOEXCEPT; | ||
|
|
||
| // These are wrappers for __cxa_increment_exception_refcount and | ||
| // __cxa_decrement_exception_refcount so that these can be called from JS. When | ||
| // you catch a Wasm exception from JS and do not rethrow it, its refcount is | ||
| // still greater than 0 so memory is leaked; users call JS library functions | ||
| // that call these to fix it. | ||
|
|
||
| void __increment_wasm_exception_refcount( | ||
| void* unwind_exception) _NOEXCEPT { | ||
| // In Wasm EH, the thrown value is 'unwindHeader' field of __cxa_exception. So | ||
| // we need to get the real pointer thrown by user. | ||
| void* thrown_object = thrown_object_from_exception_unwind_exception( | ||
| static_cast<_Unwind_Exception*>(unwind_exception)); | ||
| __cxa_increment_exception_refcount(thrown_object); | ||
| } | ||
|
|
||
| void __decrement_wasm_exception_refcount( | ||
| void* unwind_exception) _NOEXCEPT { | ||
| // In Wasm EH, the thrown value is 'unwindHeader' field of __cxa_exception. So | ||
| // we need to get the real pointer thrown by user. | ||
| void* thrown_object = thrown_object_from_exception_unwind_exception( | ||
| static_cast<_Unwind_Exception*>(unwind_exception)); | ||
| __cxa_decrement_exception_refcount(thrown_object); | ||
| } | ||
| #endif // __USING_WASM_EXCEPTIONS__ | ||
| } | ||
|
|
||
| #endif // __USING_EMSCRIPTEN_EXCEPTIONS__ || __USING_WASM_EXCEPTIONS__ | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we call this function
getCppExceptionThrownObject? Or is thrown value a thing that is different?Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah these are confusing. So far in library_exceptions.js, I tried to use 'object' for
WebAssembly.Exceptionobject thrown, and 'value' for the user-thrown value. So this function takes an object and returns the user-thrown value. This got more confusing by the param name for this function isexwhile other functions' param name isobj, when they denote the same thing.At the same time libc++abi uses 'object' to mean the user-thrown value, as you can see in the name of
thrown_object_from_unwind_exception, which adds to the confusion. It's hard to rename it because that function is copied from cxa_exception.cpp, and changing the function name will make our libc++abi more confusing. I guess we should make these terms clearer.How about this?
getCppExceptionThrownObjectas you suggested.WebAssembly.Exception. So we rename currentobjparams in other functions, which meantWebAssembly.Exceptions, toex.If you think this sound fine, I'll make this change as a followup PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe "JSObject" or "JSException"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the thing you want to represent with "JSObject" or "JSException"?
WebAssembly.Exceptionor the user-thrown value(or object)? I guess the latter? In that case it's confusing in another way because this is a Wasm exception and that sounds like this is a JS exception thrown from JS, a foreign exception..There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WebAssembly.Exceptionis what I propose to refer to as JS object. The thrown object lives in wasm memory, as does the exception object, right? They are both allocated with malloc.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For example a longer name for this function might be something like
getCppThrownObjectFromJSCaughtObject?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure
JSCaughtObjectis clearer to someone who doesn't know this context. How about justgetCppThrownObjectFromWebassemblyException, with comments clarifying what this means? This name is long but I guess at least not misleading..There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, sounds reasonable. I think if was a user I would be looking for something do with the thing that I caught.. so I guess
JSCaughtObjectandWebassemblyExceptionboth describe that thing.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll explain in the comment that this is
WebAssembly.Exceptionobject that Wasm EH JS API provides.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Anyway, will do this in a followup. Thanks for the discussion!