You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
With #2145 we will have the basic runtime mechanism for dispatching exceptions in place, however, much work still remains for the implementation to reach non-prototype level of quality.
Correctness:
Inter-frame dispatch and filter ordering.
Capture the shadow stack of the throwing frame inside the native exception.
Call dispatchers "on" this shadow stack (will require some dispatch pieces to be moved to native code).
Capture the list of pending fault/finally handlers in the first pass and invoke them in the second.
Should the managed or native exception carry this list? Can we avoid heap allocations for this case by using the shadow stack somehow?
Hard problem: dynamic stackalloc live into handlers.
Current plan of action is to implement this with a custom stack-like allocator.
We should find/write an extensive set of tests for this scenario.
We need to be able to identify the "top frame", one after which the exception will go unhanded. This implies wrapping RPI methods inside catch-all try/catch (perhaps a native one):
Exceptional exits from runtime imports will fail to restore the shadow stack, leading to shadow stack top corruption. This should be fixed by moving the shadow stack top restore logic into RPI frames.
wasi-wasm needs to be done using "manual" unwind (in both passes). Fortunately, that is feasible because exceptions cannot propagate across any managed<->unmanaged boundaries, even when it comes the the native runtime (in other words, the runtime can only invoke managed code when in a tail position).
Utilize WASM EH instead of JS-based Emscripten exceptions. We will still want to retain the C++-based implementation so that porting to non-WASM platforms is possible.
Better CQ heuristics for unwind index insertion: do not expand the group if the predecessor is in a different protected region, or is a throw helper block, etc.
Skip exceptional predecessors in unwind index insertion for which we know the edge is dead because the source block never throws.
Possible ideas:
Do not pass the shadow stack to the catch helper (somehow).
Throw in the catch helper instead of using rethrow (measured perf degradation is ~2.5x).
Create specialized catch helpers for common indices (2/3).
Define the unwind index on entry to catch handlers via the helper.
Shrink the EH info by not wasting leading bytes on padding. Will require adding support for unaligned relocations to the object writer, using Unsafe.ReadUnaliged at runtime and reworking the format a bit.
With #2145 we will have the basic runtime mechanism for dispatching exceptions in place, however, much work still remains for the implementation to reach non-prototype level of quality.
Correctness:
stackalloc
live into handlers.try/catch
(perhaps a native one):main
,Thread.Start
entrypoints.throw null
should be translated intothrow new NullReferenceException()
.src\tests\JIT\Methodical\eh\nested\general\methodthrowsinfinally_d.csproj
.wasi-wasm
needs to be done using "manual" unwind (in both passes). Fortunately, that is feasible because exceptions cannot propagate across any managed<->unmanaged boundaries, even when it comes the the native runtime (in other words, the runtime can only invoke managed code when in a tail position).Performance / code size:
Unsafe.ReadUnaliged
at runtime and reworking the format a bit.Debugging:
Documentation:
Code cleanup:
ExceptionHandling.cs
i. e. the usual EH dispatch, in the WASM build.The text was updated successfully, but these errors were encountered: