Unity 熱更新 之 如何使用AST轉(zhuǎn)換 C# -> Lua

本文轉(zhuǎn)自Unity Connect博主 郡墻

本篇主要論述 如何將 C# 代碼自動(dòng)轉(zhuǎn)換為 Lua 代碼的解決方案

方案流程

  1. 利用 Mono ceil 庫(kù)分析程序集中的類、字段、方法簽名,然后將其翻譯成對(duì)應(yīng)的Lua 模塊所模擬的類型結(jié)構(gòu)

  2. 通過 ILSpy工具分析IL指令集,重建由語(yǔ)句表達(dá)式組成的AST(抽象語(yǔ)法樹),并翻譯成對(duì)應(yīng)的Lua方法體

  3. 把Lua類型與Lua方法體合并成完整的Lua代碼

按照同樣的原理可以翻譯成其他的語(yǔ)言 其中 Mono ceil 負(fù)責(zé)從程序集中提取類、字段、方法;ILSpy(基于Mono ceil 開發(fā)的工具) 則負(fù)責(zé)分析方法體指令序列。 架構(gòu)設(shè)想

  • 整體分析 : 分析程序集和多程序集關(guān)系

  • 類型生成 : 分析程序集中的類、字段、方法,生成對(duì)應(yīng)的Lua結(jié)構(gòu)

  • 表達(dá)式生成 : 分析方法體,利用ILSpy重建AST,生成對(duì)應(yīng)的Lua表達(dá)式

翻譯流程思路分享

  1. 類型結(jié)構(gòu)翻譯,通過Mono.ceil 分析程序集中包含的所有類,以及類中定義的字段和方法,收集到這些信息后,就可以生成Lua對(duì)應(yīng)的類型和結(jié)構(gòu)及方法定義(無(wú)方法體)

  2. 方法體翻譯,利用ILSpy將方法體中的IL指令序列重建成AST,翻譯工具將AST轉(zhuǎn)換成Lua語(yǔ)句和表達(dá)式,形成Lua方法體

  3. 整合1,2步驟

因?yàn)樵创a在編譯后,將會(huì)對(duì)字符串、常量、枚舉、計(jì)算等進(jìn)行一系列優(yōu)化,比如刪除無(wú)效的無(wú)用代碼,預(yù)處理各種字符串、減少運(yùn)行時(shí)開銷等 。對(duì)翻譯后的 Lua 代碼邏輯也是編譯器優(yōu)化后的。

翻譯細(xì)節(jié)分析

類關(guān)系

  • Partial類:編譯后自動(dòng)合并,由標(biāo)準(zhǔn)編譯器完成

  • 匿名類: 編譯后生成具體的實(shí)名類,由標(biāo)準(zhǔn)編譯器完成

  • 嵌套類: 生成Lua形式的嵌套關(guān)系,由工具完成

  • 繼承類: 生成繼承關(guān)系的類型,由工具完成

  • 泛型類: 編碼實(shí)現(xiàn)

類成員

  • 字段初始化:編譯后,在初始化函數(shù)中生成賦值過程,由標(biāo)準(zhǔn)編譯器完成

  • 屬性:編譯后,添加get/set具體函數(shù),由標(biāo)準(zhǔn)編譯器完成

  • 索引器:編譯后,索引對(duì)應(yīng)的函數(shù)過程由標(biāo)準(zhǔn)編譯器完成

  • 擴(kuò)展方法: 編譯后為類擴(kuò)展的方法變成靜態(tài)函數(shù)調(diào)用,由標(biāo)準(zhǔn)編譯器完成

  • 運(yùn)算符重載:編譯后運(yùn)算符重載變成具體的函數(shù)調(diào)用,由標(biāo)準(zhǔn)編譯器完成

  • 匿名函數(shù):編譯后,匿名函數(shù)自動(dòng)變成實(shí)名函數(shù),由標(biāo)準(zhǔn)編譯器完成

  • 方法:生成對(duì)應(yīng)的Lua方法,由翻譯工具實(shí)現(xiàn)

  • 構(gòu)造函數(shù):生成對(duì)應(yīng)的Lua初始化函數(shù),由翻譯工具完成

  • 泛型函數(shù):泛型函數(shù)變成函數(shù)參數(shù),生成對(duì)應(yīng)的lua函數(shù),由翻譯工具完成

  • 匿名構(gòu)造函數(shù)和類成員初始化:標(biāo)準(zhǔn)編譯器將自動(dòng)合并到構(gòu)造函數(shù)中,由標(biāo)準(zhǔn)編譯器完成

  • 可選參數(shù):編譯后,未填寫的參數(shù)將自動(dòng)使用默認(rèn)值填充,由標(biāo)準(zhǔn)編譯器完成

  • 多參數(shù):編譯后,等價(jià)于數(shù)組參數(shù),由標(biāo)準(zhǔn)編譯器完成

