lua脚本加载解析机制

时间:2024-04-14 20:09:04

blog的源码参考来自于lua5.3.4

lua字节指令处理

脚本指令处理过程一般分为 加载脚本、解析脚本、生成虚拟机能处理的指令、根据生成的指令执行相应的功能。lua虚拟机支持.lua脚本文件加载解析以及lua脚本字符串的解析处理。lua字节码指令加载解析处理的时序如下图
lua脚本加载解析机制

lua加载脚本

lua在API接口层面提供了两种加载脚本的方式:luaL_loadbufferx加载lua脚本字符串,luaL_loadfilex加载*.lua脚本文件。不过两者后面的处理逻辑还是由lua_load来执行,实际的脚本解析功能由函数luaD_protectedparser完成。
脚本解析将脚本抽象成expdesc(表达式)、Labeldesc(goto或者label)、Dyndata(解析器使用的动态结构)。解析所使用的结构如图
lua脚本加载解析机制
实际解析使用的主体由FuncState(进行函数解析)、LexState(语法语义解析) 、BlockCnt(针对代码块的描述结构)合作进行处理得以进行。这几个结构的说明如下图
lua脚本加载解析机制

解析过程在上面的时序图中luaY_parser的相关调用来完成,其中涉及到解析处理的过程就会使用到上图的这些结构。Dyndata的作用之一是存放LexState解析出的goto和label指令的信息,为lexstate处理goto和label提供支持;另一个作用时存放local变量的索引,为快速取得local变量提供支持。总而言之,Dyndata主要的作用时辅助lexstate更好地解析处理脚本。

相关概念的说明

BlockCnt

BlockCnt表示形如

if condition then 
dosomething

同时block的概念包含了for以及while循环,当然repeat… until的语句也被视为block, block作为解析过程中完整的一个单元,再由不同的语法来完成对block内部代码的解析。

local vars

local表示形如

local a

这样的变量

upval

引用的不是当前block中的local变量