Cranelift: add get_exception_handler_address.#11629
Cranelift: add get_exception_handler_address.#11629alexcrichton merged 3 commits intobytecodealliance:mainfrom
Conversation
7a0489a to
ba1ae00
Compare
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`).
ba1ae00 to
52ec229
Compare
fitzgen
left a comment
There was a problem hiding this comment.
LGTM, thanks for whipping this up!
alexcrichton
left a comment
There was a problem hiding this comment.
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?
|
Updated, thanks @alexcrichton ! Will wait for your r+ as well before merging. |
|
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) |
* 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.
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 (ortry_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.,
LEAorADRorAUIPC+ADDI).