Skip to content

[interpreter] Resolve open virtual delegates invoked through the shuffle thunk (wasm, Apple mobile) - #134699

Open
lewing wants to merge 9 commits into
mainfrom
lewing-wasm-r2r-open-virtual-delegate
Open

lewing wants to merge 9 commits into
mainfrom
lewing-wasm-r2r-open-virtual-delegate

Conversation

@lewing

@lewing lewing commented Sep 26, 2026 •

Copy link
Copy Markdown
Member

Invoking an open virtual delegate from compiled code crashes CoreCLR on platforms that use the interpreter with cached interface dispatch:

Cause

For an open virtual delegate, _methodPtr is the delegate shuffle thunk and _methodPtrAux is CID_VirtualOpenDelegateDispatch. The shuffle thunk is an IL stub that does calli _methodPtrAux, and on these platforms it runs in the interpreter.

CID_VirtualOpenDelegateDispatch can't be invoked through a plain calli, because it expects the address of _methodPtrAux in a hidden argument that calli cannot express:

  • On arm64 it expects the address of _methodPtrAux in x11, which the interpreter's calli doesn't set.
  • On wasm it is only a PORTABILITY_ASSERT stub, not a portable entry point, so PortableEntryPoint::GetMethodDesc returns garbage.

Interpreted callers don't hit this, because INTOP_CALLDELEGATE already recognizes the value and skips the shuffle thunk. Compiled (R2R) callers invoke _methodPtr directly and reach the calli.

Change

This is an interpreter-side workaround for #134733. The IL shuffle thunk's calli can't pass the hidden argument that open virtual delegate dispatch stubs expect, under both cached interface dispatch and virtual stub dispatch. The general fix belongs in the shuffle thunk and is tracked by that issue.

Validation (local)

Configuration Test Without fix With fix
browser-wasm CoreCLR ReadyToRun + trimming (Chrome) System.Linq.Expressions.Tests Trap in PrepareInterpreterCode 35,116 run, 0 failed
browser-wasm CoreCLR ReadyToRun + trimming (Chrome) System.Runtime.Tests DelegateTests Trap in the new test 58 run, 0 failed
maccatalyst-arm64 CoreCLR Release System.Runtime.Tests (full) Hang (crash in CID_VirtualOpenDelegateDispatchWorker) 79,181 run, 0 failed

The browser Debug build compiles the new asserts.

Resolves #134261

Note

This PR description was generated with GitHub Copilot.

lewing and others added 2 commits September 25, 2026 23:05
…e shuffle thunk

When compiled (R2R) code invokes an open virtual delegate on portable entry point
platforms, it calls the IL delegate shuffle thunk, which does a calli on
_methodPtrAux. For open virtual delegates that is CID_VirtualOpenDelegateDispatch,
which is not a portable entry point, so treating it as one read a garbage
MethodDesc and trapped in PrepareInterpreterCode. Resolve the virtual target in
INTOP_CALLI the same way INTOP_CALLDELEGATE does.

Re-enable System.Linq.Expressions.Tests on the browser CoreCLR R2R lane.

Fixes #134261

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Extract ResolveOpenVirtualDelegateTarget for INTOP_CALLDELEGATE and INTOP_CALLI,
use #else for the portable entry point branch, and add a DelegateTests case that
invokes open virtual delegates (class override, boxed struct, enum, interface).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@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: @JulieLeeMSFT, @BrzVlad, @janvorli
See info in area-owners.md if you want to be subscribed.

@lewing
lewing requested a review from radekdoulik September 26, 2026 04:41
@lewing lewing added the arch-wasm WebAssembly architecture label Sep 26, 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.

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

🟢 Approval recommended

No blocking issues remain; only a documentation nit was noted.

Review effort: Lite
Findings: 1 Low severity

Open (1)
What changed in this PR

Fixes browser-Wasm CoreCLR ReadyToRun crashes when invoking open virtual delegates.

Changes:

  • Resolves open virtual delegate targets in interpreter calli handling.
  • Shares delegate resolution logic and adds regression coverage.
  • Re-enables LINQ Expressions tests for the affected lane.
File Summary
src/​libraries/​tests.proj Re-enables the affected ReadyToRun test project.
src/​libraries/​System.Runtime/​tests/​System.Runtime.Tests/​System/​DelegateTests.cs Adds open virtual delegate dispatch tests.
src/​coreclr/​vm/​interpexec.cpp Resolves portable open virtual delegate targets; update the related preprocessor guard comments.

Comment thread src/coreclr/vm/interpexec.cpp Outdated
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…Mono AOT

Mono AOT on browser crashes invoking an open-instance interface delegate
(#134707).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@lewing
lewing requested a review from pavelsavara September 26, 2026 16:29
…-dispatch platforms

CID_VirtualOpenDelegateDispatch needs the delegate (on arm64 it reads &_methodPtrAux
from x11), so interpreted shuffle thunks cannot invoke it through calli. On
maccatalyst/iOS/tvOS the interpreter called the native stub without x11 set and
crashed in CID_VirtualOpenDelegateDispatchWorker (found by the new DelegateTests on
maccatalyst-arm64 CoreCLR). Apply the INTOP_CALLI resolution under
FEATURE_CACHED_INTERFACE_DISPATCH instead of only FEATURE_PORTABLE_ENTRYPOINTS.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@lewing lewing changed the title [wasm][interpreter] Resolve open virtual delegates invoked through the shuffle thunk [interpreter] Resolve open virtual delegates invoked through the shuffle thunk (wasm, Apple mobile) Sep 26, 2026
@lewing
lewing requested a review from vitek-karas September 26, 2026 17:37
@lewing lewing added os-maccatalyst MacCatalyst OS and removed arch-wasm WebAssembly architecture labels Sep 26, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'os-maccatalyst': @vitek-karas, @kotlarmilos, @steveisok, @akoeplinger
See info in area-owners.md if you want to be subscribed.

@lewing lewing added the arch-wasm WebAssembly architecture label Sep 26, 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.

@lewing

lewing commented Sep 26, 2026 •

Copy link
Copy Markdown
Member Author

The tests that were added showed that the problem was general to CID platforms so the PR has been updated to fix the apple mobile platforms as well. That means this is probably a candidate for a backport as well.

Comment thread src/coreclr/vm/interpexec.cpp Outdated
…calli

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Comment thread src/coreclr/vm/comdelegate.cpp Outdated
Comment thread src/coreclr/vm/interpexec.cpp Outdated
@jkotas

jkotas commented Sep 27, 2026

Copy link
Copy Markdown
Member

LGTM otherwise

lewing and others added 2 commits September 27, 2026 09:35
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@lewing
lewing enabled auto-merge (squash) September 27, 2026 15:05

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[browser][CoreCLR][R2R] System.Linq.Expressions tests trap in PrepareInterpreterCode

3 participants