首页 > 代码库 > lua.5.2.3源码阅读(03):通用变量

lua.5.2.3源码阅读(03):通用变量

lua的堆栈中存放的是通用变量,通用变量实际上就是一个union内存块,根据不同的类型,采用不同的组织方式,

看一下通用类型的相关定义,截取了lobject.h相关代码,从代码上看,不太清楚numfield为什么会有两个相关定义。

堆栈中可以根据情况分为一下几种类型:

1、双精度浮点数:double d__;

2、复合类型,通过tt__来表示类型;

3、复合类型中分为两种:可回收类型和不可回收类型;

4、可回收类型可以是:TString、Udata、Closure、Table、Proto、UpVal、lua_State

5、不可回收类型可以是:light userdata、booleans、light C functions

 1 typedef TValue *StkId;  /* 堆栈中的元素 */ 2 typedef struct lua_TValue TValue; 3  4 struct lua_TValue { 5   TValuefields;  /* 堆栈中的元素 */ 6 }; 7  8 // 定义了双精度浮点或者通用类型定义 9 #define TValuefields  10     union { struct { Value v__; int tt__; } i; double d__; } u11 12 #define LUA_NUMBER    double13 typedef LUA_NUMBER    lua_Number;14 #define numfield    lua_Number n;    /* 双精度浮点数 */15 #define numfield    /* no such field; numbers are the entire struct(另外一种定义) */16 17 // Value包括可回收对象和不可回收对象两种类型18 // 不可回收对象包括:bool、19 union Value {20   GCObject *gc;    /* collectable objects */21   void *p;         /* light userdata */22   int b;           /* booleans */23   lua_CFunction f; /* light C functions */24   numfield         /* 双精度浮点数,实际上可能为空 */25 };26 27 /*28 ** Union of all collectable objects29 */30 union GCObject {31   GCheader gch;  /* common header */32   union TString ts; /* 字符串 */33   union Udata u; /* 用户自定义数据 */34   union Closure cl; /* 函数闭包,其实似乎Proto的一个实例 */35   struct Table h; /* 表结构 */36   struct Proto p; /* 函数原型,被闭包共享同一个定义 */37   struct UpVal uv; /* 闭包所引用的变量 */38   struct lua_State th;  /* thread */39 };

 

为了方便复合结构的类型判断增加了一些宏的定义,复合结构中的t__类型定义:

1、0~3未表示类型;

2、4~5用来 表示类型的变体,例如:字符串LUA_TSTRING有两种变体(短字符串:LUA_TSHRSTR和长字符串:LUA_TLNGSTR)

