lundi 1 juin 2020

What am i doing wrong with this IL generation

I started to dive into System.Reflection.Emit and am trying to generate the IL of a constructor and execute some code in the body.

I want to generate the IL for the following piece of code:

public SomeConstructor()
{
   var prop = typeof(string).GetField(NavigationProxy", BindingFlags.Instance | BindingFlags.Public);
   prop.SetValue(this, new NavigationProxy(this));
}

So far I have the following:

var emitter = ctor.GetILGenerator();
emitter.Emit(OpCodes.Nop);

emitter.Emit(OpCodes.Ldarg_0);
for (var i = 1; i <= parameters.Length; ++i)
{
   emitter.Emit(OpCodes.Ldarg, i);
}
emitter.Emit(OpCodes.Call, constructor);
emitter.Emit(OpCodes.Nop);

emitter.Emit(OpCodes.Nop);
emitter.Emit(OpCodes.Ldtoken, typeof(Application));
emitter.Emit(OpCodes.Call, typeof(Type).GetMethod(nameof(Type.GetTypeFromHandle), new Type[1] { typeof(RuntimeTypeHandle) }));
emitter.Emit(OpCodes.Ldstr, nameof(Application.NavigationProxy));
emitter.Emit(OpCodes.Ldc_I4_S, 20);
emitter.Emit(OpCodes.Callvirt, typeof(Type).GetMethod(nameof(Type.GetField), new Type[2] { typeof(string), typeof(BindingFlags) }));
emitter.Emit(OpCodes.Stloc_0);
emitter.Emit(OpCodes.Ldloc_0);
emitter.Emit(OpCodes.Ldarg_0);
emitter.Emit(OpCodes.Ldarg_0);
emitter.Emit(OpCodes.Newobj, typeof(XamarinNavigationProxy).GetConstructor(new Type[1] { typeof(Application) }));
emitter.Emit(OpCodes.Callvirt, typeof(FieldInfo).GetMethod(nameof(FieldInfo.SetValue), new Type[2] { typeof(object), typeof(object) }));
emitter.Emit(OpCodes.Nop);
emitter.Emit(OpCodes.Ret);

However when generating an instance of my new type using

Activator.CreateInstance(myType);

I get the following error:

System.Reflection.TargetInvocationException: 'Exception has been thrown by the target of an invocation.'
Inner Exception
InvalidProgramException: Common Language Runtime detected an invalid program

I've tried decompiling the code in LINQPad and have copied the IL directly and still no luck, anyone got any ideas?





Aucun commentaire:

Enregistrer un commentaire