Skip to content

Conversation

@radekdoulik
Copy link
Member

The 2nd part generates reverse thunks for methods decorated with UnmanagedCallersOnlyAttribute. It also generates entrypoints when specified by the attribute.

These methods can be called either through the entrypoint or as function pointers (from IL or native code).

Sample code that will use the generated callhelpers:

using System.Runtime.InteropServices;

unsafe {
    var fn = (delegate* unmanaged<void>)&UMCOMethod;

    fn();
}

[UnmanagedCallersOnly]
static void UMCOMethod()
{
    Console.WriteLine("Hello from UMCOMethod");
}

The calls using function pointers use hashing tables with keys and fallback keys. The primary key is used when the assembly containing the UMCO method hasn't changed, and the key is based on assembly FQN and method token. The fallback key is used when the assembly has changed (for example during trimming), and is based on assembly name, method name, namespace, type, and number of parameters.

@radekdoulik radekdoulik added this to the Future milestone Nov 26, 2025
@radekdoulik radekdoulik requested a review from maraf as a code owner November 26, 2025 21:47
Copilot AI review requested due to automatic review settings November 26, 2025 21:47
@dotnet-policy-service
Copy link
Contributor

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

Copilot finished reviewing on behalf of radekdoulik November 26, 2025 21:50
Copy link
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 implements the second part of the call helpers generator for WASM and CoreCLR, focusing on reverse thunks for methods decorated with UnmanagedCallersOnlyAttribute. The implementation enables native code to call managed methods through generated C++ thunks, using a dual hash-based lookup system with primary keys (based on assembly FQN and method token) and fallback keys (based on method properties) to handle assembly changes during trimming.

Key changes:

  • Adds new PInvokeTableGenerator and PInvokeCollector classes for both mono and coreclr runtimes
  • Implements hash-based reverse thunk lookup with fallback mechanism in the CoreCLR VM
  • Generates C++ reverse thunks with lazy MethodDesc lookup and proper argument marshaling

Reviewed changes

Copilot reviewed 8 out of 10 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/tasks/WasmAppBuilder/mono/PInvokeTableGenerator.cs New generator for mono runtime that creates PInvoke tables and native-to-interp entry functions
src/tasks/WasmAppBuilder/mono/PInvokeCollector.cs New collector for mono that scans assemblies for PInvoke and callback methods
src/tasks/WasmAppBuilder/coreclr/PInvokeTableGenerator.cs New generator for CoreCLR that creates reverse thunks with dual-key hash table entries
src/tasks/WasmAppBuilder/coreclr/PInvokeCollector.cs New collector for CoreCLR that scans assemblies and builds callback metadata
src/tasks/WasmAppBuilder/coreclr/SignatureMapper.cs Adds TypeToNameType helper for converting types to name strings in generated code
src/tasks/WasmAppBuilder/WasmAppBuilder.csproj Updates target framework and output path configurations for the generator task
src/coreclr/vm/wasm/helpers.cpp Implements dual-key lookup mechanism with primary and fallback hash tables
src/coreclr/vm/wasm/callhelpers.hpp Adds fallbackKey field to ReverseThunkMapEntry structure
src/coreclr/vm/wasm/callhelpers-reverse.cpp Generated reverse thunks with lazy MethodDesc lookup for UnmanagedCallersOnly methods
src/coreclr/vm/wasm/callhelpers-interp-to-managed.cpp Removes duplicate entry in thunk table

Co-authored-by: Copilot <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants