diff --git a/VM/include/lua.h b/VM/include/lua.h index dbf19cb4..35c1cd02 100644 --- a/VM/include/lua.h +++ b/VM/include/lua.h @@ -159,6 +159,7 @@ LUA_API const char* lua_namecallatom(lua_State* L, int* atom); LUA_API int lua_objlen(lua_State* L, int idx); LUA_API lua_CFunction lua_tocfunction(lua_State* L, int idx); LUA_API void* lua_tolightuserdata(lua_State* L, int idx); +LUA_API void* lua_tolightuserdatatagged(lua_State* L, int idx, int tag); LUA_API void* lua_touserdata(lua_State* L, int idx); LUA_API void* lua_touserdatatagged(lua_State* L, int idx, int tag); LUA_API int lua_userdatatag(lua_State* L, int idx); @@ -186,7 +187,7 @@ LUA_API void lua_pushcclosurek(lua_State* L, lua_CFunction fn, const char* debug LUA_API void lua_pushboolean(lua_State* L, int b); LUA_API int lua_pushthread(lua_State* L); -LUA_API void lua_pushlightuserdata(lua_State* L, void* p); +LUA_API void lua_pushlightuserdatatagged(lua_State* L, void* p, int tag); LUA_API void* lua_newuserdatatagged(lua_State* L, size_t sz, int tag); LUA_API void* lua_newuserdatadtor(lua_State* L, size_t sz, void (*dtor)(void*)); @@ -370,6 +371,7 @@ LUA_API void lua_unref(lua_State* L, int ref); #define lua_pushliteral(L, s) lua_pushlstring(L, "" s, (sizeof(s) / sizeof(char)) - 1) #define lua_pushcfunction(L, fn, debugname) lua_pushcclosurek(L, fn, debugname, 0, NULL) #define lua_pushcclosure(L, fn, debugname, nup) lua_pushcclosurek(L, fn, debugname, nup, NULL) +#define lua_pushlightuserdata(L, p) lua_pushlightuserdatatagged(L, p, 0); #define lua_setglobal(L, s) lua_setfield(L, LUA_GLOBALSINDEX, (s)) #define lua_getglobal(L, s) lua_getfield(L, LUA_GLOBALSINDEX, (s)) diff --git a/VM/src/lapi.cpp b/VM/src/lapi.cpp index 355e4e21..7fc0db50 100644 --- a/VM/src/lapi.cpp +++ b/VM/src/lapi.cpp @@ -505,6 +505,12 @@ void* lua_tolightuserdata(lua_State* L, int idx) return (!ttislightuserdata(o)) ? NULL : pvalue(o); } +void* lua_tolightuserdatatagged(lua_State* L, int idx, int tag) +{ + StkId o = index2addr(L, idx); + return (!ttislightuserdata(o) || o->extra[0] != tag) ? NULL : pvalue(o); +} + void* lua_touserdata(lua_State* L, int idx) { StkId o = index2addr(L, idx); @@ -665,9 +671,10 @@ void lua_pushboolean(lua_State* L, int b) api_incr_top(L); } -void lua_pushlightuserdata(lua_State* L, void* p) +void lua_pushlightuserdatatagged(lua_State* L, void* p, int tag) { setpvalue(L->top, p); + L->top->extra[0] = tag; api_incr_top(L); } diff --git a/tests/Conformance.test.cpp b/tests/Conformance.test.cpp index b7f77711..429ab1d9 100644 --- a/tests/Conformance.test.cpp +++ b/tests/Conformance.test.cpp @@ -1667,6 +1667,24 @@ TEST_CASE("UserdataApi") CHECK(dtorhits == 42); } +TEST_CASE("LightuserdataApi") +{ + StateRef globalState(luaL_newstate(), lua_close); + lua_State* L = globalState.get(); + + void* value = (void*)0x12345678; + + lua_pushlightuserdata(L, value); + CHECK(lua_tolightuserdatatagged(L, -1, 0) == value); + CHECK(lua_tolightuserdatatagged(L, -1, 1) == nullptr); + + lua_pushlightuserdatatagged(L, value, 1); + CHECK(lua_tolightuserdatatagged(L, -1, 0) == nullptr); + CHECK(lua_tolightuserdatatagged(L, -1, 1) == value); + + globalState.reset(); +} + TEST_CASE("Iter") { runConformance("iter.lua");