diff --git a/VM/include/lua.h b/VM/include/lua.h index 43c60d77..002dd492 100644 --- a/VM/include/lua.h +++ b/VM/include/lua.h @@ -323,6 +323,9 @@ LUA_API void lua_clonefunction(lua_State* L, int idx); LUA_API void lua_cleartable(lua_State* L, int idx); +LUA_API lua_Alloc lua_getallocf(lua_State* L, void** ud); +LUA_API void lua_setallocf(lua_State* L, lua_Alloc f, void* ud); + /* ** reference system, can be used to pin objects */ diff --git a/VM/src/lapi.cpp b/VM/src/lapi.cpp index 2b98e47d..5efba158 100644 --- a/VM/src/lapi.cpp +++ b/VM/src/lapi.cpp @@ -1432,3 +1432,17 @@ size_t lua_totalbytes(lua_State* L, int category) api_check(L, category < LUA_MEMORY_CATEGORIES); return category < 0 ? L->global->totalbytes : L->global->memcatbytes[category]; } + +lua_Alloc lua_getallocf(lua_State* L, void** ud) +{ + lua_Alloc f = L->global->frealloc; + if (ud) + *ud = L->global->ud; + return f; +} + +void lua_setallocf(lua_State* L, lua_Alloc f, void* ud) +{ + L->global->frealloc = f; + L->global->ud = ud; +} diff --git a/tests/Conformance.test.cpp b/tests/Conformance.test.cpp index 1e520100..0fe8cda1 100644 --- a/tests/Conformance.test.cpp +++ b/tests/Conformance.test.cpp @@ -1163,6 +1163,28 @@ TEST_CASE("ApiType") CHECK(lua_type(L, -1) == LUA_TUSERDATA); } +TEST_CASE("AllocApi") +{ + int ud = 0; + StateRef globalState(lua_newstate(limitedRealloc, &ud), lua_close); + lua_State* L = globalState.get(); + + void* ud_check = nullptr; + bool allocfIsSet = lua_getallocf(L, &ud_check) == limitedRealloc; + CHECK(allocfIsSet); + CHECK(ud_check == &ud); + + auto limitedReallocAlt = [](void* ud, void* ptr, size_t osize, size_t nsize) -> void* { + return limitedRealloc(ud, ptr, osize, nsize); + }; + + int ud2 = 0; + lua_setallocf(L, limitedReallocAlt, &ud2); + allocfIsSet = lua_getallocf(L, &ud_check) == limitedReallocAlt; + CHECK(allocfIsSet); + CHECK(ud_check == &ud2); +} + #if !LUA_USE_LONGJMP TEST_CASE("ExceptionObject") {