(Win32 / D) lua_rawgeti() pushes nil

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

(Win32 / D) lua_rawgeti() pushes nil

Markus Koskimies
Hi!

I have been writing small D module to use Lua scripts with my project. Yesterday I ran in to a problem that I have not been able to solve. I posted the question to stackoverflow:

https://stackoverflow.com/questions/56036831/d-win32-lua-rawgeti-pushes-nil  

Shortly, it seems that on 32-bit Windows, lua_rawgeti() pushes nil to stack. Either luaL_ref() fails to create correct reference, or lua_rawgeti() fails to get correct value. The code in question:

lua_getglobal(L, toStringz("_G"));
int t1 = lua_type(L, -1);
auto r = luaL_ref(L, LUA_REGISTRYINDEX);

lua_rawgeti(L, LUA_REGISTRYINDEX, r);
int t2 = lua_type(L, -1);
On Linux, both t1 and t2 are 5 (table). On 32-bit Windows, t1 = 5 (table), but t2 = 0 (nil).

To see if lua_rawgeti() gets correct value from D caller, I compiled Lua from sources and added printf() to lua_rawgeti() to see what values the reference gets from API user. It ensures that the reference value is correct (both D and Lua say it is 3).

Any ideas what causes this? Any ideas where to look for fixes?

Reply | Threaded
Open this post in threaded view
|

Re: (Win32 / D) lua_rawgeti() pushes nil

Viacheslav Usov
On Wed, May 8, 2019 at 5:08 PM Markus Koskimies <[hidden email]> wrote:

> lua_rawgeti(L, LUA_REGISTRYINDEX, r);

I suspect this is a bug in DerelictLua.

Lua defines lua_rawgeti thus:

int lua_rawgeti (lua_State *L, int index, lua_Integer n);

While DerelictLua defines its binding thus:

alias da_lua_rawgeti = int function(lua_State*, int, int);

Note that the last parameter is of a different type. I would guess the Lua DLL that you use was built using the "stock" config, where lua_Integer is a 64-bit integer, while D's int is always a 32-bit value. Your 64-bit Linux will use register-based ABI, where this does not matter, while 32-bit Windows will use stack-based ABI, which makes all the difference.

This should fix the problem:

alias da_lua_rawgeti = int function(lua_State*, int, long);

You might want to check all the bindings, though.

Cheers,
V.
Reply | Threaded
Open this post in threaded view
|

Re: (Win32 / D) lua_rawgeti() pushes nil

Markus Koskimies
Hi!

You were absolutely right. I made the change and the problem went away! Thanks a lot! :D

On Wed, May 8, 2019 at 7:02 PM Viacheslav Usov <[hidden email]> wrote:
On Wed, May 8, 2019 at 5:08 PM Markus Koskimies <[hidden email]> wrote:

> lua_rawgeti(L, LUA_REGISTRYINDEX, r);

I suspect this is a bug in DerelictLua.

Lua defines lua_rawgeti thus:

int lua_rawgeti (lua_State *L, int index, lua_Integer n);

While DerelictLua defines its binding thus:

alias da_lua_rawgeti = int function(lua_State*, int, int);

Note that the last parameter is of a different type. I would guess the Lua DLL that you use was built using the "stock" config, where lua_Integer is a 64-bit integer, while D's int is always a 32-bit value. Your 64-bit Linux will use register-based ABI, where this does not matter, while 32-bit Windows will use stack-based ABI, which makes all the difference.

This should fix the problem:

alias da_lua_rawgeti = int function(lua_State*, int, long);

You might want to check all the bindings, though.

Cheers,
V.