0x0. 解析
在解析过程中,不管是左值还是右值,我们可以分为两种类型:
- 变量:lua中的变量是没有类型的,只有作用域,因此变量在lua里面可以分为全局变量,局部变量,upvalue
- 全局变量:保存在全局的hash表中,也叫环境变量。每个lua线程只有一份。
- 局部变量:局部变量保存在函数栈中,也叫做寄存器。由于在lua中变量没有类型,所以每个寄存器的大小是一样的。
- upvalue:upvalue也可以称之为函数环境变量。
- 常量:常量也就是lua里面的数据类型,有VOID,NIL,字符串,数字
``c typedef enum { VVOID, /* no value */ VNIL, VTRUE, VFALSE, VK, /* info = index of constant in
k’ / VKNUM, / nval = numerical value / VLOCAL, / info = local register / VUPVAL, / info = index of upvalue inupvalues' */ VGLOBAL, /* info = index of table; aux = index of global name in
k’ / VINDEXED, / info = table register; aux = index register (or `k’) / VJMP, / info = instruction pc / VRELOCABLE, / info = instruction pc / VNONRELOC, / info = result register / VCALL, / info = instruction pc / VVARARG / info = instruction pc */ } expkind;
typedef struct expdesc { expkind k; union { struct { int info, aux; } s; lua_Number nval; } u; int t; / patch list of `exit when true’ / int f; / patch list of `exit when false’ / } expdesc;
<a name="Yehji"></a>
## 0x1. 左值
---
<a name="Miopi"></a>
#### local变量
```lua
local var = 1
局部变量的解析需要完成两件事:
- 解析变量名,用于后续的索引。后续可能会读这个变量。
- 分配寄存器空间用于存储。
下面是创建局部变量的代码,从中可以看出
static void new_localvar (LexState *ls, TString *name, int n) {
FuncState *fs = ls->fs;
luaY_checklimit(fs, fs->nactvar+n+1, LUAI_MAXVARS, "local variables");
fs->actvar[fs->nactvar+n] = cast(unsigned short, registerlocalvar(ls, name));
}
全局变量
var = 1
全局变量的解析需要完成:
- 解析变量名,并放置到函数常量中,后续根据这个常量索引去访问全局变量
0x2. 右值
局部变量
局部变量的访问比较简单,就是根据名字找到对于的寄存器索引就可以。
全局变量
在lua中由于所有的变量操作都是基于栈进行的,所以要访问全局变量需要将全局变量加载到栈中才能访问。因此在lua中建议多次使用的全局变量保存到局部变量,再用局部变量去访问。