2016-10-15 34 views
2

我在试图看看如何使用jmp操作码,到目前为止我还没有设法调用通用方法。对于我的测试,我有一个方法返回它的参数,另一个方法的主体只是jmp操作码跳转到第一个方法。我的问题是,当我跳转到非泛型方法时(例如jmp int32 Program::Id2(int32)带有以下用于Id2的签名:static int Id2(int x)),则在运行时没有错误,而如果我为泛型方法执行此操作(例如jmp !!0 Program::Id<int32>(!!0)具有以下Id: static T Id<T>(T x))我得到一个“公共语言运行时检测到一个无效的程序”异常。造成这个问题的原因是什么?.Net CIL jmp操作码和通用方法

P.S. :这里’ s a gist与CIL我用于我的测试。注释跳转到Id2的行并取消注释IdInt中跳转到Id的行使其在运行时出现上述异常时失败。制作IdIntId2返回参考类型,如StringBuilder doesn ’ t使其失败。

+1

你能发布一个可编译的例子吗? – thehennyy

+0

@thehennyy好点,我在测试IL中添加了一个要点。 – arjanen

+0

你有没有试过在你的代码上运行peverify? – svick

回答

2

ECMA-335分区III节3.37 - JMP表示:

控制转移到由方法规定的方法,其是元数据标记(一个methodref或 methoddef(参见分区II)的。当前参数被传输到目的地的方法。

两个MemberRef和MethodDef令牌能够引用非通用方法和开放通用方法,但以引用的封闭通用方法需要MethodSpec令牌未被列为可接受。

我怀疑jmp可能不支持泛型方法,因为它会干扰jits对同一泛型方法的不同实例重用本地代码的能力。

+0

感谢您的答案,这可能是因为我跳到一个封闭的泛型方法:这[第二个要点](https://gist.github.com/Bebere/6240be508093f51e0647a9649c8bae2c)跳转到一个开放的泛型方法的作品。 – arjanen

+0

您在第二个要点中没有使用开放泛型方法,您传递给它的类型参数来自Id2。这意味着我的回答是不正确的(稍后有更多的时间我就会调查并更新)。我怀疑真正的答案是关于这组类型参数的信息像其他参数一样从调用者传递到被调用者,并且运行时需要确保'Id'将正确解释从调用'Id2'继承的类型参数。 –