Dealing with relative indices in Lua APIs
When you use the Lua C API to implement custom
Lua bindings, you inevitably end up with internal
helper functions that accept a Lua stack index.
Lua stack indicies
can be positive, which indicates an index from the bottom of the stack or
negative, which is an index from the top of the stack. It is extremely
common to pass -1
to functions to indicate they should operate on
the value at the top of the stack.
Now, if the function that accepts the index also needs to manipulate the
stack, we have a problem. Any manipulation of the stack will invalidate
negative indices that we have received as arguments. Previously, I have
dealt with this by converting the negative index to a positive absolute
index. The code below is cribbed from abs_index
in the Lua source:
int
lua_absolute_index(lua_State *L, int relative)
{
return (relative > 0 || relative <= LUA_REGISTRYINDEX)
? relative
: lua_gettop(L) + relative + 1;
}
Recently, however, I realized that the problem is not that you have a
relative index, but that you don’t know which relative index it is. If
you lua_pushvalue
the index you receive as an argument, then you now have
the value at index -1
and you can deal with it as you would normally
deal with any stack values. This technique seems a little cleaner than
converting to absolute indicies.