1

I have exception: Operation could destabilize the runtime , and i dont know why :(. Please Help me.

I Added Local, but still not working...

Method want to create dynamically (REF000001):

public static int REF000001(int REF000002, object REF000003, DateTime REF000004)
    {
        return (int)typeof(REF000005).GetMethod("REF000006", new Type[] { typeof(int), typeof(object), typeof(DateTime) }).Invoke(REF000005.REF000008(), new object[] { REF000002, REF000003, REF000004 });
    }

This is class, which i want to invoke method from singleton.

public class REF000005
{
    private static REF000005 REF000007;

    private REF000005()
    {

    }

    public static REF000005 REF000008()
    {
        if (REF000007 == null)
            REF000007 = new REF000005();

        return REF000007;
    }

    public int REF000006(int REF000009, object REF000010, DateTime REF000011)
    {
        return 5;
    }
}

Return from ILDASM:

.method public hidebysig static int32  REF000001(int32 REF000002,
                                             object REF000003,
                                             valuetype [mscorlib]System.DateTime REF000004) cil     managed
{
// Code size       118 (0x76)
.maxstack  5
.locals init ([0] int32 CS$1$0000,
       [1] class [mscorlib]System.Type[] CS$0$0001,
       [2] object[] CS$0$0002)
IL_0000:  nop
IL_0001:  ldtoken    ConsoleApplication3.REF000005
IL_0006:  call       class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_000b:  ldstr      "REF000006"
IL_0010:  ldc.i4.3
IL_0011:  newarr     [mscorlib]System.Type
IL_0016:  stloc.1
IL_0017:  ldloc.1
IL_0018:  ldc.i4.0
IL_0019:  ldtoken    [mscorlib]System.Int32
IL_001e:  call       class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0023:  stelem.ref
IL_0024:  ldloc.1
IL_0025:  ldc.i4.1
IL_0026:  ldtoken    [mscorlib]System.Object
IL_002b:  call       class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0030:  stelem.ref
IL_0031:  ldloc.1
IL_0032:  ldc.i4.2
IL_0033:  ldtoken    [mscorlib]System.DateTime
IL_0038:  call       class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_003d:  stelem.ref
IL_003e:  ldloc.1
IL_003f:  call       instance class [mscorlib]System.Reflection.MethodInfo [mscorlib]System.Type::GetMethod(string,
                                                                                                          class [mscorlib]System.Type[])
IL_0044:  call       class ConsoleApplication3.REF000005 ConsoleApplication3.REF000005::REF000008()
IL_0049:  ldc.i4.3
IL_004a:  newarr     [mscorlib]System.Object
IL_004f:  stloc.2
IL_0050:  ldloc.2
IL_0051:  ldc.i4.0
IL_0052:  ldarg.0
IL_0053:  box        [mscorlib]System.Int32
IL_0058:  stelem.ref
IL_0059:  ldloc.2
IL_005a:  ldc.i4.1
IL_005b:  ldarg.1
IL_005c:  stelem.ref
IL_005d:  ldloc.2
IL_005e:  ldc.i4.2
IL_005f:  ldarg.2
IL_0060:  box        [mscorlib]System.DateTime
IL_0065:  stelem.ref
IL_0066:  ldloc.2
IL_0067:  callvirt   instance object [mscorlib]System.Reflection.MethodBase::Invoke(object,
                                                                                  object[])
IL_006c:  unbox.any  [mscorlib]System.Int32
IL_0071:  stloc.0
IL_0072:  br.s       IL_0074
IL_0074:  ldloc.0
IL_0075:  ret
} // end of method Program::REF000001

My code with IL generator throw exception Operation could destabilize the runtime

static DynamicMethod Method1A()
    {
        DynamicMethod method1 = new DynamicMethod("Dodaj", typeof(void), new Type[] { typeof(int), typeof(object), typeof(DateTime) });
        ILGenerator il = method1.GetILGenerator();

        Label target = il.DefineLabel();

        var tps = il.DeclareLocal(typeof(Type[]));
        var obs = il.DeclareLocal(typeof(object[]));

        il.Emit(OpCodes.Ldtoken, typeof(REF000005));
        il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle", new Type[1] { typeof(RuntimeTypeHandle) }));
        il.Emit(OpCodes.Ldstr, "REF000006");

        il.Emit(OpCodes.Ldc_I4_3);
        il.Emit(OpCodes.Newarr, typeof(Type));
        il.Emit(OpCodes.Stloc, tps);
        il.Emit(OpCodes.Ldloc, tps);
        il.Emit(OpCodes.Ldc_I4_0);
        il.Emit(OpCodes.Ldtoken, typeof(Int32));
        il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle", new Type[1] { typeof(RuntimeTypeHandle) }));
        il.Emit(OpCodes.Stelem_Ref);
        il.Emit(OpCodes.Ldloc, tps);
        il.Emit(OpCodes.Ldc_I4_1);
        il.Emit(OpCodes.Ldtoken, typeof(Object));
        il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle", new Type[1] { typeof(RuntimeTypeHandle) }));
        il.Emit(OpCodes.Stelem_Ref);
        il.Emit(OpCodes.Ldloc, tps);
        il.Emit(OpCodes.Ldc_I4_2);
        il.Emit(OpCodes.Ldtoken, typeof(DateTime));
        il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle", new Type[1] { typeof(RuntimeTypeHandle) }));
        il.Emit(OpCodes.Stelem_Ref);
        il.Emit(OpCodes.Ldloc, tps);

        il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetMethod", new Type[2] { typeof(string), typeof(Type[]) }));
        il.Emit(OpCodes.Call, typeof(REF000005).GetMethod("REF000008"));

        il.Emit(OpCodes.Ldc_I4_3);
        il.Emit(OpCodes.Newarr, typeof(object));
        il.Emit(OpCodes.Stloc, obs);
        il.Emit(OpCodes.Ldloc, obs);
        il.Emit(OpCodes.Ldc_I4_0);
        il.Emit(OpCodes.Ldarg, 0);
        il.Emit(OpCodes.Box, typeof(Int32));
        il.Emit(OpCodes.Stelem_Ref);
        il.Emit(OpCodes.Ldloc, obs);
        il.Emit(OpCodes.Ldc_I4_1);
        il.Emit(OpCodes.Ldarg, 1);
        //il.Emit(OpCodes.Box, typeof(object));
        il.Emit(OpCodes.Stelem_Ref);
        il.Emit(OpCodes.Ldloc, obs);
        il.Emit(OpCodes.Ldc_I4_2);
        il.Emit(OpCodes.Ldarg, 2);
        il.Emit(OpCodes.Box, typeof(DateTime));
        il.Emit(OpCodes.Stelem_Ref);
        il.Emit(OpCodes.Ldloc, obs);
        il.Emit(OpCodes.Box, typeof(object[]));
        il.Emit(OpCodes.Callvirt, typeof(MethodBase).GetMethod("Invoke", new Type[2] { typeof(object), typeof(object[]) }));
        il.Emit(OpCodes.Unbox_Any, typeof(Int32));
        il.Emit(OpCodes.Ret);
        return method1;
    }
JasonMArcher
  • 14,195
  • 22
  • 56
  • 52

1 Answers1

3

There is a difference between the method you're copying and the one you're creating: the former returns int, the latter void. Which is exactly why your code doesn't work: when you return from a void method, the stack has to be empty; when you return from non-void method, the stack has to contain the value to return (and nothing else).

The best way to find out about this kind of issues is to create your method in a type in dynamic assembly, save that assembly to disk and then run PEVerify on it.

To fix this, you can change the return type of the method you're creating to int. Another option would be to keep the method void, but pop the element on the stack right before you ret.


That being said, I really don't understand what you're trying to accomplish here. Your C# method already does exactly what you need, there is no need to use Reflection.Emit for that. And if you want to use Reflection.Emit to avoid the performance penalty of using reflection, you can't just use reflection from your IL.

svick
  • 236,525
  • 50
  • 385
  • 514