Search code examples
c#cil

Microsoft intermediate language code [MSIL] for array passing and return


I have created a dynamic method using MethodBuilder with the signature Int32[] Exp(Int32[])

The emitted code is as follows

Type[] myMthdParams = new Type[1];
myMthdParams[index] = typeof(int[]);
MethodBuilder myMthdBld = myTypeBld.DefineMethod("Exp",MethodAttributes.Public |MethodAttributes.Static, typeof(int[]),mthdParams);                                           
ILGenerator ILout = myMthdBld.GetILGenerator();
ILout.Emit(OpCodes.Ldarg_1);            
ILout.Emit(OpCodes.Stloc_0);    
ILout.Emit(OpCodes.Ldloc_0);
ILout.Emit(OpCodes.Ret);

The method i want to implement is as follows:

int[] Exp(int[] arr)
{
    return arr;
}

I am getting the error CLR detected an invalid program. What is it I am doing it wrong?? Any help is deeply appreciated.


Solution

  • The stloc and ldloc store into and then load from the first local. It's a bit like your code being:

    int[] Exp(int[] arr)
    {
        var temp = arr;
        return temp;
    }
    

    But if you haven't defined that temp using DeclareLocal() then it's more like:

    int[] Exp(int[] arr)
    {
        temp = arr;
        return temp;
    }
    

    Which of course is invalid (no definition of temp).

    You don't need this temporary local anyway (though debug compilations of C# will often include them to aid debugging). Why not just:

    ILGenerator ILout = myMthdBld.GetILGenerator();
    ILout.Emit(OpCodes.Ldarg_1);            
    ILout.Emit(OpCodes.Ret);
    

    Or if the method is static (and therefore doesn't have this as the first argument):

    ILGenerator ILout = myMthdBld.GetILGenerator();
    ILout.Emit(OpCodes.Ldarg_0);            
    ILout.Emit(OpCodes.Ret);