Boppity Bop
Boppity Bop

Reputation: 10463

Cant make IL work. "Could destabilize the runtime" error

I am trying few test codes for my another question on SO.

The code supposed to replicate:

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

The code:

    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>));
    }

Using:

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

Throws:

Operation could destabilize the runtime.

Cant see whats wrong (could be anything since last time I used asm-like language was 25 yrs ago)

Upvotes: 0

Views: 132

Answers (1)

user703016
user703016

Reputation: 37945

The problem is the two places where you convert to double:

il.Emit(OpCodes.Conv_R8, b);

From MSDN:

OpCodes.Conv_R8 Field Converts the value on top of the evaluation stack to float64.

That opcode takes no argument. Instead, simply use:

il.Emit(OpCodes.Conv_R8);

The code runs fine and produces 16.5988026183378 as output.

Upvotes: 3

Related Questions