Lua的数据对象表示
发表于2018-08-27
Lua并非严格意义上的面向对象语言,在语言层面上并没有直接提供诸如class这样的关键字,也没有显式的继承语法和virtual函数,但Lua提供了一种创建这些面向对象要素的能力。
Lua中的table就是一种对象。
#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked struct GCObject { CommonHeader; }; 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; #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 数据对象由lua_TValue表示,分为两部分。 int tt_表示对象的类型;Value value_为具体值。 tt_的最后4bit表示对象的主类型,倒数5、6位表示子类型,7位表示是否可回收,其它位表示对象的tag 获取对象的值的过程:根据类型tt_从联合体value_中取出相应的值。 例:tt_为LUA_TNUMBER时,获取值分两种情况 当tt_等于LUA_TNUMINT取value_的i(整型) 当tt_等于LUA_TNUMFLT取value的n(浮点型)的值。 以下分九种类型分别描述lua的对象 0、nil obj = {value_ = {NULL},tt_ = LUA_TNIL} 1、boolean true = {value_ = {b=1},tt_ = LUA_TBOOLEAN} false= {value_ = {b=0},tt_ = LUA_TBOOLEAN} 2、light userdata pc表示C语言的指针 obj = {value_ = {p=pc},tt_ = LUA_TLIGHTUSERDATA} 3、整数和浮点数 #define LUA_TNUMFLT (LUA_TNUMBER | (0 << 4)) /* float numbers */ #define LUA_TNUMINT (LUA_TNUMBER | (1 << 4)) /* integer numbers */ int_value为整数的值 float_value为浮点数的值 int_obj = {value_ = {i=int_value},tt_=LUA_TNUMINT} float_obj = {value_ = {n=float_value},tt_=LUA_TNUMFLT} 4、string lua_TValue对象并不直接存放string的字符串,gc指向TString ts str = {value_ = {gc=ts},tt_ = LUA_TSTRING} string对象的真实结构 // Header for string value; string bytes follow the end of this structure typedef struct TString { CommonHeader; lu_byte extra; /* reserved words for short strings; "has hash" for longs */ lu_byte shrlen; /* length for short strings */ unsigned int hash; union { size_t lnglen; /* length for long strings */ struct TString *hnext; /* linked list for hash table */ } u; } TString; 5、table typedef union TKey { struct { TValuefields; int next; /* for chaining (offset for next node) */ } nk; TValue tvk; } TKey; /* copy a value into a key without messing up field 'next' */ #define setnodekey(L,key,obj) \ { TKey *k_=(key); const TValue *io_=(obj); \ k_->nk.value_ = io_->value_; k_->nk.tt_ = io_->tt_; \ (void)L; checkliveness(L,io_); } typedef struct Node { TValue i_val; TKey i_key; } Node; typedef struct Table { CommonHeader; lu_byte flags; /* 1<<p means tagmethod(p) is not present */ lu_byte lsizenode; /* log2 of size of 'node' array */ unsigned int sizearray; /* size of 'array' array */ TValue *array; /* array part */ Node *node; Node *lastfree; /* any free position is before this position */ struct Table *metatable; GCObject *gclist; } Table; t指向Table的指针 lua_TValue obj = {value_ = {gc=t},tt_ = LUA_TTABLE} 6、function #define LUA_TLCL (LUA_TFUNCTION | (0 << 4)) /* Lua closure */ #define LUA_TLCF (LUA_TFUNCTION | (1 << 4)) /* light C function */ #define LUA_TCCL (LUA_TFUNCTION | (2 << 4)) /* C closure */ #define ClosureHeader \ CommonHeader; lu_byte nupvalues; GCObject *gclist typedef struct CClosure { ClosureHeader; lua_CFunction f; TValue upvalue[1]; /* list of upvalues */ } CClosure; typedef struct LClosure { ClosureHeader; struct Proto *p; UpVal *upvals[1]; /* list of upvalues */ } LClosure; typedef union Closure { CClosure c; LClosure l; } Closure; lua closure obj = {value_ = {gc=x},tt_ = LUA_TLCL} light C function typedef int (*lua_CFunction) (lua_State *L); obj = {value_ = {f=x},tt_ = LUA_TLCF} C closure obj = {value_ = {gc=x},tt_ = LUA_TCCL} 7、user data typedef struct Udata { CommonHeader; lu_byte ttuv_; /* user value's tag */ struct Table *metatable; size_t len; /* number of bytes */ union Value user_; /* user value */ } Udata; obj = {value_ = {gc=x},tt_ = LUA_TUSERDATA} 8、thread x表示lua_State指针 obj = {value_ = {gc=x},tt_ = LUA_TTHREAD}