Reputation: 10463
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
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