Reintroducing exnref #280
Description
In (https://github.com/WebAssembly/meetings/blob/main/main/2020/CG-09-15.md), the EH proposal was changed to remove exception packages as first class values. Since that time, this proposal was advanced to phase 3, implemented in the reference interpreter, in toolchains (LLVM and Binaryen), and implemented in all 3 web engines. Web browsers have subsequently enabled the feature by default. Today, there are web properties and applications that use the feature and thus there are binaries that use the feature for C++ exception handling in the wild.
Given those constraints, making any change to the proposal requires careful thought and consideration, as any change we do make could have a potential disruptive effect on producers, toolchains, and engines, and even deployed applications on the web. This proposal has also undergone a number of changes and long design discussions over the years that have taken a lot of time and energy to work through and resolve.
That said, offline discussions have led me to propose that we find a deft way to reintroduce exnref to this proposal, within a set of hard constraints. I am led to this because exnref solves a number of problems that weren’t fully anticipated when it was removed and were only encountered after-the-fact.
Problems
Several issues were identified that are either directly related to lack of exnref or related to the lexical rethrow construct introduced to avoid exnref, which adds a new form of storage to Wasm.
- Difficulty in handling the identity of thrown exceptions in the JS API spec.
- Complexity in the formal specification around lexical rethrow.
- Engine complexity around lexical rethrow, e.g. interpreters.
- Inability to CPS-transform (e.g. asyncify) Wasm functions with exceptions.
- Lack of exnref significantly restricts toolchains’ code transformations and sometimes leads to unnecessary duplication. (Specific feedback from J2CL authors).
Opportunities
Reintroducing exnref addresses the above problems and allows us to further improve the EH proposal.
- Simplification of formal specification.
- Simplification of JS specification.
- More opportunities for factoring exception handling code, e.g. it could be outlined into other functions.
- Simplification to engine decoding and validation.
- More leeway for code transformation and optimization in toolchains.
Constraints
We’re operating under a number of tight constraints and requirements.
- Don’t break the web. Binaries that work today must continue to work in the presence of adding exnref to the spec, up to some deprecation threshold (2).
- Should we decide to deprecate any part of the existing proposal, we must offer an (automated) migration path for binaries in the wild.
- Support asyncify/CPS transform.
- Avoid protracted design exploration. From offline discussions, there is no energy for any fundamental redesign among key stakeholders.
- Must document Web reality. The status quo of the proposal (i.e. Phase 3) has been “stable” and in browsers for more than a year. How it works should be documented with appropriate rigor, even if the final proposal were to deprecate any functionality.
Related issues/links
“Ambiguity/identity loss when (re)throwing external exceptions” #207
“Should wasm code be able to extract the externref from exceptions thrown from js?” #202
“Clarify how exception identity is tracked” #242
“Update JS API to better specify opaqueData exception identity” #250
“Issues discussed in J2CL” #158