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

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__; } u
11 
12 #define LUA_NUMBER    double
13 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 objects
29 */
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 #else
11 #define lua_assert(c)        ((void)0)
12 #define check_exp(c,e)        (e)
13 #define lua_longassert(c)    ((void)0)
14 #endif
15 
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); }

 

posted @ 2015-01-06 23:36  #shany  阅读(1676)  评论(0编辑  收藏  举报