Store vector metatable in registry

This commit is contained in:
Jude Melton-Houghton 2022-03-29 12:07:00 -04:00 committed by GitHub
parent 11aab4198b
commit 06d197cdd0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 36 additions and 21 deletions

@ -1,4 +1,5 @@
_G.core = {} _G.core = {}
_G.vector = {metatable = {}}
dofile("builtin/common/vector.lua") dofile("builtin/common/vector.lua")
dofile("builtin/common/misc_helpers.lua") dofile("builtin/common/misc_helpers.lua")

@ -1,4 +1,5 @@
_G.core = {} _G.core = {}
_G.vector = {metatable = {}}
_G.setfenv = require 'busted.compatibility'.setfenv _G.setfenv = require 'busted.compatibility'.setfenv

@ -1,4 +1,4 @@
_G.vector = {} _G.vector = {metatable = {}}
dofile("builtin/common/vector.lua") dofile("builtin/common/vector.lua")
describe("vector", function() describe("vector", function()

@ -6,10 +6,8 @@ Note: The vector.*-functions must be able to accept old vectors that had no meta
-- localize functions -- localize functions
local setmetatable = setmetatable local setmetatable = setmetatable
vector = {} -- vector.metatable is set by C++.
local metatable = vector.metatable
local metatable = {}
vector.metatable = metatable
local xyz = {"x", "y", "z"} local xyz = {"x", "y", "z"}

@ -1,4 +1,5 @@
_G.core = {} _G.core = {}
_G.vector = {metatable = {}}
_G.unpack = table.unpack _G.unpack = table.unpack
_G.serverlistmgr = {} _G.serverlistmgr = {}

@ -36,3 +36,15 @@ local function test_dynamic_media(cb, player)
-- if the callback isn't called this test will just hang :shrug: -- if the callback isn't called this test will just hang :shrug:
end end
unittests.register("test_dynamic_media", test_dynamic_media, {async=true, player=true}) unittests.register("test_dynamic_media", test_dynamic_media, {async=true, player=true})
local function test_v3f_metatable(player)
assert(vector.check(player:get_pos()))
end
unittests.register("test_v3f_metatable", test_v3f_metatable, {player=true})
local function test_v3s16_metatable(player, pos)
local node = minetest.get_node(pos)
local found_pos = minetest.find_node_near(pos, 0, node.name, true)
assert(vector.check(found_pos))
end
unittests.register("test_v3s16_metatable", test_v3s16_metatable, {map=true})

@ -52,25 +52,12 @@ if (value < F1000_MIN || value > F1000_MAX) { \
/** /**
* A helper which sets (if available) the vector metatable from builtin as metatable * A helper which sets the vector metatable for the table on top of the stack
* for the table on top of the stack
*/ */
static void set_vector_metatable(lua_State *L) static void set_vector_metatable(lua_State *L)
{ {
// get vector.metatable lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_VECTOR_METATABLE);
lua_getglobal(L, "vector"); lua_setmetatable(L, -2);
if (!lua_istable(L, -1)) {
// there is no global vector table
lua_pop(L, 1);
errorstream << "set_vector_metatable in c_converter.cpp: " <<
"missing global vector table" << std::endl;
return;
}
lua_getfield(L, -1, "metatable");
// set the metatable
lua_setmetatable(L, -3);
// pop vector global
lua_pop(L, 1);
} }
void push_v3f(lua_State *L, v3f p) void push_v3f(lua_State *L, v3f p)

@ -55,6 +55,7 @@ extern "C" {
#define CUSTOM_RIDX_CURRENT_MOD_NAME (CUSTOM_RIDX_BASE + 2) #define CUSTOM_RIDX_CURRENT_MOD_NAME (CUSTOM_RIDX_BASE + 2)
#define CUSTOM_RIDX_BACKTRACE (CUSTOM_RIDX_BASE + 3) #define CUSTOM_RIDX_BACKTRACE (CUSTOM_RIDX_BASE + 3)
#define CUSTOM_RIDX_HTTP_API_LUA (CUSTOM_RIDX_BASE + 4) #define CUSTOM_RIDX_HTTP_API_LUA (CUSTOM_RIDX_BASE + 4)
#define CUSTOM_RIDX_VECTOR_METATABLE (CUSTOM_RIDX_BASE + 5)
// Determine if CUSTOM_RIDX_SCRIPTAPI will hold a light or full userdata // Determine if CUSTOM_RIDX_SCRIPTAPI will hold a light or full userdata

@ -121,6 +121,14 @@ ScriptApiBase::ScriptApiBase(ScriptingType type):
lua_newtable(m_luastack); lua_newtable(m_luastack);
lua_setglobal(m_luastack, "core"); lua_setglobal(m_luastack, "core");
// vector.metatable is stored in the registry for quick access from C++.
lua_newtable(m_luastack);
lua_rawseti(m_luastack, LUA_REGISTRYINDEX, CUSTOM_RIDX_VECTOR_METATABLE);
lua_newtable(m_luastack);
lua_rawgeti(m_luastack, LUA_REGISTRYINDEX, CUSTOM_RIDX_VECTOR_METATABLE);
lua_setfield(m_luastack, -2, "metatable");
lua_setglobal(m_luastack, "vector");
if (m_type == ScriptingType::Client) if (m_type == ScriptingType::Client)
lua_pushstring(m_luastack, "/"); lua_pushstring(m_luastack, "/");
else else

@ -98,6 +98,7 @@ void ScriptApiSecurity::initializeSecurity()
"type", "type",
"unpack", "unpack",
"_VERSION", "_VERSION",
"vector",
"xpcall", "xpcall",
}; };
static const char *whitelist_tables[] = { static const char *whitelist_tables[] = {
@ -254,6 +255,10 @@ void ScriptApiSecurity::initializeSecurity()
lua_pushnil(L); lua_pushnil(L);
lua_setfield(L, old_globals, "core"); lua_setfield(L, old_globals, "core");
// 'vector' as well.
lua_pushnil(L);
lua_setfield(L, old_globals, "vector");
lua_pop(L, 1); // Pop globals_backup lua_pop(L, 1); // Pop globals_backup
@ -296,6 +301,7 @@ void ScriptApiSecurity::initializeSecurityClient()
"type", "type",
"unpack", "unpack",
"_VERSION", "_VERSION",
"vector",
"xpcall", "xpcall",
// Completely safe libraries // Completely safe libraries
"coroutine", "coroutine",