博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Lua1.0 代码分析 table.c
阅读量:4519 次
发布时间:2019-06-08

本文共 6152 字,大约阅读时间需要 20 分钟。

转载出处:http://my.oschina.net/xhan/blog/307961

 

table.c 代码分析

全局符号,常量,字符串,关联数组,文件列表的定义。

全局符号: 初始有 5 个基本的符号,Lua 预设的函数和库函数都注册在里面。

常量: 初始的几个常量是 Lua 中 type 的名字。

字符串表,关联数组表,文件列表 所有的这些在 table.c 中定义的这些数组可以认为是 Lua 的全局注册表空间,Lua 的环境。

 

函数分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/*
** Given a name, search it at symbol table and return its index. If not
** found, allocate at end of table, checking oveflow and return its index.
** On error, return -1.
*/
int 
lua_findsymbol (
char 
*s)
{
 
int 
i;
 
for 
(i=0; i<lua_ntable; i++)
  
if 
(streq(s,s_name(i)))
   
return 
i;
 
if 
(lua_ntable >= MAXSYMBOL-1)
 
{
  
lua_error (
"symbol table overflow"
);
  
return 
-1;
 
}
 
s_name(lua_ntable) = strdup(s);
 
if 
(s_name(lua_ntable) == NULL)
 
{
  
lua_error (
"not enough memory"
);
  
return 
-1;
 
}
 
s_tag(lua_ntable++) = T_NIL;
  
 
return 
(lua_ntable-1);
}

注释说得比较清楚了: 给定一个名字,在符号表中查找,如果找到,返回它的索引。如果没有找到,在数组尾部添加注意不要越界。 如果出错, 返回 -1。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/*
** Given a constant string, eliminate its delimeters (" or '), search it at
** constant table and return its index. If not found, allocate at end of
** the table, checking oveflow and return its index.
**
** For each allocation, the function allocate a extra char to be used to
** mark used string (it's necessary to deal with constant and string
** uniformily). The function store at the table the second position allocated,
** that represents the beginning of the real string. On error, return -1.
**
*/
int 
lua_findenclosedconstant (
char 
*s)
{
 
int 
i, j, l=
strlen
(s);
 
char 
*c = 
calloc 
(l, 
sizeof
(
char
)); 
/* make a copy */
  
 
c++; 
/* create mark space */
 
/* introduce scape characters */
 
for 
(i=1,j=0; i<l-1; i++)
 
{
  
if 
(s[i] == 
'\\'
)
  
{
   
switch 
(s[++i])
   
{
    
case 
'n'
: c[j++] = 
'\n'
break
;
    
case 
't'
: c[j++] = 
'\t'
break
;
    
case 
'r'
: c[j++] = 
'\r'
break
;
    
default 
: c[j++] = 
'\\'
; c[j++] = c[i]; 
break
;
   
}
  
}
  
else
   
c[j++] = s[i];
 
}
 
c[j++] = 0;
  
 
for 
(i=0; i<lua_nconstant; i++)
  
if 
(streq(c,lua_constant[i]))
  
{
   
free 
(c-1);
   
return 
i;
  
}
 
if 
(lua_nconstant >= MAXCONSTANT-1)
 
{
  
lua_error (
"lua: constant string table overflow"
);
  
return 
-1;
 
}
 
lua_constant[lua_nconstant++] = c;
 
return 
(lua_nconstant-1);
}

给定一个常量字符串,在常量表中查找它,如果找到返回它的索引。如果没有,在结尾分配,返回它的索引。注意溢出。 对于每一个新的分配的常量字符串,在它的前面多分配一个字符用来做标记位。真正的字符串从第二位开始存放。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/*
** Given a constant string, search it at constant table and return its index.
** If not found, allocate at end of the table, checking oveflow and return
** its index.
**
** For each allocation, the function allocate a extra char to be used to
** mark used string (it's necessary to deal with constant and string
** uniformily). The function store at the table the second position allocated,
** that represents the beginning of the real string. On error, return -1.
**
*/
int 
lua_findconstant (
char 
*s)
{
 
int 
i;
 
for 
(i=0; i<lua_nconstant; i++)
  
if 
(streq(s,lua_constant[i]))
   
return 
i;
 
if 
(lua_nconstant >= MAXCONSTANT-1)
 
{
  
lua_error (
"lua: constant string table overflow"
);
  
return 
-1;
 
}
 
{
  
char 
*c = 
calloc
(
strlen
(s)+2,
sizeof
(
char
));
  
c++; 
/* create mark space */
  
lua_constant[lua_nconstant++] = 
strcpy
(c,s);
 
}
 
return 
(lua_nconstant-1);
}

和上面的操作差不多,没有上面的复杂。上面的针对的是长的字符串(字符串中的特殊符号的,例如字符串的有单引号或双引号的),下面的针对的是短字符串。由于 Lua1.0 的词法分析和语法分析都没有源文件,暂时这么认为。到以后的版本中再看类似的问题。

