关于Lua数据类型源代码分析是本文要介绍的内容,主要是来了解lua源代码的分析理解,具体内容的实现来看本文详解。
Lua语言是不用声明变量的类型的,而且是类型可变的,如下面的语句:
local a = 1;
a = “hello”;
- 1.
- 2.
开始是a的类型是number,当复制为字符串时,类型改为string,可以通过type(a)查看。那么它是怎么做到的呢?参见如下的TValue定义:
typedef struct lua_TValue { // lobject.h, line 73
TValuefields;
} TValue;
#define TValuefields Value value; int tt // lobject.h, line 71
typedef union { // lobject.h, line 59
GCObject *gc;
void *p;
lua_Number n;
int b;
} Value;
typedef LUA_NUMBER lua_Number; // lua.h, line 100
#define LUA_NUMBER double // luaconf.h, line 505
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
Lua中所有的类型都定义为TValue类型。tt表示类型,定义参见:
#define LUA_TNONE (-1) // lua.h, line 73
#define LUA_TNIL 0
#define LUA_TBOOLEAN 1
#define LUA_TLIGHTUSERDATA 2 // light userdata
#define LUA_TNUMBER 3
#define LUA_TSTRING 4
#define LUA_TTABLE 5
#define LUA_TFUNCTION 6
#define LUA_TUSERDATA 7
#define LUA_TTHREAD 8
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
上面的定义中,除了8种基本的数据类型之外,还包括未知类型和light userdata,light userdata表示仅仅在lua中保存了userdata的指针,占用的内存不归lua管。Value代表变量的具体值,b表示整形,n表示浮点型;gc表示可以用于垃圾回收的对象的指针;当gc取gch值时,p应该是lua对象的指针,否则有可能只想TValue本身。其中相关的定义如下:
union GCObject { // lstate.h, line 136
GCheader gch;
union TString ts;
union Udata u;
union Closure cl;
struct Table h;
struct Proto p;
struct UpVal uv;
struct lua_State th; /* thread */
};
typedef struct GCheader { // lobject.h, line 49
CommonHeader;
} GCheader;
#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked // lobject.h, line 43
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
GCObject定义中,gch用于垃圾回收;ts表示用于字符串表的类型;u表示userdata;cl表示闭合函数;h表示表;p表示函数;uv表示upvalue;th表示线程,每一个lua_State相当于一个线程;具体的定义及注释如下:
TString
typedef union TString { // lobject.h, line 200
L_Umaxalign dummy; /* ensures maximum alignment for strings */// 对齐用
struct {
CommonHeader;
lu_byte reserved;
unsigned int hash;
size_t len;
} tsv;
} TString;
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
Udata表示userdata
typedef union Udata { // lobject.h, line 216
L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
struct {
CommonHeader;
struct Table *metatable;
struct Table *env;
size_t len;
} uv;
} Udata;
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
Closure又分为两种,一种用于lua中,另一种用于C代码中。
#define ClosureHeader / // lobject.h, line 292
CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; /
struct Table *env
typedef struct CClosure {
ClosureHeader;
lua_CFunction f;
TValue upvalue[1];
} CClosure;
typedef struct LClosure {
ClosureHeader;
struct Proto *p;
UpVal *upvals[1];
} LClosure;
typedef union Closure {
CClosure c;
LClosure l;
} Closure;
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
C代码中使用的函数类型是lua_CFunction,而lua中使用的函数是Proto;
table
typedef struct Table {
CommonHeader; // for GC
lu_byte flags; /* 1<<p means tagmethod(p) is not present */
lu_byte lsizenode; /* log2 of size of `node' array */ // size of node array
struct Table *metatable; // 元表
TValue *array; /* array part */// 数组,没有索引值时使用
Node *node; // node array
Node *lastfree; /* any free position is before this position */
GCObject *gclist;
int sizearray; /* size of `array' array */// 数组的大小
} Table;
Proto
typedef struct Proto {
CommonHeader; // for GC
TValue *k; /* constants used by the function */ // 常量
Instruction *code; // function code is here, code array?
struct Proto **p; /* functions defined inside the function */
int *lineinfo; /* map from opcodes to source lines */
struct LocVar *locvars; /* information about local variables */
TString **upvalues; /* upvalue names */
TString *source; // 源代码?
int sizeupvalues; // size of upvalue names
int sizek; /* size of `k' */
int sizecode; // size of code
int sizelineinfo; // size of line
int sizep; /* size of `p' */ // size of Protos
int sizelocvars; // size of local values
int linedefined;
int lastlinedefined;
GCObject *gclist;
lu_byte nups; /* number of upvalues */
lu_byte numparams; // 参数个数
lu_byte is_vararg; // 是否是变参
lu_byte maxstacksize; // 函数用到的栈?
} Proto;
UpVal
typedef struct UpVal {
CommonHeader;
TValue *v; /* points to stack or to its own value */
union {
TValue value; /* the value (when closed) */
struct { /* double linked list (when open) */
struct UpVal *prev;
struct UpVal *next;
} l;
} u;
} UpVal;
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
后续会不断补充,分析数据类型每个的确切用途。
小结:关于Lua数据类型源代码分析的内容介绍完了,希望通过本文的学习能对你有所帮助!