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 }
函数的开始和最后,分别调了
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 ===> 1skynet_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.
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? 用意暂时不清楚