首页 > 代码库 > 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):通用变量
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。