Lua 源码学习笔记(1)数据类型
参考书籍:《Lua设计与实现》
作者书籍对应Github:https://github.com/lichuang/Lua-Source-Internal
云风的 BLOG:https://blog.codingnow.com/2011/03/lua_gc_1.html
Lua源码下载:http://www.lua.org/ftp/
lua 5.3.4 GC管理对象类型的变化:https://www.jianshu.com/p/df948258e32c
- Lua版本:5.3.5
定义的类型
// lua.h 59行开始
/*
** basic types
*/
#define LUA_TNONE (-1)
#define LUA_TNIL 0
#define LUA_TBOOLEAN 1
#define LUA_TLIGHTUSERDATA 2
#define LUA_TNUMBER 3
#define LUA_TSTRING 4
#define LUA_TTABLE 5
#define LUA_TFUNCTION 6
#define LUA_TUSERDATA 7
#define LUA_TTHREAD 8
#define LUA_NUMTAGS 9
其中的
LUA_TLIGHTUSERDATA
和LUA_TUSERDATA
一样,对应的都是void*
指针,区别在于,LUA_TLIGHTUSERDATA
的分配释放是由Lua外部的使用者来完成,而LUA_TUSERDATA
则是通过Lua内部来完成的,换言之,前者不需要Lua去关心它的生存期,由使用者自己去关注,后者则反之.
宏定义iscollectable
:类型是否需要进行GC操作
// lobject.h
#define iscollectable(o) (rttype(o) & BIT_ISCOLLECTABLE)
/* raw type tag of a TValue */
// 获取复合类型,见下面
#define rttype(o) ((o)->tt_)
// BIT_ISCOLLECTABLE 复合类型包含标记位:会被GC标记
tt_
:
// lobject.h tt_ 的定义 复合类型
/*
** tags for Tagged Values have the following use of bits:
** bits 0-3: actual tag (a LUA_T* value)
** bits 4-5: variant bits
** bit 6: whether value is collectable
*/
/*
** LUA_TFUNCTION variants:
** 0 - Lua function
** 1 - light C function
** 2 - regular C function (closure)
*/
// 0-3表示大类型(基础类型)
// 4-5表示表示类型的变体,例如:字符串LUA_TSTRING有两种变体(短字符串:LUA_TSHRSTR和长字符串:LUA_TLNGSTR)
// 6表示是否可以垃圾回收
// LUA_TNUMFLT:见下面定义
/* Variant tags for numbers */
#define LUA_TNUMFLT (LUA_TNUMBER | (0 << 4)) /* float numbers 实际定义为double*/
#define LUA_TNUMINT (LUA_TNUMBER | (1 << 4)) /* integer numbers */
// 一个大类和子类:
// 字符串大类:LUA_TNUMBER = 4 = 000010
// 字符串子类:LUA_TNUMINT = 1<<4 = 010000
// 或运算结果为:010010
BIT_ISCOLLECTABLE
:
// lobject.h
/* Bit mark for collectable types */
#define BIT_ISCOLLECTABLE (1 << 6)
/* mark a tag as collectable */
#define ctb(t) ((t) | BIT_ISCOLLECTABLE)
- 标记-清除 GC:
// lstate.h
/*
** Union of all collectable objects (only for conversions)
*/
union GCUnion {
GCObject gc; /* common header */
struct TString ts;
struct Udata u;
union Closure cl;
struct Table h;
struct Proto p;
struct lua_State th; /* thread */
};
- UpVal:不用 标记-清除GC 管理,使用引用计数处理。
宏定义CommonHeader
:要进行 标记-清除 GC操作的数据类型
// lobject.h
/*
** Common Header for all collectable objects (in macro form, to be
** included in other objects)
*/
#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked
/*
** Common type has only the common header
*/
struct GCObject {
CommonHeader;
};
next :指向下一个GC链表的成员。
tt : 表示数据的类型。
marked : GC 相关的标记位。
联合体 Value
:Lua基本数据类型
// lobject.h
/*
** Union of all Lua values
*/
typedef union Value {
GCObject *gc; /* collectable objects */
void *p; /* light userdata */
int b; /* booleans */
lua_CFunction f; /* light C functions */
lua_Integer i; /* integer numbers */
lua_Number n; /* float numbers */
} Value;
#define TValuefields Value value_; int tt_
typedef struct lua_TValue {
TValuefields;
} TValue;
- 设置一个值,例:设置float值
// lobject.h
/* Macros to set values */
#define settt_(o,t) ((o)->tt_=(t))
#define setfltvalue(obj,x) \
{ TValue *io=(obj); val_(io).n=(x); settt_(io, LUA_TNUMFLT); }
// TValue *io=(obj): 创建值指针对象
// val_(io).n=(x): 赋值Value的成员 n 为 x
// settt_(io, LUA_TNUMFLT) : 设置类型为float类型