diff --git a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IEnumerator1.cs b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IEnumerator1.cs
index 9eb83a639..34741288d 100644
--- a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IEnumerator1.cs
+++ b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IEnumerator1.cs
@@ -100,6 +100,7 @@ public static void IIteratorMethods(
{ Stloc_1 },
{ Ldloc_1 },
{ Ldloca_S, loc_2_currentNative },
+ { Conv_U },
{ Ldloc_1 },
{ Ldind_I },
{ Ldfld, interopDefinitions.IEnumerator1Vftbl.GetField("get_Current"u8) },
@@ -445,15 +446,13 @@ public static void ImplType(
module: module);
// Define the 'get_HasCurrent' method
- MethodDefinition hasCurrentMethod = InteropMethodDefinitionFactory.IEnumerator1Impl.HasCurrentOrMoveNext(
- nameUtf8: "get_HasCurrent"u8,
+ MethodDefinition hasCurrentMethod = InteropMethodDefinitionFactory.IEnumerator1Impl.get_HasCurrent(
enumeratorType: enumeratorType,
interopReferences: interopReferences,
module: module);
// Define the 'MoveNext' method
- MethodDefinition moveNextMethod = InteropMethodDefinitionFactory.IEnumerator1Impl.HasCurrentOrMoveNext(
- nameUtf8: "MoveNext"u8,
+ MethodDefinition moveNextMethod = InteropMethodDefinitionFactory.IEnumerator1Impl.MoveNext(
enumeratorType: enumeratorType,
interopReferences: interopReferences,
module: module);
diff --git a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IMapChangedEventArgs1.cs b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IMapChangedEventArgs1.cs
index 9bb8629da..e71bc9c99 100644
--- a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IMapChangedEventArgs1.cs
+++ b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IMapChangedEventArgs1.cs
@@ -3,7 +3,6 @@
using System.Runtime.InteropServices;
using AsmResolver.DotNet;
-using AsmResolver.DotNet.Code.Cil;
using AsmResolver.DotNet.Signatures;
using AsmResolver.PE.DotNet.Metadata.Tables;
using WindowsRuntime.InteropGenerator.Factories;
@@ -27,12 +26,14 @@ public static class IMapChangedEventArgs1
/// The for the args type.
/// The instance to use.
/// The instance to use.
+ /// The emit state for this invocation.
/// The interop module being built.
/// The resulting methods type.
public static void Methods(
GenericInstanceTypeSignature argsType,
InteropDefinitions interopDefinitions,
InteropReferences interopReferences,
+ InteropGeneratorEmitState emitState,
ModuleDefinition module,
out TypeDefinition argsMethodsType)
{
@@ -70,30 +71,18 @@ public static void Methods(
argsMethodsType.Methods.Add(collectionChangeMethod);
- // Define the 'Key' method as follows:
- //
- // public static Key(WindowsRuntimeObjectReference thisReference)
- MethodDefinition keyMethod = new(
- name: "Key"u8,
- attributes: MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Static,
- signature: MethodSignature.CreateStatic(
- returnType: elementType.Import(module),
- parameterTypes: [interopReferences.WindowsRuntimeObjectReference.Import(module).ToReferenceTypeSignature()]));
+ // Define the 'Key' method
+ MethodDefinition keyMethod = InteropMethodDefinitionFactory.IMapChangedEventArgs1Methods.Key(
+ argsType: argsType,
+ interopDefinitions: interopDefinitions,
+ interopReferences: interopReferences,
+ emitState: emitState,
+ module: module);
// Add and implement the 'Key' method
argsMethodsType.AddMethodImplementation(
declaration: interopReferences.IMapChangedEventArgsImpl1Key(elementType).Import(module),
method: keyMethod);
-
- // Create a method body for the 'Key' method
- keyMethod.CilMethodBody = new CilMethodBody()
- {
- Instructions =
- {
- { Ldnull },
- { Throw } // TODO
- }
- };
}
///
diff --git a/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IAsyncInfoMethods.cs b/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IAsyncInfoMethods.cs
index d48778629..7ca960f53 100644
--- a/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IAsyncInfoMethods.cs
+++ b/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IAsyncInfoMethods.cs
@@ -308,7 +308,7 @@ public static MethodDefinition GetResults(
{ Ldloc_1 },
{ Ldind_I },
{ Ldfld, vftblField },
- { Calli, WellKnownTypeSignatureFactory.get_TypedRetVal(resultType.GetAbiType(interopReferences).MakePointerType(), interopReferences).Import(module).MakeStandAloneSignature() },
+ { Calli, WellKnownTypeSignatureFactory.get_UntypedRetVal(interopReferences).Import(module).MakeStandAloneSignature() },
{ Call, interopReferences.RestrictedErrorInfoThrowExceptionForHR.Import(module) },
{ Leave_S, nop_finallyEnd.CreateLabel() },
diff --git a/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IEnumerator1Impl.cs b/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IEnumerator1Impl.cs
index 23789f3dd..12462937c 100644
--- a/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IEnumerator1Impl.cs
+++ b/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IEnumerator1Impl.cs
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-using System;
+using AsmResolver;
using AsmResolver.DotNet;
using AsmResolver.DotNet.Code.Cil;
using AsmResolver.DotNet.Signatures;
@@ -25,6 +25,48 @@ internal static partial class InteropMethodDefinitionFactory
///
public static class IEnumerator1Impl
{
+ ///
+ /// Creates a for the get_HasCurrent export method.
+ ///
+ /// The for the type.
+ /// The instance to use.
+ /// The interop module being built.
+ public static MethodDefinition get_HasCurrent(
+ GenericInstanceTypeSignature enumeratorType,
+ InteropReferences interopReferences,
+ ModuleDefinition module)
+ {
+ TypeSignature elementType = enumeratorType.TypeArguments[0];
+
+ return HasCurrentOrMoveNext(
+ methodName: "get_HasCurrent"u8,
+ adapterMethod: interopReferences.IEnumeratorAdapter1get_HasCurrent(elementType),
+ enumeratorType,
+ interopReferences: interopReferences,
+ module: module);
+ }
+
+ ///
+ /// Creates a for the MoveNext export method.
+ ///
+ /// The for the type.
+ /// The instance to use.
+ /// The interop module being built.
+ public static MethodDefinition MoveNext(
+ GenericInstanceTypeSignature enumeratorType,
+ InteropReferences interopReferences,
+ ModuleDefinition module)
+ {
+ TypeSignature elementType = enumeratorType.TypeArguments[0];
+
+ return HasCurrentOrMoveNext(
+ methodName: "MoveNext"u8,
+ adapterMethod: interopReferences.IEnumeratorAdapter1MoveNext(elementType),
+ enumeratorType,
+ interopReferences: interopReferences,
+ module: module);
+ }
+
///
/// Creates a for the get_Current export method.
///
@@ -124,71 +166,76 @@ public static MethodDefinition get_Current(
}
///
- /// Creates a for the get_Current export method.
+ /// Creates a for the GetMany export method.
///
- /// The name of the method to generate.
/// The for the type.
/// The instance to use.
/// The interop module being built.
- public static MethodDefinition HasCurrentOrMoveNext(
- ReadOnlySpan nameUtf8,
+ public static MethodDefinition GetMany(
GenericInstanceTypeSignature enumeratorType,
InteropReferences interopReferences,
ModuleDefinition module)
{
TypeSignature elementType = enumeratorType.TypeArguments[0];
- // Define the method as follows:
+ // Define the 'GetMany' method as follows:
//
// [UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
- // private static int (void* thisPtr, bool* result)
- MethodDefinition boolMethod = new(
- name: nameUtf8,
+ // private static int GetMany(void* thisPtr, uint itemsSize, * items, uint* writtenCount)
+ MethodDefinition currentMethod = new(
+ name: "GetMany"u8,
attributes: MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.Static,
signature: MethodSignature.CreateStatic(
returnType: module.CorLibTypeFactory.Int32,
parameterTypes: [
module.CorLibTypeFactory.Void.MakePointerType(),
- module.CorLibTypeFactory.Boolean.MakePointerType()]))
+ module.CorLibTypeFactory.UInt32,
+ elementType.GetAbiType(interopReferences).Import(module).MakePointerType(),
+ module.CorLibTypeFactory.UInt32.MakePointerType()]))
{
CustomAttributes = { InteropCustomAttributeFactory.UnmanagedCallersOnly(interopReferences, module) }
};
- // Get the reference to the target method to invoke
- MemberReference adapterMethod = nameUtf8.SequenceEqual("get_HasCurrent"u8)
- ? interopReferences.IEnumeratorAdapter1get_HasCurrent(elementType)
- : interopReferences.IEnumeratorAdapter1MoveNext(elementType);
-
// Labels for jumps
+ CilInstruction ldc_I4_e_pointer = new(Ldc_I4, unchecked((int)0x80004003));
CilInstruction nop_beforeTry = new(Nop);
- CilInstruction ldarg_1_tryStart = new(Ldarg_1);
+ CilInstruction ldarg_0_tryStart = new(Ldarg_0);
CilInstruction ldloc_0_returnHResult = new(Ldloc_0);
CilInstruction call_catchStartMarshalException = new(Call, interopReferences.RestrictedErrorInfoExceptionMarshallerConvertToUnmanaged.Import(module));
+ CilInstruction nop_implementation = new(Nop);
- // Create a method body for the 'get_HasCurrent' method
- boolMethod.CilMethodBody = new CilMethodBody()
+ // Create a method body for the 'get_Current' method
+ currentMethod.CilMethodBody = new CilMethodBody()
{
- // Declare 1 variable:
+ // Declare 2 variables:
// [0]: 'int' (the 'HRESULT' to return)
- LocalVariables = { new CilLocalVariable(module.CorLibTypeFactory.Int32) },
+ // [1]: 'IEnumeratorAdapter<>' (the adapter instance)
+ LocalVariables =
+ {
+ new CilLocalVariable(module.CorLibTypeFactory.Int32),
+ new CilLocalVariable(interopReferences.IEnumeratorAdapter1.MakeGenericReferenceType(elementType).Import(module))
+ },
Instructions =
{
- // Return 'E_POINTER' if the argument is 'null'
- { Ldarg_1 },
+ // Return 'E_POINTER' if either pointer argument is 'null'
+ { Ldarg_2 },
+ { Ldc_I4_0 },
+ { Conv_U },
+ { Beq_S, ldc_I4_e_pointer.CreateLabel() },
+ { Ldarg_3 },
{ Ldc_I4_0 },
{ Conv_U },
{ Bne_Un_S, nop_beforeTry.CreateLabel() },
- { Ldc_I4, unchecked((int)0x80004003) },
+ { ldc_I4_e_pointer },
{ Ret },
{ nop_beforeTry },
// '.try' code
- { ldarg_1_tryStart },
- { Ldarg_0 },
+ { ldarg_0_tryStart },
{ Call, interopReferences.ComInterfaceDispatchGetInstance.MakeGenericInstanceMethod(enumeratorType).Import(module) },
{ Call, interopReferences.IEnumeratorAdapter1GetInstance(elementType).Import(module) },
- { Callvirt, adapterMethod.Import(module) },
- { Stind_I1 },
+ { Stloc_1 },
+ { nop_implementation },
{ Ldc_I4_0 },
{ Stloc_0 },
{ Leave_S, ldloc_0_returnHResult.CreateLabel() },
@@ -207,7 +254,7 @@ public static MethodDefinition HasCurrentOrMoveNext(
new CilExceptionHandler
{
HandlerType = CilExceptionHandlerType.Exception,
- TryStart = ldarg_1_tryStart.CreateLabel(),
+ TryStart = ldarg_0_tryStart.CreateLabel(),
TryEnd = call_catchStartMarshalException.CreateLabel(),
HandlerStart = call_catchStartMarshalException.CreateLabel(),
HandlerEnd = ldloc_0_returnHResult.CreateLabel(),
@@ -216,80 +263,74 @@ public static MethodDefinition HasCurrentOrMoveNext(
}
};
- return boolMethod;
+ // TODO: replace 'nop_implementation' with the actual implementation of the method
+
+ return currentMethod;
}
///
- /// Creates a for the GetMany export method.
+ /// Creates a for the get_Current export method.
///
+ /// The name of the method to generate.
+ /// The adapter method to forward the call to.
/// The for the type.
/// The instance to use.
/// The interop module being built.
- public static MethodDefinition GetMany(
+ private static MethodDefinition HasCurrentOrMoveNext(
+ Utf8String methodName,
+ MemberReference adapterMethod,
GenericInstanceTypeSignature enumeratorType,
InteropReferences interopReferences,
ModuleDefinition module)
{
TypeSignature elementType = enumeratorType.TypeArguments[0];
- // Define the 'GetMany' method as follows:
+ // Define the method as follows:
//
// [UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
- // private static int GetMany(void* thisPtr, uint itemsSize, * items, uint* writtenCount)
- MethodDefinition currentMethod = new(
- name: "GetMany"u8,
+ // private static int (void* thisPtr, bool* result)
+ MethodDefinition boolMethod = new(
+ name: methodName,
attributes: MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.Static,
signature: MethodSignature.CreateStatic(
returnType: module.CorLibTypeFactory.Int32,
parameterTypes: [
module.CorLibTypeFactory.Void.MakePointerType(),
- module.CorLibTypeFactory.UInt32,
- elementType.GetAbiType(interopReferences).Import(module).MakePointerType(),
- module.CorLibTypeFactory.UInt32.MakePointerType()]))
+ module.CorLibTypeFactory.Boolean.MakePointerType()]))
{
CustomAttributes = { InteropCustomAttributeFactory.UnmanagedCallersOnly(interopReferences, module) }
};
// Labels for jumps
- CilInstruction ldc_I4_e_pointer = new(Ldc_I4, unchecked((int)0x80004003));
CilInstruction nop_beforeTry = new(Nop);
- CilInstruction ldarg_0_tryStart = new(Ldarg_0);
+ CilInstruction ldarg_1_tryStart = new(Ldarg_1);
CilInstruction ldloc_0_returnHResult = new(Ldloc_0);
CilInstruction call_catchStartMarshalException = new(Call, interopReferences.RestrictedErrorInfoExceptionMarshallerConvertToUnmanaged.Import(module));
- CilInstruction nop_implementation = new(Nop);
- // Create a method body for the 'get_Current' method
- currentMethod.CilMethodBody = new CilMethodBody()
+ // Create a method body for the 'get_HasCurrent' method
+ boolMethod.CilMethodBody = new CilMethodBody()
{
- // Declare 2 variables:
+ // Declare 1 variable:
// [0]: 'int' (the 'HRESULT' to return)
- // [1]: 'IEnumeratorAdapter<>' (the adapter instance)
- LocalVariables =
- {
- new CilLocalVariable(module.CorLibTypeFactory.Int32),
- new CilLocalVariable(interopReferences.IEnumeratorAdapter1.MakeGenericReferenceType(elementType).Import(module))
- },
+ LocalVariables = { new CilLocalVariable(module.CorLibTypeFactory.Int32) },
Instructions =
{
- // Return 'E_POINTER' if either pointer argument is 'null'
- { Ldarg_2 },
- { Ldc_I4_0 },
- { Conv_U },
- { Beq_S, ldc_I4_e_pointer.CreateLabel() },
- { Ldarg_3 },
+ // Return 'E_POINTER' if the argument is 'null'
+ { Ldarg_1 },
{ Ldc_I4_0 },
{ Conv_U },
{ Bne_Un_S, nop_beforeTry.CreateLabel() },
- { ldc_I4_e_pointer },
+ { Ldc_I4, unchecked((int)0x80004003) },
{ Ret },
{ nop_beforeTry },
// '.try' code
- { ldarg_0_tryStart },
+ { ldarg_1_tryStart },
+ { Ldarg_0 },
{ Call, interopReferences.ComInterfaceDispatchGetInstance.MakeGenericInstanceMethod(enumeratorType).Import(module) },
{ Call, interopReferences.IEnumeratorAdapter1GetInstance(elementType).Import(module) },
- { Stloc_1 },
- { nop_implementation },
+ { Callvirt, adapterMethod.Import(module) },
+ { Stind_I1 },
{ Ldc_I4_0 },
{ Stloc_0 },
{ Leave_S, ldloc_0_returnHResult.CreateLabel() },
@@ -308,7 +349,7 @@ public static MethodDefinition GetMany(
new CilExceptionHandler
{
HandlerType = CilExceptionHandlerType.Exception,
- TryStart = ldarg_0_tryStart.CreateLabel(),
+ TryStart = ldarg_1_tryStart.CreateLabel(),
TryEnd = call_catchStartMarshalException.CreateLabel(),
HandlerStart = call_catchStartMarshalException.CreateLabel(),
HandlerEnd = ldloc_0_returnHResult.CreateLabel(),
@@ -317,9 +358,7 @@ public static MethodDefinition GetMany(
}
};
- // TODO: replace 'nop_implementation' with the actual implementation of the method
-
- return currentMethod;
+ return boolMethod;
}
}
}
\ No newline at end of file
diff --git a/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IMapChangedEventArgs1Impl.cs b/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IMapChangedEventArgs1Impl.cs
index ba1fc64f3..44e0a7b8f 100644
--- a/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IMapChangedEventArgs1Impl.cs
+++ b/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IMapChangedEventArgs1Impl.cs
@@ -127,7 +127,7 @@ public static MethodDefinition Key(
//
// [UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
// private static int get_Key(void* thisPtr, * result)
- MethodDefinition currentMethod = new(
+ MethodDefinition get_KeyMethod = new(
name: "get_Key"u8,
attributes: MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.Static,
signature: MethodSignature.CreateStatic(
@@ -146,8 +146,8 @@ public static MethodDefinition Key(
CilInstruction call_catchStartMarshalException = new(Call, interopReferences.RestrictedErrorInfoExceptionMarshallerConvertToUnmanaged.Import(module));
CilInstruction nop_convertToUnmanaged = new(Nop);
- // Create a method body for the 'get_Current' method
- currentMethod.CilMethodBody = new CilMethodBody()
+ // Create a method body for the 'get_Key' method
+ get_KeyMethod.CilMethodBody = new CilMethodBody()
{
// Declare 1 variable:
// [0]: 'int' (the 'HRESULT' to return)
@@ -199,10 +199,10 @@ public static MethodDefinition Key(
// Track the method for rewrite to marshal the result value
emitState.TrackRetValValueMethodRewrite(
retValType: keyType,
- method: currentMethod,
+ method: get_KeyMethod,
marker: nop_convertToUnmanaged);
- return currentMethod;
+ return get_KeyMethod;
}
}
}
\ No newline at end of file
diff --git a/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IMapChangedEventArgs1Methods.cs b/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IMapChangedEventArgs1Methods.cs
new file mode 100644
index 000000000..47de4d65d
--- /dev/null
+++ b/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IMapChangedEventArgs1Methods.cs
@@ -0,0 +1,123 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using AsmResolver.DotNet;
+using AsmResolver.DotNet.Code.Cil;
+using AsmResolver.DotNet.Signatures;
+using AsmResolver.PE.DotNet.Cil;
+using AsmResolver.PE.DotNet.Metadata.Tables;
+using WindowsRuntime.InteropGenerator.Generation;
+using WindowsRuntime.InteropGenerator.References;
+using static AsmResolver.PE.DotNet.Cil.CilOpCodes;
+
+namespace WindowsRuntime.InteropGenerator.Factories;
+
+///
+internal partial class InteropMethodDefinitionFactory
+{
+ ///
+ /// Helpers for method types for Windows.Foundation.Collections.IMapChangedEventArgs<K> interfaces.
+ ///
+ public static class IMapChangedEventArgs1Methods
+ {
+ ///
+ /// Creates a for the get_Key export method.
+ ///
+ /// The for the args type.
+ /// The instance to use.
+ /// The instance to use.
+ /// The emit state for this invocation.
+ /// The interop module being built.
+ public static MethodDefinition Key(
+ GenericInstanceTypeSignature argsType,
+ InteropDefinitions interopDefinitions,
+ InteropReferences interopReferences,
+ InteropGeneratorEmitState emitState,
+ ModuleDefinition module)
+ {
+ TypeSignature keyType = argsType.TypeArguments[0];
+ TypeSignature keyAbiType = keyType.GetAbiType(interopReferences);
+
+ // Define the 'Key' method as follows:
+ //
+ // public static Key(WindowsRuntimeObjectReference thisReference)
+ MethodDefinition keyMethod = new(
+ name: "Key"u8,
+ attributes: MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Static,
+ signature: MethodSignature.CreateStatic(
+ returnType: keyType.Import(module),
+ parameterTypes: [interopReferences.WindowsRuntimeObjectReference.Import(module).ToReferenceTypeSignature()]))
+ { NoInlining = true };
+
+ // Declare the local variables:
+ // [0]: 'WindowsRuntimeObjectReferenceValue' (for 'thisValue')
+ // [1]: 'void*' (for 'thisPtr')
+ // [2]: '' (the native value that was retrieved)
+ CilLocalVariable loc_0_thisValue = new(interopReferences.WindowsRuntimeObjectReferenceValue.ToValueTypeSignature().Import(module));
+ CilLocalVariable loc_1_thisPtr = new(module.CorLibTypeFactory.Void.MakePointerType());
+ CilLocalVariable loc_2_keyNative = new(keyAbiType.Import(module));
+
+ // Jump labels
+ CilInstruction ldloca_s_0_tryStart = new(Ldloca_S, loc_0_thisValue);
+ CilInstruction ldloca_s_0_finallyStart = new(Ldloca_S, loc_0_thisValue);
+ CilInstruction nop_finallyEnd = new(Nop);
+ CilInstruction nop_returnValueRewrite = new(Nop);
+
+ // Create a method body for the 'Key' method
+ keyMethod.CilMethodBody = new CilMethodBody()
+ {
+ LocalVariables = { loc_0_thisValue, loc_1_thisPtr, loc_2_keyNative },
+ Instructions =
+ {
+ // Initialize 'thisValue'
+ { Ldarg_0 },
+ { Callvirt, interopReferences.WindowsRuntimeObjectReferenceAsValue.Import(module) },
+ { Stloc_0 },
+
+ // '.try' code
+ { ldloca_s_0_tryStart },
+ { Call, interopReferences.WindowsRuntimeObjectReferenceValueGetThisPtrUnsafe.Import(module) },
+ { Stloc_1 },
+ { Ldloc_1 },
+ { Ldloca_S, loc_2_keyNative },
+ { Conv_U },
+ { Ldloc_1 },
+ { Ldind_I },
+ { Ldfld, interopDefinitions.IMapChangedEventArgsVftbl.GetField("get_Key"u8) },
+ { Calli, WellKnownTypeSignatureFactory.get_UntypedRetVal(interopReferences).Import(module).MakeStandAloneSignature() },
+ { Call, interopReferences.RestrictedErrorInfoThrowExceptionForHR.Import(module) },
+ { Leave_S, nop_finallyEnd.CreateLabel() },
+
+ // '.finally' code
+ { ldloca_s_0_finallyStart },
+ { Call, interopReferences.WindowsRuntimeObjectReferenceValueDispose.Import(module) },
+ { Endfinally },
+ { nop_finallyEnd },
+
+ // Marshal and return the result
+ { nop_returnValueRewrite }
+ },
+ ExceptionHandlers =
+ {
+ new CilExceptionHandler
+ {
+ HandlerType = CilExceptionHandlerType.Finally,
+ TryStart = ldloca_s_0_tryStart.CreateLabel(),
+ TryEnd = ldloca_s_0_finallyStart.CreateLabel(),
+ HandlerStart = ldloca_s_0_finallyStart.CreateLabel(),
+ HandlerEnd = nop_finallyEnd.CreateLabel()
+ }
+ }
+ };
+
+ // Track rewriting the return value for this method
+ emitState.TrackReturnValueMethodRewrite(
+ returnType: keyType,
+ method: keyMethod,
+ marker: nop_returnValueRewrite,
+ source: loc_2_keyNative);
+
+ return keyMethod;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.KeyValuePairMethods.cs b/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.KeyValuePairMethods.cs
index fbf6871ee..e4de7cb9e 100644
--- a/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.KeyValuePairMethods.cs
+++ b/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.KeyValuePairMethods.cs
@@ -70,6 +70,7 @@ public static MethodDefinition get_KeyOrValue(
{
{ Ldarg_0 },
{ Ldloca_S, loc_0_resultNative },
+ { Conv_U },
{ Ldarg_0 },
{ Ldind_I },
{ Ldfld, vftblType.GetField(vftblMethodName) },
diff --git a/src/WinRT.Interop.Generator/Factories/WellKnownTypeDefinitionFactory.cs b/src/WinRT.Interop.Generator/Factories/WellKnownTypeDefinitionFactory.cs
index 2bacdf01d..d23c550b4 100644
--- a/src/WinRT.Interop.Generator/Factories/WellKnownTypeDefinitionFactory.cs
+++ b/src/WinRT.Interop.Generator/Factories/WellKnownTypeDefinitionFactory.cs
@@ -854,27 +854,9 @@ public static TypeDefinition IMapChangedEventArgsVftbl(InteropReferences interop
MethodSignature getRuntimeClassNameType = WellKnownTypeSignatureFactory.GetRuntimeClassNameImpl(interopReferences);
MethodSignature getTrustLevelType = WellKnownTypeSignatureFactory.GetTrustLevelImpl(interopReferences);
- // Signature for 'delegate* unmanaged[MemberFunction]'
- MethodSignature collectionChangeType = new(
- attributes: CallingConventionAttributes.Unmanaged,
- returnType: new CustomModifierTypeSignature(
- modifierType: interopReferences.CallConvMemberFunction,
- isRequired: false,
- baseType: module.CorLibTypeFactory.Int32),
- parameterTypes: [
- module.CorLibTypeFactory.Void.MakePointerType(),
- interopReferences.CollectionChange.MakePointerType()]);
-
- // Signature for 'delegate* unmanaged[MemberFunction]'
- MethodSignature keyType = new(
- attributes: CallingConventionAttributes.Unmanaged,
- returnType: new CustomModifierTypeSignature(
- modifierType: interopReferences.CallConvMemberFunction,
- isRequired: false,
- baseType: module.CorLibTypeFactory.Int32),
- parameterTypes: [
- module.CorLibTypeFactory.Void.MakePointerType(),
- module.CorLibTypeFactory.Void.MakePointerType()]);
+ // Get the 'IMapChangedEventArgs`1' signatures
+ MethodSignature collectionChangeType = WellKnownTypeSignatureFactory.IMapChangedEventArgs1get_CollectionChangeImpl(interopReferences);
+ MethodSignature keyType = WellKnownTypeSignatureFactory.get_UntypedRetVal(interopReferences);
// The vtable layout for 'IMapChangedEventArgs`1' looks like this:
//
diff --git a/src/WinRT.Interop.Generator/Factories/WellKnownTypeSignatureFactory.cs b/src/WinRT.Interop.Generator/Factories/WellKnownTypeSignatureFactory.cs
index d3b3acf21..9cd443c9f 100644
--- a/src/WinRT.Interop.Generator/Factories/WellKnownTypeSignatureFactory.cs
+++ b/src/WinRT.Interop.Generator/Factories/WellKnownTypeSignatureFactory.cs
@@ -203,26 +203,6 @@ public static MethodSignature set_Handler(InteropReferences interopReferences)
interopReferences.CorLibTypeFactory.Void.MakePointerType()]);
}
- ///
- /// Creates a type signature for the get accessor for some property returning a typed value.
- ///
- /// The type of return value.
- /// The instance to use.
- /// The resulting instance.
- public static MethodSignature get_TypedRetVal(TypeSignature returnValue, InteropReferences interopReferences)
- {
- // Signature for 'delegate* unmanaged[MemberFunction]*, HRESULT>'
- return new(
- attributes: CallingConventionAttributes.Unmanaged,
- returnType: new CustomModifierTypeSignature(
- modifierType: interopReferences.CallConvMemberFunction,
- isRequired: false,
- baseType: interopReferences.CorLibTypeFactory.Int32),
- parameterTypes: [
- interopReferences.CorLibTypeFactory.Void.MakePointerType(),
- returnValue.MakePointerType()]);
- }
-
///
/// Creates a type signature for the get accessor for some property returning an untyped value (any type).
///
@@ -810,6 +790,25 @@ public static MethodSignature IDictionary2ClearImpl(InteropReferences interopRef
return IList1ClearImpl(interopReferences);
}
+ ///
+ /// Creates a type signature for the get_CollectionChange vtable entry for some map changed event args.
+ ///
+ /// The instance to use.
+ /// The resulting instance.
+ public static MethodSignature IMapChangedEventArgs1get_CollectionChangeImpl(InteropReferences interopReferences)
+ {
+ // Signature for 'delegate* unmanaged[MemberFunction]'
+ return new(
+ attributes: CallingConventionAttributes.Unmanaged,
+ returnType: new CustomModifierTypeSignature(
+ modifierType: interopReferences.CallConvMemberFunction,
+ isRequired: false,
+ baseType: interopReferences.CorLibTypeFactory.Int32),
+ parameterTypes: [
+ interopReferences.CorLibTypeFactory.Void.MakePointerType(),
+ interopReferences.CollectionChange.MakePointerType()]);
+ }
+
///
/// Creates a type signature for in Guid values.
///
diff --git a/src/WinRT.Interop.Generator/Generation/InteropGenerator.Emit.cs b/src/WinRT.Interop.Generator/Generation/InteropGenerator.Emit.cs
index fff810735..d45f21950 100644
--- a/src/WinRT.Interop.Generator/Generation/InteropGenerator.Emit.cs
+++ b/src/WinRT.Interop.Generator/Generation/InteropGenerator.Emit.cs
@@ -1281,6 +1281,7 @@ private static void DefineIMapChangedEventArgsTypes(
argsType: typeSignature,
interopDefinitions: interopDefinitions,
interopReferences: interopReferences,
+ emitState: emitState,
module: module,
argsMethodsType: out TypeDefinition argsMethodsType);