转载出处:http://my.oschina.net/xhan/blog/308557
opcode.c 代码分析 Lua1.0 虚拟机的实现,语法分析中生成的字节码交给它 lua_execute 来执行。
这个文件的主要部分就是 lua_execute 函数,而它就是很大的 switch case,Lua1.0 中定义的字节码有多少种,这里就有多少个相对应的 case 语句。这个函数不再详细分析,因为 Lua1.0 生成的字节码在不好打印出来,或者在调试的时候能打印出来,但很不好看。到 Lua1.1 里就有比较好看的字节码的输出格式,到时候,看下输出的字节码就清楚多了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
/*
** Concatenate two given string, creating a mark space at the beginning.
** Return the new string pointer.
*/
static
char
*lua_strconc (
char
*l,
char
*r)
{
char
*s =
calloc
(
strlen
(l)+
strlen
(r)+2,
sizeof
(
char
));
if
(s == NULL)
{
lua_error (
"not enough memory"
);
return
NULL;
}
*s++ = 0;
/* create mark space */
return
strcat
(
strcpy
(s,l),r);
}
|
连接两个字符串,在开头空出一个标记位。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
/*
** Duplicate a string, creating a mark space at the beginning.
** Return the new string pointer.
*/
char
*lua_strdup (
char
*l)
{
char
*s =
calloc
(
strlen
(l)+2,
sizeof
(
char
));
if
(s == NULL)
{
lua_error (
"not enough memory"
);
return
NULL;
}
*s++ = 0;
/* create mark space */
return
strcpy
(s,l);
}
|
拷贝字符串,开头空一个标记位。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
/*
** Convert, if possible, to a number tag.
** Return 0 in success or not 0 on error.
*/
static
int
lua_tonumber (Object *obj)
{
char
*ptr;
if
(tag(obj) != T_STRING)
{
lua_reportbug (
"unexpected type at conversion to number"
);
return
1;
}
nvalue(obj) =
strtod
(svalue(obj), &ptr);
if
(*ptr)
{
lua_reportbug (
"string to number convertion failed"
);
return
2;
}
tag(obj) = T_NUMBER;
return
0;
}
|
把 Object 转化为数值,这里只有字符串可以转化,转化后改变 Object 的类型标签和值。
如果成功,返回0,否则返回其它。
static Object *lua_convtonumber (Object *obj)
判断是否可以转化为数值型,如果可以,返回转化后的 Object, 如果不可以,返回空。
static int lua_tostring (Object *obj)
把 Object 转化为字符串类型,这里只有数值才可以转化,转化后改变 Object 的类型标签和值。
如果成功,返回0,否则返回其它。
void lua_markstack (void)
标记栈中所有的字符串和数组。
int lua_dofile (char *filename)
给定文件名,打开文件,语法分析(语法分析如果成功分析完成后,会 lua_execute 执行。
int lua_dostring (char *string)
和上面的差不多,只不过这里直接分析就是字符串。
int lua_call (char *functionname, int nparam)
给定函数名和参数个数,执行相应的字节码。
Object *lua_getparam (int number)
返回参数,如果要返回第一个参数则应传入1
real lua_getnumber (Object *object)
返回给定 Object 的数值,如果出错的话,返回 0.0 。
char *lua_getstring (Object *object)
和上面的类似,只不过这里返回的是字符串。
char *lua_copystring (Object *object)
和上面的类似,这里返回的是它的一个拷贝。
lua_CFunction lua_getcfunction (Object *object)
返回给定 Object 的 函数指针,如果出错,返回空。
void *lua_getuserdata (Object *object)
和上面的类似
Object *lua_getfield (Object *object, char *field)
给定数组和引用,返回相应的 Object.
Object *lua_getindexed (Object *object, float index)
同上,这里传入的是下标。
Object *lua_getglobal (char *name)
返回给定名字的全局对象,如果没有,返回空。
Object *lua_pop (void)
对象出栈
int lua_pushnil (void)
空对象笔记本
int lua_pushnumber (real n)
number 入栈
int lua_pushstring (char *s)
int lua_pushcfunction (lua_CFunction fn)
int lua_pushuserdata (void *u)
int lua_pushobject (Object *o)
int lua_storeglobal (char *name)
int lua_storefield (lua_Object object, char *field)
int lua_storeindexed (lua_Object object, float index)
和上面的差不多,除了类型不一样。和数据的传输方向不一样,这里是设置,上面是返回。
int lua_isnil (Object *object)
int lua_isnumber (Object *object)
int lua_isstring (Object *object)
int lua_istable (Object *object)
int lua_iscfunction (Object *object)
int lua_isuserdata (Object *object)
检查对象是否是指定的类型。
void lua_type (void)
返回对象的类型。
void lua_obj2number (void)
对象转化为数值。
void lua_print (void)
打印对象值。