-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Closed
Labels
area-VM-reflection-monoReflection issues specific to MonoVMReflection issues specific to MonoVM
Milestone
Description
When using System.Reflection.Emit with Mono, using MethodBuilder.SetReturnType and MethodBuilder.SetParameters on methods that are supposed to implement interface methods does not work - the method is not considered to implement the interface method. Using the long form of TypeBuilder.DefineMethod works.
using System;
using System.Reflection;
using System.Reflection.Emit;
public interface IStr
{
public string MStr(string x);
}
public class P {
public static void Main()
{
var aname = "TestAssembly";
var assemblyName = new AssemblyName(aname);
var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
var moduleBuilder = assemblyBuilder.DefineDynamicModule(aname);
var typeBuilder = moduleBuilder.DefineType("TestType", TypeAttributes.Public, typeof(object), new Type[] { typeof(IStr) });
#if false
//works
var methodBuilder = typeBuilder.DefineMethod("MStr", MethodAttributes.Public | MethodAttributes.Virtual, typeof(string), new Type[] { typeof(string) });
#else
// throws "Invalid VTable" from CreateInstance, below
var methodBuilder = typeBuilder.DefineMethod("MStr", MethodAttributes.Public | MethodAttributes.Virtual);
methodBuilder.SetReturnType(typeof(string));
methodBuilder.SetParameters(new Type[] { typeof(string) });
#endif
var ilg = methodBuilder.GetILGenerator();
ilg.Emit(OpCodes.Ldarg_1);
ilg.Emit(OpCodes.Ret);
var type = typeBuilder.CreateType();
var obj = Activator.CreateInstance(type);
var m = type.GetMethod("MStr");
var r = m.Invoke(obj, new object[] { "hello" });
Console.WriteLine($"r = {r}");
}
}Update simpler repro and better diagnosis; original issue below
Needs some investigation still. Some of the System.Reflection.Emit code generates a class with a bad vtable on net8.0.
The TypedClientBuilder is from aspnetcore:
Repro:
Clone this repo https://github.com/lambdageek/repro-iclientproxy-vtable-fail
Expected
$ dotnet run
SendCoreAsync - M1Actual
$ dotnet run
Unhandled Exception:
System.TypeLoadException: VTable setup of type Microsoft.AspNetCore.SignalR.TypedClientBuilder.I1Impl failed
at System.RuntimeType.GetMethodsByName(String name, BindingFlags bindingAttr, MemberListType listType, RuntimeType reflectedType)
at System.RuntimeType.GetMethodCandidates(String name, BindingFlags bindingAttr, CallingConventions callConv, Type[] types, Int32 genericParamCount, Boolean allowPrefixLookup)
at System.RuntimeType.GetMethodImpl(String name, Int32 genericParamCount, BindingFlags bindingAttr, Binder binder, CallingConventions callConv, Type[] types, ParameterModifier[] modifiers)
at System.RuntimeType.GetMethodImpl(String name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
at System.Type.GetMethod(String name, BindingFlags bindingAttr)
at Retrofit.TypedClientBuilder`1[[I1, promo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].GenerateClientBuilder() in /private/tmp/promo/TypedClientBuilder.cs:line 42
at System.Lazy`1[[System.Func`2[[Retrofit.IClientProxy, promo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[I1, promo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy`1[[System.Func`2[[Retrofit.IClientProxy, promo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[I1, promo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy`1[[System.Func`2[[Retrofit.IClientProxy, promo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[I1, promo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].CreateValue()
at System.Lazy`1[[System.Func`2[[Retrofit.IClientProxy, promo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[I1, promo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].get_Value()
at Retrofit.TypedClientBuilder`1[[I1, promo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].Build(IClientProxy proxy) in /private/tmp/promo/TypedClientBuilder.cs:line 24
at P.Main() in /private/tmp/promo/Program.cs:line 19
at P.<Main>()Metadata
Metadata
Assignees
Labels
area-VM-reflection-monoReflection issues specific to MonoVMReflection issues specific to MonoVM