4

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.

SwDevMan81
  • 48,814
  • 22
  • 151
  • 184
  • The registry is not the same as the global table. The global table was `LUA_GLOBALSINDEX` in lua 5.1. – Etan Reisner Feb 04 '15 at 22:12
  • 1
    Have you looked at [Changes in the API](http://www.lua.org/manual/5.2/manual.html#8.3)? – Etan Reisner Feb 04 '15 at 22:13
  • @Etan - I did come across that page, but it doesnt provide a translation, only recommendation to get the global environment from the registry. I very easily could be confusing the registry and global tables. – SwDevMan81 Feb 04 '15 at 22:18
  • It does explicitly indicate that you get one from the other so, while yes some confusion is possible, it is fairly clear that they aren't the same. Also `LUA_REGISTRYINDEX` hasn't gone anywhere so your questions about replacing that with something else are unnecessary. – Etan Reisner Feb 04 '15 at 22:22
  • 1
    Replacing a `get` call with a `set` call isn't exactly a meaningful statement either (item `11`) and `luaL_getmetatable` [still exists in lua 5.2](http://www.lua.org/manual/5.2/manual.html#luaL_getmetatable). – Etan Reisner Feb 04 '15 at 22:23
  • Right, `LUA_REGISTRYINDEX` was a constant value, so before we could just hardcode it, but that is no longer the case in 5.2. `luaL_getmetatable` is a #define and not accessible through P/Invoke. `11)` is actually number `9)` so I've removed it (I had a helper function called the same thing that pointed to `lua_getfield...` – SwDevMan81 Feb 04 '15 at 22:29
  • `LUA_REGISTRYINDEX` is still a define in 5.2 from what I can see. – Etan Reisner Feb 04 '15 at 22:33
  • Yes, `luaL_getmetatable` is a define. So you can't use that but you can use what it is a define for, no? Which is [`(lua_getfield(L, LUA_REGISTRYINDEX, (n)))`](http://www.lua.org/source/5.2/lauxlib.h.html#luaL_getmetatable). – Etan Reisner Feb 04 '15 at 22:34
  • But again, I dont know what `LUA_REGISTRYINDEX` is. Its no longer `-10000`. So before I could do `lua_getfield(L, -10000, n)`, but now I cant. because its a `pseudo-index`. – SwDevMan81 Feb 04 '15 at 22:38
  • It was **always** a [`pseudo-index`](http://www.lua.org/manual/5.1/manual.html#3.3). Have you looked at the [5.2 define for it](http://www.lua.org/source/5.2/lua.h.html#LUA_REGISTRYINDEX)? – Etan Reisner Feb 04 '15 at 22:43
  • If I hardcode LUA_REGISTRYINDEX to `-1001000`, the first call to `lua_pushvalue(luaState, LUA_GLOBALSINDEX);` throws a `AccessViolationException`. However in 5.1, when the value was `-10000` it worked. – SwDevMan81 Feb 04 '15 at 22:50
  • If I hardocde LUA_REGISTRYINDEX to `-16000`, the first call to `lua_settable(luaState, LUA_REGISTRYINDEX);` throws a `AccessViolationException`. This also worked in 5.1. – SwDevMan81 Feb 04 '15 at 22:54
  • 4 and 5 are the same example, is this a copy paste error? – greatwolf Feb 04 '15 at 22:57
  • You need to find out what `LUAI_BITSINT` is set to to find out what the value of `LUAI_MAXSTACK` is before you can find out what `LUA_REGISTRYINDEX` is. – Etan Reisner Feb 04 '15 at 22:58
  • @greatwolf - Yeah I think I just copied it twice, updated. – SwDevMan81 Feb 04 '15 at 23:01
  • @Etan - The examples in my comments are with both of the possible options. Hardcoding to either one doesnt seem to work. Just for completeness, its set to `#define LUAI_BITSINT 32` – SwDevMan81 Feb 04 '15 at 23:01
  • Ah, I missed the difference there. Apologies. Compile a small program against the appropriate header that prints out the value and see what it is? – Etan Reisner Feb 04 '15 at 23:13
  • Also try preprocessing c source it'll show exactly what those constants are. – greatwolf Feb 04 '15 at 23:14
  • I'm still a little unclear why, you need to hardcode those pseudo-indices since that's kind of fragile. It should be treated as implementation detail. – greatwolf Feb 04 '15 at 23:16
  • @greatwolf - I'm not trying to hardcore them, I'm looking for how to update the code so it no longer uses those values – SwDevMan81 Feb 05 '15 at 03:16

1 Answers1

1

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);
}
SwDevMan81
  • 48,814
  • 22
  • 151
  • 184