2016-10-15 36 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'繼承的類型參數。 –