`Common Language Runtime обнаружил ошибку недопустимой программы`, создав простой динамический методC#

Место общения программистов C#
Anonymous
`Common Language Runtime обнаружил ошибку недопустимой программы`, создав простой динамический метод

Сообщение Anonymous »

Я работаю над JIT-компилятором для эмуляции машин MIPS, чтобы преобразовать MIPS в CLI. Я работаю над созданием почти жестко запрограммированного метода Shift, но всякий раз, когда я пытаюсь выполнить инструкцию операции со значением, загруженным из памяти, происходит сбой.
Это код, который терпит неудачу, выдавая Общеязыковому времени выполнения обнаруженную недопустимую программу сообщение об исключении:

Код: Выделить всё

    private unsafe bool Shift(ILGenerator il, MipsInstruction inst, OpCode ilOpCode)
{
long baseAddress = (long)_cpu.RegisterFile.Regs;
long regAddress = baseAddress + ((int)inst.RT * sizeof(T));

// Push Address
if (IntPtr.Size == 4) il.Emit(OpCodes.Ldc_I4, (int)regAddress);
else il.Emit(OpCodes.Ldc_I8, regAddress);
il.Emit(OpCodes.Conv_I);

// Load the value from memory
il.Emit(OpCodes.Ldind_U4);

// Load shift amount
il.Emit(OpCodes.Ldc_I4, inst.ShiftAmount);

// Apply shift
il.Emit(ilOpCode);

// Pop value (not even trying to store yet)
il.Emit(OpCodes.Pop);

return false;
}

Код: Выделить всё

_cpu.RegisterFile.Regs
— это T*, где T — это либо uint, либо ulong в зависимости от того, является ли сконфигурированная версия MIPS 32- или 64-битной. В моем тестировании я использовал MIPS32R2, поэтому это uint.
Для дополнительной информации: следующие два метода не создают исключения:

Код: Выделить всё

    private unsafe bool Shift(ILGenerator il, MipsInstruction inst, OpCode ilOpCode)
{
il.Emit(OpCodes.Ldc_I4, inst.ShiftAmount);
il.Emit(OpCodes.Ldc_I4, inst.ShiftAmount);
il.Emit(ilOpCode);
il.Emit(OpCodes.Pop);

return false;
}

Код: Выделить всё

    private unsafe bool Shift(ILGenerator il, MipsInstruction inst, OpCode ilOpCode)
{
long baseAddress = (long)_cpu.RegisterFile.Regs;
long regAddress = baseAddress + ((int)inst.RT * sizeof(T));

// Push Address
if (IntPtr.Size == 4) il.Emit(OpCodes.Ldc_I4, (int)regAddress);
else il.Emit(OpCodes.Ldc_I8, regAddress);
il.Emit(OpCodes.Conv_I);

// Load the value from memory
il.Emit(OpCodes.Ldind_U4);
il.Emit(OpCodes.Pop);

return false;
}
Наконец, вот постоянная ссылка на все еще неработающую версию, которая содержит окружающий код: постоянная ссылка

Вернуться в «C#»