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

发布于 2024-12-21 13:42:39 字数 943 浏览 0 评论 0 原文

我正在使用第 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”(Over Ldnull),并且 Ldfld 上发生 BANG 异常(全尺寸屏幕截图 此处)::

有什么建议吗?

I'm using 3rd party library JInt (the JavaScript interpriter) which was working fine until I've switched to Mac OS X, after that I keep on getting ArgumentNullExceptions, after some investigation I've found out that JInt uses dynamic code generation for making some sort of Js-Clr bridge. This method has the following instructions in the end:

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

Here's how these lines are executed (Full size screenshot here)

enter image description here

It is clearly seen that fieldInfo argument is not null, though when it comes to executing these lines, notice that LDFLD has no argument! (Full size screenshot here):

enter image description here

My current statement that will get executed is Ldnull, I performing "Step In"(Over Ldnull) and BANG exception occurs over Ldfld (Full size screenshot here)::

enter image description here

Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

醉态萌生 2024-12-28 13:42:39

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

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

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

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

这会让你继续前进。

This issue you describe is a combination of different issues:

  • The IL disassembly doesn't show the fields operands. It's not only for your field, you can see it in the disassembly before for a ldsfld. I'd not worry about that, I encourage you to report it has a MonoDevelop bug though.

  • JInt is using a weird pattern to load a static field on the stack. I can reproduce the issue and the NRE on Mono 2.10.6 by emitting this pattern. Good news is that it is fixed in master. As you have access to JInt's code, to prevent the NRE, you can modify the else branch to simply read:

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

This will get you going.

残疾 2024-12-28 13:42:39

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

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

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

The ldfld should always come with an argument, otherwise you get an invalid CLR and the runtime environment should refuse to load it (assemblies with malformed CIL throw exceptions upon loading).

I believe then that for some reason the field reference which is an argument of this ldfld cannot be resolved in the run time (although it exists when the code is created). On one hand this is why you get the ldfld without arguments in the IDE (it doesn't show the type because it is unable to load it) and on the other hand you get null exception upon executing this particular line.

Are you sure that the dynamically created assembly correctly references the assembly containing the JsUndefined type? The code generator could be able to see it but the does the generated code see it?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文