漫談lua虛擬機器
什麼是虛擬機器?
大部分人都用c語言寫過簡單的小程式吧,寫好後用編譯器,比如turbo c或者visual c++編譯生成exe檔案,然後執行exe程式。exe檔案裡面其實存放著c程式碼對應的機器指令,執行exe就是排程cpu去一句句執行機器指令。
lua與c語言不同的地方在於,lua不需要編譯成exe檔案,可以由lua虛擬機器執行lua程式碼檔案。lua虛擬機器用c語言編寫,執行程式碼時先將lua檔案轉換成位元組碼指令,然後再逐個執行位元組碼指令。
舉個例子,lua原始檔如下:
local a=18
local b=a
對應的位元組碼指令為:
; (1) local a=18
[1] loadk 0 0 ; 18
; (2) local b=a
[2] move 1 0
[3] return 0 1
這種指令稱之為三地址指令,即1個操作碼和2~3個引數組成一條指令。虛擬機器每次取出一條指令,可以順序往下執行,也可以跳行執行,比如從指令1直接跳到指令3,跳行執行一般用於if等條件語句。
虛擬機器內部流程
虛擬機器的輸入就是原始碼檔案,輸出是程式碼執行結果。內部流程分為以下幾個環節:
-
讀取檔案:一個程式碼檔案作為一個長字串讀入。
-
詞法分析:根據lua語法進行簡單的單詞切分,每個單詞稱為token,token有多個型別,比如 "local a=18"可以拆分為local、a、=、18
-
語法分析:檢查是否滿足lua語法,比如 function要以end結束,若發現有語法錯誤,立即報錯停止執行。
-
生成中間位元組碼:若滿足語法規則,可生成對應的位元組碼,比如 “local a=18”對應的位元組碼為 “loadk 0 0”,第一個0表示變數a所在的位置,第2個0表示常量18所在的位置,即將常量18賦給變數a。
-
執行位元組碼:生成位元組碼列表後,從第一行開始逐行執行,根據位元組碼的opcode執行對應的邏輯。
簡單的說就是:
原始碼檔案 -> 中間位元組碼 -> 虛擬機器執行位元組碼