Skip to content

Commit ccc97cd

Browse files
authored
Create option for easy exception printing (#17219)
After #17064 and #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 `EXPORT_EXCEPTION_HANDLING_HELPERS` 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.
1 parent b6c666a commit ccc97cd

File tree

3 files changed

+43
-7
lines changed

3 files changed

+43
-7
lines changed

emcc.py

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

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

26182630
return target, wasm_target

src/settings.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,35 @@ 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 Wasm 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_EXPORT_EXCEPTION_HANDLING_HELPERS in tests/test_core.py for an
715+
// example usage.
716+
var EXPORT_EXCEPTION_HANDLING_HELPERS = false;
717+
689718
// Internal: Tracks whether Emscripten should link in exception throwing (C++
690719
// 'throw') support library. This does not need to be set directly, but pass
691720
// -fno-exceptions to the build disable exceptions support. (This is basically

tests/test_core.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1635,13 +1635,8 @@ def test_exceptions_rethrow_missing(self):
16351635

16361636
@no_wasm64('MEMORY64 does not yet support exceptions')
16371637
@with_both_eh_sjlj
1638-
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-
1638+
def test_EXPORT_EXCEPTION_HANDLING_HELPERS(self):
1639+
self.set_setting('EXPORT_EXCEPTION_HANDLING_HELPERS')
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)