├── Makefile ├── tablepointer.c └── test.lua /Makefile: -------------------------------------------------------------------------------- 1 | tablepointer.dll : tablepointer.c 2 | gcc -Wall --shared -o $@ $^ -I/d/project/lua/src -L/usr/local/bin -llua53 3 | 4 | clean: 5 | rm *.dll 6 | -------------------------------------------------------------------------------- /tablepointer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "lapi.h" 4 | #include "ltable.h" 5 | 6 | /* 7 | table 8 | return pointer 9 | */ 10 | static int 11 | ltopointer(lua_State *L) { 12 | luaL_checktype(L, 1, LUA_TTABLE); 13 | const void * t = lua_topointer(L, 1); 14 | lua_pushlightuserdata(L, (void *)t); 15 | return 1; 16 | } 17 | 18 | /* 19 | pointer 20 | return table 21 | */ 22 | static int 23 | lcreatetable(lua_State *L) { 24 | luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); 25 | Table *t = lua_touserdata(L, 1); 26 | int narr = t->sizearray; 27 | int nrec = 1 << t->lsizenode; 28 | lua_createtable(L, narr, nrec); 29 | return 1; 30 | } 31 | 32 | static int 33 | array_next(const Table *t, int index) { 34 | while(t->sizearray > index) { 35 | if (!ttisnil(&t->array[index++])) { 36 | return index; 37 | } 38 | } 39 | return 0; 40 | } 41 | 42 | static int 43 | hash_next(const Table *t, int index) { 44 | index = -index; 45 | int nrec = 1 << t->lsizenode; 46 | while(nrec > index) { 47 | if (!ttisnil(gval(gnode(t, index++)))) { 48 | return -index; 49 | } 50 | } 51 | return 0; 52 | } 53 | 54 | static void 55 | pushvalue(lua_State *L, const TValue *v) { 56 | int t = ttnov(v); 57 | if (!iscollectable(v)) { 58 | if (t == LUA_TLIGHTUSERDATA) { 59 | luaL_error(L, "Don't support lightuserdata"); 60 | } 61 | lua_lock(L); 62 | setobj2s(L, L->top, v); 63 | api_incr_top(L); 64 | lua_unlock(L); 65 | return; 66 | } 67 | switch (t) { 68 | case LUA_TTABLE: 69 | lua_pushlightuserdata(L, hvalue(v)); 70 | break; 71 | case LUA_TSTRING: 72 | lua_pushlstring(L, svalue(v), vslen(v)); 73 | break; 74 | default: 75 | luaL_error(L, "Don't support %s", lua_typename(L, t)); 76 | } 77 | } 78 | 79 | /* 80 | pointer 81 | index 0:start 1:array part -1:hash part 82 | 83 | return index, key, value 84 | */ 85 | static int 86 | literator(lua_State *L) { 87 | luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); 88 | Table *t = lua_touserdata(L, 1); 89 | int index = luaL_checkinteger(L, 2); 90 | if (index >= 0) { 91 | if (t->sizearray > 0) { 92 | index = array_next(t, index); 93 | if (index != 0) { 94 | lua_pushinteger(L, index); 95 | lua_pushinteger(L, index); 96 | pushvalue(L, &t->array[index-1]); 97 | return 3; 98 | } 99 | } 100 | } 101 | index = hash_next(t, index); 102 | if (index != 0) { 103 | Node *n = gnode(t, -index-1); 104 | lua_pushinteger(L, index); 105 | pushvalue(L, gkey(n)); 106 | pushvalue(L, gval(n)); 107 | return 3; 108 | } 109 | return 0; 110 | } 111 | 112 | /* 113 | pointer table 114 | return function iterator, pointer, 0 115 | */ 116 | static int 117 | lpairs(lua_State *L) { 118 | luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); 119 | lua_pushcfunction(L, literator); 120 | lua_pushvalue(L,1); 121 | lua_pushinteger(L, 0); 122 | 123 | return 3; 124 | } 125 | 126 | int 127 | luaopen_tablepointer(lua_State *L) { 128 | luaL_checkversion(L); 129 | luaL_Reg l[] = { 130 | { "topointer", ltopointer }, 131 | { "createtable", lcreatetable }, 132 | { "pairs", lpairs }, 133 | { NULL, NULL }, 134 | }; 135 | luaL_newlib(L,l); 136 | return 1; 137 | } 138 | -------------------------------------------------------------------------------- /test.lua: -------------------------------------------------------------------------------- 1 | local tptr = require "tablepointer" 2 | 3 | local sub = { 1,2,3,4 } 4 | local a = { true, false, nil,2,3, a= sub, b= "hello", c = { a = 1 } } 5 | local p = tptr.topointer(a) 6 | tptr.createtable(p) 7 | 8 | for _,k,v in tptr.pairs(p) do 9 | print(k,v) 10 | if type(v) == "userdata" then 11 | for _,k,v in tptr.pairs(v) do 12 | print("\t", k, v) 13 | end 14 | end 15 | end 16 | --------------------------------------------------------------------------------