lua sample code analysis

Posted cutepig

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了lua sample code analysis相关的知识,希望对你有一定的参考价值。

What is a meta table

a meta table has a __name attr whose value is name of metatable
a meta table is stored in LUA_REGISTRYINDEX whose key is its name

Code analysis

Appl

DUMP_STACK(L);
/*{ "foo", "C:\jshe\codes\mylualib\test\../build/v100+x64+Debug/foo_vc100_64.
dll" }*/    
    //1. 创建元表,并将该元表指定给newArray函数新创建的userdata。在Lua中userdata也是以table的身份表现的。
    //这样在调用对象函数时,可以通过验证其metatable的名称来确定参数userdata是否合法。
    luaL_newmetatable(L,"myarray");
    lua_pushvalue(L,-1);

    /*
top=4
4/-1: type=table{__name='myarray', }
3/-2: type=table{__name='myarray', }    -->name it mt
2/-3: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
1/-4: type=string'foo'

    */
    
    //2. 为了实现面对对象的调用方式,需要将元表的__index字段指向自身,同时再将arraylib_m数组中的函数注册到
    //元表中,之后基于这些注册函数的调用就可以以面向对象的形式调用了。
    //lua_setfield在执行后会将栈顶的table弹出。
    lua_setfield(L, -2, "__index"); // mt.__index = mt

    /*
top=3
3/-1: type=table{__index={__index={__index={__index={__index=, __name=, }, __name='myarray', }, __name='myarray', }, __name='myarray', }, __name='myarray', }
2/-2: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
1/-3: type=string'foo'*/
    
    //将这些成员函数注册给元表,以保证Lua在寻找方法时可以定位。NULL参数表示将用栈顶的table代替第二个参数。
    luaL_register(L, NULL, arraylib_m);

    //这里只注册的工厂方法。
    luaL_register(L,"testuserdata",arraylib_f);

    DUMP_STACK(L);
/*{ "foo", "C:\jshe\codes\mylualib\test\../build/v100+x64+Debug/foo_vc100_64.
dll", <1>{
    __gc = <function 1>,
    __index = <table 1>,
    __name = "myarray",
    __tostring = <function 2>,
    get = <function 3>,
    set = <function 4>,
    size = <function 5>
  }, {
    new = <function 6>
  } }
*/
    luaL_register(L,"testuserdatafm",arraylib_f_and_m);

    DUMP_STACK(L);
/*{ "foo", "C:\jshe\codes\mylualib\test\../build/v100+x64+Debug/foo_vc100_64.
dll", <1>{
    __gc = <function 1>,
    __index = <table 1>,
    __name = "myarray",
    __tostring = <function 2>,
    get = <function 3>,
    set = <function 4>,
    size = <function 5>
  }, {
    new = <function 6>
  }, {
    get = <function 3>,
    new = <function 6>,
    set = <function 4>,
    size = <function 5>,
    tostring = <function 2>
  } }*/
    luaopen_packet(L);
/*{ "foo", "C:\jshe\codes\mylualib\test\../build/v100+x64+Debug/foo_vc100_64.
dll", <1>{
    __gc = <function 1>,
    __index = <table 1>,
    __name = "myarray",
    __tostring = <function 2>,
    get = <function 3>,
    set = <function 4>,
    size = <function 5>
  }, {
    new = <function 6>
  }, {
    get = <function 3>,
    new = <function 6>,
    set = <function 4>,
    size = <function 5>,
    tostring = <function 2>
  }, {
    creatPacket = <function 7>
  } }
*/
    
    =========

luaL_newmetatable

LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
  if (luaL_getmetatable(L, tname) != LUA_TNIL)  /* name already in use? */  // top=1
    return 0;  /* leave previous value on top, but return 0 */
    /*top=3
3/-1: type=nil
2/-2: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
1/-3: type=string'foo'
*/
  lua_pop(L, 1);    // =0
  lua_createtable(L, 0, 2);  /* create metatable */ // =1
/*top=3
3/-1: type=table{}
2/-2: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
1/-3: type=string'foo'*/  
  lua_pushstring(L, tname); // =2
 /*top=4
4/-1: type=string'myarray'
3/-2: type=table{}
2/-3: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
1/-4: type=string'foo'*/ 
  lua_setfield(L, -2, "__name");  /* metatable.__name = tname */    // =1
  /*top=3
3/-1: type=table{'myarray', }
2/-2: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
1/-3: type=string'foo'*/
  lua_pushvalue(L, -1); // =2
    /*top=4
4/-1: type=table{__name='myarray', }
3/-2: type=table{__name='myarray', }
2/-3: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
1/-4: type=string'foo'*/
  lua_setfield(L, LUA_REGISTRYINDEX, tname);  /* registry.name = metatable */
/*top=3
3/-1: type=table{__name='myarray', }
2/-2: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
1/-3: type=string'foo'*/  
  return 1;
}
    

EnumTableItem

