TValue结构

TValue这个结构体是Lua的通用结构体,,Lua中的所有的数据都可以使用这个结构体来表示.很容易想到,在面向对象中,这个结构体是一个基类,派生出来的都是其他的子类.

TValue结构体内部有几个宏, 展开之后就是这样的:

typedef struct lua_TValue {
union {
union GCObject {
struct GCheader {
GCObject *next; lu_byte tt; lu_byte marked;
} gch; union TString ts;
union Udata u;
union Closure cl;
struct Table h;
struct Proto p;
struct UpVal uv;
struct lua_State th; /* thread */
} gc; void *p;
lua_Number n;
int b;
} value;
int tt;
} TValue;

这个结构体定义,总体来说分为两个部分:tt存放的数据类型,而value域存放的是各种数据.而在其中,又划分为两个部分,可gc的数据类型使用union放在一起,剩下的就是不可gc的数据类型了:void*,lua_Number,int.

gc union

gc union的定义,可以看到各种可gc的类型(Tstring,Udata..etc)和一个GCHeader放在 一起,也就是说,当这部分还是数据的时候,数据部分启用,否则就是gc部分了.这里的GCHeader包括了三个部分:next指针将可gc的数据串联成链表,tt表示数据类型,marked存放的gc处理时的颜色值.

这是另一种方式的使用C语言实现的面向对象,对外部而言,TValue结构体可以看作是”基类”,真正进行处理时,再根据数据类型决定到底使用value union中的哪个数据部分.可以看到lua源代码中定义了很多宏就是这样操作Tvalue数据指针的,比如:

#define hvalue(o)	check_exp(ttistable(o), &(o)->value.gc->h)

这个宏定义了如何从TValue指针得到Table结构体:首先判断数据类型是Table,然后将value的gc union中Table *h取出.

反之,要从一个具体的类型转换再赋值为相应的TValue,Lua源代码中也提供了相应的宏.因为TValue结构体的中的value域是一个union,所以其实随便强制转换为其中的哪一种类型都可以,不过看上去最舒服的写法还是直接转换为公共类型GCObject了,比如:

#define setsvalue(L,obj,x) \
{ TValue *i_o=(obj); \
i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \
checkliveness(G(L),i_o); }

GCObject

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

其中的GCheader展开是这样的:

typedef struct GCheader {
CommonHeader;
} GCheader;

而随便抽在GCObject结构体中的数据类型结构体定义,都发现也包含了一个CommonHeader结构体,比如:

