经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Lua » 查看文章
lua通用数据类型
来源:cnblogs  作者:bytemode  时间:2018/12/17 9:42:55  对本文有异议

TValue结构

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

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

  1. typedef struct lua_TValue {
  2. union {
  3. union GCObject {
  4. struct GCheader {
  5. GCObject *next; lu_byte tt; lu_byte marked;
  6. } gch;
  7. union TString ts;
  8. union Udata u;
  9. union Closure cl;
  10. struct Table h;
  11. struct Proto p;
  12. struct UpVal uv;
  13. struct lua_State th; /* thread */
  14. } gc;
  15. void *p;
  16. lua_Number n;
  17. int b;
  18. } value;
  19. int tt;
  20. } 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数据指针的,比如:

  1. #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了,比如:

  1. #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

  1. union GCObject {
  2. GCheader gch;
  3. union TString ts;
  4. union Udata u;
  5. union Closure cl;
  6. struct Table h;
  7. struct Proto p;
  8. struct UpVal uv;
  9. struct lua_State th; /* thread */
  10. };

其中的GCheader展开是这样的:

  1. typedef struct GCheader {
  2. CommonHeader;
  3. } GCheader;

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

  1. typedef struct Table {
  2. CommonHeader;
  3. lu_byte flags;
  4. lu_byte lsizenode; /* log2 of size of `node' array */
  5. struct Table *metatable;
  6. TValue *array; /* array part */
  7. Node *node;
  8. Node *lastfree; /* any free position is before this position */
  9. GCObject *gclist;
  10. int sizearray; /* size of `array' array */
  11. } Table;

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

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号