Mac OS X / Mono下的Ldfld问题,可能是Mono bug

时间:2011-12-15 18:15:40

标签: c# .net cil jint

我正在使用第三方库JInt(JavaScript interpriter)工作正常,直到我切换到Mac OS X,之后我继续获取ArgumentNullExceptions,经过一些调查我发现JInt使用了动态用于制作某种Js-Clr桥的代码生成。该方法最后有以下说明:

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

以下是这些行的执行方式(全尺寸屏幕截图here

enter image description here

可以清楚地看到fieldInfo参数不为空,但是在执行这些行时,请注意LDFLD没有参数! (全尺寸屏幕截图here):

enter image description here

我将要执行的当前声明是Ldnull,我执行“Step In”(Over Ldnull)并且在Ldfld上发生BANG异常(全尺寸屏幕截图here)::

enter image description here

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

您描述的这个问题是不同问题的组合:

  • IL反汇编不显示字段操作数。它不仅适用于您的领域,您可以在拆卸之前在ldsfld中看到它。我不担心,我鼓励你报告它有一个MonoDevelop错误。

  • JInt使用奇怪的模式在堆栈上加载静态字段。我可以通过发出这种模式来重现问题和Mono 2.10.6上的NRE。好消息是它固定在主人身上。由于您可以访问JInt的代码,为了防止NRE,您可以修改else分支,只需阅读:

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

这会让你前进。

答案 1 :(得分:0)

ldfld应该总是带有一个参数,否则你会得到一个无效的CLR,运行时环境应该拒绝加载它(加载时有错误的CIL抛出异常的程序集)。

我认为由于某种原因,在运行时无法解析作为此ldfld的参数的字段引用(尽管在创建代码时它存在)。一方面,这就是为什么你在IDE中得到没有参数的ldfld(它没有显示类型,因为它无法加载它),另一方面你在执行这个特定的行时得到null异常。

您确定动态创建的程序集是否正确引用了包含JsUndefined类型的程序集?代码生成器可以看到它,但生成的代码看到了吗?