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_NUMBER  double // 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 userdatalight userdata表示仅仅在lua中保存了userdata的指针,占用的内存不归lua管。Value代表变量的具体值,b表示整形,n表示浮点型;gc表示可以用于垃圾回收的对象的指针;当gcgch值时,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表示userdatacl表示闭合函数;h表示表;p表示函数;uv表示upvalueth表示线程,每一个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[1];

} CClosure;

 

 

typedef struct LClosure {

  ClosureHeader;

  struct Proto *p;

  UpVal *upvals[1];

} 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;

后续会不断补充,分析数据类型每个的确切用途。

 

 

参考资料

1.         Lua源码分析(2) -- 对象表示

http://blog.csdn.net/INmouse/archive/2007/03/25/1540424.aspx

2.         Lua源代码阅读之一

http://blog.sina.com.cn/s/blog_48cbc19a010003x4.html

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值