summaryrefslogtreecommitdiff
path: root/src/lua51
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2020-09-10 20:55:10 +0800
committerchai <chaifix@163.com>2020-09-10 20:55:10 +0800
commitd9c2d065698641837bc75ded236b23d5aaa36fd4 (patch)
tree9acb1fe3f61121bc5963b9b76f22265d8cd00f0e /src/lua51
parent229a3937a3b99a175b551e28d09b9a45d37c44f7 (diff)
*table string comment
Diffstat (limited to 'src/lua51')
-rw-r--r--src/lua51/lcode.h2
-rw-r--r--src/lua51/lobject.h20
-rw-r--r--src/lua51/lstate.h7
-rw-r--r--src/lua51/lstring.c36
-rw-r--r--src/lua51/ltable.c16
-rw-r--r--src/lua51/lvm.c1
-rw-r--r--src/lua51/lvm.h2
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);