diff --git a/src/lgc.c b/src/lgc.c index a3094ff..1fe073d 100644 --- a/src/lgc.c +++ b/src/lgc.c @@ -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! */ diff --git a/src/llex.c b/src/llex.c index 229264d..5b3a705 100644 --- a/src/llex.c +++ b/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 [] = { "", "", "", "" }; - +// 把当前字符保存到缓冲区,并且读取下一个字符 #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; iextra+255== RESERVED ts->extra = cast_byte(i+1); /* reserved word */ } } diff --git a/src/llex.h b/src/llex.h index 389d2f8..91cc355 100644 --- a/src/llex.h +++ b/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; diff --git a/src/llimits.h b/src/llimits.h index 2bfb3aa..0363ad8 100644 --- a/src/llimits.h +++ b/src/llimits.h @@ -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) diff --git a/src/lobject.h b/src/lobject.h index 556608e..b46db1f 100644 --- a/src/lobject.h +++ b/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;