Skip to content

Comments

Cranelift: add get_exception_handler_address.#11629

Merged
alexcrichton merged 3 commits intobytecodealliance:mainfrom
cfallin:oh-exception-handler-what-is-your-address
Sep 5, 2025
Merged

Cranelift: add get_exception_handler_address.#11629
alexcrichton merged 3 commits intobytecodealliance:mainfrom
cfallin:oh-exception-handler-what-is-your-address

Conversation

@cfallin
Copy link
Member

@cfallin cfallin commented Sep 5, 2025

This is designed to enable applications such as #11592 that use alternative unwinding mechanisms that may not necessarily want to walk a stack and look up exception tables. The idea is that whenever it would be valid to resume to an exception handler that is active on the stack, we can provide the same PC as a first-class runtime value that would be found in the exception table for the given handler edge. A "custom" resume step can then use this PC as a resume-point as long as it follows the relevant exception ABI (i.e.: restore SP, FP, any other saved registers that the exception ABI specifies, and provide appropriate payload value(s)).

Handlers are associated with edges out of try_calls (or try_call_indirects); and edges specifically, not blocks, because there could be multiple out-edges to one block. The instruction thus takes the block that contains the try-call and an immediate that indexes its exceptional edges.

This CLIF instruction required a bit of infrastructure to (i) allow naming raw blocks, not just block calls, as instruction arguments, and (ii) allow getting the MachLabel for any other lowered block during lowering. But given that, the lowerings themselves are straightforward uses of MachBuffer labels to fix-up PC-relative address-loading instructions (e.g., LEA or ADR or AUIPC+ADDI).

@cfallin cfallin requested a review from alexcrichton September 5, 2025 20:39
@cfallin cfallin requested a review from a team as a code owner September 5, 2025 20:39
@cfallin cfallin force-pushed the oh-exception-handler-what-is-your-address branch 2 times, most recently from 7a0489a to ba1ae00 Compare September 5, 2025 20:59
This is designed to enable applications such as bytecodealliance#11592 that use
alternative unwinding mechanisms that may not necessarily want to walk a
stack and look up exception tables. The idea is that whenever it would
be valid to resume to an exception handler that is active on the stack,
we can provide the same PC as a first-class runtime value that would be
found in the exception table for the given handler edge. A "custom"
resume step can then use this PC as a resume-point as long as it follows
the relevant exception ABI (i.e.: restore SP, FP, any other saved
registers that the exception ABI specifies, and provide appropriate
payload value(s)).

Handlers are associated with edges out of `try_call`s (or
`try_call_indirect`s); and edges specifically, not blocks, because there
could be multiple out-edges to one block. The instruction thus takes the
block that contains the try-call and an immediate that indexes its
exceptional edges.

This CLIF instruction required a bit of infrastructure to (i) allow
naming raw blocks, not just block calls, as instruction arguments, and
(ii) allow getting the MachLabel for any other lowered block during
lowering. But given that, the lowerings themselves are straightforward
uses of MachBuffer labels to fix-up PC-relative address-loading
instructions (e.g., `LEA` or `ADR` or `AUIPC`+`ADDI`).
@cfallin cfallin force-pushed the oh-exception-handler-what-is-your-address branch from ba1ae00 to 52ec229 Compare September 5, 2025 21:00
Copy link
Member

@fitzgen fitzgen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for whipping this up!

@cfallin cfallin enabled auto-merge September 5, 2025 21:11
@cfallin cfallin added this pull request to the merge queue Sep 5, 2025
Copy link
Member

@alexcrichton alexcrichton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this! This'll definitely help cleanup #11592. I think the main thing that I was missing was that the target in question is a MachLabel that the MachBuffer already has on its creation since it reserves for all blocks. That makes total sense in retrospect, but bypasses what I was worried about where new labels might need be created and bound to previously-added addresses.

Otherwise I'm curious below about the lookup of the handler in vcode where it doesn't have an adjust-by-1 I'd otherwise expect. Also I'm curious about how this interacts with tables that have a mixture of blocks/defaults/contexts, specifically contexts, and clarifying that the index effectively skips all context arguments?

@cfallin cfallin removed this pull request from the merge queue due to a manual request Sep 5, 2025
@cfallin
Copy link
Member Author

cfallin commented Sep 5, 2025

Updated, thanks @alexcrichton ! Will wait for your r+ as well before merging.

@alexcrichton
Copy link
Member

Oh protocol-wise I'm fine having feedback handled in a follow-up PR myself, but thanks though! I'm kind of tired so I'm going to call it for today, but I'll once-over on Monday (I suspect everything is fine though)

@alexcrichton alexcrichton added this pull request to the merge queue Sep 5, 2025
Merged via the queue into bytecodealliance:main with commit 4c01ee2 Sep 5, 2025
74 checks passed
@cfallin cfallin deleted the oh-exception-handler-what-is-your-address branch September 5, 2025 23:59
bongjunj pushed a commit to prosyslab/wasmtime that referenced this pull request Oct 20, 2025
* Cranelift: add get_exception_handler_address.

This is designed to enable applications such as bytecodealliance#11592 that use
alternative unwinding mechanisms that may not necessarily want to walk a
stack and look up exception tables. The idea is that whenever it would
be valid to resume to an exception handler that is active on the stack,
we can provide the same PC as a first-class runtime value that would be
found in the exception table for the given handler edge. A "custom"
resume step can then use this PC as a resume-point as long as it follows
the relevant exception ABI (i.e.: restore SP, FP, any other saved
registers that the exception ABI specifies, and provide appropriate
payload value(s)).

Handlers are associated with edges out of `try_call`s (or
`try_call_indirect`s); and edges specifically, not blocks, because there
could be multiple out-edges to one block. The instruction thus takes the
block that contains the try-call and an immediate that indexes its
exceptional edges.

This CLIF instruction required a bit of infrastructure to (i) allow
naming raw blocks, not just block calls, as instruction arguments, and
(ii) allow getting the MachLabel for any other lowered block during
lowering. But given that, the lowerings themselves are straightforward
uses of MachBuffer labels to fix-up PC-relative address-loading
instructions (e.g., `LEA` or `ADR` or `AUIPC`+`ADDI`).

* Review feedback.

* Review feedback: more tests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants