?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? 用意暫時不清楚