From fc4871989a147be7bc817573f09e49361853f999 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petri=20H=C3=A4kkinen?= Date: Thu, 22 Sep 2022 19:54:03 +0300 Subject: [PATCH] Add lua_cleartable (#678) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To my understanding lua_cleartable does not need GC barriers because it's only removing elements and not modifying the stack. But I'm not a GC expert so please correct if I'm wrong. resolves #672 Co-authored-by: Petri Häkkinen --- VM/include/lua.h | 2 ++ VM/src/lapi.cpp | 10 ++++++++++ tests/Conformance.test.cpp | 5 +++++ 3 files changed, 17 insertions(+) diff --git a/VM/include/lua.h b/VM/include/lua.h index 0a3acb4..5c61f13 100644 --- a/VM/include/lua.h +++ b/VM/include/lua.h @@ -316,6 +316,8 @@ LUA_API void lua_setuserdatadtor(lua_State* L, int tag, void (*dtor)(lua_State*, LUA_API void lua_clonefunction(lua_State* L, int idx); +LUA_API void lua_cleartable(lua_State* L, int idx); + /* ** reference system, can be used to pin objects */ diff --git a/VM/src/lapi.cpp b/VM/src/lapi.cpp index cbcaa3c..968b8d0 100644 --- a/VM/src/lapi.cpp +++ b/VM/src/lapi.cpp @@ -1376,6 +1376,16 @@ void lua_clonefunction(lua_State* L, int idx) api_incr_top(L); } +void lua_cleartable(lua_State* L, int idx) +{ + StkId t = index2addr(L, idx); + api_check(L, ttistable(t)); + Table* tt = hvalue(t); + if (tt->readonly) + luaG_runerror(L, "Attempt to modify a readonly table"); + luaH_clear(tt); +} + lua_Callbacks* lua_callbacks(lua_State* L) { return &L->global->cb; diff --git a/tests/Conformance.test.cpp b/tests/Conformance.test.cpp index 25129bf..cf4a14c 100644 --- a/tests/Conformance.test.cpp +++ b/tests/Conformance.test.cpp @@ -778,6 +778,11 @@ TEST_CASE("ApiTables") CHECK(strcmp(lua_tostring(L, -1), "test") == 0); lua_pop(L, 1); + // lua_cleartable + lua_cleartable(L, -1); + lua_pushnil(L); + CHECK(lua_next(L, -2) == 0); + lua_pop(L, 1); }