2010-07-05 5 views
1

Я создаю компилятор с reflection.emit в свое свободное время, и я пришел к проблеме, которую я не понимаю.System.AccessViolationException сохранение переменной с reflectio.emit

Небольшой контекст, у меня есть среда выполнения с несколькими типами, а одна из них - Float2, более простая векторная структура с двумя значениями float (X и Y). Я создал пару свойств, которые позволяют мне пересказывать значения (a la hlsl). Например, если у меня есть новый Float2 (1.0f, 2.0f), если я что-то сделаю (новый Float2 (1.0f, 2.0f)). YX я собираюсь получить Float2 (2.0f, 1.0f) Я использую этот тип на моем языке и в настоящее время тестирует этот случай (незначительные детали языка опущена):

float2 a = float2(1.0, 2.0).yx; 
return a; 

Я преобразуя float2 (1.0, 2.0) в новый вызов и доступ к собственности YX из мой тип Float2 в .yx.

Проблема заключается в том, что я получаю «System.AccessViolationException: Попытка чтения или записи защищенной памяти. Это часто свидетельствует о том, что другая память повреждена». Я не понимаю, потому что, если я сделаю что-то вроде этого:

float2 a = float2(1.0, 2.0); 
return a; 

Все идет хорошо.

код IL, что я производящая следующий (я думаю, что проблема возникает в «L_0014: stloc.0», я не знаю, почему это происходит, хотя):

.method public virtual final instance valuetype 
[Bifrost.Psl]Bifrost.Psl.Compiler.Runtime.Float2 Main() cil managed 
{ 
    .maxstack 3 
    .locals init (
     [0] valuetype [Bifrost.Psl]Bifrost.Psl.Compiler.Runtime.Float2 num) 
    L_0000: ldc.r4 1 
    L_0005: ldc.r4 2 
    L_000a: newobj instance void [Bifrost.Psl]Bifrost.Psl.Compiler.Runtime.Float2::.ctor(float32, float32) 
    L_000f: call instance valuetype [Bifrost.Psl]Bifrost.Psl.Compiler.Runtime.Float2 [Bifrost.Psl]Bifrost.Psl.Compiler.Runtime.Float2::get_XY() 
    L_0014: stloc.0 
    L_0015: ldloc.0 
    L_0016: ret 
} 

Результат peverify:

[IL]: Ошибка: [смещение 0x0000000F] [найденное значение 'Bifrost.Psl.Compiler.Runtime.Float2'] [ожидается, адрес значения 'Bifrost.Psl.Compiler.Runtime.Float2'] Неожиданный тип в стеке.

+0

Я не вижу ничего плохого в ИЛ. Я должен догадаться, что проблема заключается либо в конструкторе, либо в элементе XY. Ваши фрагменты кода плохие, они не имеют ключевое слово * new *. –

+0

Извините, но на моем языке нет новых. float2 (1.0, 2.0) создает значение. Для IL я генерирую newobj для этой команды –

ответ

4

IL выглядит нормально, хотя я не знаю, как выглядит ваш Float2.

Я нашел лучший способ отладить это, чтобы сохранить сборку на диск, затем запустите peverify. Любой код, который генерирует AccessViolationException, приведет к ошибке в peverify.

Редактировать: Обсуждение вопроса о нажатии ссылки на объект на стек, который я выбрал как указатель на тип значения. Если вы получаете эту ошибку от peverify то я думаю, что вам нужно

  1. newobj
  2. stloc к временному переменному
  3. ldloca, чтобы получить адрес типа значения, хранящийся в переменных временных
  4. call

Теперь, когда я думаю об этом, это то, что C# компилятор делает, если вы делаете прямой вызов по типу значения, например 4.ToString();.

+0

Humm nice tip, я получаю [IL]: Ошибка: [смещение 0x0000000F] [найденное значение «Bifrost.Psl.Compiler.Runtime.Float2»] [ожидается адрес значения «Bifrost.Psl.Compiler.Runtime.Float2»] Неожиданный тип в стеке. Это должно быть связано с тем, что возвращает конструктор ... –

+0

См. Мое редактирование ... :) –

+0

Я попробую это много. Я буду обновлять как ответ после –

 Смежные вопросы

  • Нет связанных вопросов^_^