Im generating some IL with the ILGenerator here is my code:
DynamicMethod method = new DynamicMethod("test", null, Type.EmptyTypes);
ILGenerator gen = method.GetILGenerator();
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldarg_1);
gen.Emit(OpCodes.Ldc_I4_S, 100);
This generated this IL:
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: ldc.i4.s 100
IL_0004: nop
IL_0005: nop
IL_0006: nop
(I get the IL Code from a VS Virtulizer named ILStream)
From where do the nops code? is there any way to get rid of them? Im trying to imitate some c# code and it doesn't have 3 nops.
You are in the right direction to get rid of the "nop"s :
When you provide an additional argument to an Emit call, always be sure to check on MSDN for the proper argument type.
For OpCodes.Ldc_I4_S, MSDN states :
ldc.i4.s is a more efficient encoding for pushing the integers from -128 to 127 onto the >evaluation stack.
The following Emit method overload can use the ldc.i4.s opcode:
ILGenerator.Emit(OpCode, byte)
So the second part of your code will have unpredictable results (besides those pesky nop's) at run-time, since you're trying to load an "int8" on the stack, but providing an "int32" or "short" value :
else if (IsBetween(value, short.MinValue, short.MaxValue))
{
gen.Emit(OpCodes.Ldc_I4_S, (short)value);
}
else
{
gen.Emit(OpCodes.Ldc_I4_S, value);
}
You should use Ldc_I4 instead of Ldc_I4_S if you want to properly load an int32/short (or anything of greater magnitude than a byte) onto the stack. So your code should look like this instead of the above sample :
else
{
gen.Emit(OpCodes.Ldc_I4, value);
}
This is a wild guess, but the three nop's that were generated probably have something to do with the extra bytes from your int32
Hope that helps...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With