_init() 函数分析 (一) 2014.11.04

 1  static   int
 2  _init( struct  snlua  * l,  struct  skynet_context  * ctx,  const   char   *  args, size_t sz) {
 3      lua_State  * =  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. 


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? 用意暂时不清楚

你可能感兴趣的:(_init() 函数分析 (一) 2014.11.04)