方法體

  • Lambda表達(dá)式: 編譯后,表達(dá)式展開為具體函數(shù)調(diào)用,由標(biāo)準(zhǔn)編譯器完成工作

  • 常量: 編譯后,常量名被替換為整型值,由標(biāo)準(zhǔn)編譯器完成

  • 枚舉:編譯后,引用關(guān)系變成類型之間的相互調(diào)用,由標(biāo)準(zhǔn)編譯器完成

  • typeof: 編譯后,替換成具體類型,由標(biāo)準(zhǔn)編譯器完成

  • 泛型構(gòu)造: 編譯后,泛型參數(shù)被實(shí)例化,由標(biāo)準(zhǔn)編譯器完成

  • 賦值:生成Lua賦值,連續(xù)賦值將被拆解,由翻譯器完成

  • 循環(huán)語(yǔ)句:反編譯后,所有的循環(huán)都變成單一的Loop結(jié)構(gòu),由翻譯工具生成lua的for循環(huán)

  • 條件語(yǔ)句:生成Lua的if條件,由翻譯工具完成

  • switch語(yǔ)句:由if條件判斷和repeat循環(huán)組合模擬,由翻譯工具完成工作

  • 集合初始化:標(biāo)準(zhǔn)編譯器生成結(jié)構(gòu)花指令,由翻譯工具完成工作

  • try..catch語(yǔ)句:生成Lua的xpcall,由翻譯工具完成工作

  • 問號(hào)表達(dá)式:生成等價(jià)的 ‘或與表達(dá)式’

  • 其他:直接翻譯,由翻譯工具完成

  • 其他高級(jí)特由編譯器完成

原文鏈接:https://connect.unity.com/p/unity-re-geng-xin-zhi-ru-he-shi-yong-astzhuan-huan-c-lua?app=true

歡迎戳上方原文鏈接,下載Unity官方技術(shù)社區(qū)app,在線技術(shù)答疑,發(fā)現(xiàn)更多資源干貨!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 第一篇 語(yǔ)言 第0章 序言 Lua僅讓你用少量的代碼解決關(guān)鍵問題。 Lua所提供的機(jī)制是C不擅長(zhǎng)的:高級(jí)語(yǔ)言,動(dòng)態(tài)...
    testfor閱讀 2,936評(píng)論 1 7
  • 1. 寫在前面 很多時(shí)候我們都需要借助一些腳本語(yǔ)言來(lái)為我們實(shí)現(xiàn)一些動(dòng)態(tài)的配置,那么就會(huì)涉及到如何讓腳本語(yǔ)言跟原生語(yǔ)...
    杰嗒嗒的阿杰閱讀 3,500評(píng)論 9 31
  • 3. 類設(shè)計(jì)者工具 3.1 拷貝控制 五種函數(shù)拷貝構(gòu)造函數(shù)拷貝賦值運(yùn)算符移動(dòng)構(gòu)造函數(shù)移動(dòng)賦值運(yùn)算符析構(gòu)函數(shù)拷貝和移...
    王偵閱讀 2,062評(píng)論 0 1
  • 蘋果官方文檔翻譯 《Objective-C語(yǔ)言編程》(Programming with Objective-C) ...
    fever105閱讀 26,289評(píng)論 19 129
  • 1.晨,早起,完善第一周彩色課表,并制作了幾張部首歸類的字源課件。感覺讀過《漢字密碼》和《細(xì)說(shuō)漢字》后,制作時(shí)感覺...
    蕭蕭蘆葦閱讀 180評(píng)論 0 0

友情鏈接更多精彩內(nèi)容