Skip to content

[wasm][R2R] Root interpreter thunks for closed static delegate targets - #134497

Merged
pavelsavara merged 6 commits into
dotnet:mainfrom
pavelsavara:wasm_r2r_closed_static_delegate_thunks
Sep 25, 2026
Merged

pavelsavara merged 6 commits into
dotnet:mainfrom
pavelsavara:wasm_r2r_closed_static_delegate_thunks

Conversation

@pavelsavara

Copy link
Copy Markdown
Member

Summary

Root the R2R-to-interpreter thunk needed when a Wasm delegate invocation reaches a closed static target, including a runtime-generated expression or dynamic call-site target.

The delegate call site has an instance signature, while the closed static target takes the bound object as an explicit first parameter. These can have identical physical Wasm parameter types but different interpreter thunk keys. For example, the caller can root IiTiiS4p while the dynamic target requires IiiiiS4p. When the latter is absent, entry-point preparation leaves the code field null and the R2R delegate invocation traps.

Changes

  • Construct the closed static target as a MethodSignature, prepending the bound object and using normal Wasm lowering rather than rewriting signature strings.
  • Root the corresponding interpreter thunk specifically when resolving Wasm delegate Invoke calls.
  • Add ten compiler layout cases covering nullable structs, return buffers, generic-context arguments, and async-continuation arguments.
  • Add a three-case runtime regression for a compiled expression capturing state and accepting a nullable argument, with static and generic-instance delegate controls.

No VM dispatch changes, diagnostic probes, or experimental switches are included.

Validation

On this branch, based directly on upstream main at 206bf81aa71b157cb03ae7ed1a42d1ed7d3aa2dc:

  • Compiler build and WasmArgumentLayoutTests: 77 passed, zero failures or skipped tests.
  • Patch whitespace checks passed.

Before transferring the same four-file patch from the investigation branch, using browser CoreCLR Release with trimming and R2R:

  • Full Microsoft.CSharp.Tests: 4,805 passed, zero failures or skipped tests, after removing diagnostics and rebuilding native/runtime-loader artifacts.
  • DynamicMethodCreateDelegateTests: 14 passed.
  • Negative control: disabling only the new thunk dependency makes the new nullable-expression regression request missing IiiS4p and trap; enabling it passes.
  • Generated and deployed test-image SHA-256 hashes matched.
  • A matched 39-image test-closure comparison measured an additional 31,368 bytes (0.0715%) of R2R output.

The complete browser runtime suite has not been rerun against a freshly rebuilt main-based runtime; this remains a draft. The broader expression LambdaTests slice also exposed an interpreter memory-access failure in InvokeComputedLambda, reproduced with the new dependency disabled at the same native instruction, and is not addressed here.

Scope

This is complementary to #134108, which supplies the closed static delegate return-buffer adapter. This PR supplies missing target thunk coverage, including scalar-returning targets; it does not implement that adapter.

Found while investigating #134200. That issue describes a broader startup failure, so this PR does not claim to resolve it in full.

Note

This pull request was prepared with GitHub Copilot assistance.

@azure-pipelines

Copy link
Copy Markdown
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.

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/crossgen-contrib
See info in area-owners.md if you want to be subscribed.

@pavelsavara pavelsavara added the arch-wasm WebAssembly architecture label Sep 23, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@pavelsavara pavelsavara added this to the 12.0.0 milestone Sep 23, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

The closed-static signature construction drops non-Static flags, which can leave required thunks unrooted.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity

Open (1)
What changed in this PR

Fixes missing WebAssembly R2R interpreter thunks for closed static delegate targets and adds regression coverage.

Changes:

  • Constructs lowered closed-static delegate signatures.
  • Roots matching interpreter thunks during delegate invocation.
  • Adds compiler layout and nullable-expression regression tests.
File Summary
src/​libraries/​tests.proj Re-enables Microsoft.CSharp tests for Wasm R2R.
src/​libraries/​Microsoft.CSharp/​tests/​DelegateInDynamicTests.cs Adds nullable closed-static delegate regression coverage.
src/​coreclr/​tools/​Common/​JitInterface/​WasmLowering.cs Builds closed-static delegate signatures; must preserve all original signature flags.
src/​coreclr/​tools/​aot/​ILCompiler.ReadyToRun/​JitInterface/​CorInfoImpl.ReadyToRun.cs Roots the required interpreter thunk.
src/​coreclr/​tools/​aot/​ILCompiler.ReadyToRun.Tests/​WasmArgumentLayoutTests.cs Tests ABI layouts and hidden arguments.

Comment thread src/coreclr/tools/Common/JitInterface/WasmLowering.cs Outdated
Build the target signature with the delegate Invoke flags, and cover default, varargs, and unmanaged calling conventions with a regression test.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: bd5418a9-09c6-4017-a1e1-edb2cf396b39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Fix hidden-argument flag handling and retain or narrow the test exclusion for the known dispatch failure.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity

Open (1)
Resolved since last review (1)

Source the interpreter-thunk lowering flags from the resolved call signature instead of the delegate Invoke MethodDesc, so a shared generic delegate's generic-context hidden argument is reflected, and skip unmanaged calls to match the other call-signature recording paths.
Copilot AI review requested due to automatic review settings September 24, 2026 08:00

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🔵 Needs a closer look

Full runtime validation remains incomplete, with a broader expression test failure still outside this change.

Review effort: Lite
Findings: None

Resolved since last review (1)

Delegate Invoke cannot be unmanaged, so assert the invariant and root the closed-static interpreter thunk unconditionally.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 24, 2026 16:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Address the three unresolved moderate findings before approval.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 Medium severity

Open (1)

@pavelsavara

Copy link
Copy Markdown
Member Author

/ba-g unrelated CI issues

@pavelsavara
pavelsavara enabled auto-merge (squash) September 25, 2026 09:10
@pavelsavara
pavelsavara merged commit 6727c91 into dotnet:main Sep 25, 2026
132 of 134 checks passed
@pavelsavara
pavelsavara deleted the wasm_r2r_closed_static_delegate_thunks branch September 25, 2026 16:07
lewing added a commit to lewing/runtime that referenced this pull request Sep 25, 2026
Consume GetClosedStaticDelegateTargetSignature from dotnet#134497 for the closed-static retbuf thunk dependency, removing the duplicate signature construction.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: bd5418a9-09c6-4017-a1e1-edb2cf396b39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arch-wasm WebAssembly architecture area-ReadyToRun

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants