Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
using AsmResolver.PE.DotNet.Cil;
using AsmResolver.PE.DotNet.Metadata.Tables;
using WindowsRuntime.InteropGenerator.Factories;
using WindowsRuntime.InteropGenerator.References;
using WindowsRuntime.InteropGenerator.Generation;
using WindowsRuntime.InteropGenerator.Helpers;
using WindowsRuntime.InteropGenerator.References;
using static AsmResolver.PE.DotNet.Cil.CilOpCodes;

namespace WindowsRuntime.InteropGenerator.Builders;
Expand Down Expand Up @@ -71,28 +72,37 @@ public static void IIDs(
/// <param name="delegateType">The <see cref="TypeSignature"/> for the <see cref="Delegate"/> type.</param>
/// <param name="interopDefinitions">The <see cref="InteropDefinitions"/> instance to use.</param>
/// <param name="interopReferences">The <see cref="InteropReferences"/> instance to use.</param>
/// <param name="emitState">The emit state for this invocation.</param>
/// <param name="module">The interop module being built.</param>
/// <param name="implType">The resulting implementation type.</param>
public static void ImplType(
GenericInstanceTypeSignature delegateType,
InteropDefinitions interopDefinitions,
InteropReferences interopReferences,
InteropGeneratorEmitState emitState,
ModuleDefinition module,
out TypeDefinition implType)
{
MemberReference delegateInvokeMethod = interopReferences.DelegateInvoke(delegateType, module);

// Prepare the sender and arguments types. This path is only ever reached for valid
// generic Windows Runtime delegate types, and they all have exactly two type arguments.
TypeSignature senderType = ((MethodSignature)delegateInvokeMethod.Signature!).ParameterTypes[0];
TypeSignature argsType = ((MethodSignature)delegateInvokeMethod.Signature!).ParameterTypes[1];

// Define the 'Invoke' method as follows:
//
// [UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
// private static int Invoke(void* thisPtr, void* sender, void* e)
// private static int Invoke(void* thisPtr, <ABI_SENDER_TYPE> sender, <ABI_ARGS_TYPE> e)
MethodDefinition invokeMethod = new(
name: "Invoke"u8,
attributes: MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.Static,
signature: MethodSignature.CreateStatic(
returnType: module.CorLibTypeFactory.Int32,
parameterTypes: [
module.CorLibTypeFactory.Void.MakePointerType(),
module.CorLibTypeFactory.Void.MakePointerType(),
module.CorLibTypeFactory.Void.MakePointerType()]))
senderType.GetAbiType(interopReferences).Import(module),
argsType.GetAbiType(interopReferences).Import(module)]))
{
CustomAttributes = { InteropCustomAttributeFactory.UnmanagedCallersOnly(interopReferences, module) }
};
Expand All @@ -101,6 +111,8 @@ public static void ImplType(
CilInstruction ldloc_0_returnHResult = new(Ldloc_0);
CilInstruction ldarg_0_tryStart = new(Ldarg_0);
CilInstruction call_catchStartMarshalException = new(Call, interopReferences.RestrictedErrorInfoExceptionMarshallerConvertToUnmanaged.Import(module));
CilInstruction nop_parameter1Rewrite = new(Nop);
CilInstruction nop_parameter2Rewrite = new(Nop);

// Create a method body for the 'Invoke' method
invokeMethod.CilMethodBody = new CilMethodBody()
Expand All @@ -113,11 +125,9 @@ public static void ImplType(
// '.try' code
{ ldarg_0_tryStart },
{ Call, interopReferences.ComInterfaceDispatchGetInstance.MakeGenericInstanceMethod(delegateType).Import(module) },
{ Ldarg_1 },
{ Call, interopReferences.WindowsRuntimeObjectMarshallerConvertToManaged.Import(module) },
{ Ldarg_2 },
{ Call, interopReferences.WindowsRuntimeObjectMarshallerConvertToManaged.Import(module) },
{ Callvirt, interopReferences.DelegateInvoke(delegateType, module).Import(module) },
{ nop_parameter1Rewrite },
{ nop_parameter2Rewrite },
{ Callvirt, delegateInvokeMethod.Import(module) },
{ Ldc_I4_0 },
{ Stloc_0 },
{ Leave_S, ldloc_0_returnHResult.CreateLabel() },
Expand Down Expand Up @@ -145,6 +155,19 @@ public static void ImplType(
}
};

// Track rewriting the two parameters for this method
emitState.TrackManagedParameterMethodRewrite(
paraneterType: senderType,
method: invokeMethod,
marker: nop_parameter1Rewrite,
parameterIndex: 1);

emitState.TrackManagedParameterMethodRewrite(
paraneterType: argsType,
Comment on lines +160 to +166
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

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

Corrected spelling of 'paraneterType' to 'parameterType'.

Suggested change
paraneterType: senderType,
method: invokeMethod,
marker: nop_parameter1Rewrite,
parameterIndex: 1);
emitState.TrackManagedParameterMethodRewrite(
paraneterType: argsType,
parameterType: senderType,
method: invokeMethod,
marker: nop_parameter1Rewrite,
parameterIndex: 1);
emitState.TrackManagedParameterMethodRewrite(
parameterType: argsType,

Copilot uses AI. Check for mistakes.
Comment on lines +160 to +166
Copy link

Copilot AI Dec 18, 2025

Choose a reason for hiding this comment

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

Corrected spelling of 'paraneterType' to 'parameterType'.

Suggested change
paraneterType: senderType,
method: invokeMethod,
marker: nop_parameter1Rewrite,
parameterIndex: 1);
emitState.TrackManagedParameterMethodRewrite(
paraneterType: argsType,
parameterType: senderType,
method: invokeMethod,
marker: nop_parameter1Rewrite,
parameterIndex: 1);
emitState.TrackManagedParameterMethodRewrite(
parameterType: argsType,

Copilot uses AI. Check for mistakes.
method: invokeMethod,
marker: nop_parameter2Rewrite,
parameterIndex: 2);

Impl(
interfaceType: ComInterfaceType.InterfaceIsIUnknown,
ns: InteropUtf8NameFactory.TypeNamespace(delegateType),
Expand Down Expand Up @@ -387,6 +410,12 @@ public static void NativeDelegateType(
ModuleDefinition module,
out TypeDefinition nativeDelegateType)
{
MemberReference delegateInvokeMethod = interopReferences.DelegateInvoke(delegateType, module);

// Prepare the sender and arguments types (same as for the 'Impl' type above)
TypeSignature senderType = ((MethodSignature)delegateInvokeMethod.Signature!).ParameterTypes[0];
TypeSignature argsType = ((MethodSignature)delegateInvokeMethod.Signature!).ParameterTypes[1];

// We're declaring an 'internal static class' type
nativeDelegateType = new(
ns: InteropUtf8NameFactory.TypeNamespace(delegateType),
Expand All @@ -396,9 +425,6 @@ public static void NativeDelegateType(

module.TopLevelTypes.Add(nativeDelegateType);

// Construct the 'Invoke' method on the delegate type, so we can get the constructed parameter types
MethodSignature invokeSignature = delegateType.Import(module).Resolve()!.GetMethod("Invoke"u8).Signature!.InstantiateGenericTypes(GenericContext.FromType(delegateType));

// Define the 'Invoke' method as follows:
//
// public static void Invoke(WindowsRuntimeObjectReference objectReference, <PARAMETER#0> arg0, <PARAMETER#1> arg1)
Expand All @@ -409,8 +435,8 @@ public static void NativeDelegateType(
returnType: module.CorLibTypeFactory.Void,
parameterTypes: [
interopReferences.WindowsRuntimeObjectReference.ToReferenceTypeSignature().Import(module),
invokeSignature.ParameterTypes[0].Import(module),
invokeSignature.ParameterTypes[1].Import(module)]))
senderType.Import(module),
argsType.Import(module)]))
{ CilMethodBody = new CilMethodBody() };

nativeDelegateType.Methods.Add(invokeMethod);
Expand Down Expand Up @@ -626,6 +652,7 @@ public static void ComWrappersMarshallerAttribute(
/// <param name="get_IidMethod">The 'IID' get method for the 'IDelegate' interface.</param>
/// <param name="get_ReferenceIidMethod">The resulting 'IID' get method for the boxed 'IDelegate' interface.</param>
/// <param name="interopReferences">The <see cref="InteropReferences"/> instance to use.</param>
/// <param name="emitState">The emit state for this invocation.</param>
/// <param name="module">The module that will contain the type being created.</param>
/// <param name="marshallerType">The resulting marshaller type.</param>
public static void Marshaller(
Expand All @@ -634,6 +661,7 @@ public static void Marshaller(
MethodDefinition get_IidMethod,
MethodDefinition get_ReferenceIidMethod,
InteropReferences interopReferences,
InteropGeneratorEmitState emitState,
ModuleDefinition module,
out TypeDefinition marshallerType)
{
Expand Down Expand Up @@ -744,6 +772,9 @@ public static void Marshaller(
};

marshallerType.Methods.Add(unboxToUnmanagedMethod);

// Track the type (it may be needed to marshal parameters or return values)
emitState.TrackTypeDefinition(marshallerType, delegateType, "Marshaller");
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,32 +227,6 @@ public static void ComWrappersMarshallerAttribute(
out marshallerType);
}

/// <summary>
/// Creates a new type definition for the marshaller of some <c>IAsyncActionWithProgress&lt;TProgress&gt;</c> interface.
/// </summary>
/// <param name="actionType">The <see cref="GenericInstanceTypeSignature"/> for the async action type.</param>
/// <param name="operationComWrappersCallbackType">The <see cref="TypeDefinition"/> instance returned by <see cref="ComWrappersCallbackType"/>.</param>
/// <param name="get_IidMethod">The 'IID' get method for <paramref name="actionType"/>.</param>
/// <param name="interopReferences">The <see cref="InteropReferences"/> instance to use.</param>
/// <param name="module">The module that will contain the type being created.</param>
/// <param name="marshallerType">The resulting marshaller type.</param>
public static void Marshaller(
GenericInstanceTypeSignature actionType,
TypeDefinition operationComWrappersCallbackType,
MethodDefinition get_IidMethod,
InteropReferences interopReferences,
ModuleDefinition module,
out TypeDefinition marshallerType)
{
InteropTypeDefinitionBuilder.Marshaller(
typeSignature: actionType,
interfaceComWrappersCallbackType: operationComWrappersCallbackType,
get_IidMethod: get_IidMethod,
interopReferences: interopReferences,
module: module,
out marshallerType);
}

/// <summary>
/// Creates a new type definition for the interface implementation of some <c>IAsyncActionWithProgress&lt;TProgress&gt;</c> interface.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,32 +180,6 @@ public static void ComWrappersMarshallerAttribute(
out marshallerType);
}

/// <summary>
/// Creates a new type definition for the marshaller of some <c>IAsyncOperation1&lt;TResult&gt;</c> interface.
/// </summary>
/// <param name="operationType">The <see cref="GenericInstanceTypeSignature"/> for the async operation type.</param>
/// <param name="operationComWrappersCallbackType">The <see cref="TypeDefinition"/> instance returned by <see cref="ComWrappersCallbackType"/>.</param>
/// <param name="get_IidMethod">The 'IID' get method for <paramref name="operationType"/>.</param>
/// <param name="interopReferences">The <see cref="InteropReferences"/> instance to use.</param>
/// <param name="module">The module that will contain the type being created.</param>
/// <param name="marshallerType">The resulting marshaller type.</param>
public static void Marshaller(
GenericInstanceTypeSignature operationType,
TypeDefinition operationComWrappersCallbackType,
MethodDefinition get_IidMethod,
InteropReferences interopReferences,
ModuleDefinition module,
out TypeDefinition marshallerType)
{
InteropTypeDefinitionBuilder.Marshaller(
typeSignature: operationType,
interfaceComWrappersCallbackType: operationComWrappersCallbackType,
get_IidMethod: get_IidMethod,
interopReferences: interopReferences,
module: module,
out marshallerType);
}

/// <summary>
/// Creates a new type definition for the interface implementation of some <c>IAsyncOperation1&lt;TResult&gt;</c> interface.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,32 +222,6 @@ public static void ComWrappersMarshallerAttribute(
out marshallerType);
}

/// <summary>
/// Creates a new type definition for the marshaller of some <c>IAsyncOperationWithProgress&lt;TResult, TProgress&gt;</c> interface.
/// </summary>
/// <param name="operationType">The <see cref="GenericInstanceTypeSignature"/> for the async operation type.</param>
/// <param name="operationComWrappersCallbackType">The <see cref="TypeDefinition"/> instance returned by <see cref="ComWrappersCallbackType"/>.</param>
/// <param name="get_IidMethod">The 'IID' get method for <paramref name="operationType"/>.</param>
/// <param name="interopReferences">The <see cref="InteropReferences"/> instance to use.</param>
/// <param name="module">The module that will contain the type being created.</param>
/// <param name="marshallerType">The resulting marshaller type.</param>
public static void Marshaller(
GenericInstanceTypeSignature operationType,
TypeDefinition operationComWrappersCallbackType,
MethodDefinition get_IidMethod,
InteropReferences interopReferences,
ModuleDefinition module,
out TypeDefinition marshallerType)
{
InteropTypeDefinitionBuilder.Marshaller(
typeSignature: operationType,
interfaceComWrappersCallbackType: operationComWrappersCallbackType,
get_IidMethod: get_IidMethod,
interopReferences: interopReferences,
module: module,
out marshallerType);
}

/// <summary>
/// Creates a new type definition for the interface implementation of some <c>IAsyncOperationWithProgress&lt;TResult, TProgress&gt;</c> interface.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -729,37 +729,6 @@ public static void ComWrappersMarshallerAttribute(
out marshallerType);
}

/// <summary>
/// Creates a new type definition for the marshaller of some <c>IMap&lt;K, V&gt;</c> interface.
/// </summary>
/// <param name="dictionaryType">The <see cref="GenericInstanceTypeSignature"/> for the <see cref="System.Collections.Generic.IDictionary{TKey, TValue}"/> type.</param>
/// <param name="dictionaryComWrappersCallbackType">The <see cref="TypeDefinition"/> instance returned by <see cref="ComWrappersCallbackType"/>.</param>
/// <param name="get_IidMethod">The 'IID' get method for <paramref name="dictionaryType"/>.</param>
/// <param name="interopReferences">The <see cref="InteropReferences"/> instance to use.</param>
/// <param name="emitState">The emit state for this invocation.</param>
/// <param name="module">The module that will contain the type being created.</param>
/// <param name="marshallerType">The resulting marshaller type.</param>
public static void Marshaller(
GenericInstanceTypeSignature dictionaryType,
TypeDefinition dictionaryComWrappersCallbackType,
MethodDefinition get_IidMethod,
InteropReferences interopReferences,
InteropGeneratorEmitState emitState,
ModuleDefinition module,
out TypeDefinition marshallerType)
{
InteropTypeDefinitionBuilder.Marshaller(
typeSignature: dictionaryType,
interfaceComWrappersCallbackType: dictionaryComWrappersCallbackType,
get_IidMethod: get_IidMethod,
interopReferences: interopReferences,
module: module,
out marshallerType);

// Track the type (it may be needed to marshal parameters or return values)
emitState.TrackTypeDefinition(marshallerType, dictionaryType, "Marshaller");
}

/// <summary>
/// Creates a new type definition for the interface implementation of some <c>IMap&lt;K, V&gt;</c> interface.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -342,37 +342,6 @@ public static void ComWrappersMarshallerAttribute(
out marshallerType);
}

/// <summary>
/// Creates a new type definition for the marshaller of some <c>IIterable&lt;T&gt;</c> interface.
/// </summary>
/// <param name="enumerableType">The <see cref="GenericInstanceTypeSignature"/> for the <see cref="System.Collections.Generic.IEnumerable{T}"/> type.</param>
/// <param name="enumerableComWrappersCallbackType">The <see cref="TypeDefinition"/> instance returned by <see cref="ComWrappersCallbackType"/>.</param>
/// <param name="get_IidMethod">The 'IID' get method for <paramref name="enumerableType"/>.</param>
/// <param name="interopReferences">The <see cref="InteropReferences"/> instance to use.</param>
/// <param name="emitState">The emit state for this invocation.</param>
/// <param name="module">The module that will contain the type being created.</param>
/// <param name="marshallerType">The resulting marshaller type.</param>
public static void Marshaller(
GenericInstanceTypeSignature enumerableType,
TypeDefinition enumerableComWrappersCallbackType,
MethodDefinition get_IidMethod,
InteropReferences interopReferences,
InteropGeneratorEmitState emitState,
ModuleDefinition module,
out TypeDefinition marshallerType)
{
InteropTypeDefinitionBuilder.Marshaller(
typeSignature: enumerableType,
interfaceComWrappersCallbackType: enumerableComWrappersCallbackType,
get_IidMethod: get_IidMethod,
interopReferences: interopReferences,
module: module,
out marshallerType);

// Track the type (it may be needed to marshal parameters or return values)
emitState.TrackTypeDefinition(marshallerType, enumerableType, "Marshaller");
}

/// <summary>
/// Creates a new type definition for the interface implementation of some <c>IIterable&lt;T&gt;</c> interface.
/// </summary>
Expand Down
Loading
Loading