Lua设计与实现
QQ : 1841545843
邮箱 : jiaxx903@163.com
-
Lua中我们使用一个通用的数据结构lua_TValue 来统一表示所有在Lua虚拟机中需要保存的数据类型。
-
首先在C语言中实现通用数据结构的一般做法
首先两点:
- 需要一个字段来存储数据的类型
- 需要存储不同的类型的数据
有两种方法来表示:
-
定义一个公共的数据结构作为基础类型,其他基本类型是从这个具体的类型中派生出来的
struct base{ int type; // 定义基础的数据类型 }; struct string { struct base info; int len; cahr* data[0]; }; struct number { struct base info; double num; };
-
使用联合将所有的数据包起来
struct string{ int len; char * data[0]; }; struct number { double num; }; struct value { int type; union{ string str; number num; } value; };
-
Lua通用数据结构的实现
主要有:数字,字符串,关联表,nil, userdata, Lua函数, C函数
/* ** basic types // 类型 对应的数据结构 */ #define LUA_TNONE (-1) // 无类型 无 #define LUA_TNIL 0 // 空类型 无 #define LUA_TBOOLEAN 1 // 布尔类型 无 #define LUA_TLIGHTUSERDATA 2 // 指针 void* #define LUA_TNUMBER 3 // 数据 lua_Number #define LUA_TSTRING 4 // 字符串 TString #define LUA_TTABLE 5 // 表 Table #define LUA_TFUNCTION 6 // 函数 CClosure\ LClosure #define LUA_TUSERDATA 7 // 指针 void* #define LUA_TTHREAD 8 // Lua虚拟机,协程 lua_State
Lua内部用一个宏表示那些数据类型需要GC
// LUS_TSTRING 之后的数据类型都需要GC操作 #define iscollectable(o) (ttype(o) >= LUA_TSTRING)
这些需要进行GC操作的数据类型都会有一个CommonHeader宏定义的成员,并且这个成员在结构体定义的最开始部分
typedef struct Table { CommonHeader; // 作为需要GC回收的标志 lu_byte flags; /* 1<<p means tagmethod(p) is not present */ lu_byte lsizenode; /* log2 of size of `node' array */ struct Table *metatable; TValue *array; /* array part */ Node *node; Node *lastfree; /* any free position is before this position */ GCObject *gclist; int sizearray; /* size of `array' array */ } Table;
CommonHeader的定义:
/* ** Common Header for all collectable objects (in macro(巨大的) form, to be ** included in other objects) ** ** next 指向下一个GC链表的成员 ** tt 表示数据类型,即前面表示那些数据类型的宏 ** marked GC相关的标志位 */ #define CommonHeader GCObject *next; lu_byte tt; lu_byte marked
还有一个GCheader结构体,其中成员只有CommonHeader
/* ** Common header in struct form */ typedef struct GCheader { CommonHeader; } GCheader;
在Lua中就使用GCObject;联合体将所有需要进行垃圾回收的数据类型囊括起来
/* ** Union of all collectable objects */ union GCObject { GCheader gch; union TString ts; union Udata u; union Closure cl; struct Table h; struct Proto p; struct UpVal uv; struct lua_State th; /* thread */ };
结论:
- 任何需要进行垃圾回收的Lua数据类型,必然是以CommonHeader作为该结构体定义的最开始部分。
- GCobject这个联合体将所有需要垃圾回收的数据类型全部囊括其中,这样定位和查找不同类型的数据就比较方便。
/* ** Union of all Lua values ** 这几种类型不需要进行垃圾回收 */ typedef union { GCObject *gc; void *p; lua_Number n; int b; } Value;
/* ** Tagged Values */ #define TValuefields Value value; int tt typedef struct lua_TValue { TValuefields; } TValue;
Lua通用数据结构组织
- 具体类型中有CommonHeader,用来存放所有数据类型都通用的字段
- TValue作为统一表示所有数据的数据结构,内部使用了联合体Value将所有数据都包含起来。