lua源码笔记-基本数据结构
最近读了《lua设计与实现》,配合着看了lua的源代码,把学习的心得做一个笔记记录下来。看的源代码版本是最新的v5.4-beta。
value
每一门动态语言中都会用一个通用的结构来存储数据,这样才能实现给一个变量赋不同类型的值,lua中这个数据结构是 TValue
。
(lobject.h)
/*
** Union of all Lua values
*/
typedef union Value {
struct GCObject *gc; /* collectable objects */
void *p; /* light userdata */
int b; /* booleans */
lua_CFunction f; /* light C functions */
lua_Integer i; /* integer numbers */
lua_Number n; /* float numbers */
} Value;
/*
** Tagged Values. This is the basic representation of values in Lua:
** an actual value plus a tag with its type.
*/
typedef struct TValue {
TValuefields;
} TValue;
(llimits.h)
typedef unsigned char lu_byte;
可以看到TValue
分成两个部分:value_
是一个union
用来存储不同数据,tt_
是一个无符号字节类型用于存储类型信息。
tt_
中最低的0-3四位用于存储数据类型,4-5两位用于存储variant子类型,第6位用于标记是否可回收。
(lobject.h)
/*
** tags for Tagged Values have the following use of bits:
** bits 0-3: actual tag (a LUA_T* value)
** bits 4-5: variant bits
** bit 6: whether value is collectable
*/
actual tag
lua中一共八种基本类型nil
、boolean
、number
、string
、table
、function
、thread
、userdata
,lightuserdata
是userdata
的一种内部实现。另外三种类型none
、upval
、prototype
为解释器内部的类型,每个类型的标志位如下。
(lua.h)
/*
** basic types
*/
(lobject.h)
/*
** Extra tags for non-values
*/
/*
** number of all possible tags (including LUA_TNONE)
*/
is collactable
tt_
中第6位为可回收标志位,如果为1,value_
的值作为一个GCObject
的指针指向下一个垃圾回收(GC)中的下一个对象。用这个指针来实现垃圾回收中的链表。
(lobject.h)
/*
** Common Header for all collectable objects (in macro form, to be
** included in other objects)
*/
/* Common type for all collectable objects */
typedef struct GCObject {
CommonHeader;
} GCObject;
/* Bit mark for collectable types */
从这可以看出来lua类型的继承关系。
nil
基本nil
类型的value_
字段并没有保存数据,所有数据都保存在tt_
字段中。nil
有两种特殊的值,variant
为1 用作table中的空槽和 2 用作table的key没找到的返回值。
(lobject.h)
/*
** Variant tag, used only in tables to signal an empty slot
** (which might be different from a slot containing nil)
*/
/*
** Variant used only in the value returned for a key not found in a
** table (absent key).
*/
boolean
boolean
类型没有特殊的子类型,只是使用了value_
字段当作int b
保存值。
(lobject.h)
number
number
类型使用 variant
来区分 float
和integer
,把value_
当作不同类型来存储数据。
(lobject.h)
/* Variant tags for numbers */
(ttisinteger(o) ? cast_num(ivalue(o)) : fltvalue(o)))
以上就是lua保存三种基本数据类型的结构,下期分析一下string
类型的数据结构和相关操作。