Lua位元組碼分析

2021-10-12 03:04:25 字數 2249 閱讀 7891

lua**首先會被lua編譯器(通常所指的luac)編譯為二進位制檔案,編譯是以乙個lua檔案為單位,比如乙個lua檔案內有語法錯誤,即使你不執行相關**,這個檔案也是編譯不過去的;編譯完成後,然後二進位制檔案被lua虛擬機器載入執行。

但實際上我們並不能看到編譯器的這個過程,這是因為lua直譯器是隱式呼叫編譯器和lvm的,也就是lua的編譯和執行是被封裝起來的,對外部是完全透明的;具體過程如下圖所示:

提前將lua檔案編譯為二進位制檔案,也就是二進位制chunk。

預編譯的主要優點:更快的載入速度,保護源**;

編譯成二進位制chunk只能提高lua虛擬機器的載入速度,執行速度還是不變的。

使用luac可以編譯生成乙個二進位制檔案,如luac main.lua,這裡沒有指定輸出檔案,它就會預設輸出檔名luac.out;

luac主要有兩個用途:

luac相關命令

luac -l [filename],生成已編譯位元組碼的列表,如果沒有給出檔名,則預設載入luac.out並列出位元組碼;使用luac -l -l [filename]可以得到更詳細的資訊

luac -o filename,指定輸出檔名,如果只是luac,那麼會預設生成luac.out;

luac -p,載入檔案但不生成任何輸出檔案。主要用於語法檢查和測試預編譯塊,只起到乙個編譯檢查的作用。

luac -s,在寫入檔案之前剝離除錯資訊;

luac -v,顯示版本資訊;

如下所示,新建乙個lua檔案,輸入一條語句print('hello world'),然後進行編譯和反編譯,反編譯結果如下:

編譯器在對乙個lua原始檔進行編譯時,會自動為指令碼新增乙個main函式,並且把整個程式都放進這個函式裡,然後再以它為起點進行編譯。這個函式不僅是編譯的起點,也是未來lua虛擬機器解釋執行程式時的入口,我們寫的上述print語句就會變成下面的樣子:

function main(...)

print('hello world')

return

end

反編譯列印出的函式資訊分為兩個部分:前面兩行是函式基礎資訊,後面是指令列表;

如下是乙個測試源**和反編譯結果,用於解讀函式基礎資訊;

第一行如果是main,說明是編譯器為我們新增的主函式,如果是function,則說明是乙個普通函式;跟在後面的是源檔名(檔案路徑)和函式在檔案裡的起止行號,對於主函式,起止都是0,對於自定義函式,就是檔案內的行號(不過由於我的原始檔裡前面有幾行注釋,所以這裡的起止和上面的原始碼沒有對應上,但和我本地的行號是對應的);最後就是指令數量和函式的位址;

第二行依次給出函式的固定引數數量(有+號代表是乙個vararg函式)、執行函式所必要的暫存器數量、upvalue數量、區域性變數數量、常量數量、子函式數量;

可以使用luac -l -l列印詳細資訊:

lua中的二進位制chunk格式也只是乙個位元組流,該格式屬於lua虛擬機器內部實現細節;

chunk格式沒有考慮跨平台需求,編譯指令碼時,直接按照本機的大小端方式生成二進位制檔案,當載入二進位制chunk檔案時,會探測被載入檔案的大小端方式,如果和本機不匹配,就拒絕載入。

二進位制chunk格式的設計也沒有考慮不同lua版本之間的相容問題,編譯時直接按照當時的lua版本生成二進位制chunk檔案,當載入二進位制chunk檔案時,會檢測被載入檔案的版本號,如果和當前lua版本不匹配,則拒絕載入。

二進位制chunk格式沒有被刻意得設計很緊湊,編譯成二進位制chunk之後,甚至會比文字形式的原始檔還要大,但把lua指令碼預編譯成二進位制chunk的主要目的是為了獲得更快的載入速度,所以這並沒有什麼影響。

對 Lua 位元組碼進行加密

由於 luajit 不支援 64 位,quick 新的版本預設使用 lua 5.1.5 版本,並提供將 lua 原始碼打包成通用位元組碼的工具 luac 為了增強安全性,quick 提供了乙個基本加密方案,使開發者可以對位元組碼作自定義的加密,防止對位元組碼的簡單反編譯工作。此方案配合原有的xxte...

python位元組碼 Python位元組碼簡介

python位元組碼 如果您曾經編寫過python,或者甚至只是使用過python,那麼您可能已經習慣了檢視python源 檔案。它們的名稱以.py結尾。而且您可能還看到了另一種型別的檔案,其名稱以.pyc結尾,並且您可能已經聽說它們是python的 位元組碼 檔案。這些在python 3上很難看到...

python 位元組碼 優化 位元組碼優化

python是一種動態語言。這意味著您在編寫 方面有很大的自由度。由於python公開了大量的自省 順便說一句,這非常有用 許多優化根本無法執行。例如,在第乙個示例中,python無法知道呼叫它時list是什麼資料型別。我可以建立乙個非常奇怪的類 class crazylist object pri...