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. Eigen学习

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

  2. MVC $.Ajax()+Json实现数据库访问并显示数据

    我们在使用搜索引擎时经常会看到这样一个效果 在输出输入相关文字时会有与之对应的相关提醒,作为一个MVC初学者我也做了一个简单版的“搜索工具”,分享给初学mvc和ajax的童鞋(各位大神勿喷),也加深我 ...

  3. swift版的StringAttribute

    swift版的StringAttribute 效果 源码 https://github.com/YouXianMing/Swift-StringAttribute // // StringAttrib ...

  4. svn回退到具体的版本

    svn回退到具体的版本 找到项目的版本号 命令行中输入相关命令  到指定地点找到项目即可

  5. Python常见报错问题(不定时更新)

    1.TabError: inconsistent use of tabs and spaces in indentation 在缩进中不一致地使用tab键和空格键. 报错原因:混用了tab和space ...

  6. 铁乐学python_day01-和python有关的唠嗑

    铁乐学python_day01-和python有关的唠嗑 文:铁乐与猫 2018-03-16 01_python的历史 python的创始人为荷兰人吉多·范罗苏姆(Guido van Rossum). ...

  7. http协议的状态码——400,401,403,404,500,502,503,301,302等常见网页错误代码

    http协议的状态码 1xx(临时响应) 表示临时响应并需要请求者继续执行操作的状态码. 100(继续) 请求者应当继续提出请求.服务器返回此代码表示已收到请求的第一部分,正在等待其余部分. 101( ...

  8. C++中重载决议与可访问性检查的顺序

    http://blog.csdn.net/starlee/article/details/1406781 对于如下的类: class ClxECS{public:    double Test(dou ...

  9. pthread线程内存布局

    http://www.cnblogs.com/snake-hand/p/3148191.html 我们从图上可以看出,两个线程之间的栈是独立的,其他是共享的,所以,在操作共享区域的时候才有可能出现同步 ...

  10. 【转】Python数据处理(四舍五入、除法部分)

    转自:https://www.cnblogs.com/junyiningyuan/p/5338378.html 关于除法 传统除法 对两个整数进行除的运算,同时结果会舍去小数部分,返回一个整数.但如果 ...