Description
This issue has been created to track the implementation of exception handling support. This is based on the:
Current Status
Exception handling is currently supported by Web browsers and the Emscripten compiler tool chain, but at the time of writing there isn't support for the exception handling in WAMR. Indeed exception handling in general appears to be missing from many non-browser based runtimes.
Current Focus
This work focuses on the addition of support for exception handling in the WAMR runtime. It excludes work on language run times (e.g. C++ RT), and compiler tool chains. It is assumed that this work has already been completed, see current status above and Emscripten's existing support.
Plan
Source Control Guidance - Working Branch
Implementation will be done on a git branch, dev/exce_handling
. When the code on this branch is stable and the necessary quality bar and tests have passed then, this branch will be peer reviewed and merged into the main branch.
Feature Switch for Exception Handling
The feature will be developed with a switch, enabling it to be turned on / off. This feature switch is WAMR_BUILD_EXCE_HANDLING
and can be enabled by specifying the following at the command line:
cmake -DWAMR_BUILD_EXCE_HANDLING=1
This can be turned on / off within build-scripts or defined in config_common.cmake
.
This means that the code base will use the WASM_ENABLE_EXCE_HANDLING
C macro to control the feature in code, e.g.
#ifdef WASM_ENABLE_EXCE_HANDLING
// Feature implementatation here
// ...
// ...
#endif // WASM_ENABLE_EXCE_HANDLING
Approach
The proposal breaks down adding exception handling into three key steps, each step reflecting execution style used by WAMR.
- Step 1 : The initial focus will be on the fully interpreted mode, it will deliberatly exclude any JIT implementations. This allows us to ensure that the implementation is correct and behaves as expected.
- Step 2 : Once Step 1 is completed, Step 2 will start. This is focused on the Fast JIT and LLVM JIT implementation. At the moment this is considered out of scope.
- Step 3 : The final step focuses on the AOT implementation, ensuring that the behaviour and performance is a expected. At the moment this is considered out of scope.
At the time of writing focus is only on Step 1.
Step 1 Task Breakdown
- Complete the Design (Jan 2022)
- Implement and Manually Test the Classic Interpreter (estimated Feb 2022)
- Push to git branch
dev/exce_handling
- Peer review code for the Classic Interpreter
- Investigate implementation within JIT and AOT and determine feasibility/effort
- Possibly implement within JIT and AOT
- Integrate tests into WAMR test scripts and CI
- Push to git branch
dev/exce_handling
- Update documentation and push to git branch
dev/exce_handling
- Peer review code and tests and update as needed
- Merge to main branch once complete
Design
- The new Tag section will be parsed and stored, the new opcodes (try, catch, catch_all, delegate, throw, rethrow) will be added to the code.
- The new opcodes will be handled somewhat similarly to the if/block/loop/else opcodes, with a new label type for the "try".
- Exceptions are already "caught" in the current WAMR code in that a common method is now called when they occur due to executing op code
- Modification to the design will be needed to determine if within a try block, with the ability to search up through nested try blocks. If there is a catch, the enclosing label from the catch will be searched for and the stack shifted to that location.
- An additional modification to the existing WAMR exception handling is that the current strings used for exceptions will have to become a more easily matched type or enumeration.
Implementation
- Implementation will start with the parsing
- Interested parties are welcome to assist
Compatibility
See Open Questions (below).. .
Test
-
The spec cases in the spec proposal must pass: https://github.com/WebAssembly/exception-handling/tree/main/test/core
-
Once these tests pass manually, they will then need to be integrated into the existing WAMR scripted tests
-
See also LLVM tests for Exceptions such as
llvm-project\lldb\test\API\lang\cpp\exceptions\exceptions.cpp
and in\llvm-project\clang-tools-extra\test\clang-tidy\checkers\bugprone
Open Questions
-
The specification (documentation) is not clear, it currently has text which says "todo" (see below), can the authors provide any additional clarity?
Todo
Add prose for the following execution steps.
(...)
Todo
Add explainer note. -
When a catch is meant to catch just a specific type of exception mapping to the specific catch of that type might still be problematic, e.g. how to map from the "integer overflow" string in WAMR to a C++ std::overflow_error exception type and match that up to specific catch in the WASI bytecode - this has not yet been prototyped.
-
What other sources for C++ Exception examples exist?
-
What level of testing is appropriate for languages other than C++? - Was this addressed by the previous browser implementations?
-
Compiling to WASM with Emscripten using
-fwasm-exceptions
and compiling with clang++ using-fwasm-exceptions
produces different results; why ? -
Attempts to compile code with exceptions using the WASI SDK result in linker errors. It appears as if the C++ runtime used by WASI SDK excludes the functions necessary for correct handling of exceptions. Why is this the case? Are we just missing a linker statement to include an exception handling C++ RT library? Or is the C++ exception handling library simply missing from the WASI C++
-
For compatibility purposes it should be possible to build WASM binaries using Emscripten and execute these within the WAMR runtime. Initial investigation shows additional function links between the Emscripten WASM binary and the browser runtime. TASK: We should double check to ensure that no additional interdependcies exists.
-
Future Question (out of scope - for Step 3) : AOT will need to be implemented differently than the interpreter for handling the exceptions