Проблемы с Ldfld в Mac OS X / Mono, возможно ошибка Mono - PullRequest
1 голос
/ 15 декабря 2011

Я использую стороннюю библиотеку JInt (интерпретатор JavaScript), которая работала нормально, пока я не переключился на Mac OS X, после чего я продолжаю получать ArgumentNullExceptions, после некоторого исследования я обнаружил, что JInt использует динамическийгенерация кода для создания своего рода моста Js-Clr.Этот метод имеет следующие инструкции в конце:

code.Emit(OpCodes.Ldnull);
FieldInfo fieldInfo = typeof(JsUndefined).GetField("Instance");
code.Emit(OpCodes.Ldfld, fieldInfo);

Вот как эти строки выполняются (полный размер экрана здесь )

enter image description here

Хорошо видно, что аргумент fieldInfo не является нулевым, хотя когда дело доходит до выполнения этих строк, обратите внимание, что LDFLD не имеет аргумента!(Полный скриншот здесь ):

enter image description here

Мой текущий оператор, который будет выполнен, - это Ldnull, я выполняю «Step In» (Over Ldnull) и BANGисключение происходит через Ldfld (полный размер экрана здесь ) ::

enter image description here

Есть предложения?

Ответы [ 2 ]

1 голос
/ 15 декабря 2011

Эта проблема, которую вы описываете, является комбинацией различных проблем:

  • Разборка IL не отображает операнды полей. Это не только для вашей области, вы можете увидеть это в разборке ранее для ldsfld. Я бы не беспокоился об этом, я призываю вас сообщить, что в нем есть ошибка MonoDevelop.

  • JInt использует странный шаблон для загрузки статического поля в стек. Я могу воспроизвести проблему и NRE на Mono 2.10.6, испустив этот паттерн. Хорошей новостью является то, что это исправлено в мастере. Поскольку у вас есть доступ к коду JInt, чтобы предотвратить NRE, вы можете изменить ветку else так, чтобы она просто читала:

    code.Emit (OpCodes.Ldsfld, typeof (JsUndefined) .GetField ("Instance"));

Это поможет вам.

0 голосов
/ 15 декабря 2011

ldfld всегда должен идти с аргументом, в противном случае вы получите недопустимый CLR, а среда выполнения должна отказать в его загрузке (сборки с искаженными исключениями CIL при загрузке).

Я считаю, что по какой-то причине ссылка на поле, являющаяся аргументом этого ldfld, не может быть разрешена во время выполнения (хотя она существует при создании кода). С одной стороны, именно поэтому вы получаете ldfld без аргументов в IDE (он не показывает тип, потому что не может его загрузить), а с другой стороны, вы получаете нулевое исключение при выполнении этой конкретной строки.

Вы уверены, что динамически созданная сборка правильно ссылается на сборку, содержащую тип JsUndefined? Генератор кода мог бы видеть это, но сгенерированный код видит это?

...