Search code examples
c#c++luaportinglua-5.2

Porting from Lua 5.1 to 5.2


I'm having some issues porting some older Lua 5.1 code to Lua 5.2. I would like to be able to use the stock Lua 5.2 dll/lib, so any porting would need to be completed using the existing API for Lua 5.2. To make it a little more complicated, I'm using DllImport to P/Invoke some of the Lua API calls. This means any of the #define shortcuts offered will not work. For example using lua_pushglobaltable wont be possible. Most of the updates are needed because LUA_REGISTRYINDEX is not longer accessible.

What I have so far is the following:


1a) Replace

lua_pushstring(luaState, "tablename");
lua_settable(luaState, LUA_REGISTRYINDEX); // LUA_REGISTRYINDEX no longer accessible

1b) With

lua_setglobal(luaState, "tablename");

2a) Replace

lua_pushstring(luaState, "tablename");
lua_gettable(luaState, LUA_REGISTRYINDEX); // LUA_REGISTRYINDEX no longer accessible

2b) With

lua_getglobal(luaState, "tablename");

3a) Replace

lua_pushvalue(luaState, LUA_GLOBALSINDEX);

3b) With

// not sure, something equivalent to lua_pushglobaltable(L)

4a) Replace

lua_replace(luaState, LUA_GLOBALSINDEX);

4b) With

// I dont even have a guess here

5a) Replace

luaL_ref(luaState, (int)LuaIndexes.LUA_REGISTRYINDEX); // also luaL_unref

5b) With

luaL_ref(luaState, <some arbitrary constant>); // this is probably wrong

6a) Replace

lua_rawgeti(luaState, LUA_REGISTRYINDEX, reference);

6b) With

lua_rawgeti(luaState, <same arbitrary constant>, reference); // this is probably wrong

7a) Replace

lua_pcall(IntPtr luaState, int nArgs, int nResults, int errfunc);

7b) With

lua_pcallk(IntPtr luaState, int nArgs, int nResults, int errfunc, int ctx, [MarshalAs(UnmanagedType.FunctionPtr)]LuaCSFunction function);
lua_pcallk(luaState, nArgs, nResults, errfunc, 0, null);

8a) Replace

lua_getfield(luaState, LUA_REGISTRYINDEX, meta);

8b) With

luaL_setmetatable(IntPtr luaState, string meta);

9a) Replace

lua_rawset(luaState, LUA_REGISTRYINDEX);

9b) With

lua_settable(luaState, -3);

Right now everything compiles, but I get memory access violation exceptions, which means I probably substituted something incorrectly. Any help would be appreciated.


Solution

  • I believe I've managed to upgrade this, so I'll add the details of what I did below and the conversion. I created a C wrapper into the LUA lower level API to export the functionality I needed:

    1a) Replaced

    lua_settable(luaState, LUA_REGISTRYINDEX); // LUA_REGISTRYINDEX no longer accessible
    

    1b) With

    lua_settablereg(luaState);
    

    2a) Replaced

    lua_gettable(luaState, LUA_REGISTRYINDEX); // LUA_REGISTRYINDEX no longer accessible
    

    2b) With

    lua_gettablereg(luaState);
    

    3a) Replaced

    lua_pushvalue(luaState, LUA_GLOBALSINDEX);
    

    3b) With

    lua_pushglobaltablefunction(luaState)
    

    4a) Replaced

    lua_replace(luaState, LUA_GLOBALSINDEX);
    

    4b) With

    lua_popglobaltablefunction(luaState)
    

    5a) Replaced

    luaL_ref(luaState, (int)LuaIndexes.LUA_REGISTRYINDEX); // also luaL_unref
    

    5b) With

    luaL_refreg(luaState); // also luaL_unrefreg
    

    6a) Replaced

    lua_rawgeti(luaState, LUA_REGISTRYINDEX, reference);
    

    6b) With

    lua_rawgetireg(luaState, reference);
    

    7a) Replaced

    lua_pcall(luaState, nArgs, nResults, errfunc);
    

    7b) With

    lua_pcalla(luaState, nArgs, nResults, errfunc);
    

    8a) Replaced

    lua_getfield(luaState, LUA_REGISTRYINDEX, meta);
    

    8b) With

    lua_getfieldreg(luaState, string meta);
    

    9a) Replaced

    lua_rawset(luaState, LUA_REGISTRYINDEX);
    

    9b) With

    lua_rawsetreg(luaState);
    

    Definitions look like this:

    __declspec(dllexport) void lua_pushglobaltablefunction(lua_State *L) 
    {
       lua_pushglobaltable(L);
    }
    
    __declspec(dllexport) void lua_popglobaltablefunction(lua_State *L) 
    {
       lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS);
    }
    
    __declspec(dllexport) int luaL_regref(lua_State *L) 
    {
       return luaL_ref(L, LUA_REGISTRYINDEX);
    }
    
    __declspec(dllexport) void luaL_unregref(lua_State *L, int reference)
    {
       luaL_unref(L, LUA_REGISTRYINDEX, reference);
    }
    
    __declspec(dllexport) void lua_settablereg(lua_State *L)
    {
       lua_settable(L, LUA_REGISTRYINDEX);
    }
    
    __declspec(dllexport) void lua_gettablereg(lua_State *L)
    {
       lua_gettable(L, LUA_REGISTRYINDEX);
    }
    
    __declspec(dllexport) void lua_rawsetreg(lua_State *L)
    {
       lua_rawset(L, LUA_REGISTRYINDEX);
    }
    
    __declspec(dllexport) void lua_rawgetreg(lua_State *L)
    {
       lua_rawget(L, LUA_REGISTRYINDEX);
    }
    
    __declspec(dllexport) void lua_rawgetireg(lua_State *L, int reference)
    {
       lua_rawgeti(L, LUA_REGISTRYINDEX, reference);
    }
    
    __declspec(dllexport) void lua_getfieldreg(lua_State *L,const char *fieldname)
    {
       lua_getfield(L, LUA_REGISTRYINDEX, fieldname);
    }
    
    __declspec(dllexport) int luaL_loadbuffername(lua_State *L,const char *buff, int size,const char * name)
    {
       return luaL_loadbuffer(L,buff,size,name);
    }
    
    __declspec(dllexport) double lua_tonum(lua_State *L, int index)
    {
       return lua_tonumber(L, index);
    }
    
    __declspec(dllexport) int lua_pcalla(lua_State *L,int nArgs,int nResults,int errfunc)
    {
       return lua_pcall(L,nArgs,nResults,errfunc);
    }