lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Mon, 03 Aug 2009 09:52:22 +0300, Juris Kalnins <juris@mt.lv> wrote:

Lua has a rather obscure feature, C function environment, which in case of lua_cpcall is initialized from the environment of currently active function. If lua_cpcall is changed to look like the code below (which doesn't use function pointer casts and thus is still ANSI C in this regard), it has perfomance comparable to lua_pcall, and is even a little faster than lua_pcall if two lines marked with /**/ are removed. However, LUA_ENVIRONINDEX behaves differently than with the original. The question is how much trouble this difference can cause in practice, i.e. how widely is LUA_ENVIRONINDEX used by existing libraries?


==== the code below ====

LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) {
  struct CallS c;
  int status;
  TValue *o;
  lua_lock(L);
o = index2adr(L, LUA_REFAUXCPC); /* Load address of one per global_State CClosure object, used as a temporary */
  setobj2s(L, L->top, o);
  api_incr_top(L);
  setpvalue(L->top, ud);  /* push only argument */
  api_incr_top(L);

  clvalue(o)->c.f = func;

  /* Is this good enough approximation of original behaviour? */
  /**/ clvalue(o)->c.env = getcurrenv(L);
  /**/ luaC_objbarrier(L, gcvalue(o), clvalue(o)->c.env);

  c.func = L->top - 2;  /* function to be called */
  c.nresults = 0;
  status = luaD_pcall(L, f_call, &c, savestack(L, c.func), 0);
  lua_unlock(L);
  return status;
}