lua-users home
lua-l archive

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


Quoth Rena <hyperhacker@gmail.com>, on 2012-04-24 01:00:22 -0600:
> Right now if you want to retrieve a field using the C API, it takes
> three lines per field:
> lua_getfield(L, index, "field name");
> lua_Integer val = lua_tointeger(L, -1);
> lua_pop(L, 1);

FWLIW, this isn't generally what I do if there are multiple fields
around (and indeed I tend not to use lua_pop at all, because it's easy
for it to get desynchronized with the surrounding code).

I would tend to do something like:

  int const orig_top = lua_gettop(L);
  double const foo = (lua_getfield(L, idx, "foo"), lua_tonumber(L, -1));
  char const *const bar = (lua_getfield(L, idx, "bar"), lua_tostring(L, -1));
  bool const baz = (lua_getfield(L, idx, "baz"), lua_toboolean(L, -1));
  [processing...]
  lua_settop(L, orig_top);

and those preamble/postamble lines only appear if necessary; if I'm
about to return from the C function anyway and don't have any other
reason to reclaim the space, I just let the stackframe teardown clear
away all the extra values.  If there's a lot of values you might need
a luaL_checkstack in front; if there's a number of values that is not
bounded by a small enough constant at compile time, or you're doing a
lot of processing afterwards, then intermediary cleanup stages become
useful.

Note that the lifetime of a string pointer isn't guaranteed to extend
beyond its being pinned by the C-function Lua stack anyway, so
grabbing a string data pointer and then immediately popping the value
off is theoretically dangerous (in 5.1; the canonical implementation
doesn't use a moving GC last I checked, but the manual doesn't forbid
it).

   ---> Drake Wilson