3、6未用来表示是否是垃圾回收类型,其中短字符串不是可回收(#define LUA_TSHRSTR (LUA_TSTRING | (0 << 4)) ),

而长字符串为可回收类型(#define LUA_TLNGSTR (LUA_TSTRING | (1 << 4)) )。

类型判断相关的宏如下:

 1 /* raw type tag of a TValue */ 2 #define rttype(o)    ((o)->tt_) 3  4 /* tag with no variants (bits 0-3) */ 5 #define novariant(x)    ((x) & 0x0F) 6  7 /* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */ 8 #define ttype(o)    (rttype(o) & 0x3F) 9 10 /* type tag of a TValue with no variants (bits 0-3) */11 #define ttypenv(o)    (novariant(rttype(o)))12 13 /* mark a tag as collectable */14 #define ctb(t)            ((t) | BIT_ISCOLLECTABLE)15 16 /* Macros to test type */17 #define checktag(o,t)        (rttype(o) == (t))18 #define checktype(o,t)        (ttypenv(o) == (t))19 #define ttisnumber(o)        checktag((o), LUA_TNUMBER)20 #define ttisnil(o)        checktag((o), LUA_TNIL)21 #define ttisboolean(o)        checktag((o), LUA_TBOOLEAN)22 #define ttislightuserdata(o)    checktag((o), LUA_TLIGHTUSERDATA)23 #define ttisstring(o)        checktype((o), LUA_TSTRING)24 #define ttisshrstring(o)    checktag((o), ctb(LUA_TSHRSTR))25 #define ttislngstring(o)    checktag((o), ctb(LUA_TLNGSTR))26 #define ttistable(o)        checktag((o), ctb(LUA_TTABLE))27 #define ttisfunction(o)        checktype(o, LUA_TFUNCTION)28 #define ttisclosure(o)        ((rttype(o) & 0x1F) == LUA_TFUNCTION)29 #define ttisCclosure(o)        checktag((o), ctb(LUA_TCCL))30 #define ttisLclosure(o)        checktag((o), ctb(LUA_TLCL))31 #define ttislcf(o)        checktag((o), LUA_TLCF)32 #define ttisuserdata(o)        checktag((o), ctb(LUA_TUSERDATA))33 #define ttisthread(o)        checktag((o), ctb(LUA_TTHREAD))34 #define ttisdeadkey(o)        checktag((o), LUA_TDEADKEY)35 36 #define ttisequal(o1,o2)    (rttype(o1) == rttype(o2))

 

复合类型的值获取相关宏定义:

 1 /* Macros to access values */ 2 #define val_(o)        ((o)->value_) 3 #define num_(o)        (val_(o).n) 4  5 /* internal assertions for in-house debugging */ 6 #if defined(lua_assert) 7 #define check_exp(c,e)        (lua_assert(c), (e)) 8 /* to avoid problems with conditions too long */ 9 #define lua_longassert(c)    { if (!(c)) lua_assert(0); }10 #else11 #define lua_assert(c)        ((void)0)12 #define check_exp(c,e)        (e)13 #define lua_longassert(c)    ((void)0)14 #endif15 16 #define nvalue(o)    check_exp(ttisnumber(o), num_(o))17 #define gcvalue(o)    check_exp(iscollectable(o), val_(o).gc)18 #define pvalue(o)    check_exp(ttislightuserdata(o), val_(o).p)19 #define rawtsvalue(o)    check_exp(ttisstring(o), &val_(o).gc->ts)20 #define tsvalue(o)    (&rawtsvalue(o)->tsv)21 #define rawuvalue(o)    check_exp(ttisuserdata(o), &val_(o).gc->u)22 #define uvalue(o)    (&rawuvalue(o)->uv)23 #define clvalue(o)    check_exp(ttisclosure(o), &val_(o).gc->cl)24 #define clLvalue(o)    check_exp(ttisLclosure(o), &val_(o).gc->cl.l)25 #define clCvalue(o)    check_exp(ttisCclosure(o), &val_(o).gc->cl.c)26 #define fvalue(o)    check_exp(ttislcf(o), val_(o).f)27 #define hvalue(o)    check_exp(ttistable(o), &val_(o).gc->h)28 #define bvalue(o)    check_exp(ttisboolean(o), val_(o).b)29 #define thvalue(o)    check_exp(ttisthread(o), &val_(o).gc->th)

 

复合类型值设置相关宏定义:

 1 /* Macros to set values */ 2 #define settt_(o,t)    ((o)->tt_=(t)) 3 #define val_(o)        ((o)->value_) 4 #define num_(o)        (val_(o).n) 5  6 #define setnvalue(obj,x)  7   { TValue *io=(obj); num_(io)=(x); settt_(io, LUA_TNUMBER); } 8  9 #define setnilvalue(obj) settt_(obj, LUA_TNIL)10 11 #define setfvalue(obj,x) 12   { TValue *io=(obj); val_(io).f=(x); settt_(io, LUA_TLCF); }13 14 #define setpvalue(obj,x) 15   { TValue *io=(obj); val_(io).p=(x); settt_(io, LUA_TLIGHTUSERDATA); }16 17 #define setbvalue(obj,x) 18   { TValue *io=(obj); val_(io).b=(x); settt_(io, LUA_TBOOLEAN); }19 20 #define setgcovalue(L,obj,x) 21   { TValue *io=(obj); GCObject *i_g=(x); 22     val_(io).gc=i_g; settt_(io, ctb(gch(i_g)->tt)); }23 24 #define setsvalue(L,obj,x) 25   { TValue *io=(obj); 26     TString *x_ = (x); 27     val_(io).gc=cast(GCObject *, x_); settt_(io, ctb(x_->tsv.tt)); 28     checkliveness(G(L),io); }29 30 #define setuvalue(L,obj,x) 31   { TValue *io=(obj); 32     val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TUSERDATA)); 33     checkliveness(G(L),io); }34 35 #define setthvalue(L,obj,x) 36   { TValue *io=(obj); 37     val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTHREAD)); 38     checkliveness(G(L),io); }39 40 #define setclLvalue(L,obj,x) 41   { TValue *io=(obj); 42     val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TLCL)); 43     checkliveness(G(L),io); }44 45 #define setclCvalue(L,obj,x) 46   { TValue *io=(obj); 47     val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TCCL)); 48     checkliveness(G(L),io); }49 50 #define sethvalue(L,obj,x) 51   { TValue *io=(obj); 52     val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTABLE)); 53     checkliveness(G(L),io); }

 

lua.5.2.3源码阅读(03):通用变量