第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

跟蹤類字節(jié)碼中方法實(shí)現(xiàn)的變化

跟蹤類字節(jié)碼中方法實(shí)現(xiàn)的變化

智慧大石 2023-04-13 10:32:32
我在一些 kotlin 代碼中有一些抽象項目(讓我們稱之為項目)字節(jié)碼(它是每個類的),每個類字節(jié)碼都存儲為 ByteArray;任務(wù)是告訴每個類中的哪些特定方法在項目的構(gòu)建之間被修改。也就是說,同一個類的The Project有兩個ByteArray,但是屬于不同的版本,需要比較準(zhǔn)確。一個簡單的例子。假設(shè)我們有一個簡單的類:class Rst {    fun getjson(): String {        abc("""ss""");        return "jsonValid"    }    public fun abc(s: String) {        println(s)    }}它的字節(jié)碼存儲在 oldByteCode 中?,F(xiàn)在類發(fā)生了一些變化:class Rst {        fun getjson(): String {            abc("""ss""");            return "someOtherValue"        }        public fun newMethod(s: String) {            println("it's not abc anymore!")        }    }它的字節(jié)碼存儲在 newByteCode 中。這是主要目標(biāo):將 oldByteCode 與 newByteCode 進(jìn)行比較。這里我們有以下變化:getjson() 方法已更改;abc() 方法已被刪除;newMethod() 已創(chuàng)建。因此,如果方法的簽名保持不變,則該方法已更改。如果沒有,它已經(jīng)是一些不同的方法了?,F(xiàn)在回到實(shí)際問題。我必須通過字節(jié)碼了解每個方法的確切狀態(tài)。我現(xiàn)在擁有的是 jacoco 分析器,它將類字節(jié)碼解析為“包”。在這些包中,我有包、類、方法的層次結(jié)構(gòu),但只有它們的簽名,所以我無法判斷方法的主體是否有任何變化。我只能跟蹤簽名差異。是否有任何工具、庫可以將類字節(jié)碼拆分為其方法字節(jié)碼?例如,我可以用它們計算哈希值并進(jìn)行比較。也許 asm 庫對此有任何處理?歡迎任何想法。
查看完整描述

1 回答

?
富國滬深

TA貢獻(xiàn)1790條經(jīng)驗 獲得超9個贊

僅比較字節(jié)碼甚至哈希的方法不會產(chǎn)生可靠的解決方案,事實(shí)上,對于此類問題根本沒有合理的解決方案。

我不知道,其中有多少適用于 Kotlin 編譯器,Java 編譯器不需要生成相同的字節(jié)碼,即使使用相同的版本來編譯完全相同的源代碼。

即使我們假設(shè) Kotlin 編譯器具有出色的確定性,甚至跨版本,它也不能忽視 JVM 的演變。例如,任何編譯器都不能忽略/指令的刪除,即使在嘗試保守時也是如此。jsrret但它很可能也會包含其他改進(jìn),即使不是被迫的1。

所以簡而言之,即使整個源代碼沒有改變,假設(shè)編譯后的形式必須保持不變也是不安全的。即使使用顯式確定性編譯器,我們也必須在使用更新版本重新編譯時為更改做好準(zhǔn)備。

更糟糕的是,如果一種方法發(fā)生變化,它可能會對其他方法的編譯形式產(chǎn)生影響,因為只要需要常量或鏈接信息,指令就會引用常量池中的項目,并且這些索引可能會發(fā)生變化,具體取決于其他方法如何使用常量池。當(dāng)訪問前 255 個池索引之一時,某些指令也有優(yōu)化的形式,因此編號的更改可能需要更改指令的形式。這反過來可能對其他指令有影響,例如開關(guān)指令具有填充字節(jié),具體取決于它們的字節(jié)代碼位置。

另一方面,如果新常量碰巧在池中與舊常量相同的位置結(jié)束,則僅在一個方法中使用的常量值的簡單更改可能根本不會影響方法的字節(jié)碼。

所以,要判斷兩個方法的代碼是否實(shí)際上相同,無法繞過指令解析并在一定程度上理解它們的含義。只比較字節(jié)或哈希是行不通的。

1 命名一些非強(qiáng)制性更改,類文字的編譯已更改,同樣,字符串連接從 using 更改StringBuffer為 useStringBuilder并再次更改為 useStringConcatFactory,getClass()內(nèi)部null檢查的使用更改為requireNonNull(…),等等。不同語言的編譯器不會必須跟隨,但沒有人愿意被落在后面……

還有一些錯誤需要修復(fù),比如過時的指令,沒有編譯器會為了保持確定性而保留這些錯誤。


查看完整回答
反對 回復(fù) 2023-04-13
  • 1 回答
  • 0 關(guān)注
  • 135 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號