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);