JIT/wasm: pass type-context arg for LDVIRTFTN calls#129903
Conversation
Wasm routes all virtual calls through LDVIRTFTN, whose import path dropped the hidden instantiation arg some callees need (e.g. the array Address accessor), so the call_indirect signature was a param short and trapped. Add the arg in the wasm path; factor the shared logic into impGetInstParamArg. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
There was a problem hiding this comment.
Pull request overview
Fixes missing hidden instantiation (“type context” / CORINFO_CALLCONV_PARAMTYPE) argument insertion for Wasm virtual-call lowering that routes through the LDVIRTFTN (CORINFO_HELP_VIRTUAL_FUNC_PTR) importer path, by factoring the inst-param computation into a shared helper and using it from the Wasm LDVIRTFTN path.
Changes:
- Factor shared instantiation-parameter argument computation into
Compiler::impGetInstParamArg. - On
TARGET_WASM, insert the instantiation parameter for LDVIRTFTN-based virtual dispatch whensig->hasTypeArg(). - Update
compiler.hwith the new helper declaration.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/coreclr/jit/importercalls.cpp | Adds impGetInstParamArg helper and uses it to insert the instantiation param in the Wasm LDVIRTFTN import path. |
| src/coreclr/jit/compiler.h | Declares Compiler::impGetInstParamArg. |
| if (sig->hasTypeArg()) | ||
| { | ||
| GenTree* wasmInstParam = | ||
| impGetInstParamArg(pResolvedToken, callInfo, exactContextHnd, exactContextNeedsRuntimeLookup, | ||
| clsFlags, isReadonlyCall); | ||
| if (wasmInstParam == nullptr) | ||
| { | ||
| assert(compDonotInline()); | ||
| return TYP_UNDEF; | ||
| } | ||
|
|
||
| call->AsCall()->gtArgs.InsertInstParam(this, wasmInstParam); | ||
| } |
|
@adamperlin PTAL Inching closer to 100% pass on the JIT subtree Pri1 tests. |
Mirror the shared hasTypeArg() handling in the wasm LDVIRTFTN path: consume and clear lvaNextCallGenericContext before computing the type-context arg, so an explicit generic context is not ignored or leaked to a later call. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Good catch. In practice |
On wasm, virtual stub dispatch is unsupported, so all virtual calls are routed through LDVIRTFTN (
CORINFO_HELP_VIRTUAL_FUNC_PTR). That importer path reaches the call epilogue viagoto DEVIRT, jumping over the shared code that appends the hidden instantiation ("generic context") argument for calls that need one.Some callees reached this way still require that hidden argument -- most notably the multidimensional-array
Addressaccessor, which is markedCORINFO_CALLCONV_PARAMTYPEto capture the callsite element type for its store-type check. With the argument missing, the emitted wasmcall_indirectsignature is one parameter short of the callee (and its R2R-to-interpreter thunk), so the call traps at runtime. (Get/Settake no type arg, and rank <=GT_ARR_MAX_RANKarray accessors are inlined, so only the non-inlinedAddresspath was affected.)This is the wasm-R2R subset of #129622.
Fix: in the wasm LDVIRTFTN path, add the type-context argument when
sig->hasTypeArg(). The hidden-arg computation is factored out of the existinghasTypeArg()handling into a shared helperimpGetInstParamArgused by both call sites.Validation
#ifdef TARGET_WASM.