# HG changeset patch # User jbe # Date 1408509198 -7200 # Node ID a95fbd16473fc2632711c86830fcbe15b094e941 # Parent 03ed3361f3327ed0b429e8ccf89bc73e618e348e Removed unnecessary creation of closures for callable values (through __call) diff -r 03ed3361f332 -r a95fbd16473f README --- a/README Wed Aug 20 06:08:03 2014 +0200 +++ b/README Wed Aug 20 06:33:18 2014 +0200 @@ -171,15 +171,11 @@ printcsv(assert(io.open("testfile")):lines()) -- prints: line1,line2,... of "testfile" -NOTE: ``seqlua_iterinit`` will store one extra element on the stack during -iteration. When ``seqlua_iternext`` returns 0, this extra element is popped -from the stack automatically. - Additionally, ``seqlualib`` includes a function ``seqlua_iterclosure(L, idx)``, which converts a table at a given stack index into a function closure (stored on the same stack index) that iterates over the elements of the table. If the -value at the given stack index is already a function, it leaves the value -unchanged. If the value is convertible to a function using ``__call,`` then the -value is replaced by a closure calling the ``__call`` metamethod. +value at the given stack index is already a function (or if it is callable +through a ``__call`` metamethod), then ``seqlua_iterclosure(L, idx)`` leaves +the value at ``idx`` unchanged. diff -r 03ed3361f332 -r a95fbd16473f seqlua.c --- a/seqlua.c Wed Aug 20 06:08:03 2014 +0200 +++ b/seqlua.c Wed Aug 20 06:33:18 2014 +0200 @@ -1,13 +1,6 @@ #include #include -static int seqlua_aux_call(lua_State *L) { // TODO: avoid - lua_pushvalue(L, lua_upvalueindex(1)); - lua_pushvalue(L, lua_upvalueindex(2)); - lua_call(L, 1, 1); - return 1; -} - static int seqlua_ipairsaux_raw(lua_State *L) { lua_Integer i; luaL_checktype(L, 1, LUA_TTABLE); @@ -27,7 +20,7 @@ } static int seqlua_ipairsaux_func(lua_State *L) { - luaL_checktype(L, 1, LUA_TFUNCTION); + //luaL_checktype(L, 1, LUA_TFUNCTION); lua_pushinteger(L, luaL_checkinteger(L, 2) + 1); lua_insert(L, 1); lua_settop(L, 2); @@ -74,10 +67,7 @@ } lua_pushcfunction(L, seqlua_ipairsaux_func); } else if (luaL_getmetafield(L, 1, "__call")) { - if (lua_type(L, -1) != LUA_TFUNCTION) luaL_error(L, "__call is not a function"); - lua_pushvalue(L, 1); - lua_pushcclosure(L, seqlua_aux_call, 2); - lua_replace(L, 1); + lua_pop(L, 1); goto seqlua_ipairs_function; } else if (luaL_getmetafield(L, 1, "__index")) { lua_pushcfunction(L, seqlua_ipairsaux_meta); @@ -135,10 +125,7 @@ lua_pushcclosure(L, seqlua_iteratoraux_triplet, 3); } } else if (luaL_getmetafield(L, 1, "__call")) { - if (lua_type(L, -1) != LUA_TFUNCTION) luaL_error(L, "__call is not a function"); - lua_pushvalue(L, 1); - lua_pushcclosure(L, seqlua_aux_call, 2); - lua_replace(L, 1); + lua_pop(L, 1); goto seqlua_iterator_function; } else if (luaL_getmetafield(L, 1, "__index")) { lua_pushvalue(L, 1); diff -r 03ed3361f332 -r a95fbd16473f seqlualib.c --- a/seqlualib.c Wed Aug 20 06:08:03 2014 +0200 +++ b/seqlualib.c Wed Aug 20 06:33:18 2014 +0200 @@ -2,33 +2,25 @@ #include #include "seqlualib.h" -#define SEQLUA_ITERTYPE_CALL 1 -#define SEQLUA_ITERTYPE_FUNC 2 -#define SEQLUA_ITERTYPE_META 3 -#define SEQLUA_ITERTYPE_RAW 4 +#define SEQLUA_ITERTYPE_FUNC 1 +#define SEQLUA_ITERTYPE_META 2 +#define SEQLUA_ITERTYPE_RAW 3 void seqlua_iterinit(lua_State *L, seqlua_Iterator *iter, int idx) { luaL_checkany(L, idx); // provides better error message iter->L = L; - if (luaL_getmetafield(L, idx, "__call")) { - if (lua_type(L, -1) != LUA_TFUNCTION) luaL_error(L, "__call is not a function"); - iter->idx = lua_gettop(L); - iter->callargidx = idx; - iter->itertype = SEQLUA_ITERTYPE_CALL; - } else if (lua_type(L, idx) == LUA_TFUNCTION) { - lua_pushnil(L); // dummy value - iter->idx = idx; + iter->idx = idx; + if (lua_type(L, idx) == LUA_TFUNCTION) { iter->itertype = SEQLUA_ITERTYPE_FUNC; + } else if (luaL_getmetafield(L, idx, "__call")) { + lua_pop(L, 1); + iter->itertype = SEQLUA_ITERTYPE_FUNC; + } else if (luaL_getmetafield(L, idx, "__index")) { + lua_pop(L, 1); + iter->itertype = SEQLUA_ITERTYPE_META; } else { - iter->idx = idx; - if (luaL_getmetafield(L, idx, "__index")) { - iter->itertype = SEQLUA_ITERTYPE_META; - // leave __index as dummy value - } else { - lua_pushnil(L); // dummy value - luaL_checktype(L, idx, LUA_TTABLE); - iter->itertype = SEQLUA_ITERTYPE_RAW; - } + luaL_checktype(L, idx, LUA_TTABLE); + iter->itertype = SEQLUA_ITERTYPE_RAW; } iter->i = 0; } @@ -37,11 +29,6 @@ lua_State *L = iter->L; lua_Integer i = ++iter->i; switch (iter->itertype) { - case SEQLUA_ITERTYPE_CALL: - lua_pushvalue(L, iter->idx); - lua_pushvalue(L, iter->callargidx); - lua_call(L, 1, 1); - break; case SEQLUA_ITERTYPE_FUNC: lua_pushvalue(L, iter->idx); lua_call(L, 0, 1); @@ -55,7 +42,7 @@ break; } if (lua_isnil(L, -1)) { - lua_pop(L, 2); // remove nil and dummy value + lua_pop(L, 1); return 0; } return 1; @@ -80,22 +67,12 @@ return 1; } -static int seqlua_iterclosureaux_call(lua_State *L) { - lua_pushvalue(L, lua_upvalueindex(1)); - lua_pushvalue(L, lua_upvalueindex(2)); - lua_call(L, 1, 1); - return 1; -} - void seqlua_iterclosure(lua_State *L, int idx) { luaL_checkany(L, idx); // provides better error message if (lua_type(L, idx) == LUA_TFUNCTION) { // do nothing } else if (luaL_getmetafield(L, idx, "__call")) { - if (lua_type(L, -1) != LUA_TFUNCTION) luaL_error(L, "__call is not a function"); - lua_pushvalue(L, idx); - lua_pushcclosure(L, seqlua_iterclosureaux_call, 2); - lua_replace(L, idx); + lua_pop(L, 1); } else if (luaL_getmetafield(L, idx, "__index")) { lua_pop(L, 1); lua_pushvalue(L, idx); diff -r 03ed3361f332 -r a95fbd16473f seqlualib.h --- a/seqlualib.h Wed Aug 20 06:08:03 2014 +0200 +++ b/seqlualib.h Wed Aug 20 06:33:18 2014 +0200 @@ -4,7 +4,6 @@ typedef struct { lua_State *L; int idx; - int callargidx; int itertype; lua_Integer i; } seqlua_Iterator;