无法使IL工作。 “可能会破坏运行时的稳定性”错误

时间:2012-06-17 09:05:38

标签: .net c#-4.0 cil

我正在为SO上的另一个问题尝试几个测试代码。

代码应该复制:

(a, z) => a * b - Math.Log(z * b);

代码:

    static Func<int, int, double> IL_EmbedConst(int b)
    {
        var method = new DynamicMethod("EmbedConstIL", typeof(double), new[] { typeof(int), typeof(int) });

        var log = typeof(Math).GetMethod("Log", new Type[] { typeof(double) });

        var il = method.GetILGenerator();

        il.Emit(OpCodes.Ldarg_0);
        il.Emit(OpCodes.Ldc_I4, b);
        il.Emit(OpCodes.Mul);
        il.Emit(OpCodes.Conv_R8, b);

        il.Emit(OpCodes.Ldarg_1);
        il.Emit(OpCodes.Ldc_I4, b);
        il.Emit(OpCodes.Mul);
        il.Emit(OpCodes.Conv_R8, b);

        il.Emit(OpCodes.Call, log);

        il.Emit(OpCodes.Sub);

        il.Emit(OpCodes.Ret);

        return (Func<int, int, double>)method.CreateDelegate(typeof(Func<int, int, double>));
    }

使用:

        var mul1 = IL_EmbedConst(5);
        double res = mul1(4,6);

抛出:

Operation could destabilize the runtime.

看不出什么错(自从上次我使用asm-like语言以来可能是25年前的任何事情)

1 个答案:

答案 0 :(得分:3)

问题在于您转换为double的两个地方:

il.Emit(OpCodes.Conv_R8, b);

来自MSDN

  

OpCodes.Conv_R8字段   将评估堆栈顶部的值转换为float64。

该操作码不带参数。相反,只需使用:

il.Emit(OpCodes.Conv_R8);

代码运行正常并产生16.5988026183378作为输出。