2019年8月刚入职新公司时,因为之前的项目都没有使用lua的经验,所以jojo老大出了一份题让我想尽办法找出答案,当时对于一个无经验的小菜鸟来说,属实费了不少功夫,如今分享出来,希望能对刚使用lua的朋友们有所帮助,如果有大佬看到有错误的地方,欢迎指出,感激不尽。
1、Lua的基础工作原理,.lua文件实时编译之后,给到虚拟机的是什么指令.
具体指令形式有看吗?这个指令占了多少位数据,第n位主句代表啥,稍微看一下,有一个认识。 然后这些指令,具体怎么跟lua源码的模块代码相结合呢?比如我们是怎么调用到Talbe里面的add的? 其实每个指令具体执行,都有一个switch(指令类型)这样执行的,找到这个文件,然后有时间可以大概了解一下lua的文件结构,大概每个文件都放了一些啥,可以更深入了解一下。 lua源码(window项目)可以打开tolua_rumtime-master_5_3_2lua-5.3.3lua.sln来看
- Lua使用虚拟堆栈向C传递值。此堆栈中的每个元素表示Lua值(nil,number,string等)。API中的函数可以通过它们接收的Lua状态参数访问此堆栈。
- Lua运行代码时,首先把代码编译成虚拟机的指令("opcode"),然后执行它们。 Lua编译器为每个函数创建一个原型(prototype),这个原型包含函数执行的一组指令和函数所用到的数据表。
虚拟机指令类型
/*
**虚拟机指令类型;;
**必须是无符号的(至少)4字节(请参阅lopcode .h中的详细信息)
*/
#if LUAI_BITSINT >= 32
typedef unsigned int Instruction;
#else
typedef unsigned long Instruction;
#endif
2、Lua的数据类型
(如果要看源码了,可以看一下会被gc的那个类型数据,是如何被定义的,为啥lua不需要定义数据类型就可以赋值?什么要的数据类型会被放到_G那里去。然后可能还有一些数据类型不不会暴露给我们使用的,比如Proto,这个跟function的实现相关,有兴趣可以了解一下。还有lua_State)
- Lua 中有 8 个基本类型分别为:nil、boolean、number、string、userdata、function、thread 和 table。
为啥lua不需要定义数据类型就可以赋值?
在赋值的时候,会调用函数expr解析表达式,=号右边的值,它最终会走入函数simpleexp中,在simpleexp中会根据expr解析出来的expdesc结构体里的t.token,用一个switch判断该表达式的类型,初始化expdesc结构体,将具体的数据赋值给expdesc结构体中的nval,所以,lua不需要定义数据类型就可以赋值,因为在解析器中会根据值的类型来进行初始化。
在函数localstat中,会读取“=”号左边的所有变量,首先看到在函数localstat中,首先会有一个循环调用函数new_localvar,将“=”左边的所有以","分隔的变量都生成一个相应的局部变量。 每一个局部变量,存储它的信息时使用的是LocVar结构体:
static void localstat (LexState *ls) {
/* stat -> LOCAL NAME {',' NAME} ['=' explist] */
int nvars = 0;
int nexps;
expdesc e;
do {
new_localvar(ls, str_checkname(ls));
nvars++;
} while (testnext(ls, ','));
if (testnext(ls, '='))
nexps = explist(ls, &e);
else {
e.k = VVOID;
nexps = 0;
}
adjust_assign(ls, nvars, nexps, &e);
adjustlocalvars(ls, nvars);
}
typedef struct LocVar