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:\jshe\codes\mylualib\test\../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:\jshe\codes\mylualib\test\../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:\jshe\codes\mylualib\test\../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:\jshe\codes\mylualib\test\../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:\jshe\codes\mylualib\test\../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:\jshe\codes\mylualib\test\../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:\jshe\codes\mylualib\test\../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:\jshe\codes\mylualib\test\../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:\jshe\codes\mylualib\test\../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:\jshe\codes\mylualib\test\../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:\jshe\codes\mylualib\test\../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:\jshe\codes\mylualib\test\../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:\jshe\codes\mylualib\test\../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:\jshe\codes\mylualib\test\../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:\jshe\codes\mylualib\test\../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:\jshe\codes\mylualib\test\../build/v100+x64+Debug/foo_vc100_64.dll'
1/-3: type=string'foo'
*/
}

原文地址:https://www.cnblogs.com/cutepig/p/12268898.html

时间: 2024-08-29 21:33:14

lua sample code analysis的相关文章

如何将经纬度利用Google Map API显示C# VS2005 Sample Code

原文 如何将经纬度利用Google Map API显示C# VS2005 Sample Code 日前写了一篇如何用GPS抓取目前所在,并回传至资料库储存,这篇将会利用这些回报的资料,将它显示在地图上,这个做法有两种,最简单的就是直接传值到Google Maps上. 举例来说,当我们知道经纬度后,只要将数据套到以下网址即可. http://maps.google.com/maps?q=25.048346%2c121.516396 在参数q=后面,就可以加上经纬度了. 25.048346是Lati

Memcached source code analysis -- Analysis of change of state--reference

This article mainly introduces the process of Memcached, libevent structure of the main thread and worker thread based on the processing of the connection state of mutual conversion (not involving data access operations), the main business logic is t

Compilation of OpenGL Redbook sample code

http://download.csdn.net/detail/gflytu/4110817#comment [email protected]:~/Downloads/redbook$ gcc -lglut -lGL -lGLU aaindex.c aaindex.c:(.text+0x2f7): undefined reference to `glutInit'aaindex.c:(.text+0x303): undefined reference to `glutInitDisplayMo

Memcached source code analysis (threading model)--reference

Look under the start memcahced threading process memcached multi-threaded mainly by instantiating multiple libevent, are a main thread and n workers thread is the main thread or workers thread all through the the libevent management network event, in

CEPH CRUSH 算法源码分析 原文CEPH CRUSH algorithm source code analysis

原文地址 CEPH CRUSH algorithm source code analysis http://www.shalandis.com/original/2016/05/19/CEPH-CRUSH-algorithm-source-code-analysis/ 文章比较深入的写了CRUSH算法的原理和过程.通过调试深入的介绍了CRUSH计算的过程.文章中添加了些内容. 写在前面 读本文前,你需要对ceph的基本操作,pool和CRUSH map非常熟悉.并且较深入的读过源码. 分析的方法

十四、详述 IntelliJ IDEA 提交代码前的 Code Analysis 机制

在我们用 IntelliJ IDEA 向 SVN 或者 Git 提交代码的时候,IntelliJ IDEA 提供了一个自动分析代码的功能,即Perform code analysis: 如上图所示,当我们勾选Perform code analysis之后,点击commit,IntelliJ IDEA 就会在提交代码之前对项目的代码进行分析检查,并将检查结果以错误和警告的形式展示出来: 如上图所示,这是Code Analysis的结果示例,为No errors and 6 warnings. 如果

Top 40 Static Code Analysis Tools

https://www.softwaretestinghelp.com/tools/top-40-static-code-analysis-tools/ In this article, I have summarised some of the top static code analysis tools. Can we ever imagine sitting back and manually reading each line of codes to find flaws? To eas

AOP spring source code analysis

例子 1 在使用 New 的情况下实现 AOP public class TraceTest { public static void main(String args[]) { TraceTest test = new TraceTest(); test.rpcCall(); } // 虽然 intellij 没有给出提示,但是这个 Trace 还是成功的 @Trace public void rpcCall() { System.out.println("call rpc"); }

Golang Template source code analysis(Parse)

This blog was written at go 1.3.1 version. We know that we use template thought by followed way: func main() { name := "waynehu" tmpl := template.New("test") tmpl, err := tmpl.Parse("hello {{.}}") if err != nil { panic(err) }