2012-02-08 62 views
3

背景:我爲一個學校項目編寫了一個.NET編譯器(非常類似於C#)。我目前試圖添加的功能之一是在方法內調用遞歸。CIL(MSIL)實例方法中的尾調用遞歸

更多信息:在CIL中,「this」被傳遞給實例方法,就好像它只是另一個參數。因此,訪問靜態方法的第一個參數時,您將發出ldarg.0,但訪問實例方法的第一個參數,則會發出ldarg.1,並在實例方法中訪問「this」,您將發出ldarg.0 。 (實例方法與我想象中的擴展方法更相似。)

問題:你可以使用starg.0設置「this」而沒有任何副作用嗎?

爲什麼會出現這樣的問題:方法是否是實例方法是通過MethodBuilder設置的,這是一個黑盒子。儘管「this」看起來和其他任何爭論一樣,但我知道一些JIT編譯器會分別跟蹤「this」並根據這個值改變它們的行爲。如果在實例方法中設置「this」時存在副作用,那麼我該如何避免它們?

+0

雖然這是一個有趣的問題,但我想補充一點,你問的是我認爲會成爲一個特例的情況:只有在不同的類實例上調用當前方法時,您的問題才重要。按照你描述的方式,不同的方式是不可能的,使用相同的'this'來調用當前的方法並不需要修改參數0. – hvd 2012-02-09 00:03:38

回答

2

你可能想看看how F# implements tail-call

+0

完美!謝謝! – aboveyou00 2012-02-09 00:05:04

+0

有人可以指出相關部分嗎? – Stilgar 2012-02-09 00:11:09

+0

我在下面的評論中也是這樣說的,但我會在這裏重複一遍。回想起來,我沒有問我的意思,只是如何解決它的一個症狀。這是一個誠實的錯誤,但是我很抱歉我無論如何都在誤導。 – aboveyou00 2012-02-09 00:35:47

1

您可以將其作爲局部變量提取。這樣你就會知道你可以安全地設置它。 (我希望我能正確理解你的問題)

+0

這並不能解決問題 - 將會發生相同的副作用如果你只發出starg.0,並且假定JIT編譯器也被更新。不過謝謝你的回答。 – aboveyou00 2012-02-08 23:55:29

+0

@ aboveyou00這是一個正確的答案,即使'starg.0'不安全(我不明白爲什麼會這樣,但我不確定),使用額外的變量代替參數0肯定是必須的注意安全。 – hvd 2012-02-09 00:06:07

+0

所以你擔心即使你將引用傳遞給本地變量,JIT編譯器也會跟蹤「this」嗎? – Stilgar 2012-02-09 00:06:07