Lua设计与实现(二) -- Lua中的数据类型

Lua设计与实现

QQ : 1841545843
邮箱 : jiaxx903@163.com

  1. Lua中我们使用一个通用的数据结构lua_TValue 来统一表示所有在Lua虚拟机中需要保存的数据类型。

  2. 首先在C语言中实现通用数据结构的一般做法

    首先两点:

    • 需要一个字段来存储数据的类型
    • 需要存储不同的类型的数据

    有两种方法来表示:

    • 定义一个公共的数据结构作为基础类型,其他基本类型是从这个具体的类型中派生出来的

      struct base{
          int type;       // 定义基础的数据类型
          
      };
      
      struct string {
          struct base info;
          int len;
          cahr* data[0];
          
      };
      
      struct number {
          struct base info;
          double num;
          
      };
      
    • 使用联合将所有的数据包起来

      struct string{
       int len;
       char * data[0];
          
      };
      
      struct number {
          double num;
          
      };
      
      struct value {
          int type;
          union{
              string str;
              number num;
              
          } value;
          
      };
      
  3. Lua通用数据结构的实现

    主要有:数字,字符串,关联表,nil, userdata, Lua函数, C函数

    /*
    ** basic types                     //  类型          对应的数据结构
    */
    #define LUA_TNONE		(-1)       //  无类型        无
                                  
    #define LUA_TNIL		0          //  空类型        无
    #define LUA_TBOOLEAN		1      //  布尔类型      无
    #define LUA_TLIGHTUSERDATA	2      //  指针          void*
    #define LUA_TNUMBER		3          //  数据         lua_Number 
    #define LUA_TSTRING		4          //  字符串       TString
    #define LUA_TTABLE		5          //  表           Table
    #define LUA_TFUNCTION		6      //  函数         CClosure\ LClosure
    #define LUA_TUSERDATA		7      //  指针         void*
    #define LUA_TTHREAD		8          //  Lua虚拟机,协程  lua_State
    

    Lua内部用一个宏表示那些数据类型需要GC

    // LUS_TSTRING 之后的数据类型都需要GC操作
    #define iscollectable(o)	(ttype(o) >= LUA_TSTRING)
    

    这些需要进行GC操作的数据类型都会有一个CommonHeader宏定义的成员,并且这个成员在结构体定义的最开始部分

    typedef struct Table {
      CommonHeader;                 // 作为需要GC回收的标志
      lu_byte flags;                /* 1<<p means tagmethod(p) is not present */ 
      lu_byte lsizenode;  /* log2 of size of `node' array */
      struct Table *metatable;
      TValue *array;  /* array part */
      Node *node;
      Node *lastfree;  /* any free position is before this position */
      GCObject *gclist;
      int sizearray;  /* size of `array' array */
    } Table;
    

    CommonHeader的定义:

    /*
    ** Common Header for all collectable objects (in macro(巨大的) form, to be
    ** included in other objects)
    ** 
    ** next 指向下一个GC链表的成员
    ** tt   表示数据类型,即前面表示那些数据类型的宏
    ** marked  GC相关的标志位
    */
    
    #define CommonHeader	GCObject *next; lu_byte tt; lu_byte marked
    

    还有一个GCheader结构体,其中成员只有CommonHeader

    /*
    ** Common header in struct form
    */
    typedef struct GCheader {
      CommonHeader;
    } GCheader;
    

    在Lua中就使用GCObject;联合体将所有需要进行垃圾回收的数据类型囊括起来

    /*
    ** Union of all collectable objects
    */
    union GCObject {
      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 */
    };
    

    结论:

    • 任何需要进行垃圾回收的Lua数据类型,必然是以CommonHeader作为该结构体定义的最开始部分。
    • GCobject这个联合体将所有需要垃圾回收的数据类型全部囊括其中,这样定位和查找不同类型的数据就比较方便。
    /*
    ** Union of all Lua values 
    ** 这几种类型不需要进行垃圾回收
    */
    typedef union {
      GCObject *gc;
      void *p;
      lua_Number n;
      int b;
    } Value;
    
    
    
    
    
    /*
    ** Tagged Values
    */
    
    #define TValuefields	Value value; int tt
    
    typedef struct lua_TValue {
      TValuefields;
    } TValue;
    
    

    Lua通用数据结构组织

    • 具体类型中有CommonHeader,用来存放所有数据类型都通用的字段
    • TValue作为统一表示所有数据的数据结构,内部使用了联合体Value将所有数据都包含起来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值