[Wasm RyuJit] Call Codegen Fixes for R2R#126778
[Wasm RyuJit] Call Codegen Fixes for R2R#126778adamperlin wants to merge 19 commits intodotnet:mainfrom
Conversation
…into locations in the R2R file work - Notably, a new level of indirection is needed
… in helper call codegen in Wasm
…-fix-call-codegen
|
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
There was a problem hiding this comment.
Pull request overview
This PR adjusts WebAssembly RyuJIT call lowering/emission for ReadyToRun (R2R) so call targets and PortableEntryPoints (PEPs) are loaded through the correct number of indirections when the host exposes symbols as indirection cells (indirection cell -> PEP -> target).
Changes:
- Add an extra indirection when materializing the R2R indirection-cell argument on WASM so the value passed reflects the PEP rather than the cell itself.
- Update WASM direct-call lowering for
IAT_PVALUEto dereference throughindirection cell -> PEP -> target. - Update WASM helper-call emission to load the PEP from the indirection cell (for managed helpers) and to load the final call target via an additional dereference.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
src/coreclr/jit/morph.cpp |
Adds a WASM-specific extra indirection when preparing the R2R indirection-cell argument so the runtime sees the expected PEP pointer. |
src/coreclr/jit/lower.cpp |
Ensures WASM IAT_PVALUE direct call targets are lowered with an additional dereference to reach the actual dispatch target. |
src/coreclr/jit/codegenwasm.cpp |
Fixes helper-call emission to load the PEP from the indirection cell and to load the indirect call target by dereferencing the PEP. |
| // Push the call target onto the wasm evaluation stack by dereferencing the PEP. | ||
| // Push the call target onto the wasm evaluation stack by dereferencing the indirection cell | ||
| // and then the PEP pointed to by the indirection cell. | ||
| assert(helperFunction.accessType == IAT_PVALUE); |
There was a problem hiding this comment.
See if it's possible to use the new ADDR_REL reloc type for this to avoid the i32.const <address>; i32.load pattern.
|
Maybe a picture would be useful here? I imagine it something like this: We have an indirection cell that refers to a PEP which refers to a function index, which we then call indirectly. |
This picture is missing the part that passes portable entrypoint address (the value fetched from R2R import table) as the hidden argument that it somewhat important detail. |
Ah I wasn't sure whether to include that bit, I've updated the diagram to include it! |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
Could I get another review when you have a moment @jkotas @jakobbotsch? I've updated the PR based on your feedback to explicitly handle the PEP calling convention transformation in lower. Thinking about this further exposed some dead case handling in Wasm codegen around the handling of the indirection cell arg which will now not be materialized on wasm. This also exposed a bug in the stackifier that I'm currently working through here: #127412 |
…lin/runtime into adamperlin/wasm-fix-call-codegen
5c9ee85 to
3981152
Compare
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
jakobbotsch
left a comment
There was a problem hiding this comment.
LGTM, feel free to address the ifdef nit in a follow up

Initially cherry-picked commit from #126662;
This PR:
WellKnownArg::R2RIndireictionCellfrom wasm code gen.Lowering Transformation Details
The lowering transformation introduces a temp local (call it
pep) to hold the PEP, which we then add to a managed call as a final parameter with associated ABI info. We then rewrite the control expr of the call to be*pep. This ensures that, conceptually, any call with an entrypoint of access typePVALUEwill be lowered to something roughly like the following, in C notation: