seqlua
changeset 15:a95fbd16473f
Removed unnecessary creation of closures for callable values (through __call)
author | jbe |
---|---|
date | Wed Aug 20 06:33:18 2014 +0200 (2014-08-20) |
parents | 03ed3361f332 |
children | 040a0ca089c1 |
files | README seqlua.c seqlualib.c seqlualib.h |
line diff
1.1 --- a/README Wed Aug 20 06:08:03 2014 +0200 1.2 +++ b/README Wed Aug 20 06:33:18 2014 +0200 1.3 @@ -171,15 +171,11 @@ 1.4 printcsv(assert(io.open("testfile")):lines()) 1.5 -- prints: line1,line2,... of "testfile" 1.6 1.7 -NOTE: ``seqlua_iterinit`` will store one extra element on the stack during 1.8 -iteration. When ``seqlua_iternext`` returns 0, this extra element is popped 1.9 -from the stack automatically. 1.10 - 1.11 Additionally, ``seqlualib`` includes a function ``seqlua_iterclosure(L, idx)``, 1.12 which converts a table at a given stack index into a function closure (stored 1.13 on the same stack index) that iterates over the elements of the table. If the 1.14 -value at the given stack index is already a function, it leaves the value 1.15 -unchanged. If the value is convertible to a function using ``__call,`` then the 1.16 -value is replaced by a closure calling the ``__call`` metamethod. 1.17 +value at the given stack index is already a function (or if it is callable 1.18 +through a ``__call`` metamethod), then ``seqlua_iterclosure(L, idx)`` leaves 1.19 +the value at ``idx`` unchanged. 1.20 1.21
2.1 --- a/seqlua.c Wed Aug 20 06:08:03 2014 +0200 2.2 +++ b/seqlua.c Wed Aug 20 06:33:18 2014 +0200 2.3 @@ -1,13 +1,6 @@ 2.4 #include <lua.h> 2.5 #include <lauxlib.h> 2.6 2.7 -static int seqlua_aux_call(lua_State *L) { // TODO: avoid 2.8 - lua_pushvalue(L, lua_upvalueindex(1)); 2.9 - lua_pushvalue(L, lua_upvalueindex(2)); 2.10 - lua_call(L, 1, 1); 2.11 - return 1; 2.12 -} 2.13 - 2.14 static int seqlua_ipairsaux_raw(lua_State *L) { 2.15 lua_Integer i; 2.16 luaL_checktype(L, 1, LUA_TTABLE); 2.17 @@ -27,7 +20,7 @@ 2.18 } 2.19 2.20 static int seqlua_ipairsaux_func(lua_State *L) { 2.21 - luaL_checktype(L, 1, LUA_TFUNCTION); 2.22 + //luaL_checktype(L, 1, LUA_TFUNCTION); 2.23 lua_pushinteger(L, luaL_checkinteger(L, 2) + 1); 2.24 lua_insert(L, 1); 2.25 lua_settop(L, 2); 2.26 @@ -74,10 +67,7 @@ 2.27 } 2.28 lua_pushcfunction(L, seqlua_ipairsaux_func); 2.29 } else if (luaL_getmetafield(L, 1, "__call")) { 2.30 - if (lua_type(L, -1) != LUA_TFUNCTION) luaL_error(L, "__call is not a function"); 2.31 - lua_pushvalue(L, 1); 2.32 - lua_pushcclosure(L, seqlua_aux_call, 2); 2.33 - lua_replace(L, 1); 2.34 + lua_pop(L, 1); 2.35 goto seqlua_ipairs_function; 2.36 } else if (luaL_getmetafield(L, 1, "__index")) { 2.37 lua_pushcfunction(L, seqlua_ipairsaux_meta); 2.38 @@ -135,10 +125,7 @@ 2.39 lua_pushcclosure(L, seqlua_iteratoraux_triplet, 3); 2.40 } 2.41 } else if (luaL_getmetafield(L, 1, "__call")) { 2.42 - if (lua_type(L, -1) != LUA_TFUNCTION) luaL_error(L, "__call is not a function"); 2.43 - lua_pushvalue(L, 1); 2.44 - lua_pushcclosure(L, seqlua_aux_call, 2); 2.45 - lua_replace(L, 1); 2.46 + lua_pop(L, 1); 2.47 goto seqlua_iterator_function; 2.48 } else if (luaL_getmetafield(L, 1, "__index")) { 2.49 lua_pushvalue(L, 1);
3.1 --- a/seqlualib.c Wed Aug 20 06:08:03 2014 +0200 3.2 +++ b/seqlualib.c Wed Aug 20 06:33:18 2014 +0200 3.3 @@ -2,33 +2,25 @@ 3.4 #include <lauxlib.h> 3.5 #include "seqlualib.h" 3.6 3.7 -#define SEQLUA_ITERTYPE_CALL 1 3.8 -#define SEQLUA_ITERTYPE_FUNC 2 3.9 -#define SEQLUA_ITERTYPE_META 3 3.10 -#define SEQLUA_ITERTYPE_RAW 4 3.11 +#define SEQLUA_ITERTYPE_FUNC 1 3.12 +#define SEQLUA_ITERTYPE_META 2 3.13 +#define SEQLUA_ITERTYPE_RAW 3 3.14 3.15 void seqlua_iterinit(lua_State *L, seqlua_Iterator *iter, int idx) { 3.16 luaL_checkany(L, idx); // provides better error message 3.17 iter->L = L; 3.18 - if (luaL_getmetafield(L, idx, "__call")) { 3.19 - if (lua_type(L, -1) != LUA_TFUNCTION) luaL_error(L, "__call is not a function"); 3.20 - iter->idx = lua_gettop(L); 3.21 - iter->callargidx = idx; 3.22 - iter->itertype = SEQLUA_ITERTYPE_CALL; 3.23 - } else if (lua_type(L, idx) == LUA_TFUNCTION) { 3.24 - lua_pushnil(L); // dummy value 3.25 - iter->idx = idx; 3.26 + iter->idx = idx; 3.27 + if (lua_type(L, idx) == LUA_TFUNCTION) { 3.28 iter->itertype = SEQLUA_ITERTYPE_FUNC; 3.29 + } else if (luaL_getmetafield(L, idx, "__call")) { 3.30 + lua_pop(L, 1); 3.31 + iter->itertype = SEQLUA_ITERTYPE_FUNC; 3.32 + } else if (luaL_getmetafield(L, idx, "__index")) { 3.33 + lua_pop(L, 1); 3.34 + iter->itertype = SEQLUA_ITERTYPE_META; 3.35 } else { 3.36 - iter->idx = idx; 3.37 - if (luaL_getmetafield(L, idx, "__index")) { 3.38 - iter->itertype = SEQLUA_ITERTYPE_META; 3.39 - // leave __index as dummy value 3.40 - } else { 3.41 - lua_pushnil(L); // dummy value 3.42 - luaL_checktype(L, idx, LUA_TTABLE); 3.43 - iter->itertype = SEQLUA_ITERTYPE_RAW; 3.44 - } 3.45 + luaL_checktype(L, idx, LUA_TTABLE); 3.46 + iter->itertype = SEQLUA_ITERTYPE_RAW; 3.47 } 3.48 iter->i = 0; 3.49 } 3.50 @@ -37,11 +29,6 @@ 3.51 lua_State *L = iter->L; 3.52 lua_Integer i = ++iter->i; 3.53 switch (iter->itertype) { 3.54 - case SEQLUA_ITERTYPE_CALL: 3.55 - lua_pushvalue(L, iter->idx); 3.56 - lua_pushvalue(L, iter->callargidx); 3.57 - lua_call(L, 1, 1); 3.58 - break; 3.59 case SEQLUA_ITERTYPE_FUNC: 3.60 lua_pushvalue(L, iter->idx); 3.61 lua_call(L, 0, 1); 3.62 @@ -55,7 +42,7 @@ 3.63 break; 3.64 } 3.65 if (lua_isnil(L, -1)) { 3.66 - lua_pop(L, 2); // remove nil and dummy value 3.67 + lua_pop(L, 1); 3.68 return 0; 3.69 } 3.70 return 1; 3.71 @@ -80,22 +67,12 @@ 3.72 return 1; 3.73 } 3.74 3.75 -static int seqlua_iterclosureaux_call(lua_State *L) { 3.76 - lua_pushvalue(L, lua_upvalueindex(1)); 3.77 - lua_pushvalue(L, lua_upvalueindex(2)); 3.78 - lua_call(L, 1, 1); 3.79 - return 1; 3.80 -} 3.81 - 3.82 void seqlua_iterclosure(lua_State *L, int idx) { 3.83 luaL_checkany(L, idx); // provides better error message 3.84 if (lua_type(L, idx) == LUA_TFUNCTION) { 3.85 // do nothing 3.86 } else if (luaL_getmetafield(L, idx, "__call")) { 3.87 - if (lua_type(L, -1) != LUA_TFUNCTION) luaL_error(L, "__call is not a function"); 3.88 - lua_pushvalue(L, idx); 3.89 - lua_pushcclosure(L, seqlua_iterclosureaux_call, 2); 3.90 - lua_replace(L, idx); 3.91 + lua_pop(L, 1); 3.92 } else if (luaL_getmetafield(L, idx, "__index")) { 3.93 lua_pop(L, 1); 3.94 lua_pushvalue(L, idx);