添加 lobject.h 和llex.h 文件的一些注释
This commit is contained in:
@@ -239,7 +239,7 @@ void luaC_barrierback_ (lua_State *L, GCObject *o) {
|
||||
setage(o, G_TOUCHED1); /* touched in current cycle */
|
||||
}
|
||||
|
||||
|
||||
// 添加进gc灰名单,永远不要回收
|
||||
void luaC_fix (lua_State *L, GCObject *o) {
|
||||
global_State *g = G(L);
|
||||
lua_assert(g->allgc == o); /* object must be 1st in 'allgc' list! */
|
||||
|
11
src/llex.c
11
src/llex.c
@@ -33,7 +33,7 @@
|
||||
#define next(ls) (ls->current = zgetc(ls->z))
|
||||
|
||||
|
||||
|
||||
// 当前字符是新行吗?
|
||||
#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r')
|
||||
|
||||
|
||||
@@ -48,10 +48,10 @@ static const char *const luaX_tokens [] = {
|
||||
"<number>", "<integer>", "<name>", "<string>"
|
||||
};
|
||||
|
||||
|
||||
// 把当前字符保存到缓冲区,并且读取下一个字符
|
||||
#define save_and_next(ls) (save(ls, ls->current), next(ls))
|
||||
|
||||
|
||||
// 报错
|
||||
static l_noret lexerror (LexState *ls, const char *msg, int token);
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ static void save (LexState *ls, int c) {
|
||||
if (luaZ_sizebuffer(b) >= MAX_SIZE/2)
|
||||
lexerror(ls, "lexical element too long", 0);
|
||||
newsize = luaZ_sizebuffer(b) * 2;
|
||||
// 这里会重新申请内存
|
||||
luaZ_resizebuffer(ls->L, b, newsize);
|
||||
}
|
||||
b->buffer[luaZ_bufflen(b)++] = cast_char(c);
|
||||
@@ -72,11 +73,15 @@ static void save (LexState *ls, int c) {
|
||||
|
||||
void luaX_init (lua_State *L) {
|
||||
int i;
|
||||
// 创建一个新的字符串
|
||||
TString *e = luaS_newliteral(L, LUA_ENV); /* create env name */
|
||||
luaC_fix(L, obj2gco(e)); /* never collect this name */
|
||||
for (i=0; i<NUM_RESERVED; i++) {
|
||||
// 创建保留字字符串
|
||||
TString *ts = luaS_new(L, luaX_tokens[i]);
|
||||
// 永远不要回收保留字字符串
|
||||
luaC_fix(L, obj2gco(ts)); /* reserved words are never collected */
|
||||
// 字符串对应的符号码,ts->extra+255== RESERVED
|
||||
ts->extra = cast_byte(i+1); /* reserved word */
|
||||
}
|
||||
}
|
||||
|
18
src/llex.h
18
src/llex.h
@@ -43,9 +43,10 @@ enum RESERVED {
|
||||
};
|
||||
|
||||
/* number of reserved words */
|
||||
// 保留字长度
|
||||
#define NUM_RESERVED (cast_int(TK_WHILE-FIRST_RESERVED + 1))
|
||||
|
||||
|
||||
// 语义信息
|
||||
typedef union {
|
||||
lua_Number r;
|
||||
lua_Integer i;
|
||||
@@ -60,20 +61,33 @@ typedef struct Token {
|
||||
|
||||
|
||||
/* state of the lexer plus state of the parser when shared by all
|
||||
functions */
|
||||
functions
|
||||
词法分析器的状态加上所有函数共享时解析器的状态
|
||||
*/
|
||||
typedef struct LexState {
|
||||
// 当前字符 用int类型来表示
|
||||
int current; /* current character (charint) */
|
||||
// 行编号
|
||||
int linenumber; /* input line counter */
|
||||
int lastline; /* line of last token 'consumed' */
|
||||
// 当前标识
|
||||
Token t; /* current token */
|
||||
// 前瞻性标识?
|
||||
Token lookahead; /* look ahead token */
|
||||
// 当前函数(解析器)
|
||||
struct FuncState *fs; /* current function (parser) */
|
||||
struct lua_State *L;
|
||||
// 输入流
|
||||
ZIO *z; /* input stream */
|
||||
// 标识的buffer
|
||||
Mbuffer *buff; /* buffer for tokens */
|
||||
// 避免收集/重用字符串
|
||||
Table *h; /* to avoid collection/reuse strings */
|
||||
// 解析器使用的动态结构体数据
|
||||
struct Dyndata *dyd; /* dynamic structures used by the parser */
|
||||
// 当前源文件名称
|
||||
TString *source; /* current source name */
|
||||
// 环境变量名称
|
||||
TString *envn; /* environment variable name */
|
||||
} LexState;
|
||||
|
||||
|
@@ -109,6 +109,7 @@ typedef LUAI_UACINT l_uacInt;
|
||||
#if defined(lua_assert)
|
||||
#define check_exp(c,e) (lua_assert(c), (e))
|
||||
/* to avoid problems with conditions too long */
|
||||
// 解决条件太长的问题 c为真时返回0
|
||||
#define lua_longassert(c) ((c) ? (void)0 : lua_assert(0))
|
||||
#else
|
||||
#define lua_assert(c) ((void)0)
|
||||
|
145
src/lobject.h
145
src/lobject.h
@@ -18,27 +18,33 @@
|
||||
|
||||
/*
|
||||
** Extra types for collectable non-values
|
||||
可收藏非贵重物品的额外类型
|
||||
*/
|
||||
// 上升值?
|
||||
#define LUA_TUPVAL LUA_NUMTYPES /* upvalues */
|
||||
// 函数原型
|
||||
#define LUA_TPROTO (LUA_NUMTYPES+1) /* function prototypes */
|
||||
// 在表中被删除的键
|
||||
#define LUA_TDEADKEY (LUA_NUMTYPES+2) /* removed keys in tables */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** number of all possible types (including LUA_TNONE but excluding DEADKEY)
|
||||
所有lua中可能的类型数量 包括 none 但是不包括 deadkey
|
||||
*/
|
||||
#define LUA_TOTALTYPES (LUA_TPROTO + 2)
|
||||
|
||||
|
||||
/*
|
||||
** tags for Tagged Values have the following use of bits:
|
||||
** bits 0-3: actual tag (a LUA_T* constant)
|
||||
** bits 4-5: variant bits
|
||||
** bit 6: whether value is collectable
|
||||
** bits 0-3: actual tag (a LUA_T* constant) 实际标签
|
||||
** bits 4-5: variant bits 可变比特
|
||||
** bit 6: whether value is collectable 是否可收集
|
||||
*/
|
||||
|
||||
/* add variant bits to a type */
|
||||
// 向tag中添加 variant , t,tag;v,variant
|
||||
#define makevariant(t,v) ((t) | ((v) << 4))
|
||||
|
||||
|
||||
@@ -47,12 +53,18 @@
|
||||
** Union of all Lua values
|
||||
*/
|
||||
typedef union Value {
|
||||
// 可被收集的对象
|
||||
struct GCObject *gc; /* collectable objects */
|
||||
// 轻量用户数据
|
||||
void *p; /* light userdata */
|
||||
// 轻量c语言函数
|
||||
lua_CFunction f; /* light C functions */
|
||||
// 整形数
|
||||
lua_Integer i; /* integer numbers */
|
||||
// 浮点数
|
||||
lua_Number n; /* float numbers */
|
||||
/* not used, but may avoid warnings for uninitialized value */
|
||||
// 没有使用,但是可以用来避免未初始化警告
|
||||
lu_byte ub;
|
||||
} Value;
|
||||
|
||||
@@ -60,6 +72,7 @@ typedef union Value {
|
||||
/*
|
||||
** Tagged Values. This is the basic representation of values in Lua:
|
||||
** an actual value plus a tag with its type.
|
||||
lua中的基本值,一个实际值加上一个类型标签
|
||||
*/
|
||||
|
||||
#define TValuefields Value value_; lu_byte tt_
|
||||
@@ -68,33 +81,43 @@ typedef struct TValue {
|
||||
TValuefields;
|
||||
} TValue;
|
||||
|
||||
|
||||
// 获取TValue 中的实际值
|
||||
// 用法 valraw(obj)
|
||||
#define val_(o) ((o)->value_)
|
||||
#define valraw(o) (val_(o))
|
||||
|
||||
|
||||
/* raw type tag of a TValue */
|
||||
// 获取TValue 中的类型标签
|
||||
// 用法 valtt(obj)
|
||||
#define rawtt(o) ((o)->tt_)
|
||||
|
||||
/* tag with no variants (bits 0-3) */
|
||||
// tag 去除variant部分
|
||||
#define novariant(t) ((t) & 0x0F)
|
||||
|
||||
/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */
|
||||
// 获取变量类型 基本值+可变部分
|
||||
// 用法 ttypetag(obj)
|
||||
#define withvariant(t) ((t) & 0x3F)
|
||||
#define ttypetag(o) withvariant(rawtt(o))
|
||||
|
||||
/* type of a TValue */
|
||||
// 用法 ttype(obj) 基本值
|
||||
#define ttype(o) (novariant(rawtt(o)))
|
||||
|
||||
|
||||
/* Macros to test type */
|
||||
// checktag 用于校验tag 需要完全相等 用法 checktag(obj,t)
|
||||
#define checktag(o,t) (rawtt(o) == (t))
|
||||
// checktype 用于校验基本类型 只需基本部分相等即可
|
||||
#define checktype(o,t) (ttype(o) == (t))
|
||||
|
||||
|
||||
/* Macros for internal tests */
|
||||
|
||||
/* collectable object has the same tag as the original value */
|
||||
// TValue中的类型值与 使用gcvalue函数获取的值完全相等
|
||||
#define righttt(obj) (ttypetag(obj) == gcvalue(obj)->tt)
|
||||
|
||||
/*
|
||||
@@ -102,6 +125,13 @@ typedef struct TValue {
|
||||
** collectable, or the collectable object has the right tag
|
||||
** and it is not dead. The option 'L == NULL' allows other
|
||||
** macros using this one to be used where L is not available.
|
||||
程序操纵的任何值要么是不可收集的,要么是可收集对象具有正确的标签并且没有死。
|
||||
选项“L==NULL”允许在L不可用的情况下使用使用此宏的其他宏。
|
||||
L 是指 lua_State
|
||||
|
||||
判断obj是否有效
|
||||
如果 obj不可被收集 则有效
|
||||
在类型校验通过的情况下 L为 NULL时 有效; L不为NULL时,通过调用isdead函数来判断是否有效
|
||||
*/
|
||||
#define checkliveness(L,obj) \
|
||||
((void)L, lua_longassert(!iscollectable(obj) || \
|
||||
@@ -111,10 +141,12 @@ typedef struct TValue {
|
||||
/* Macros to set values */
|
||||
|
||||
/* set a value's tag */
|
||||
// 设置标签
|
||||
#define settt_(o,t) ((o)->tt_=(t))
|
||||
|
||||
|
||||
/* main macro to copy values (from 'obj2' to 'obj1') */
|
||||
// 指针复制 ,复制之后检查是否存活?
|
||||
#define setobj(L,obj1,obj2) \
|
||||
{ TValue *io1=(obj1); const TValue *io2=(obj2); \
|
||||
io1->value_ = io2->value_; settt_(io1, io2->tt_); \
|
||||
@@ -123,11 +155,15 @@ typedef struct TValue {
|
||||
/*
|
||||
** Different types of assignments, according to source and destination.
|
||||
** (They are mostly equal now, but may be different in the future.)
|
||||
不同类型的任务,根据来源和目的地的不同
|
||||
*/
|
||||
|
||||
/* from stack to stack */
|
||||
// 在栈中把o2复制给o1,宏s2v用于把栈中变量转换为TValue
|
||||
// 宏 setobjs2s 中的o1和o2是指栈变量
|
||||
#define setobjs2s(L,o1,o2) setobj(L,s2v(o1),s2v(o2))
|
||||
/* to stack (not from same stack) */
|
||||
// 把一个游离变量复制到栈变量
|
||||
#define setobj2s(L,o1,o2) setobj(L,s2v(o1),o2)
|
||||
/* from table to same table */
|
||||
#define setobjt2t setobj
|
||||
@@ -144,6 +180,9 @@ typedef struct TValue {
|
||||
** in an unsigned short. They are represented by delta==0, and
|
||||
** their real delta is always the maximum value that fits in
|
||||
** that field.
|
||||
Lua堆栈中的条目。字段“tbclist”形成此堆栈中所有活动的待关闭变量的列表。
|
||||
当两个tbc变量之间的距离不适合无符号short时,使用伪条目。它们由delta==0表示,
|
||||
它们的实际delta始终是该字段中的最大值。
|
||||
*/
|
||||
typedef union StackValue {
|
||||
TValue val;
|
||||
@@ -161,6 +200,7 @@ typedef StackValue *StkId;
|
||||
/*
|
||||
** When reallocating the stack, change all pointers to the stack into
|
||||
** proper offsets.
|
||||
重新分配堆栈时,将指向堆栈的所有指针更改为适当的偏移量。
|
||||
*/
|
||||
typedef union {
|
||||
StkId p; /* actual pointer */
|
||||
@@ -180,31 +220,37 @@ typedef union {
|
||||
*/
|
||||
|
||||
/* Standard nil */
|
||||
// 基本的空类型
|
||||
#define LUA_VNIL makevariant(LUA_TNIL, 0)
|
||||
|
||||
/* Empty slot (which might be different from a slot containing nil) */
|
||||
// 空
|
||||
#define LUA_VEMPTY makevariant(LUA_TNIL, 1)
|
||||
|
||||
/* Value returned for a key not found in a table (absent key) */
|
||||
// 未找到的key
|
||||
#define LUA_VABSTKEY makevariant(LUA_TNIL, 2)
|
||||
|
||||
|
||||
/* macro to test for (any kind of) nil */
|
||||
// 是否是空类型
|
||||
#define ttisnil(v) checktype((v), LUA_TNIL)
|
||||
|
||||
|
||||
/* macro to test for a standard nil */
|
||||
// 是否是基本的空类型
|
||||
#define ttisstrictnil(o) checktag((o), LUA_VNIL)
|
||||
|
||||
|
||||
// 设置空类型标签
|
||||
#define setnilvalue(obj) settt_(obj, LUA_VNIL)
|
||||
|
||||
|
||||
// 是否是未找到key的空类型
|
||||
#define isabstkey(v) checktag((v), LUA_VABSTKEY)
|
||||
|
||||
|
||||
/*
|
||||
** macro to detect non-standard nils (used only in assertions)
|
||||
是否是空类型但不是基本的空类型
|
||||
*/
|
||||
#define isnonstrictnil(v) (ttisnil(v) && !ttisstrictnil(v))
|
||||
|
||||
@@ -213,15 +259,18 @@ typedef union {
|
||||
** By default, entries with any kind of nil are considered empty.
|
||||
** (In any definition, values associated with absent keys must also
|
||||
** be accepted as empty.)
|
||||
默认情况下,任何类型为nil的条目都被视为空。(在任何定义中,与缺失键关联的值也必须被接受为空。)
|
||||
*/
|
||||
#define isempty(v) ttisnil(v)
|
||||
|
||||
|
||||
/* macro defining a value corresponding to an absent key */
|
||||
// 宏定义与缺失键对应的值
|
||||
#define ABSTKEYCONSTANT {NULL}, LUA_VABSTKEY
|
||||
|
||||
|
||||
/* mark an entry as empty */
|
||||
// 设置对象为空
|
||||
#define setempty(v) settt_(v, LUA_VEMPTY)
|
||||
|
||||
|
||||
@@ -235,19 +284,23 @@ typedef union {
|
||||
** ===================================================================
|
||||
*/
|
||||
|
||||
|
||||
// 布尔值假
|
||||
#define LUA_VFALSE makevariant(LUA_TBOOLEAN, 0)
|
||||
// 布尔值真
|
||||
#define LUA_VTRUE makevariant(LUA_TBOOLEAN, 1)
|
||||
|
||||
// 是否是布尔值
|
||||
#define ttisboolean(o) checktype((o), LUA_TBOOLEAN)
|
||||
// 是否为假
|
||||
#define ttisfalse(o) checktag((o), LUA_VFALSE)
|
||||
// 是否为真
|
||||
#define ttistrue(o) checktag((o), LUA_VTRUE)
|
||||
|
||||
|
||||
// 布尔值为假或空类型都视为假
|
||||
#define l_isfalse(o) (ttisfalse(o) || ttisnil(o))
|
||||
|
||||
|
||||
// 设置为布尔值假
|
||||
#define setbfvalue(obj) settt_(obj, LUA_VFALSE)
|
||||
// 设置为布尔值真
|
||||
#define setbtvalue(obj) settt_(obj, LUA_VTRUE)
|
||||
|
||||
/* }================================================================== */
|
||||
@@ -259,17 +312,19 @@ typedef union {
|
||||
** ===================================================================
|
||||
*/
|
||||
|
||||
// 线程类型
|
||||
#define LUA_VTHREAD makevariant(LUA_TTHREAD, 0)
|
||||
|
||||
// 线程是可回收的
|
||||
#define ttisthread(o) checktag((o), ctb(LUA_VTHREAD))
|
||||
|
||||
// 如果不是线程类型则进断言?
|
||||
#define thvalue(o) check_exp(ttisthread(o), gco2th(val_(o).gc))
|
||||
|
||||
// 设置线程对象
|
||||
#define setthvalue(L,obj,x) \
|
||||
{ TValue *io = (obj); lua_State *x_ = (x); \
|
||||
val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_VTHREAD)); \
|
||||
checkliveness(L,io); }
|
||||
|
||||
// 把线程对象设置到栈中
|
||||
#define setthvalue2s(L,o,t) setthvalue(L,s2v(o),t)
|
||||
|
||||
/* }================================================================== */
|
||||
@@ -284,6 +339,7 @@ typedef union {
|
||||
/*
|
||||
** Common Header for all collectable objects (in macro form, to be
|
||||
** included in other objects)
|
||||
所有可收集对象的公共头(以宏形式,包含在其他对象中)
|
||||
*/
|
||||
#define CommonHeader struct GCObject *next; lu_byte tt; lu_byte marked
|
||||
|
||||
@@ -296,16 +352,17 @@ typedef struct GCObject {
|
||||
|
||||
/* Bit mark for collectable types */
|
||||
#define BIT_ISCOLLECTABLE (1 << 6)
|
||||
|
||||
// 是否是可收集的
|
||||
#define iscollectable(o) (rawtt(o) & BIT_ISCOLLECTABLE)
|
||||
|
||||
/* mark a tag as collectable */
|
||||
// 把tag标记为可回收的
|
||||
#define ctb(t) ((t) | BIT_ISCOLLECTABLE)
|
||||
|
||||
// 不是可收集类型则进断言?
|
||||
#define gcvalue(o) check_exp(iscollectable(o), val_(o).gc)
|
||||
|
||||
// 获取gc值
|
||||
#define gcvalueraw(v) ((v).gc)
|
||||
|
||||
// 设置gc值
|
||||
#define setgcovalue(L,obj,x) \
|
||||
{ TValue *io = (obj); GCObject *i_g=(x); \
|
||||
val_(io).gc = i_g; settt_(io, ctb(i_g->tt)); }
|
||||
@@ -320,30 +377,35 @@ typedef struct GCObject {
|
||||
*/
|
||||
|
||||
/* Variant tags for numbers */
|
||||
// 整形数
|
||||
#define LUA_VNUMINT makevariant(LUA_TNUMBER, 0) /* integer numbers */
|
||||
// 浮点数
|
||||
#define LUA_VNUMFLT makevariant(LUA_TNUMBER, 1) /* float numbers */
|
||||
|
||||
// 是否是数类型,整形数和浮点数皆可
|
||||
#define ttisnumber(o) checktype((o), LUA_TNUMBER)
|
||||
// 是否是浮点数
|
||||
#define ttisfloat(o) checktag((o), LUA_VNUMFLT)
|
||||
// 是否是整形数
|
||||
#define ttisinteger(o) checktag((o), LUA_VNUMINT)
|
||||
|
||||
// 不是数类型则进断言
|
||||
#define nvalue(o) check_exp(ttisnumber(o), \
|
||||
(ttisinteger(o) ? cast_num(ivalue(o)) : fltvalue(o)))
|
||||
#define fltvalue(o) check_exp(ttisfloat(o), val_(o).n)
|
||||
#define ivalue(o) check_exp(ttisinteger(o), val_(o).i)
|
||||
|
||||
// 获取整形值
|
||||
#define fltvalueraw(v) ((v).n)
|
||||
// 获取浮点值
|
||||
#define ivalueraw(v) ((v).i)
|
||||
|
||||
// TValue设置为浮点数,同时设置数据类型
|
||||
#define setfltvalue(obj,x) \
|
||||
{ TValue *io=(obj); val_(io).n=(x); settt_(io, LUA_VNUMFLT); }
|
||||
|
||||
// 修改浮点数,如果数据类型不为浮点数则进断言
|
||||
#define chgfltvalue(obj,x) \
|
||||
{ TValue *io=(obj); lua_assert(ttisfloat(io)); val_(io).n=(x); }
|
||||
|
||||
// 设置为整形数,同时设置数据类型
|
||||
#define setivalue(obj,x) \
|
||||
{ TValue *io=(obj); val_(io).i=(x); settt_(io, LUA_VNUMINT); }
|
||||
|
||||
// 修改整形数,如果数据类型不为整形数则进断言
|
||||
#define chgivalue(obj,x) \
|
||||
{ TValue *io=(obj); lua_assert(ttisinteger(io)); val_(io).i=(x); }
|
||||
|
||||
@@ -357,26 +419,32 @@ typedef struct GCObject {
|
||||
*/
|
||||
|
||||
/* Variant tags for strings */
|
||||
// 短字符串
|
||||
#define LUA_VSHRSTR makevariant(LUA_TSTRING, 0) /* short strings */
|
||||
// 长字符串
|
||||
#define LUA_VLNGSTR makevariant(LUA_TSTRING, 1) /* long strings */
|
||||
|
||||
// 是否是字符串类型
|
||||
#define ttisstring(o) checktype((o), LUA_TSTRING)
|
||||
// 是否是短字符串类型
|
||||
#define ttisshrstring(o) checktag((o), ctb(LUA_VSHRSTR))
|
||||
// 是否是长字符串类型
|
||||
#define ttislngstring(o) checktag((o), ctb(LUA_VLNGSTR))
|
||||
|
||||
// 获取字符串?
|
||||
#define tsvalueraw(v) (gco2ts((v).gc))
|
||||
|
||||
// 如果不是字符串则进入断言 否则获取这个字符串
|
||||
#define tsvalue(o) check_exp(ttisstring(o), gco2ts(val_(o).gc))
|
||||
|
||||
// 设置字符串值 同时修改变量类型为字符串类型
|
||||
#define setsvalue(L,obj,x) \
|
||||
{ TValue *io = (obj); TString *x_ = (x); \
|
||||
val_(io).gc = obj2gco(x_); settt_(io, ctb(x_->tt)); \
|
||||
checkliveness(L,io); }
|
||||
|
||||
/* set a string to the stack */
|
||||
// 设置栈中的字符串变量
|
||||
#define setsvalue2s(L,o,s) setsvalue(L,s2v(o),s)
|
||||
|
||||
/* set a string to a new object */
|
||||
// 设置一个新的字符串
|
||||
#define setsvalue2n setsvalue
|
||||
|
||||
|
||||
@@ -399,17 +467,21 @@ typedef struct TString {
|
||||
|
||||
/*
|
||||
** Get the actual string (array of bytes) from a 'TString'.
|
||||
// 获得字符串类型的实际字符
|
||||
*/
|
||||
#define getstr(ts) ((ts)->contents)
|
||||
|
||||
|
||||
/* get the actual string (array of bytes) from a Lua value */
|
||||
// 从TValue中获得字符串的原始数据指针
|
||||
#define svalue(o) getstr(tsvalue(o))
|
||||
|
||||
/* get string length from 'TString *s' */
|
||||
// 获得字符串的长度
|
||||
#define tsslen(s) ((s)->tt == LUA_VSHRSTR ? (s)->shrlen : (s)->u.lnglen)
|
||||
|
||||
/* get string length from 'TValue *o' */
|
||||
// 从TValue中获得字符串的长度
|
||||
#define vslen(o) tsslen(tsvalue(o))
|
||||
|
||||
/* }================================================================== */
|
||||
@@ -425,22 +497,25 @@ typedef struct TString {
|
||||
/*
|
||||
** Light userdata should be a variant of userdata, but for compatibility
|
||||
** reasons they are also different types.
|
||||
轻量级用户数据应该是用户数据的变体,但出于兼容性原因,它们也是不同类型的。
|
||||
*/
|
||||
#define LUA_VLIGHTUSERDATA makevariant(LUA_TLIGHTUSERDATA, 0)
|
||||
|
||||
#define LUA_VUSERDATA makevariant(LUA_TUSERDATA, 0)
|
||||
|
||||
// 是否是轻量用户数据
|
||||
#define ttislightuserdata(o) checktag((o), LUA_VLIGHTUSERDATA)
|
||||
// 是否是完整用户数据
|
||||
#define ttisfulluserdata(o) checktag((o), ctb(LUA_VUSERDATA))
|
||||
|
||||
// 获取轻量用户数据的指针
|
||||
#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p)
|
||||
// 获取完整用户数据
|
||||
#define uvalue(o) check_exp(ttisfulluserdata(o), gco2u(val_(o).gc))
|
||||
|
||||
// 从Value中获取p指针
|
||||
#define pvalueraw(v) ((v).p)
|
||||
|
||||
// 设置轻量用户数据,修改变量类型为轻量用户数据
|
||||
#define setpvalue(obj,x) \
|
||||
{ TValue *io=(obj); val_(io).p=(x); settt_(io, LUA_VLIGHTUSERDATA); }
|
||||
|
||||
// 设置用户数据 修改变量类型为用户数据
|
||||
#define setuvalue(L,obj,x) \
|
||||
{ TValue *io = (obj); Udata *x_ = (x); \
|
||||
val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_VUSERDATA)); \
|
||||
@@ -476,6 +551,10 @@ typedef struct Udata {
|
||||
** This structure here is used only to compute the correct size for
|
||||
** this representation. (The 'bindata' field in its end ensures correct
|
||||
** alignment for binary data following this header.)
|
||||
没有用户值的用户数据的标头。这些用户数据在GC期间不需要是灰色的,因此不需要“gclist”字段。
|
||||
为了简化,代码总是对这两种用户数据都使用“Udata”,
|
||||
确保它永远不会在没有用户值的用户数据上访问“gclist”。
|
||||
这里的结构仅用于计算此表示的正确大小。(末尾的“bindata”字段可确保此标头后的二进制数据正确对齐。)
|
||||
*/
|
||||
typedef struct Udata0 {
|
||||
CommonHeader;
|
||||
|
Reference in New Issue
Block a user