level 1
清源妙道二郎神
楼主
int main (int argc, char **argv) {
int status, result;
lua_State *L = luaL_newstate(); /* create state */
if (L == NULL) {
l_message(argv[0], "cannot create state: not enough memory");
return EXIT_FAILURE;
}
/* call 'pmain' in protected mode */
lua_pushcfunction(L, &pmain);
lua_pushinteger(L, argc); /* 1st argument */
lua_pushlightuserdata(L, argv); /* 2nd argument */
status = lua_pcall(L, 2, 1, 0);
result = lua_toboolean(L, -1); /* get result */
finalreport(L, status);
lua_close(L);
return (result && status == LUA_OK) ? EXIT_SUCCESS : EXIT_FAILURE;
}
根据lua在线手册对lua_pcall的描述: Calls a function in protected mode.
Both nargs and nresults have the same meaning as in lua_call. If there are no errors during the call, lua_pcall behaves exactly like lua_call. However, if there is any error, lua_pcall catches it, pushes a single value on the stack (the error message), and returns an error code. Like lua_call, lua_pcall always removes the function and its arguments from the stack.
If errfunc is 0, then the error message returned on the stack is exactly the original error message. Otherwise, errfunc is the stack index of an error handler function. (In the current implementation, this index cannot be a pseudo-index.) In case of runtime errors, this function will be called with the error message and its return value will be the message returned on the stack by lua_pcall.
Typically, the error handler function is used to add more debug information to the error message, such as a stack traceback. Such information cannot be gathered after the return of lua_pcall, since by then the stack has unwound.
The lua_pcall function returns 0 in case of success or one of the following error codes (defined in lua.h):
•LUA_ERRRUN: a runtime error.
•LUA_ERRMEM: memory allocation error. For such errors, Lua does not call the error handler function.
•LUA_ERRERR: error while running the error handler function.
得知lua_pcall是可以失败的,如失败返回错误代码并在栈上压入错误信息,可为什么lua.c中为什么不检查错误代码,不管对错的调用lua_toboolean来获取pmain的返回值? 然后再调用失败报告函数。平行的使用toboolean和tostring去访问栈-1处,5.2这么写代码的用意是什么? 与5.1不同呀。
static int pmain (lua_State *L) {
int argc = (int)lua_tointeger(L, 1);
char **argv = (char **)lua_touserdata(L, 2);
int script;
int args[num_has];
args[has_i] = args[has_v] = args[has_e] = args[has_E] = 0;
if (argv[0] && argv[0][0]) progname = argv[0];
script = collectargs(argv, args);
if (script < 0) { /* invalid arg? */
print_usage(argv[-script]);
return 0;
}
if (args[has_v]) print_version();
if (args[has_E]) { /* option '-E'? */
lua_pushboolean(L, 1); /* signal for libraries to ignore env. vars. */
lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
}
/* open standard libraries */
luaL_checkversion(L);
lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */
luaL_openlibs(L); /* open libraries */
lua_gc(L, LUA_GCRESTART, 0);
if (!args[has_E] && handle_luainit(L) != LUA_OK)
return 0; /* error running LUA_INIT */
/* execute arguments -e and -l */
if (!runargs(L, argv, (script > 0) ? script : argc)) return 0;
/* execute main script (if there is one) */
if (script && handle_script(L, argv, script) != LUA_OK) return 0;
if (args[has_i]) /* -i option? */
dotty(L);
else if (script == 0 && !args[has_e] && !args[has_v]) { /* no arguments? */
if (lua_stdin_is_tty()) {
print_version();
dotty(L);
}
else dofile(L, NULL); /* executes stdin as a file */
}
lua_pushboolean(L, 1); /* signal no errors */
return 1;
}
之前理解lua_CFunction型的函数,返回的是一个数量,而真正的返回值保存在栈上,可pmain的代码却是执行成功返回1个值,执行失败却没有返回值,那这让调用者多尴尬呀? main中还有toboolean在等着呢。 代码成功则压入true,失败则压入false,而pmain一直返回1,不是该这么理解吗? 看了5.2的lua.c我被颠覆了。还请前辈高人赐教,
正确的
理解。
2014年12月23日 16点12分
1
int status, result;
lua_State *L = luaL_newstate(); /* create state */
if (L == NULL) {
l_message(argv[0], "cannot create state: not enough memory");
return EXIT_FAILURE;
}
/* call 'pmain' in protected mode */
lua_pushcfunction(L, &pmain);
lua_pushinteger(L, argc); /* 1st argument */
lua_pushlightuserdata(L, argv); /* 2nd argument */
status = lua_pcall(L, 2, 1, 0);
result = lua_toboolean(L, -1); /* get result */
finalreport(L, status);
lua_close(L);
return (result && status == LUA_OK) ? EXIT_SUCCESS : EXIT_FAILURE;
}
根据lua在线手册对lua_pcall的描述: Calls a function in protected mode.
Both nargs and nresults have the same meaning as in lua_call. If there are no errors during the call, lua_pcall behaves exactly like lua_call. However, if there is any error, lua_pcall catches it, pushes a single value on the stack (the error message), and returns an error code. Like lua_call, lua_pcall always removes the function and its arguments from the stack.
If errfunc is 0, then the error message returned on the stack is exactly the original error message. Otherwise, errfunc is the stack index of an error handler function. (In the current implementation, this index cannot be a pseudo-index.) In case of runtime errors, this function will be called with the error message and its return value will be the message returned on the stack by lua_pcall.
Typically, the error handler function is used to add more debug information to the error message, such as a stack traceback. Such information cannot be gathered after the return of lua_pcall, since by then the stack has unwound.
The lua_pcall function returns 0 in case of success or one of the following error codes (defined in lua.h):
•LUA_ERRRUN: a runtime error.
•LUA_ERRMEM: memory allocation error. For such errors, Lua does not call the error handler function.
•LUA_ERRERR: error while running the error handler function.
得知lua_pcall是可以失败的,如失败返回错误代码并在栈上压入错误信息,可为什么lua.c中为什么不检查错误代码,不管对错的调用lua_toboolean来获取pmain的返回值? 然后再调用失败报告函数。平行的使用toboolean和tostring去访问栈-1处,5.2这么写代码的用意是什么? 与5.1不同呀。
static int pmain (lua_State *L) {
int argc = (int)lua_tointeger(L, 1);
char **argv = (char **)lua_touserdata(L, 2);
int script;
int args[num_has];
args[has_i] = args[has_v] = args[has_e] = args[has_E] = 0;
if (argv[0] && argv[0][0]) progname = argv[0];
script = collectargs(argv, args);
if (script < 0) { /* invalid arg? */
print_usage(argv[-script]);
return 0;
}
if (args[has_v]) print_version();
if (args[has_E]) { /* option '-E'? */
lua_pushboolean(L, 1); /* signal for libraries to ignore env. vars. */
lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
}
/* open standard libraries */
luaL_checkversion(L);
lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */
luaL_openlibs(L); /* open libraries */
lua_gc(L, LUA_GCRESTART, 0);
if (!args[has_E] && handle_luainit(L) != LUA_OK)
return 0; /* error running LUA_INIT */
/* execute arguments -e and -l */
if (!runargs(L, argv, (script > 0) ? script : argc)) return 0;
/* execute main script (if there is one) */
if (script && handle_script(L, argv, script) != LUA_OK) return 0;
if (args[has_i]) /* -i option? */
dotty(L);
else if (script == 0 && !args[has_e] && !args[has_v]) { /* no arguments? */
if (lua_stdin_is_tty()) {
print_version();
dotty(L);
}
else dofile(L, NULL); /* executes stdin as a file */
}
lua_pushboolean(L, 1); /* signal no errors */
return 1;
}
之前理解lua_CFunction型的函数,返回的是一个数量,而真正的返回值保存在栈上,可pmain的代码却是执行成功返回1个值,执行失败却没有返回值,那这让调用者多尴尬呀? main中还有toboolean在等着呢。 代码成功则压入true,失败则压入false,而pmain一直返回1,不是该这么理解吗? 看了5.2的lua.c我被颠覆了。还请前辈高人赐教,
正确的
理解。