1

我正在使用第 3 方库 JInt(JavaScript 解释器),它在我切换到 Mac OS X 之前运行良好,之后我不断收到 ArgumentNullExceptions,经过一番调查,我发现 JInt 使用动态代码生成制作某种 Js-Clr 桥梁。该方法最后有以下说明:

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

以下是这些行的执行方式(此处为全尺寸截图)

在此处输入图像描述

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

在此处输入图像描述

我当前将要执行的语句是 Ldnull,我执行“Step In”(在 Ldnull 上)并且在 Ldfld 上发生 BANG 异常(此处为全尺寸屏幕截图)::

在此处输入图像描述

有什么建议么?

4

2 回答 2

1

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

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

  • JInt 使用一种奇怪的模式在堆栈上加载一个静态字段。我可以通过发出此模式在 Mono 2.10.6 上重现该问题和 NRE。好消息是它已在 master 中修复。由于您可以访问 JInt 的代码,为了防止 NRE,您可以修改 else 分支以简单地阅读:

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

这会让你继续前进。

于 2011-12-15T19:55:10.563 回答
0

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

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

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

于 2011-12-15T18:59:37.570 回答