什么是虚拟机?
大部分人都用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这4个token,对应的类型分别为“保留字”、“变量”、“等号”、“数字”。
-
语法分析:检查是否满足lua语法,比如 function要以end结束,若发现有语法错误,立即报错停止执行。
-
生成中间字节码:若满足语法规则,可生成对应的字节码,比如 “local a=18”对应的字节码为 “loadk 0 0”,第一个0表示变量a所在的位置,第2个0表示常量18所在的位置,即将常量18赋给变量a。
-
执行字节码:生成字节码列表后,从第一行开始逐行执行,根据字节码的opcode执行对应的逻辑。
简单的说就是:
源码文件 -> 中间字节码 -> 虚拟机执行字节码