Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 发射MSIL以发射MSIL会遇到JIT限制_C#_Cil_Reflection.emit - Fatal编程技术网

C# 发射MSIL以发射MSIL会遇到JIT限制

C# 发射MSIL以发射MSIL会遇到JIT限制,c#,cil,reflection.emit,C#,Cil,Reflection.emit,所以我想回答这个问题,并决定发出MSIL代码来进行整数加法。因为这是成功的,所以我决定发出MSIL代码,这将发出我的第一个代码。因此,调用代码构造了一个方法,该方法构造了一个调用int.op\u Addition的方法。这失败得很惨,JIT抱怨我做得太过分了!哼 异常为System.SystemException:{“JIT编译器遇到内部限制。”}在调用动态方法时位于最后一行 我的问题是,我正确地假设JIT以某种方式不允许发出代码来发出代码。另一种选择是,我犯了一个错误,这很可能是错误的,但我检

所以我想回答这个问题,并决定发出MSIL代码来进行整数加法。因为这是成功的,所以我决定发出MSIL代码,这将发出我的第一个代码。因此,调用代码构造了一个方法,该方法构造了一个调用
int.op\u Addition
的方法。这失败得很惨,JIT抱怨我做得太过分了!哼

异常为
System.SystemException:{“JIT编译器遇到内部限制。”}
在调用动态方法时位于最后一行

我的问题是,我正确地假设JIT以某种方式不允许发出代码来发出代码。另一种选择是,我犯了一个错误,这很可能是错误的,但我检查了我的代码与
Reflector
生成的MSIL代码

以下是代码,供您娱乐:

class Program
{
    static void Main(string[] args)
    {
        int z2=Add2(1, 2);
        // z2 = "JIT Compiler encountered an internal limitation."
    }

