1
static
int
2 _init( struct snlua * l, struct skynet_context * ctx, const char * args, size_t sz) {
3 lua_State * L = l -> L;
4 l -> ctx = ctx;
5 lua_gc(L, LUA_GCSTOP, 0 );
6 lua_pushboolean(L, 1 ); /* signal for libraries to ignore env. vars. */
7 lua_setfield(L, LUA_REGISTRYINDEX, " LUA_NOENV " );
8 luaL_openlibs(L);
9 lua_pushlightuserdata(L, ctx);
10 lua_setfield(L, LUA_REGISTRYINDEX, " skynet_context " );
11 luaL_requiref(L, " skynet.codecache " , codecache , 0 );
12 lua_pop(L, 1 );
13
14 const char * path = optstring(ctx, " lua_path " , " ./lualib/?.lua;./lualib/?/init.lua " );
15 lua_pushstring(L, path);
16 lua_setglobal(L, " LUA_PATH " );
17 const char * cpath = optstring(ctx, " lua_cpath " , " ./luaclib/?.so " );
18 lua_pushstring(L, cpath);
19 lua_setglobal(L, " LUA_CPATH " );
20 const char * service = optstring(ctx, " luaservice " , " ./service/?.lua " );
21 lua_pushstring(L, service);
22 lua_setglobal(L, " LUA_SERVICE " );
23 const char * preload = skynet_command(ctx, " GETENV " , " preload " );
24 lua_pushstring(L, preload);
25 lua_setglobal(L, " LUA_PRELOAD " );
26
27 lua_pushcfunction(L, traceback);
28 assert(lua_gettop(L) == 1 );
29
30 const char * loader = optstring(ctx, " lualoader " , " ./lualib/loader.lua " );
31
32 int r = luaL_loadfile(L,loader);
33 if (r != LUA_OK) {
34 skynet_error(ctx, " Can't load %s : %s " , loader, lua_tostring(L, - 1 ));
35 _report_launcher_error(ctx);
36 return 1 ;
37 }
38 lua_pushlstring(L, args, sz);
39 r = lua_pcall(L, 1 , 0 , 1 );
40 if (r != LUA_OK) {
41 skynet_error(ctx, " lua loader error : %s " , lua_tostring(L, - 1 ));
42 _report_launcher_error(ctx);
43 return 1 ;
44 }
45 lua_settop(L, 0 );
46
47 lua_gc(L, LUA_GCRESTART, 0 );
48
49 return 0 ;
50 }
2 _init( struct snlua * l, struct skynet_context * ctx, const char * args, size_t sz) {
3 lua_State * L = l -> L;
4 l -> ctx = ctx;
5 lua_gc(L, LUA_GCSTOP, 0 );
6 lua_pushboolean(L, 1 ); /* signal for libraries to ignore env. vars. */
7 lua_setfield(L, LUA_REGISTRYINDEX, " LUA_NOENV " );
8 luaL_openlibs(L);
9 lua_pushlightuserdata(L, ctx);
10 lua_setfield(L, LUA_REGISTRYINDEX, " skynet_context " );
11 luaL_requiref(L, " skynet.codecache " , codecache , 0 );
12 lua_pop(L, 1 );
13
14 const char * path = optstring(ctx, " lua_path " , " ./lualib/?.lua;./lualib/?/init.lua " );
15 lua_pushstring(L, path);
16 lua_setglobal(L, " LUA_PATH " );
17 const char * cpath = optstring(ctx, " lua_cpath " , " ./luaclib/?.so " );
18 lua_pushstring(L, cpath);
19 lua_setglobal(L, " LUA_CPATH " );
20 const char * service = optstring(ctx, " luaservice " , " ./service/?.lua " );
21 lua_pushstring(L, service);
22 lua_setglobal(L, " LUA_SERVICE " );
23 const char * preload = skynet_command(ctx, " GETENV " , " preload " );
24 lua_pushstring(L, preload);
25 lua_setglobal(L, " LUA_PRELOAD " );
26
27 lua_pushcfunction(L, traceback);
28 assert(lua_gettop(L) == 1 );
29
30 const char * loader = optstring(ctx, " lualoader " , " ./lualib/loader.lua " );
31
32 int r = luaL_loadfile(L,loader);
33 if (r != LUA_OK) {
34 skynet_error(ctx, " Can't load %s : %s " , loader, lua_tostring(L, - 1 ));
35 _report_launcher_error(ctx);
36 return 1 ;
37 }
38 lua_pushlstring(L, args, sz);
39 r = lua_pcall(L, 1 , 0 , 1 );
40 if (r != LUA_OK) {
41 skynet_error(ctx, " lua loader error : %s " , lua_tostring(L, - 1 ));
42 _report_launcher_error(ctx);
43 return 1 ;
44 }
45 lua_settop(L, 0 );
46
47 lua_gc(L, LUA_GCRESTART, 0 );
48
49 return 0 ;
50 }
函数的开始和最后,分别调了
lua_gc(L, LUA_GCSTOP, 0 ); //停止GC 和 lua_gc(L, LUA_GCRESTART, 0 ); //重启GC
是为了保证在整个 service 执行逻辑期间中途不会被 gc?
lua_pushboolean(L, 1 ); /* signal for libraries to ignore env. vars. */
lua_setfield(L, LUA_REGISTRYINDEX, " LUA_NOENV " );
lua_pushlightuserdata(L, ctx);
lua_setfield(L, LUA_REGISTRYINDEX, "skynet_context");
这四句可以参考 这篇BLOG的上半部份, 就是把一些数据放到 lua 的状态机( lua_State)中
"LUA_NOENV" 和 "skynet_context" 分别是 key
LUA_NOENV ===> 1
skynet_context ===> ctx
在其它地方获取的代码
lua_getfield(L, LUA_REGISTRYINDEX, "skynet_context");
struct skynet_context *ctx = lua_touserdata(L,-1);
if (ctx == NULL) {
return luaL_error(L, "Init skynet context first");
}
在 \lualib-src\lua-skynet.c 和 \lualib-src\lua-socket.c 可以找到
至于 "LUA_NOENV"是否是lua的内部变量,这里告诉lua不使用环境变量?
luaL_openlibs(L); // 载入所有lua标准库
luaL_requiref(L, " skynet.codecache " , codecache , 0 );
lua_pop(L, 1 );
在lua中调用C的函数,lua提供了一种方法,是 这样的, 但是呢, 也可以 这样来用
lua_pop(L,1); 这句未知意图,难道是调用 luaL_requiref() 后需要 pop ?
14 const char * path = optstring(ctx, " lua_path " , " ./lualib/?.lua;./lualib/?/init.lua " );
15 lua_pushstring(L, path);
16 lua_setglobal(L, " LUA_PATH " );
17 const char * cpath = optstring(ctx, " lua_cpath " , " ./luaclib/?.so " );
18 lua_pushstring(L, cpath);
19 lua_setglobal(L, " LUA_CPATH " );
20 const char * service = optstring(ctx, " luaservice " , " ./service/?.lua " );
21 lua_pushstring(L, service);
22 lua_setglobal(L, " LUA_SERVICE " );
23 const char * preload = skynet_command(ctx, " GETENV " , " preload " );
24 lua_pushstring(L, preload);
25 lua_setglobal(L, " LUA_PRELOAD " );
void lua_setglobal (lua_State *L, const char *name);
Pops a value from the stack and sets it as the new value of global name
.
大概意思,从堆栈弹出一个值,设置到全局的 name 里去
LUA_API
void
lua_setglobal (lua_State
*
L,
const
char
*
var) {
Table * reg = hvalue( & G(L) -> l_registry);
const TValue * gt; /* global table */
lua_lock(L);
api_checknelems(L, 1 );
gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
setsvalue2s(L, L -> top ++ , luaS_new(L, var));
luaV_settable(L, gt, L -> top - 1 , L -> top - 2 );
L -> top -= 2 ; /* pop value and key */
lua_unlock(L);
}
LUA_API void lua_setfield (lua_State * L, int idx, const char * k) {
StkId t;
lua_lock(L);
api_checknelems(L, 1 );
t = index2addr(L, idx);
setsvalue2s(L, L -> top ++ , luaS_new(L, k));
luaV_settable(L, t, L -> top - 1 , L -> top - 2 );
L -> top -= 2 ; /* pop value and key */
lua_unlock(L);
}
lua_setfield
[ - 1 , + 0 , e]
void lua_setfield (lua_State * L, int index, const char * k);
Does the equivalent to t[k] = v, where t is the value at the given index and v is the value at the top of the stack.
This function pops the value from the stack. As in Lua, this function may trigger a metamethod for the " newindex " event (see § 2.4 )
lua_setglobal
[ - 1 , + 0 , e]
void lua_setglobal (lua_State * L, const char * name);
Pops a value from the stack and sets it as the new value of global name.
Table * reg = hvalue( & G(L) -> l_registry);
const TValue * gt; /* global table */
lua_lock(L);
api_checknelems(L, 1 );
gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
setsvalue2s(L, L -> top ++ , luaS_new(L, var));
luaV_settable(L, gt, L -> top - 1 , L -> top - 2 );
L -> top -= 2 ; /* pop value and key */
lua_unlock(L);
}
LUA_API void lua_setfield (lua_State * L, int idx, const char * k) {
StkId t;
lua_lock(L);
api_checknelems(L, 1 );
t = index2addr(L, idx);
setsvalue2s(L, L -> top ++ , luaS_new(L, k));
luaV_settable(L, t, L -> top - 1 , L -> top - 2 );
L -> top -= 2 ; /* pop value and key */
lua_unlock(L);
}
lua_setfield
[ - 1 , + 0 , e]
void lua_setfield (lua_State * L, int index, const char * k);
Does the equivalent to t[k] = v, where t is the value at the given index and v is the value at the top of the stack.
This function pops the value from the stack. As in Lua, this function may trigger a metamethod for the " newindex " event (see § 2.4 )
lua_setglobal
[ - 1 , + 0 , e]
void lua_setglobal (lua_State * L, const char * name);
Pops a value from the stack and sets it as the new value of global name.
lua_setfield 和 lua_setglobal 从源码上看, lua_setglobal实际上也是调用 lua_setfield 放到一个 LUA_RIDX_GLOBALS 的表里而已
27 lua_pushcfunction(L, traceback);
28 assert(lua_gettop(L) == 1 );
这两句将一个C函数push到堆栈?然后 lua_gettop() 判断下? 这里为何没有 pop? 用意暂时不清楚