void EnumTableItem(lua_State *L, int index, int nDepth)
{
/*top=4
4/-1: type=table{C:000007FEEF9610EB, }
3/-2: type=table{'myarray', {, , , , , , , }, C:000007FEEF961131, C:000007FEEF9611A9, C:000007FEEF961163, C:000007FEEF961113, C:000007FEEF96103C, }
2/-3: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
1/-4: type=string'foo'
*/
    int top = lua_gettop(L);

    lua_pushvalue(L, index);    // copy the variable to stack top // +1
    int it = lua_gettop(L);
    myprintf("{");
    lua_pushnil(L); 
    /*{----------8, NA, 0
top=6
6/-1: type=nil
5/-2: type=table{C:000007FEEF9610EB, }
4/-3: type=table{C:000007FEEF9610EB, }
3/-4: type=table{'myarray', {, , , , , , , }, C:000007FEEF961131, C:000007FEEF9611A9, C:000007FEEF961163, C:000007FEEF961113, C:000007FEEF96103C, }
2/-5: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
1/-6: type=string'foo'
*/
    // 2
    while (lua_next(L, it))         // If there is data, then top++, else top-- 
    {
/*top=7
7/-1: type=functionC:000007FEEF9610EB
6/-2: type=string'new'
5/-3: type=table{C:000007FEEF9610EB, }
4/-4: type=table{C:000007FEEF9610EB, }
3/-5: type=table{'myarray', {, , , , , , , }, C:000007FEEF961131, C:000007FEEF9611A9, C:000007FEEF961163, C:000007FEEF961113, C:000007FEEF96103C, }
2/-6: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
1/-7: type=string'foo'
*/  
        DumpItemEx(L, -1, nDepth+1);
        myprintf(", ");
        lua_pop(L, 1);
    }                       // 1
    myprintf("}");
    lua_pop(L, 1);          // 0
    int top2 = lua_gettop(L);
    assert(top==top2);
}
    
#define luaL_register(L,n,l) (luaL_openlib(L,(n),(l),0))

luaL_openlib

LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
                               const luaL_Reg *l, int nup) {
/*top=3
3/-1: type=table{__index={__index={__index={__index={__index=, __name=, }, __name='myarray', }, __name='myarray', }, __name='myarray', }, __name='myarray', }
2/-2: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
1/-3: type=string'foo'
*/                             
  luaL_checkversion(L);
  if (libname) {
    luaL_pushmodule(L, libname, libsize(l));  /* get/create library table */
    lua_insert(L, -(nup + 1));  /* move library table to below upvalues */
  }
  if (l)
    luaL_setfuncs(L, l, nup);
  else
    lua_pop(L, nup);  /* remove upvalues */
}

luaL_setfuncs

// This function fills the functions to a table
// the key function is
// lua_pushcclosure, lua_setfield
//
LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
/*top=3
3/-1: type=table{__index={__index={__index={__index={__index=, __name=, }, __name='myarray', }, __name='myarray', }, __name='myarray', }, __name='myarray', }
2/-2: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
1/-3: type=string'foo'
*/
  luaL_checkstack(L, nup, "too many upvalues");
  for (; l->name != NULL; l++) {  /* fill the table with given functions */
    int i;
    for (i = 0; i < nup; i++)  /* copy upvalues to the top */
      lua_pushvalue(L, -nup);
    lua_pushcclosure(L, l->func, nup);  /* closure with those upvalues */
/*top=4
4/-1: type=functionC:000007FED9A21131
3/-2: type=table{__index={__index={__index={__index={__index=, __name=, }, __name='myarray', }, __name='myarray', }, __name='myarray', }, __name='myarray', }
2/-3: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
1/-4: type=string'foo'
*/  
    lua_setfield(L, -(nup + 2), l->name);
/*top=3
3/-1: type=table{__index={__index={__index={__index={__index=, __name=, set=, }, __name='myarray', set=C:000007FED9A21131, }, __name='myarray', set=C:000007FED9A21131, }, __name='myarray', set=C:000007FED9A21131, }, __name='myarray', set=C:000007FED9A21131, }
2/-2: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
1/-3: type=string'foo'
*/  
  }
  lua_pop(L, nup);  /* remove upvalues */
  
/*top=3
3/-1: type=table{__index={__index={__index={__index={__index=, set=, __gc=, __tostring=, get=, size=, __name=, }, set=C:000007FED9A21131, __gc=C:000007FED9A21163, __tostring=C:000007FED9A211A9, get=C:000007FED9A2103C, size=C:000007FED9A21113, __name='myarray', }, set=C:000007FED9A21131, __gc=C:000007FED9A21163, __tostring=C:000007FED9A211A9, get=C:000007FED9A2103C, size=C:000007FED9A21113, __name='myarray', }, set=C:000007FED9A21131, __gc=C:000007FED9A21163, __tostring=C:000007FED9A211A9, get=C:000007FED9A2103C, size=C:000007FED9A21113, __name='myarray', }, set=C:000007FED9A21131, __gc=C:000007FED9A21163, __tostring=C:000007FED9A211A9, get=C:000007FED9A2103C, size=C:000007FED9A21113, __name='myarray', }
2/-2: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
1/-3: type=string'foo'
*/  
}

以上是关于lua sample code analysis的主要内容,如果未能解决你的问题,请参考以下文章

有啥理由不在生产版本中启用 CODE_ANALYSIS?

Top 40 Static Code Analysis Tools

Pure C static coding analysis tools

AOP spring source code analysis

Redis source code analysis

nodeJs source code analysis