LUA的基础数据类型是TValue, 源码如下:
#define TValuefields Value value_; int tt_ typedef struct lua_TValue { TValuefields; } TValue;
TValue包含两个成员变量value_和tt_, value_是变量值,tt_是变量类型。
先看value_, 源码如下:
/* ** 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;
Value是LUA所有类型值的集合。gc是可回收的对象;p是轻量级的userdata区别于full userdata,是指向c对象的指针;b是bool型值;f是函数指针(typedef int (*lua_CFunction)(lua_State *L));i是long long整型值;n是double类型的值。
tt_的不同bit表示不同的含义:
/* ** 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 */
从注释看0-3 bit 表示真实的类型, 4-5 bits表示真实类型的多样性,例如TString还区分LUA_TSHRSTR(short string)和LUA_TLNGSTR(long string), 6 bit表示value是否是可gc的数据.
下面ttisnumber宏, 用宏novariant取tt_最后四位与上0x0F和LUA_TNUMBER比较. 可以再自行去查看宏ttisstring和宏ttisshrstring与ttisnumber的区别.
/* raw type tag of a TValue */ #define rttype(o) ((o)->tt_) /* tag with no variants (bits 0-3) */ #define novariant(x) ((x) & 0x0F) /* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */ #define ttype(o) (rttype(o) & 0x3F) /* type tag of a TValue with no variants (bits 0-3) */ #define ttnov(o) (novariant(rttype(o))) #define checktype(o,t) (ttnov(o) == (t)) #define ttisnumber(o) checktype((o), LUA_TNUMBER)
最后看下GCObject,源码如下:
/* ** Common type for all collectable objects */ typedef struct GCObject GCObject; /* ** 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处理时存放的颜色值(和GC标记流程相关,后面再详细介绍)
扫描二维码关注公众号,回复:
941378 查看本文章