typedef struct Table {
CommonHeader;
lu_byte flags;
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;

换言之,在GCObject中,无论是哪个数据结构体,都自己有一份CommonHeader.仔细观察,其实GCObject这个union的内存分布,最开始部分无论如何都是留给CommonHeader的.这样做,就保证了一个存放在TValue结构体中的数据,既可以使用CommonHeader关于GC的部分,也可以使用到自己本身的数据部分了.

lua通用数据类型的更多相关文章

  1. SQL 通用数据类型

    SQL 通用数据类型 数据类型定义列中存放的值的种类. SQL 通用数据类型 数据库表中的每个列都要求有名称和数据类型.Each column in a database table is requi ...

  2. Lua学习----Lua基础数据类型

    前言 Lua有6中数据类型,分别是nil(空).boolean(布尔).number(数字).string(字符).table(表).function(函数) 在Lua中可以使用type函数来返回一个 ...

  3. 02.Lua的数据类型

    简单认识Lua 百度了一下(偷哈懒就不自己写了) Lua 是一个小巧的脚本语言.是巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janei ...

  4. lua的数据类型

    Lua 是动态(弱)类型的语言,它有一下几种数据结构: nil(空) nil 类型表示一种没有任何有效值,它只有一个值 -- nil,例如打印一个没有赋值的变量,便会输出一个 nil 值: print ...

  5. [Unity插件]Lua行为树(十):通用行为和通用条件节点

    在行为树中,需要扩展的主要是行为节点和条件节点.一般来说,每当要创建一个节点时,就要新建一个节点文件.而对于一些简单的行为节点和条件节点,为了去掉新建文件的过程,可以写一个通用版本的行为节点和条件节点 ...

  6. Lua学习笔记(1): HelloWorld和数据类型

    Lua是一个轻量级的脚本语言,由c语言编写,容易嵌入到应用中,深受游戏开发者的青睐 环境安装 选用SciTE作为lua的IDE 可以在github找到这个开源的软件 SciTE下载链接 安装好之后打开 ...

  7. lua数据类型的的操作(三)

    上一章我们学习了lua的数据类型,以及语法的定义,今天我们学习lua的数据类型操作,其实就是lua库一些api的操作,遇到对数据类型处理时,可以根据lua库提供的操作来实现. 一.字符串操作 1.字符 ...

  8. Lua 与 Redis

    Lua 与 Redis 标签: Java与NoSQL 从 2.6版本 起, Redis 开始支持 Lua 脚本 让开发者自己扩展 Redis - 案例-实现访问频率限制: 实现访问者 $ip 在一定的 ...

  9. Lua语言模型 与 Redis应用

    Lua语言模型 与 Redis应用 标签: Java与NoSQL 从 2.6版本 起, Redis 开始支持 Lua 脚本 让开发者自己扩展 Redis. 本篇博客主要介绍了 Lua 语言不一样的设计 ...

随机推荐

  1. python匿名函数 高阶函数 内置函数 文件操作

    1.匿名函数 匿名就是没有名字 def func(x,y,z=1): return x+y+z 匿名 lambda x,y,z=1:x+y+z #与函数有相同的作用域,但是匿名意味着引用计数为0,使用 ...

  2. Java设计模式----观察者模式详解

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3 ...

  3. Eigen学习

    Eigen 是一个基于C++的线性代数库,其中实现大量常用的线性代数算法,包括常规矩阵计算,矩阵变换,矩阵分解,矩阵块操作.Eigen 广泛地应用在开源项目中,例如OpenCV,PCL(Point C ...

  4. 最常见到的runtime exception 异常

    ArithmeticException, 算术异常ArrayStoreException, 将数组类型不兼容的值赋值给数组元素时抛出的异常BufferOverflowException, 缓冲区溢出异 ...

  5. 在Windows2003下如何查看IIS站点中对应的PID值

    分享:查看IIS站点中对应的PID值 在Win2003下,提供了一个命令,可以方便的查看.cmd -> iisapp -a 显示W3WP.exe PID: 1264 AppPoolID: hxW ...

  6. Oracle EBS PO退货失败

    无法读取例程 &ROUTINE 中配置文件选项 INV_DEBUG_TRACE 的值. 系统-配置文件-地点层 INC%调试%踪 是 select *  from po_interface_e ...

  7. MySQL字符存储:charset-unicode-sets

    https://dev.mysql.com/doc/refman/8.0/en/charset-unicode-sets.html 10.10.1 Unicode Character Sets MyS ...

  8. (z转)基于CPU的Bank BRDF经验模型,实现各向异性光照效果!

    摘抄“GPU Programming And Cg Language Primer 1rd Edition” 中文 名“GPU编程与CG语言之阳春白雪下里巴人” BRDF 光照模型 10.2.1 什么 ...

  9. 项目属性的target platform和target platform version到底是什么(vs2015开发windows驱动小记)

    根据官方对属性页的介绍(General Property Page (Project))可了解: target platform是build后的结果会跑在哪个平台,例如windows,android, ...

  10. Hadoop HA on Yarn——集群配置

    集群搭建 因为服务器数量有限,这里服务器开启的进程有点多: 机器名 安装软件 运行进程 hadoop001 Hadoop,Zookeeper NameNode, DFSZKFailoverContro ...