From 6fbea7cc848a18cfaf0022dc661040521c590789 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petri=20H=C3=A4kkinen?= Date: Thu, 15 Sep 2022 18:26:54 +0300 Subject: [PATCH] Add lua_rawsetfield (#671) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Luau currently has the following functions in the C API for dealing with tables without invoking metamethods: lua_rawgetfield lua_rawget lua_rawgeti lua_rawset lua_rawseti This change adds the missing function lua_rawsetfield for consistency and because it's more efficient to use it in place of plain lua_rawset which requires pushing the key and value separately. Co-authored-by: Petri Häkkinen --- VM/include/lua.h | 1 + VM/src/lapi.cpp | 13 +++++++++++++ tests/Conformance.test.cpp | 6 ++++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/VM/include/lua.h b/VM/include/lua.h index 1f38635..0a3acb4 100644 --- a/VM/include/lua.h +++ b/VM/include/lua.h @@ -210,6 +210,7 @@ LUA_API void lua_getfenv(lua_State* L, int idx); */ LUA_API void lua_settable(lua_State* L, int idx); LUA_API void lua_setfield(lua_State* L, int idx, const char* k); +LUA_API void lua_rawsetfield(lua_State* L, int idx, const char* k); LUA_API void lua_rawset(lua_State* L, int idx); LUA_API void lua_rawseti(lua_State* L, int idx, int n); LUA_API int lua_setmetatable(lua_State* L, int objindex); diff --git a/VM/src/lapi.cpp b/VM/src/lapi.cpp index 6a9c46d..7603a79 100644 --- a/VM/src/lapi.cpp +++ b/VM/src/lapi.cpp @@ -847,6 +847,19 @@ void lua_setfield(lua_State* L, int idx, const char* k) return; } +void lua_rawsetfield(lua_State* L, int idx, const char* k) +{ + api_checknelems(L, 1); + StkId t = index2addr(L, idx); + api_check(L, ttistable(t)); + if (hvalue(t)->readonly) + luaG_runerror(L, "Attempt to modify a readonly table"); + setobj2t(L, luaH_setstr(L, hvalue(t), luaS_new(L, k)), L->top - 1); + luaC_barriert(L, hvalue(t), L->top - 1); + L->top--; + return; +} + void lua_rawset(lua_State* L, int idx) { api_checknelems(L, 2); diff --git a/tests/Conformance.test.cpp b/tests/Conformance.test.cpp index c6bdb4d..25129bf 100644 --- a/tests/Conformance.test.cpp +++ b/tests/Conformance.test.cpp @@ -746,6 +746,8 @@ TEST_CASE("ApiTables") lua_newtable(L); lua_pushnumber(L, 123.0); lua_setfield(L, -2, "key"); + lua_pushnumber(L, 456.0); + lua_rawsetfield(L, -2, "key2"); lua_pushstring(L, "test"); lua_rawseti(L, -2, 5); @@ -761,8 +763,8 @@ TEST_CASE("ApiTables") lua_pop(L, 1); // lua_rawgetfield - CHECK(lua_rawgetfield(L, -1, "key") == LUA_TNUMBER); - CHECK(lua_tonumber(L, -1) == 123.0); + CHECK(lua_rawgetfield(L, -1, "key2") == LUA_TNUMBER); + CHECK(lua_tonumber(L, -1) == 456.0); lua_pop(L, 1); // lua_rawget