Uh oh!
There was an error while loading. Please reload this page.
Implement wasm JumpStubNode with signature-matched argument forwarding - #133248
Implement wasm JumpStubNode with signature-matched argument forwarding#133248jkoritzinsky with Copilot wants to merge 5 commits into
Conversation
|
Azure Pipelines: 16 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
Uh oh!
There was an error while loading. Please reload this page.
Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara |
Tagging subscribers to this area: @agocke, @dotnet/ilc-contrib |
There was a problem hiding this comment.
🟡 Changes recommended
The new Wasm stub uses return_call (tail-call proposal opcode), which can break compatibility on runtimes that don’t enable tail calls.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR adds a real Wasm implementation of JumpStubNode so address-taken method stubs can be emitted with a signature that matches the target method, forwarding all lowered Wasm arguments and transferring control to the target.
Changes:
- Add a new Wasm instruction kind and helper for
return_call. - Implement
JumpStubNode.EmitCodefor Wasm by computing the loweredWasmFuncType, emittinglocal.getfor each parameter, and invoking the target. - Update
AddressTakenMethodNodeto implementIMethodCodeNodeWithTypeSignatureso signature metadata can flow through for Wasm emission.
File summaries
| File | Description |
|---|---|
| src/coreclr/tools/Common/Compiler/ObjectWriter/WasmInstructions.cs | Adds ReturnCall opcode support and a ControlFlow.ReturnCall helper. |
| src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_Wasm/WasmJumpStubNode.cs | Implements Wasm JumpStubNode emission with signature-based argument forwarding and target invocation. |
| src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/AddressTakenMethodNode.cs | Switches to IMethodCodeNodeWithTypeSignature to propagate method signature info for Wasm stub emission. |
Review details
- Files reviewed: 3/3 changed files
- Comments generated: 1
- Review effort level: Lite
Uh oh!
There was an error while loading. Please reload this page.
| WasmLowering.LoweringFlags flags = WasmLowering.LoweringFlags.None; | ||
| if (signatureNode.HasGenericContextArg) | ||
| { | ||
| flags |= WasmLowering.LoweringFlags.HasGenericContextArg; | ||
| } | ||
| if (signatureNode.IsAsyncCall) | ||
| { | ||
| flags |= WasmLowering.LoweringFlags.IsAsyncCall; | ||
| } | ||
| if (signatureNode.IsUnmanagedCallersOnly) | ||
| { | ||
| flags |= WasmLowering.LoweringFlags.IsUnmanagedCallersOnly; | ||
| } | ||
| WasmFuncType signature = WasmLowering.GetSignature(signatureNode.Signature, flags).FuncType; |
There was a problem hiding this comment.
Not required for this PR, but we have similar logic in CorInfoImpl.recordCallSite(), CorInfoImpl.recordWasmManagedCallSig and WasmObjectWriter.RecordMethodDeclaration(). Should we add an overloads of WasmLowering.GetSignature() that take INodeWithTypeSignature or CORINFO_SIG_INFO* and generates the flags?
| protected override void EmitCode(NodeFactory factory, ref WasmEmitter encoder, bool relocsOnly) | ||
| { | ||
| throw new NotImplementedException(); | ||
| INodeWithTypeSignature signatureNode = (INodeWithTypeSignature)this; |
There was a problem hiding this comment.
JumpStubNode doesn't implement INodeWithTypeSignature, though its only implementation, AddressTakenMethodNode, does. Should we add INodeWithTypeSignature to JumpStubNode with abstract implementations?
| List<WasmExpr> expressions = new List<WasmExpr>(signature.Params.Types.Length + 1); | ||
| for (int i = 0; i < signature.Params.Types.Length; i++) | ||
| { | ||
| expressions.Add(Local.Get(i)); | ||
| } | ||
| expressions.Add(ControlFlow.ReturnCall(_target)); | ||
| encoder.FunctionBody = new WasmFunctionBody(signature, expressions.ToArray()); |
There was a problem hiding this comment.
nit: could we preallocate the array instead of using a List and ToArray()?
jtschuster
left a comment
There was a problem hiding this comment.
Couple nits, but not necessarily blocking.
jkoritzinsky
commented
Sep 5, 2026
@copilot please address all feedback from jtschuster. |
Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
Addressed in Note AI-generated via GitHub Copilot. |
There was a problem hiding this comment.
🟡 Changes recommended
WasmLowering.GetLoweringFlags(CORINFO_SIG_INFO*) currently treats any non-zero callConv flag bits (e.g., HASTHIS) as unmanaged, which can produce incorrect lowered signatures for normal managed calls.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 7/7 changed files
- Comments generated: 1
- Review effort level: Lite
Uh oh!
There was an error while loading. Please reload this page.
…lags Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
There was a problem hiding this comment.
🟢 Approval recommended
The changes are cohesive and consistent with existing Wasm lowering/signature patterns, and no correctness issues were identified in the updated emission and flag/signature propagation.
Review details
- Files reviewed: 7/7 changed files
- Comments generated: 0 new
- Review effort level: Lite
Implements
JumpStubNodefor Wasm so address-taken method stubs no longer throwNotImplementedExceptionduring emission. The stub now preserves the target method’s lowered Wasm signature, forwards all arguments, and transfers control to the target.Wasm JumpStub emission
JumpStubNode.EmitCodestub implementation with real body generation.INodeWithTypeSignature.local.getfor each parameter and calls the target symbol.Signature propagation for address-taken methods
AddressTakenMethodNodeto implementIMethodCodeNodeWithTypeSignature.