Skip to content

Commit 2672557

Browse files
committed
Create option for easy exception printing
After emscripten-core#17064 and emscripten-core#17157 exception message printing is working, but it still requires adding a lot of functions to `EXPORTED_FUNCTIONS` and `DEFAULT_LIBRARY_FUNCS_TO_INLCLUDE`, which is difficult to use and requires users to know unnecessary library internals: https://github.com/emscripten-core/emscripten/blob/8c0fe77d8946a7ec2f73dfa74779ac957dd24530/tests/test_core.py#L1639-L1643 This adds `EXCEPTION_PRINTING_SUPPORT` option, which adds necessary symbols to those settings for easier use. This also exports functions with which you can get the C++ tag and the thrown value from `WebAssembly.Exception` object. Fixes emscripten-core#17114.
1 parent d75b460 commit 2672557

File tree

3 files changed

+41
-6
lines changed

3 files changed

+41
-6
lines changed

emcc.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2612,6 +2612,18 @@ def get_full_import_name(name):
26122612
if settings.WASM_EXCEPTIONS:
26132613
settings.REQUIRED_EXPORTS += ['__trap']
26142614

2615+
# Make `getExceptionMessage` and other necessary functions available for use.
2616+
if settings.EXCEPTION_PRINTING_SUPPORT:
2617+
# We also export refcount increasing and decreasing functions because if you
2618+
# catch an exception, be it an Emscripten exception or a Wasm exception, in
2619+
# JS, you may need to manipulate the refcount manually not to leak memory.
2620+
# What you need to do is different depending on the kind of EH you use
2621+
# (https://github.com/emscripten-core/emscripten/issues/17115).
2622+
settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$getExceptionMessage', '$incrementExceptionRefcount', '$decrementExceptionRefcount']
2623+
settings.EXPORTED_FUNCTIONS += ['getExceptionMessage', '___get_exception_message']
2624+
if settings.WASM_EXCEPTIONS:
2625+
settings.EXPORTED_FUNCTIONS += ['___cpp_exception', '___cxa_increment_exception_refcount', '___cxa_decrement_exception_refcount', '___thrown_object_from_unwind_exception']
2626+
26152627
apply_min_browser_versions(user_settings)
26162628

26172629
return target, wasm_target

src/settings.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,34 @@ var DISABLE_EXCEPTION_CATCHING = 1;
686686
// [compile+link] - affects user code at compile and system libraries at link
687687
var EXCEPTION_CATCHING_ALLOWED = [];
688688

689+
// Make the exception message printing function, 'getExceptionMessage' available
690+
// in the JS library for use, by adding necessary symbols to EXPORTED_FUNCTIONS
691+
// and DEFAULT_LIBRARY_FUNCS_TO_INCLUDE.
692+
//
693+
// This works with both Emscripten EH and Wasm EH. When you catch an exception
694+
// from JS, that gives you a user-thrown value in case of Emscripten EH, and a
695+
// WebAssembly.Exception object in case of Wasm EH. 'getExceptionMessage' takes
696+
// the user-thrown value in case of Emscripten EH and the WebAssembly.Exception
697+
// object in case of Wssm EH, meaning in both cases you can pass a caught
698+
// exception directly to the function.
699+
//
700+
// When used with Wasm EH, this option additionally provides these functions in
701+
// the JS library:
702+
// - getCppExceptionTag: Returns the C++ tag
703+
// - getCppExceptionThrownObjectFromWebAssemblyException:
704+
// Given an WebAssembly.Exception object, returns the actual user-thrown C++
705+
// object address in Wasm memory.
706+
//
707+
// Setting this option also adds refcount increasing and decreasing functions
708+
// ('incrementExceptionRefcount' and 'decrementExceptionRefcount') in the JS
709+
// library because if you catch an exception from JS, you may need to manipulate
710+
// the refcount manually not to leak memory. What you need to do is different
711+
// depending on the kind of EH you use
712+
// (https://github.com/emscripten-core/emscripten/issues/17115).
713+
//
714+
// See test_exception_message in tests/test_core.py for an example usage.
715+
var EXCEPTION_PRINTING_SUPPORT = false;
716+
689717
// Internal: Tracks whether Emscripten should link in exception throwing (C++
690718
// 'throw') support library. This does not need to be set directly, but pass
691719
// -fno-exceptions to the build disable exceptions support. (This is basically

tests/test_core.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1636,12 +1636,7 @@ def test_exceptions_rethrow_missing(self):
16361636
@no_wasm64('MEMORY64 does not yet support exceptions')
16371637
@with_both_eh_sjlj
16381638
def test_exception_message(self):
1639-
self.set_setting('DEFAULT_LIBRARY_FUNCS_TO_INCLUDE', ['$getExceptionMessage', '$incrementExceptionRefcount', '$decrementExceptionRefcount'])
1640-
self.set_setting('EXPORTED_FUNCTIONS', ['_main', 'getExceptionMessage', '___get_exception_message'])
1641-
if '-fwasm-exceptions' in self.emcc_args:
1642-
exports = self.get_setting('EXPORTED_FUNCTIONS')
1643-
self.set_setting('EXPORTED_FUNCTIONS', exports + ['___cpp_exception', '___cxa_increment_exception_refcount', '___cxa_decrement_exception_refcount', '___thrown_object_from_unwind_exception'])
1644-
1639+
self.set_setting('EXCEPTION_PRINTING_SUPPORT')
16451640
# FIXME Temporary workaround. See 'FIXME' in the test source code below for
16461641
# details.
16471642
if self.get_setting('DISABLE_EXCEPTION_CATCHING') == 0:

0 commit comments

Comments
 (0)