李程站 发表于 2013-2-4 02:17:44

关于Lua数据类型源代码分析

关于Lua数据类型源代码分析是本文要介绍的内容,主要是来了解lua源代码的分析理解,具体内容的实现来看本文详解。
Lua语言是不用声明变量的类型的,而且是类型可变的,如下面的语句:

[*]local a = 1;
[*]a = “hello”;
开始是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_NUMBERdouble // luaconf.h, line 505
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
上面的定义中,除了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
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;
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;
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;
[*]} CClosure;
[*]
[*]typedef struct LClosure {
[*]ClosureHeader;
[*]struct Proto *p;
[*]UpVal *upvals;
[*]} LClosure;
[*]
[*]typedef union Closure {
[*]CClosure c;
[*]LClosure l;
[*]} Closure;
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;
后续会不断补充,分析数据类型每个的确切用途。
小结:关于Lua数据类型源代码分析的内容介绍完了,希望通过本文的学习能对你有所帮助!
【编辑推荐】

[*]Lua在游戏开发中应用教程
[*]关于LUA环境配置学习教程
[*]了解可视化LUA脚本编辑器
[*]Lua游戏脚本开发之初始化Lua
[*]关于LUA开发环境Decoda详解
[*]LUA中关于文本编辑器SciTE配置方法
页: [1]
查看完整版本: 关于Lua数据类型源代码分析