From C# to CLR Jitted Code – ByVal and ByRef

I am trying to understand the difference between ByVal and ByRef objects. In below C# code we pass different parameter types to the Test method. Let’s see how the runtime treat them differently at the IL and Assembly level.   using System; using System.Runtime.CompilerServices; namespace CodeGen {     public class MyClass     {         public…

0

MSIL Verification Notes – 11

Tired of creating one sample for one unverifiable scenario. Here is a laundry list for the other scenarios I know of. Build the sample in your mind and be happy. calli by design unverifiable ldftn/ldvirtftn not allowedn on .ctor  “This” parameter does not match the calling method arglist is used in non-vararg method Tailcall return type…

1

MSIL Verification Notes – 10

Another one that taking ArgIterator is deemed unverifiable. This time is for making a Type Reference. .method public hidebysig static vararg void VarArg() cil managed { .maxstack 8 .locals init ( [0] valuetype [mscorlib]System.ArgIterator args, [1] valuetype [mscorlib]System.TypedReference tref) L_0000: ldloca args L_0004: arglist L_0006: call instance void [mscorlib]System.ArgIterator::.ctor(valuetype [mscorlib]System.RuntimeArgumentHandle) L_000b: ldloca args L_000f: mkrefany…

1

MSIL Verification Notes – 9

  Tail call verification rules require that no managed pointers to be passed from caller to callee if it points to a stack frame that to be removed. ArgIterator does not satisfy the condition. Therefore below code will not be verifiable. .method public hidebysig static void Main(string[] A_0) cil managed { .entrypoint .maxstack 8 .locals init…

1

MSIL Verification Notes – 8

 One more verification rule for ArgIterator. We cannot put it in an array. To avoid stack corruption, the JIT will consider below code unverifiable. IL_0000:    ldc.i4.1IL_0001:    newarr ArgIteratorIL_0006:    stloc.0IL_0007:    ret  Here is the PEVerify result. [IL]: Error: [xxx.exe : TestClass::Main][mdToken=0x6000001][offset 0x00000001] Array of ELEMENT_TYPE_BYREF or ELEMENT_TYPE_TYPEDBYREF.(Error: 0x80131890)

1

MSIL Verification Notes – 7

Box operation can operate on ValueType but not all of them. Below example is trying to box System.ArgIterator. ArgIterator can have pointer points to stack, therefor BOX it won’t be verifiable. .method public hidebysig static vararg void VarArg() cil managed { .maxstack 8 .locals init ( [0] valuetype [mscorlib]System.ArgIterator args) L_0000: ldloca args L_0004: arglist…

1

MSIL Verification Notes – 6

Recently I am running some DynamicMethod scenario. It seems very easy to Emit incorrect IL using ILGenerator. If the IL is not correct, JIT will throw unverifiable code exception or invalid program exception. I tend to debug with WinDBG+SOS for IL related issues in the past. However, for some reason, !dumpIL does not work as…

2

MSIL Verification Notes – 5

This is a short one. The arglist operation can only work when the method’s signature indicates that it accepts a variable number of arguments. The verification rule also requires a type check for System.RuntimeArgumentHandle. Below scenario is clear a violation of both conditions. .method public hidebysig static void Test() cil managed { .maxstack 8 L_0000:…

2

MSIL Verification Notes – 4

I thought I knew what is box and unbox. After reading the ECMA spec, I know that what I believed was actually wrong. Maybe you had the same incorrect impression in your mind. Box a integer will create an object on the heap and copy the date from valuetype into the newly allocated object. It…

0

MSIL Verification Notes – 3

Below code tries to return a ByRef object which points on a stack location. CLR rule considers this kind of ByRef object is not safe to return to the caller. .method public instance int32& modopt([Microsoft.VisualC]Microsoft.VisualC.IsCXXPointerModifier)           retLocalByref() cil managed  {    // Code size       30 (0x1e)    .maxstack  2    .locals init (int32 V_0)    IL_0000:  ldstr      “Returning local byref”   …

1