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);
     4.1 --- a/seqlualib.h	Wed Aug 20 06:08:03 2014 +0200
     4.2 +++ b/seqlualib.h	Wed Aug 20 06:33:18 2014 +0200
     4.3 @@ -4,7 +4,6 @@
     4.4  typedef struct {
     4.5    lua_State *L;
     4.6    int idx;
     4.7 -  int callargidx;
     4.8    int itertype;
     4.9    lua_Integer i;
    4.10  } seqlua_Iterator;

Impressum / About Us