1
2
3
4
5
6
7
8
9
10
/*
** Mark an object if it is a string or a unmarked array.
*/
void 
lua_markobject (Object *o)
{
 
if 
(tag(o) == T_STRING)
  
lua_markstring (svalue(o)) = 1;
 
else 
if 
(tag(o) == T_ARRAY && markarray(avalue(o)) == 0)
   
lua_hashmark (avalue(o));
}

标记字符串或者数组,用以垃圾回收。

1
2
3
4
5
6
7
8
9
/*
** Mark all strings and arrays used by any object stored at symbol table.
*/
static 
void 
lua_marktable (
void
)
{
 
int 
i;
 
for 
(i=0; i<lua_ntable; i++)
  
lua_markobject (&s_object(i));
}

标记字符串,数组及在符号数组中的 Object.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/*
** Simulate a garbage colection. When string table or array table overflows,
** this function check if all allocated strings and arrays are in use. If
** there are unused ones, pack (compress) the tables.
*/
static 
void 
lua_pack (
void
)
{
 
lua_markstack ();
 
lua_marktable ();
  
 
/* pack string */
  
int 
i, j;
  
for 
(i=j=0; i<lua_nstring; i++)
   
if 
(lua_markstring(lua_string[i]) == 1)
   
{
    
lua_string[j++] = lua_string[i];
    
lua_markstring(lua_string[i]) = 0;
   
}
   
else
   
{
    
free 
(lua_string[i]-1);
   
}
  
lua_nstring = j;
 
}
/* pack array */
  
int 
i, j;
  
for 
(i=j=0; i<lua_narray; i++)
   
if 
(markarray(lua_array[i]) == 1)
   
{
    
lua_array[j++] = lua_array[i];
    
markarray(lua_array[i]) = 0;
   
}
   
else
   
{
    
lua_hashdelete (lua_array[i]);
   
}
  
lua_narray = j;
 
}
}

垃圾回收,当新建字符串或者数组时,如果内存溢出,就会被调到。如果字符串或者数组有没有用到的,释放它。

标记 stack 上所有的 object

标记 table

压缩字符串数组

压缩数组。

lua_createstring

lua_createarray

lua_addfile

注释的比较清楚,不再细说。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/*
** Internal function: return next global variable
*/
void 
lua_nextvar (
void
)
{
 
int 
index;
 
Object *o = lua_getparam (1);
 
if 
(o == NULL)
 
{ lua_error (
"too few arguments to function `nextvar'"
); 
return
; }
 
if 
(lua_getparam (2) != NULL)
 
{ lua_error (
"too many arguments to function `nextvar'"
); 
return
; }
 
if 
(tag(o) == T_NIL)
 
{
  
index = 0;
 
}
 
else 
if 
(tag(o) != T_STRING)
 
{
  
lua_error (
"incorrect argument to function `nextvar'"
);
  
return
;
 
}
 
else
 
{
  
for 
(index=0; index<lua_ntable; index++)
   
if 
(streq(s_name(index),svalue(o))) 
break
;
  
if 
(index == lua_ntable)
  
{
   
lua_error (
"name not found in function `nextvar'"
);
   
return
;
  
}
  
index++;
  
while 
(index < lua_ntable-1 && tag(&s_object(index)) == T_NIL) index++;
  
if 
(index == lua_ntable-1)
  
{
   
lua_pushnil();
   
lua_pushnil();
   
return
;
  
}
 
}
 
{
  
Object name;
  
tag(&name) = T_STRING;
  
svalue(&name) = lua_createstring(lua_strdup(s_name(index)));
  
if 
(lua_pushobject (&name)) 
return
;
  
if 
(lua_pushobject (&s_object(index))) 
return
;
 
}
}

获得下一个全局变量。

必须传入一个参数,但参数可以为空,如果参数为空,则返回第一个全局变量。

参数的类型必须为字符串型。

在全局表中查找给定的字符串,如果没找到,返回错误。如果找到,则在全局变量中找它后面第一个不为空的全局变量。

 

转载于:https://www.cnblogs.com/vd01/p/4934394.html

你可能感兴趣的文章
HUE 忘记密码
查看>>
Eclipse 调试总进入Spring代理的解决办法
查看>>
【转载】Java的内存泄露
查看>>
singleton 单例模式
查看>>
JS实现图片''推拉门''效果
查看>>
PrintWriter类
查看>>
SpringMVC关于Date类型的时间根据格式显示页面上
查看>>
sql 将查询结果为多行一列合并为一行一列
查看>>
Error: couldn't connect to server 127.0.0.1:27017 src/mongo/shell/mongo.js:91
查看>>
poj 1704 阶梯博弈
查看>>
Sharepoint 2013 开启App和配置App
查看>>
2018ICPC区域赛总结
查看>>
解决Sublime There are no packages available for installation问题
查看>>
nginx反向代理 强制https请求 + 非root用户起80,443端口
查看>>
软件工程网络15个人阅读作业1(201521123049 杨泽斌)
查看>>
java 删除多层文件夹
查看>>
css中字符换行的一些问题
查看>>
oracle查询优化之子查询条件优化
查看>>
函数声明和函数表达式
查看>>
Python代码的编译
查看>>