Skip to content
Draft
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ public static void NativeDelegateType(
{ Stloc_0 },
{ nop_try_this },

// Arguments loading inside outer 'try/catch' block
// Arguments loading inside outer 'try/finally' block
{ nop_try_sender },
{ nop_try_args },

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public static void Vftbl(
// We can share the vtable type for 'void*' when both key and value types are reference types
if (isKeyReferenceType && isValueReferenceType)
{
vftblType = interopDefinitions.IReadOnlyDictionary2Vftbl;
vftblType = interopDefinitions.IDictionary2Vftbl;

return;
}
Expand All @@ -104,7 +104,7 @@ public static void Vftbl(
// the vtable type. So in this case, we just always construct a specialized new type.
if (!isKeyReferenceType && !isValueReferenceType)
{
vftblType = WellKnownTypeDefinitionFactory.IReadOnlyDictionary2Vftbl(
vftblType = WellKnownTypeDefinitionFactory.IDictionary2Vftbl(
ns: InteropUtf8NameFactory.TypeNamespace(dictionaryType),
name: InteropUtf8NameFactory.TypeName(dictionaryType, "Vftbl"),
keyType: keyType,
Expand Down Expand Up @@ -220,102 +220,57 @@ public static void IMapMethods(
// Track the type (it's needed by 'IObservableMap<K, V>')
emitState.TrackTypeDefinition(mapMethodsType, dictionaryType, "IMapMethods");

// Define the 'HasKey' method as follows:
//
// public static bool HasKey(WindowsRuntimeObjectReference thisReference, <KEY_TYPE> key)
MethodDefinition hasKeyMethod = new(
name: "HasKey"u8,
attributes: MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Static,
signature: MethodSignature.CreateStatic(
returnType: module.CorLibTypeFactory.Boolean,
parameterTypes: [
interopReferences.WindowsRuntimeObjectReference.Import(module).ToReferenceTypeSignature(),
keyType.Import(module)]))
{ NoInlining = true };
// Define the 'HasKey' method
MethodDefinition hasKeyMethod = InteropMethodDefinitionFactory.IMapViewMethods.HasKey(
readOnlyDictionaryType: dictionaryType,
vftblType: vftblType,
interopReferences: interopReferences,
emitState: emitState,
module: module);

// Add and implement the 'HasKey' method
mapMethodsType.AddMethodImplementation(
declaration: interopReferences.IMapMethodsImpl2HasKey(keyType, valueType).Import(module),
method: hasKeyMethod);

// Create a method body for the 'HasKey' method
hasKeyMethod.CilMethodBody = new CilMethodBody()
{
Instructions = { { Ldnull }, { Throw } } // TODO
};

// Define the 'Lookup' method as follows:
//
// public static <VALUE_TYPE> Lookup(WindowsRuntimeObjectReference thisReference, <KEY_TYPE> key)
MethodDefinition lookupMethod = new(
name: "Lookup"u8,
attributes: MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Static,
signature: MethodSignature.CreateStatic(
returnType: valueType.Import(module),
parameterTypes: [
interopReferences.WindowsRuntimeObjectReference.Import(module).ToReferenceTypeSignature(),
keyType.Import(module)]))
{ NoInlining = true };
// Define the 'Lookup' method
MethodDefinition lookupMethod = InteropMethodDefinitionFactory.IMapViewMethods.Lookup(
readOnlyDictionaryType: dictionaryType,
vftblType: vftblType,
interopReferences: interopReferences,
emitState: emitState,
module: module);

// Add and implement the 'Lookup' method
mapMethodsType.AddMethodImplementation(
declaration: interopReferences.IMapMethodsImpl2Lookup(keyType, valueType).Import(module),
method: lookupMethod);

// Create a method body for the 'Lookup' method
lookupMethod.CilMethodBody = new CilMethodBody()
{
Instructions = { { Ldnull }, { Throw } } // TODO
};

// Define the 'Insert' method as follows:
//
// public static bool Insert(WindowsRuntimeObjectReference thisReference, <KEY_TYPE> key, <VALUE_TYPE> value)
MethodDefinition insertMethod = new(
name: "Insert"u8,
attributes: MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Static,
signature: MethodSignature.CreateStatic(
returnType: module.CorLibTypeFactory.Boolean,
parameterTypes: [
interopReferences.WindowsRuntimeObjectReference.Import(module).ToReferenceTypeSignature(),
keyType.Import(module),
valueType.Import(module)]))
{ NoInlining = true };
// Define the 'Insert' method
MethodDefinition insertMethod = InteropMethodDefinitionFactory.IMapMethods.Insert(
dictionaryType: dictionaryType,
vftblType: vftblType,
interopReferences: interopReferences,
emitState: emitState,
module: module);

// Add and implement the 'Insert' method
mapMethodsType.AddMethodImplementation(
declaration: interopReferences.IMapMethodsImpl2Insert(keyType, valueType).Import(module),
method: insertMethod);

// Create a method body for the 'Insert' method
insertMethod.CilMethodBody = new CilMethodBody()
{
Instructions = { { Ldnull }, { Throw } } // TODO
};

// Define the 'Remove' method as follows:
//
// public static void Remove(WindowsRuntimeObjectReference thisReference, <KEY_TYPE> key)
MethodDefinition removeMethod = new(
name: "Remove"u8,
attributes: MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Static,
signature: MethodSignature.CreateStatic(
returnType: module.CorLibTypeFactory.Boolean,
parameterTypes: [
interopReferences.WindowsRuntimeObjectReference.Import(module).ToReferenceTypeSignature(),
keyType.Import(module)]))
{ NoInlining = true };
// Define the 'Remove' method
MethodDefinition removeMethod = InteropMethodDefinitionFactory.IMapMethods.Remove(
dictionaryType: dictionaryType,
vftblType: vftblType,
interopReferences: interopReferences,
emitState: emitState,
module: module);

// Add and implement the 'Remove' method
mapMethodsType.AddMethodImplementation(
declaration: interopReferences.IMapMethodsImpl2Remove(keyType, valueType).Import(module),
method: removeMethod);

// Create a method body for the 'Remove' method
removeMethod.CilMethodBody = new CilMethodBody()
{
Instructions = { { Ldnull }, { Throw } } // TODO
};
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,14 @@ public static void Vftbl(
/// <param name="readOnlyDictionaryType">The <see cref="GenericInstanceTypeSignature"/> for the <see cref="System.Collections.Generic.IReadOnlyDictionary{TKey, TValue}"/> type.</param>
/// <param name="vftblType">The type returned by <see cref="Vftbl"/>.</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="mapViewMethodsType">The resulting methods type.</param>
public static void IMapViewMethods(
GenericInstanceTypeSignature readOnlyDictionaryType,
TypeDefinition vftblType,
InteropReferences interopReferences,
InteropGeneratorEmitState emitState,
ModuleDefinition module,
out TypeDefinition mapViewMethodsType)
{
Expand All @@ -112,53 +114,31 @@ public static void IMapViewMethods(

module.TopLevelTypes.Add(mapViewMethodsType);

// Define the 'HasKey' method as follows:
//
// public static bool HasKey(WindowsRuntimeObjectReference thisReference, <KEY_TYPE> key)
MethodDefinition hasKeyMethod = new(
name: "HasKey"u8,
attributes: MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Static,
signature: MethodSignature.CreateStatic(
returnType: module.CorLibTypeFactory.Boolean,
parameterTypes: [
interopReferences.WindowsRuntimeObjectReference.Import(module).ToReferenceTypeSignature(),
keyType.Import(module)]))
{ NoInlining = true };
// Define the 'HasKey' method
MethodDefinition hasKeyMethod = InteropMethodDefinitionFactory.IMapViewMethods.HasKey(
readOnlyDictionaryType: readOnlyDictionaryType,
vftblType: vftblType,
interopReferences: interopReferences,
emitState: emitState,
module: module);

// Add and implement the 'HasKey' method
mapViewMethodsType.AddMethodImplementation(
declaration: interopReferences.IMapViewMethodsImpl2HasKey(keyType, valueType).Import(module),
method: hasKeyMethod);

// Create a method body for the 'HasKey' method
hasKeyMethod.CilMethodBody = new CilMethodBody()
{
Instructions = { { Ldnull }, { Throw } } // TODO
};

// Define the 'Lookup' method as follows:
//
// public static <VALUE_TYPE> Lookup(WindowsRuntimeObjectReference thisReference, <KEY_TYPE> key)
MethodDefinition lookupMethod = new(
name: "Lookup"u8,
attributes: MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Static,
signature: MethodSignature.CreateStatic(
returnType: valueType.Import(module),
parameterTypes: [
interopReferences.WindowsRuntimeObjectReference.Import(module).ToReferenceTypeSignature(),
keyType.Import(module)]))
{ NoInlining = true };
// Define the 'Lookup' method
MethodDefinition lookupMethod = InteropMethodDefinitionFactory.IMapViewMethods.Lookup(
readOnlyDictionaryType: readOnlyDictionaryType,
vftblType: vftblType,
interopReferences: interopReferences,
emitState: emitState,
module: module);

// Add and implement the 'Lookup' method
mapViewMethodsType.AddMethodImplementation(
declaration: interopReferences.IMapViewMethodsImpl2HasKey(keyType, valueType).Import(module),
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

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

The 'Lookup' method is incorrectly implemented against the 'HasKey' interface declaration. This should use 'IMapViewMethodsImpl2Lookup' instead of 'IMapViewMethodsImpl2HasKey'.

Suggested change
declaration: interopReferences.IMapViewMethodsImpl2HasKey(keyType, valueType).Import(module),
declaration: interopReferences.IMapViewMethodsImpl2Lookup(keyType, valueType).Import(module),

Copilot uses AI. Check for mistakes.
method: lookupMethod);

// Create a method body for the 'Lookup' method
lookupMethod.CilMethodBody = new CilMethodBody()
{
Instructions = { { Ldnull }, { Throw } } // TODO
};
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ public static MethodDefinition GetResults(
{ Ldloc_1 },
{ Ldarg_1 },
{ Ldloca_S, loc_2_resultNative },
{ Conv_U },
{ Ldloc_1 },
{ Ldind_I },
{ Ldfld, vftblField },
Expand Down
Loading
Loading