    // Emit MSIL to emit MSIL
    public static int Add2(int x, int y)
    {
        Type delegate_type=typeof(Func<int, int, int>);
        DynamicMethod method=new DynamicMethod(typeof(Program).ToString()+".GenAdd",
            typeof(int),
            new Type[] { typeof(int), typeof(int) }, typeof(Program));
        ILGenerator generator=method.GetILGenerator();

        LocalBuilder method1=generator.DeclareLocal(typeof(DynamicMethod));
        LocalBuilder generator1=generator.DeclareLocal(typeof(ILGenerator));
        LocalBuilder add1=generator.DeclareLocal(typeof(Func<int, int, int>));
        LocalBuilder args1=generator.DeclareLocal(typeof(Type[]));
        generator.Emit(OpCodes.Ldtoken, typeof(int));            

        generator.Emit(OpCodes.Call, 
            typeof(Type).GetMethod("GetTypeFromHandle", 
                System.Reflection.BindingFlags.Public | 
                System.Reflection.BindingFlags.Static));
        generator.Emit(OpCodes.Callvirt,
            typeof(object).GetMethod("ToString", 
                System.Reflection.BindingFlags.Public|
                System.Reflection.BindingFlags.Instance));
        generator.Emit(OpCodes.Ldstr, ".op_Addition");                        
        generator.Emit(OpCodes.Call,                
            typeof(string).GetMethod("Concat",
                new Type[] { typeof(string), typeof(string) } ));
        generator.Emit(OpCodes.Ldtoken, typeof(int));
        generator.Emit(OpCodes.Call,
            typeof(Type).GetMethod("GetTypeFromHandle",
                System.Reflection.BindingFlags.Public|
                System.Reflection.BindingFlags.Static));
        generator.Emit(OpCodes.Ldc_I4, 2);
        generator.Emit(OpCodes.Newarr, typeof(Type));
        generator.Emit(OpCodes.Stloc_3);
        generator.Emit(OpCodes.Ldloc_3);
        generator.Emit(OpCodes.Ldc_I4, 0);
        generator.Emit(OpCodes.Ldtoken, typeof(int));
        generator.Emit(OpCodes.Call,
            typeof(Type).GetMethod("GetTypeFromHandle",
                System.Reflection.BindingFlags.Public|
                System.Reflection.BindingFlags.Static));
        generator.Emit(OpCodes.Stelem_Ref);
        generator.Emit(OpCodes.Ldloc_3);
        generator.Emit(OpCodes.Ldc_I4, 1);
        generator.Emit(OpCodes.Ldtoken, typeof(int));
        generator.Emit(OpCodes.Call,
            typeof(Type).GetMethod("GetTypeFromHandle",
                System.Reflection.BindingFlags.Public|
                System.Reflection.BindingFlags.Static));
        generator.Emit(OpCodes.Stelem_Ref);
        generator.Emit(OpCodes.Ldloc_3);
        generator.Emit(OpCodes.Ldtoken, typeof(Program));
        generator.Emit(OpCodes.Call,
            typeof(Type).GetMethod("GetTypeFromHandle",
                System.Reflection.BindingFlags.Public|
                System.Reflection.BindingFlags.Static));

        generator.Emit(OpCodes.Newobj,
            typeof(DynamicMethod).GetConstructor(
                new Type[] { typeof(string), typeof(Type), typeof(Type[]) }));

        generator.Emit(OpCodes.Stloc_0);
        generator.Emit(OpCodes.Ldloc_0);
        generator.Emit(OpCodes.Callvirt,
            typeof(DynamicMethod).GetMethod("GetILGenerator",
                Type.EmptyTypes));
        generator.Emit(OpCodes.Stloc_1);
        generator.Emit(OpCodes.Ldloc_1);
        generator.Emit(OpCodes.Ldtoken, typeof(int));
        generator.Emit(OpCodes.Call,
            typeof(Type).GetMethod("GetTypeFromHandle",
                System.Reflection.BindingFlags.Public|
                System.Reflection.BindingFlags.Static));
        generator.Emit(OpCodes.Callvirt,
            typeof(ILGenerator).GetMethod("DeclareLocal",
                new Type[] { typeof(Type) }));
        generator.Emit(OpCodes.Pop);
        generator.Emit(OpCodes.Ldloc_1);
        generator.Emit(OpCodes.Ldsfld,
            typeof(OpCodes).GetField("Ldarg_0",
                System.Reflection.BindingFlags.Public|System.Reflection.BindingFlags.Static));
        generator.Emit(OpCodes.Callvirt,
            typeof(ILGenerator).GetMethod("Emit", new Type[] { typeof(OpCode) }));
        generator.Emit(OpCodes.Ldloc_1);
        generator.Emit(OpCodes.Ldsfld,
            typeof(OpCodes).GetField("Ldarg_1",
                System.Reflection.BindingFlags.Public|System.Reflection.BindingFlags.Static));
        generator.Emit(OpCodes.Callvirt,
            typeof(ILGenerator).GetMethod("Emit", new Type[] { typeof(OpCode) }));
        generator.Emit(OpCodes.Ldloc_1);
        generator.Emit(OpCodes.Ldsfld,
            typeof(OpCodes).GetField("Add",
                System.Reflection.BindingFlags.Public|System.Reflection.BindingFlags.Static));
        generator.Emit(OpCodes.Callvirt,
            typeof(ILGenerator).GetMethod("Emit", new Type[] { typeof(OpCode) }));
        generator.Emit(OpCodes.Ldloc_1);
        generator.Emit(OpCodes.Ldsfld,
            typeof(OpCodes).GetField("Stloc_0",
                System.Reflection.BindingFlags.Public|System.Reflection.BindingFlags.Static));
        generator.Emit(OpCodes.Callvirt,
            typeof(ILGenerator).GetMethod("Emit", new Type[] { typeof(OpCode) }));
        generator.Emit(OpCodes.Ldloc_1);
        generator.Emit(OpCodes.Ldsfld,
            typeof(OpCodes).GetField("Ldloc_0",
                System.Reflection.BindingFlags.Public|System.Reflection.BindingFlags.Static));
        generator.Emit(OpCodes.Callvirt,
            typeof(ILGenerator).GetMethod("Emit", new Type[] { typeof(OpCode) }));
        generator.Emit(OpCodes.Ldloc_1);
        generator.Emit(OpCodes.Ldsfld,
            typeof(OpCodes).GetField("Ret",
                System.Reflection.BindingFlags.Public|System.Reflection.BindingFlags.Static));
        generator.Emit(OpCodes.Callvirt,
            typeof(ILGenerator).GetMethod("Emit", new Type[] { typeof(OpCode) }));
        generator.Emit(OpCodes.Ldloc_0);
        generator.Emit(OpCodes.Ldtoken, typeof(Func<int, int, int>));
        generator.Emit(OpCodes.Call,
            typeof(Type).GetMethod("GetTypeFromHandle",
                System.Reflection.BindingFlags.Public|
                System.Reflection.BindingFlags.Static));
        generator.Emit(OpCodes.Callvirt,
            typeof(DynamicMethod).GetMethod("CreateDelegate",
                new Type[] { typeof(Type)} ));
        generator.Emit(OpCodes.Isinst, typeof(Func<int, int, int>));
        generator.Emit(OpCodes.Stloc_2);
        generator.Emit(OpCodes.Ldloc_2);
        generator.Emit(OpCodes.Ldarg_0);
        generator.Emit(OpCodes.Ldarg_1);
        generator.Emit(OpCodes.Callvirt,
            typeof(Func<int, int, int>).GetMethod("Invoke",
                System.Reflection.BindingFlags.Public|System.Reflection.BindingFlags.Instance));
        generator.Emit(OpCodes.Ret);

        Func<int, int, int> add2=method.CreateDelegate(typeof(Func<int, int, int>)) as Func<int, int, int>;

        return add2(x, y);
    }
}

我非常确定JIT能够编译使用反射的代码。否则,您将永远无法使用
Reflection.Emit
。生成的MSIL与C#编译器生成的MSIL经过相同的JIT过程

在CAS检查方面有一点不同,但我看不到任何迹象表明您首先是在部分信任场景中操作的

我看到这一行:

generator.Emit(OpCodes.Newobj,
typeof(DynamicMethod).GetConstructor(
    new Type[] { typeof(string), typeof(Type), typeof(Type[]) }));
它定位创建匿名托管方法的
DynamicMethod(string,Type,Type[])
构造函数。但是在
Add1
中,您有

DynamicMethod method = new DynamicMethod(typeof(int).ToString()+".op_Addition",
                                         typeof(int),
                                         new Type[] { typeof(int), typeof(int) }, 
                                         typeof(Program));
它调用四个参数
DynamicMethod
构造函数,向类型
程序
添加一个方法


因此,当您使用
newobj

时,操作数堆栈上的类型完全不匹配。如果代码有问题,它将生成一个
系统。SystemException:{“公共语言运行库检测到一个无效程序”。}
多亏了Ben,代码现在可以工作了,而且,JIT毕竟没有问题。仅供参考-以下是代码竞赛帖子:我将使用此构造函数
公共动态方法(字符串名称、类型returnType、类型[]参数类型、类型所有者)。你是对的。现在可以了。
DynamicMethod method = new DynamicMethod(typeof(int).ToString()+".op_Addition",
                                         typeof(int),
                                         new Type[] { typeof(int), typeof(int) }, 
                                         typeof(Program));