Skip to content

[clr-interp] Detect Swift calling convention for transient-IL P/Invokes#128257

Open
kotlarmilos wants to merge 1 commit into
dotnet:mainfrom
kotlarmilos:kotlarmilos/interp-swift-pinvoke-transient-il
Open

[clr-interp] Detect Swift calling convention for transient-IL P/Invokes#128257
kotlarmilos wants to merge 1 commit into
dotnet:mainfrom
kotlarmilos:kotlarmilos/interp-swift-pinvoke-transient-il

Conversation

@kotlarmilos
Copy link
Copy Markdown
Member

@kotlarmilos kotlarmilos commented May 15, 2026

Description

#125177 implemented Swift calling convention detection in the interpreter's calli cookie generation. It inspects m_pMethodBeingCompiled->IsILStub() and walks the IL stub resolver to its StubTargetMethodDesc. This worked when forward P/Invokes were compiled as separate IL-stub DynamicMethodDescs.

#126509 changed P/Invoke compilation: the PInvokeMethodDesc itself now carries the transient IL with the calli to the native target. MethodDesc::IsILStub() returns true only for DynamicMethodDesc, so IsILStub() returns false for a transient-IL P/Invoke and pContextMD stays NULL.

With no context MD, CallStubGenerator::ComputeCallStub cannot enter either of its Swift detection branches. It falls through to the generic calling convention switch, leaves m_isSwiftCallConv = false, and:

Never calls RewriteSignatureForSwiftLowering, so the [ref SwiftError, ref SwiftError] validation never throws InvalidProgramException. Generates a generic stub that does not preserve x21 across the native call, so SwiftError is lost on return.

Fix

In CInterpreterJitInfo::GetCookieForInterpreterCalliSig, also pass the method being compiled as pContextMD when it is a P/Invoke. The IsPInvoke branch already in ComputeCallStub then detects the Swift calling convention via PInvoke::GetCallingConvention_IgnoreErrors.

Fixes #127897
Fixes #127898

After P/Invokes were converted to transient IL (dotnet#126509), the P/Invoke
MethodDesc itself carries the IL with the calli to the native target.
MethodDesc::IsILStub() returns true only for DynamicMethodDesc, so the
Swift detection in CInterpreterJitInfo::GetCookieForInterpreterCalliSig
from dotnet#125177 leaves pContextMD NULL for transient-IL P/Invokes.
ComputeCallStub cannot then detect the Swift calling convention, never
runs RewriteSignatureForSwiftLowering, and emits a stub that does not
preserve x21. SwiftError is lost on return, and the multiple-SwiftError
InvalidProgramException validation is skipped.

Pass the method-being-compiled as pContextMD when it is a P/Invoke. The
existing IsPInvoke branch in ComputeCallStub then resolves the unmanaged
calling convention via PInvoke::GetCallingConvention_IgnoreErrors.

Fixes dotnet#127897
Fixes dotnet#127898

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @BrzVlad, @janvorli, @kg
See info in area-owners.md if you want to be subscribed.

@kotlarmilos kotlarmilos requested a review from janvorli May 15, 2026 14:02
@kotlarmilos
Copy link
Copy Markdown
Member Author

/azp run runtime-interpreter

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@kotlarmilos kotlarmilos added this to the 11.0.0 milestone May 15, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates CoreCLR interpreter calli-cookie generation so transient-IL P/Invokes provide their PInvokeMethodDesc as context to call-stub generation, allowing Swift calling-convention handling to work consistently with the earlier IL-stub path.

Changes:

  • Preserves the existing IL-stub target MethodDesc context behavior.
  • Adds P/Invoke MethodDesc context for transient-IL P/Invokes.
  • Keeps calli-cookie generation uncached on the P/Invoke MethodDesc for unmanaged target calls.
Show a summary per file
File Description
src/coreclr/vm/jitinterface.cpp Updates CInterpreterJitInfo::GetCookieForInterpreterCalliSig to pass P/Invoke context for transient-IL P/Invoke calli stubs.

Copilot's findings

  • Files reviewed: 1/1 changed files
  • Comments generated: 0

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

Projects

None yet

2 participants