4 ms·
> In Lua API, all Lua values are bound to a stack, and C functions have to exchange values via that stack - there's no free-standing "Lua value" type in the API
by shakna 6y ago
> In Lua API, all Lua values are bound to a stack, and C functions have to exchange values via that stack - there's no free-standing "Lua value" type in the API.
That's not 100% correct. You can have values unbound from the stack, they're just typed, rather than having one "value" type. (lua_Number, lua_CFunction, etc). Though functions bound from do still use the stack for taking/returning values. (However your C functions can directly work on other value types).
- int_19h 6y agoCorrect me if I'm wrong, but doesn't this only work for value types? i.e. there's no way you can hold a reference to a Lua (not C) function, or a table, without the stack.
- shakna 6y agoWhat you're looking for in that case is lua_topointer, which can turn any Lua userdata, table, thread, or function into a void pointer.
- int_19h 6y agoNot really. Looking at the doc for that function: "There is no way to convert the pointer back to its original value. Typically this function is used only for debug information." (In CPython, you can e.g. stash a PyObject* away in C globals.)
- shakna 6y agoIf what you want is a reference to any Lua object, that you can grab from somewhere random in C, that doesn't exist on the stack, then you'll be using Lua's registry. Your first stop will be luaL_ref [0]. [0] https://www.lua.org/manual/5.3/manual.html#luaL_ref https://www.lua.org/manual/5.3/manual.html#luaL_ref
- int_19h 6y agoYep, that's exactly what I meant. It goes back to the same thing - all Lua objects exist strictly in the "Lua world" (be it the stack or the registry), and anything that wants to exchange them has to go through those mechanisms. In Python, you just get a PyObject*, and you can pass it around as much as you want - the only thing you have to take care of is to reference-count it properly.
- shakna 6y agoA registry object in Lua is an integer in C, and you can pass it around as much as you want. However, you have to be careful, because it can be eliminated by the GC, in much the same way as a PyObject pointer. The registry object really is just an address. It's the equivalent of: lua_State->top+LUA_REGISTRYINDEX[reference] in C. There's no functional difference to a PyObject pointer.