JIT或CLR中可能存在的错误

时间:2014-11-26 12:15:01

标签: c# .net clr jit reflection.emit

我的代码生成一个动态创建多维数组的方法,假设一个维度长度数组,但似乎JIT编译器甚至CLR都无法正确地从维度长度数组加载项目。

不是创建int[10, 10, 10]数组,而是创建一个int[10, 10, 0]数组。它似乎在OpCodes.Ldelem_I出错了,但是,使用OpCodes.Ldelem, typeof(int)代替工作。重现此行为,任何CPU设置是必需的,x86工作正常。调试和释放模式都会出现此问题。

这是一个错误吗?我无法判断这一点,因为我无法深入研究这一点。

class Program
{
    static void Main(string[] args)
    {
        CreateMultidimensionalArrayCreator(typeof(int[, ,])).Invoke(new int[] { 10, 10, 10 }); ;            
    }

    static Func<int[], Array> CreateMultidimensionalArrayCreator(Type type)
    {
        int rank = type.GetArrayRank();

        DynamicMethod method = new DynamicMethod(String.Empty, typeof(Array), new Type[] { typeof(int[]) }, typeof(Program), false);
        ILGenerator ilGen = method.GetILGenerator();

        for (int i = 0; i < rank; i++)
        {
            // Load element from dimension lengths array
            ilGen.Emit(OpCodes.Ldarg_0);
            ilGen.Emit(OpCodes.Ldc_I4, i);
            ilGen.Emit(OpCodes.Ldelem_I); // Somehow returns 0 for last element, however, OpCodes.Ldelem appears to work fine
            // Duplicate element and write to console for diagnostics
            ilGen.Emit(OpCodes.Dup);
            ilGen.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) }));
        }

        // Get parameters for multidimensional array constructor
        //
        Type[] parameterTypes = new Type[rank];

        for (int i = 0; i < rank; i++)
        {
            parameterTypes[i] = typeof(int);
        }

        ilGen.Emit(OpCodes.Newobj, type.GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, parameterTypes, null));
        ilGen.Emit(OpCodes.Ret);

        return (Func<int[], Array>)method.CreateDelegate(typeof(Func<int[], Array>));
    }
}

1 个答案:

答案 0 :(得分:0)

替换行:

ilGen.Emit(OpCodes.Ldelem_I); // Somehow returns...

到行:

ilGen.Emit(OpCodes.Ldelem_I4); // Somehow returns 0 for last element....