diff options
| author | chai <chaifix@163.com> | 2020-09-10 20:55:10 +0800 |
|---|---|---|
| committer | chai <chaifix@163.com> | 2020-09-10 20:55:10 +0800 |
| commit | d9c2d065698641837bc75ded236b23d5aaa36fd4 (patch) | |
| tree | 9acb1fe3f61121bc5963b9b76f22265d8cd00f0e /src/lua51 | |
| parent | 229a3937a3b99a175b551e28d09b9a45d37c44f7 (diff) | |
*table string comment
Diffstat (limited to 'src/lua51')
| -rw-r--r-- | src/lua51/lcode.h | 2 | ||||
| -rw-r--r-- | src/lua51/lobject.h | 20 | ||||
| -rw-r--r-- | src/lua51/lstate.h | 7 | ||||
| -rw-r--r-- | src/lua51/lstring.c | 36 | ||||
| -rw-r--r-- | src/lua51/ltable.c | 16 | ||||
| -rw-r--r-- | src/lua51/lvm.c | 1 | ||||
| -rw-r--r-- | src/lua51/lvm.h | 2 |
7 files changed, 49 insertions, 35 deletions
diff --git a/src/lua51/lcode.h b/src/lua51/lcode.h index b941c60..45d9f68 100644 --- a/src/lua51/lcode.h +++ b/src/lua51/lcode.h @@ -1,3 +1,5 @@ +//c 生成字节码 + /* ** $Id: lcode.h,v 1.48.1.1 2007/12/27 13:02:25 roberto Exp $ ** Code generator for Lua diff --git a/src/lua51/lobject.h b/src/lua51/lobject.h index 25dc341..4e9daee 100644 --- a/src/lua51/lobject.h +++ b/src/lua51/lobject.h @@ -40,10 +40,10 @@ typedef union GCObject GCObject; ** Common Header for all collectable objects (in macro form, to be ** included in other objects) */ -// 需要垃圾回收的类型包含这个头 -//c next 指向下一个gc链表的成员 -//c tt 数据类型 -//c GC标记,用来保存颜色,有白色(2种),灰色和黑色 +// 需要垃圾回收的类型包含这个头,包含TString, Udata, Proto, UpVal, Closure, Table以及lua_State七个 +//c next 指向下一个gc链表的成员 +//c tt 数据类型 +//c marked GC标记,用来保存颜色,有白色(2种),灰色和黑色 #define CommonHeader GCObject *next; lu_byte tt; lu_byte marked @@ -211,17 +211,17 @@ typedef union TString { L_Umaxalign dummy; /* ensures maximum alignment for strings */ struct { CommonHeader; - lu_byte reserved;//标记字符串是否是lua的关键字,如果是,不会被GC回收 - unsigned int hash;//字符串的哈希值,比较字符串的依据 - size_t len; - } tsv; + lu_byte reserved;//c 标记字符串是否是lua的关键字,如果是,不会被GC回收 + unsigned int hash;//c 字符串的哈希值,比较字符串的依据 + size_t len; //c 字符串长度 + } tsv; //c tstring value } TString; #define getstr(ts) cast(const char *, (ts) + 1) #define svalue(o) getstr(rawtsvalue(o)) -// userdata,和TString比较像 +//c userdata,和TString比较像 typedef union Udata { L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ struct { @@ -240,7 +240,7 @@ typedef union Udata { */ typedef struct Proto { CommonHeader; - //c 函数的常量 + //c 常量表,能看出来lua保存常量的单元是函数原型,所有代码片段都会被编译为proto TValue *k; /* constants used by the function */ //c 函数字节码 Instruction *code; diff --git a/src/lua51/lstate.h b/src/lua51/lstate.h index 2f71e57..1c049e1 100644 --- a/src/lua51/lstate.h +++ b/src/lua51/lstate.h @@ -41,9 +41,9 @@ struct lua_longjmp; /* defined in ldo.c */ //c rehash在lstring.c -> luaS_resize typedef struct stringtable { GCObject **hash; //c 字符串,因为是散列桶,所以是** - lu_int32 nuse; //c 桶用到的容量,因为不一定size都用到了 /* number of elements */ - int size; //c 桶的总容量,是常值 - // nuse和size是用来动态控制桶容量的关键 + lu_int32 nuse; //c 桶用到的容量,因为不一定size都用到了 /* number of elements */ + int size; //c 桶的总容量,是常值 + //c nuse和size是用来动态控制桶容量的关键 } stringtable; @@ -120,7 +120,6 @@ typedef struct global_State { } global_State; -//c 一个lua_state,可以看做是一个 //c StkId引用的永远是lua_State栈上的内容 /* ** `per thread' state diff --git a/src/lua51/lstring.c b/src/lua51/lstring.c index 73d34c4..cadbb4b 100644 --- a/src/lua51/lstring.c +++ b/src/lua51/lstring.c @@ -25,19 +25,19 @@ void luaS_resize (lua_State *L, int newsize) { GCObject **newhash; stringtable *tb; int i; - if (G(L)->gcstate == GCSsweepstring)//如果GC在回收字符串阶段,不要rehash + if (G(L)->gcstate == GCSsweepstring)//如果GC在回收字符串阶段,不要rehash,等GC完了再搞 return; /* cannot resize during GC traverse */ newhash = luaM_newvector(L, newsize, GCObject *); //建立一个新的散列桶,并清空 tb = &G(L)->strt;//旧的散列桶 for (i=0; i<newsize; i++) newhash[i] = NULL; - //遍历就的散列桶,并填入新的散列桶 + //遍历旧的散列桶,并填入新的散列桶 /* rehash */ for (i=0; i<tb->size; i++) { - GCObject *p = tb->hash[i]; + GCObject *p = tb->hash[i]; // 某个桶 while (p) { /* for each node in the list */ GCObject *next = p->gch.next; /* save next */ - unsigned int h = gco2ts(p)->hash; - //新的散列值 + unsigned int h = gco2ts(p)->hash; //c 保存hash值 + //新的散列值,并加入桶中 int h1 = lmod(h, newsize); /* new position */ lua_assert(cast_int(h%newsize) == lmod(h, newsize)); p->gch.next = newhash[h1];//c 接在同一个hash的最前面 /* chain it */ @@ -45,37 +45,42 @@ void luaS_resize (lua_State *L, int newsize) { p = next; } } + // 释放旧散列桶 luaM_freearray(L, tb->hash, tb->size, TString *); tb->size = newsize; - tb->hash = newhash; + tb->hash = newhash; // 设置新散列桶 } -//c 新建字符串 +//c 新建字符串并加入散列桶 static TString *newlstr (lua_State *L, const char *str, size_t l, unsigned int h) { TString *ts; stringtable *tb; if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) luaM_toobig(L); + //c 同时申请了TString和字符串内存,字符串内容会紧跟在TString结构后边 ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString))); ts->tsv.len = l; ts->tsv.hash = h; ts->tsv.marked = luaC_white(G(L)); ts->tsv.tt = LUA_TSTRING; ts->tsv.reserved = 0; - memcpy(ts+1, str, l*sizeof(char)); + + memcpy(ts+1, str, l*sizeof(char)); //c 复制字符串内容 ((char *)(ts+1))[l] = '\0'; /* ending 0 */ - tb = &G(L)->strt; - // 计算hash值 - h = lmod(h, tb->size); + + tb = &G(L)->strt; //c 散列桶 + + h = lmod(h, tb->size); //c 计算hash值并将这个字符串加入桶 ts->tsv.next = tb->hash[h]; /* chain new entry */ tb->hash[h] = obj2gco(ts); tb->nuse++; - //c 给字符串通扩容,如果字符串数量大于桶容量 - //c 给桶扩容为2倍 + + //c 如果字符串数量大于桶容量,给字符串通扩容,给桶扩容为2倍 if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2) luaS_resize(L, tb->size*2); /* too crowded */ + return ts; } @@ -89,11 +94,14 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { //c 如果字符串非常长,不要逐位计算散列值,每step步取一个字符计算即可 for (l1=l; l1>=step; l1-=step) /* compute hash */ h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1])); + //c 遍历这个hash对应的散列桶 for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)]; o != NULL; o = o->gch.next) { TString *ts = rawgco2ts(o); - if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) {//c 如果散列值相同,用memcmp快速对比 + //c 如果长度相同,用memcmp快速对比 + if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) { + //c 这个字符串已经存在,直接返回这个引用 //c 如果字符串被标记了回收(gch.marked),重新标记它不要回收 /* string may be dead */ if (isdead(G(L), o)) changewhite(o); diff --git a/src/lua51/ltable.c b/src/lua51/ltable.c index 73464a0..38f4218 100644 --- a/src/lua51/ltable.c +++ b/src/lua51/ltable.c @@ -92,7 +92,7 @@ static Node *hashnum (const Table *t, lua_Number n) { } - +//c 计算hash不同key类型的hash值 /* ** returns the `main' position of an element in a table (that is, the index ** of its hash value) @@ -404,7 +404,7 @@ static Node *getfreepos (Table *t) { } -//c 表新建key +//c 表新建key,规则如下↓ /* ** inserts a new key into a hash table; first, check whether key's main ** position is free. If not, check whether colliding node is in its main @@ -416,6 +416,7 @@ static TValue *newkey (lua_State *L, Table *t, const TValue *key) { Node *mp = mainposition(t, key); if (!ttisnil(gval(mp)) || mp == dummynode) {//c mainposition上已经有数据 Node *othern; + //c 取一个空桶,后面可能会用到 Node *n = getfreepos(t); /* get a free place */ //c 如果没有空位,扩展hash table大小为2倍 if (n == NULL) { /* cannot find a free place? */ @@ -425,8 +426,9 @@ static TValue *newkey (lua_State *L, Table *t, const TValue *key) { } lua_assert(n != dummynode); //c 先看一下现在mainposition上的这个node,它的mainposition是不是这个值 - //c 不是的话给新的key让路 - othern = mainposition(t, key2tval(mp)); + //c 不是的话说明这个node是临时放在这里的,给新的key让路,把这个node移到一个空位上 + //c othern是原先mp位置的这个key应该对应的位置 + othern = mainposition(t, key2tval(mp)); //c key2tval(mp)那大mp的key地址,用来计算hash if (othern != mp) { /* is colliding node out of its main position? */ // 把mp空出来,mp里的值移到n(freeposition) /* yes; move colliding node into free position */ @@ -434,8 +436,9 @@ static TValue *newkey (lua_State *L, Table *t, const TValue *key) { while (gnext(othern) != mp) othern = gnext(othern); /* find previous */ gnext(othern) = n; /* redo the chain with `n' in place of `mp' */ *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */ + gnext(mp) = NULL; /* now `mp' is free */ - setnilvalue(gval(mp)); + setnilvalue(gval(mp)); // 清空这个位置,留个要加的这个key用 //mp是要赋值的位置,即新key的元素的位置 } else { /* colliding node is in its own main position */ @@ -443,7 +446,8 @@ static TValue *newkey (lua_State *L, Table *t, const TValue *key) { //c 将free position插入到mp后第一个 gnext(n) = gnext(mp); /* chain new position */ gnext(mp) = n; - //c 修改一下mp指针,指向freeposition,留个后续使用 + + //c 修改一下mp指针,指向freeposition,留给后续使用。一个hack,这样就可以和mainposition位置上是空的兼容 mp = n; } } diff --git a/src/lua51/lvm.c b/src/lua51/lvm.c index 21de678..b353500 100644 --- a/src/lua51/lvm.c +++ b/src/lua51/lvm.c @@ -393,6 +393,7 @@ void luaV_execute (lua_State *L, int nexeccalls) { base = L->base; //c base是寄存器开始地址,每个方法被调用时都会得到自己的一组虚拟寄存器 k = cl->p->k; //c 当前函数原型的常量,所有函数调用都会用到的 + //c 虚拟机主循环 /* main loop of interpreter */ for (;;) { const Instruction i = *pc++; diff --git a/src/lua51/lvm.h b/src/lua51/lvm.h index 19fec22..78c4963 100644 --- a/src/lua51/lvm.h +++ b/src/lua51/lvm.h @@ -30,7 +30,7 @@ LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val); LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val); -//c 虚拟机主入口 +//c 虚拟机主入口 luaV_execute LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls); LUAI_FUNC void luaV_concat (lua_State *L, int total, int last); |
