From 35260fa4eb0e7e69ed749357074fa0bed652f444 Mon Sep 17 00:00:00 2001 From: Josh Yelon Date: Sun, 28 Feb 2021 16:32:42 -0500 Subject: [PATCH] Completed port to eris lua 5.2 --- luprex/core/cpp/luastack.cpp | 6 ++ luprex/core/cpp/luastack.hpp | 2 +- luprex/core/cpp/source.cpp | 106 +++++++++++------------------------ luprex/core/cpp/source.hpp | 10 +--- luprex/core/cpp/world.cpp | 2 +- 5 files changed, 42 insertions(+), 84 deletions(-) diff --git a/luprex/core/cpp/luastack.cpp b/luprex/core/cpp/luastack.cpp index 2071981b..011052ba 100644 --- a/luprex/core/cpp/luastack.cpp +++ b/luprex/core/cpp/luastack.cpp @@ -137,6 +137,11 @@ int LuaStack::next(LuaSlot tab, LuaSlot key, LuaSlot value) const { return ret; } +void LuaStack::getglobaltable(LuaSlot target) const { + lua_pushglobaltable(L_); + lua_replace(L_, target); +} + void LuaStack::newtable(LuaSlot target) const { lua_newtable(L_); lua_replace(L_, target); @@ -149,6 +154,7 @@ lua_State *LuaStack::newthread(LuaSlot target) const { } void LuaStack::makeclass(LuaSlot classtab, LuaSlot classname) const { + lua_checkstack(L_, 20); LuaVar globtab; LuaStack LS(L_, globtab); diff --git a/luprex/core/cpp/luastack.hpp b/luprex/core/cpp/luastack.hpp index e934b85e..3c195c7b 100644 --- a/luprex/core/cpp/luastack.hpp +++ b/luprex/core/cpp/luastack.hpp @@ -390,8 +390,8 @@ public: void newtable(LuaSlot target) const; lua_State *newthread(LuaSlot target) const; - void makesubtable(LuaSlot sub, LuaSlot tab, const char *name) const; + void getglobaltable(LuaSlot gltab) const; int next(LuaSlot tab, LuaSlot key, LuaSlot value) const; diff --git a/luprex/core/cpp/source.cpp b/luprex/core/cpp/source.cpp index d6093016..2a51fdf1 100644 --- a/luprex/core/cpp/source.cpp +++ b/luprex/core/cpp/source.cpp @@ -50,54 +50,40 @@ LuaDefine(source_maketangible, "f") { return LS.result(); } -// Load the builtins. -static void load_builtin(lua_State *L, const char *name, lua_CFunction func) { - lua_pushcfunction(L, func); - lua_pushstring(L, name); - lua_call(L, 1, 0); +// the 'luaopen' function creates a new table. +// +// We don't want to create new tables during reload, so we call luaopen, +// then we copy the contents of the new table into the existing 'makeclass' +// table. +// +static void load_builtin_class(lua_State *L, const char *name, lua_CFunction func) { + LuaVar sourcetab, classtab, key, value; + LuaStack LS(L, sourcetab, classtab, key, value); + LS.makeclass(classtab, name); + func(L); + lua_replace(L, sourcetab.index()); + LS.set(key, LuaNil); + while (LS.next(sourcetab, key, value) != 0) { + LS.rawset(classtab, key, value); + } } static void source_install_builtins(lua_State *L) { - LuaStack LS(L); - load_builtin(L, "base", luaopen_base); - load_builtin(L, "table", luaopen_table); - load_builtin(L, "string", luaopen_string); - load_builtin(L, "math", luaopen_math); - load_builtin(L, "bit", luaopen_math); - load_builtin(L, "debug", luaopen_debug); -} + LuaVar nullstring, stringclass; + LuaStack LS(L, nullstring, stringclass); + luaopen_base(L); + load_builtin_class(L, "table", luaopen_table); + load_builtin_class(L, "string", luaopen_string); + load_builtin_class(L, "math", luaopen_math); + load_builtin_class(L, "debug", luaopen_debug); -void SourceDB::initialize(lua_State *L) { - lua_state_ = L; - LuaVar key, value, skey, svalue, snapshot, ssnapshot, globtab; - LuaStack LS(L, snapshot, key, value, skey, svalue, ssnapshot, globtab); - - // Install the builtins. - source_install_builtins(L); - - // Get the global environment. - LS.rawget(globtab, LuaRegistry, LUA_RIDX_GLOBALS); - - // Note: the global environment contains _G. This routine - // perceives this as a subtable, so it backs up the top level - // as well. - LS.newtable(snapshot); - LS.set(key, LuaNil); - while (LS.next(globtab, key, value) != 0) { - if (LS.istable(value)) { - LS.newtable(ssnapshot); - LS.rawset(snapshot, key, ssnapshot); - LS.set(skey, LuaNil); - while (LS.next(value, skey, svalue) != 0) { - if (LS.isfunction(svalue) || LS.isstring(svalue) || LS.isnumber(svalue)) { - LS.rawset(ssnapshot, skey, svalue); - } - } - } - } - LS.rawset(LuaRegistry, "source_snapshot_builtins", snapshot); - LS.result(); + // Set the metatable for strings. + // Normally, this would be done by luaopen_string, but we're + // messing with the tables so we have to redo it. + LS.makeclass(stringclass, "string"); + LS.set(nullstring, ""); + LS.setmetatable(nullstring, stringclass); } static int source_updatefile(lua_State *L) { @@ -189,9 +175,7 @@ static void source_clear_globals(lua_State *L) { LuaVar classname, classtab, key, globtab; LuaStack LS(L, classname, classtab, key, globtab); - // Get the global environment. - LS.rawget(globtab, LuaRegistry, LUA_RIDX_GLOBALS); - + LS.getglobaltable(globtab); LS.rawset(globtab, "_G", LuaNil); LS.set(classname, LuaNil); while (LS.next(globtab, classname, classtab) != 0) { @@ -205,32 +189,6 @@ static void source_clear_globals(lua_State *L) { LS.result(); } -// Restore the lua builtins from the backup snapshot. -// -static void source_restore_builtins(lua_State *L) { - LuaVar snapshot, key, value, skey, svalue, target, globtab; - LuaStack LS(L, snapshot, key, value, skey, svalue, target, globtab); - - // Get the global environment table. - LS.rawget(globtab, LuaRegistry, LUA_RIDX_GLOBALS); - - LS.rawget(snapshot, LuaRegistry, "source_snapshot_builtins"); - LS.rawset(globtab, "_G", globtab); - LS.set(key, LuaNil); - while (LS.next(snapshot, key, value) != 0) { - LS.checktable(value); - if (LS.rawequal(key, "_G")) { - LS.set(target, globtab); - } else { - LS.makeclass(target, key); - } - LS.set(skey, LuaNil); - while (LS.next(value, skey, svalue) != 0) { - LS.rawset(target, skey, svalue); - } - } - LS.result(); -} // Load all the 'LuaDefine' C functions into the lua state. // @@ -312,7 +270,7 @@ void SourceDB::rebuild() { LuaVar errs; LuaStack LS(L, errs); source_clear_globals(L); - source_restore_builtins(L); + source_install_builtins(L); source_load_cfunctions(L); source_load_lfunctions(L); lua_replace(L, errs.index()); @@ -326,7 +284,7 @@ void SourceDB::run_unittests() { LuaVar unittests, name, func, err, globtab; LuaStack LS(L, unittests, name, func, err, globtab); - LS.rawget(globtab, LuaRegistry, LUA_RIDX_GLOBALS); + LS.getglobaltable(globtab); LS.rawget(unittests, globtab, "unittests"); // Sort the unit test names. diff --git a/luprex/core/cpp/source.hpp b/luprex/core/cpp/source.hpp index 614477ac..de494dfa 100644 --- a/luprex/core/cpp/source.hpp +++ b/luprex/core/cpp/source.hpp @@ -127,14 +127,8 @@ private: lua_State *lua_state_; public: - // Initialize - // - // This must be called while the lua state is still pristine. - // This will install the builtin operators into the lua state - // and will snapshot those builtins to the registry. - // - void initialize(lua_State *L); - + void init(lua_State *L) { lua_state_ = L; } + // Update // // Read all the lua source files from disk and store them in the diff --git a/luprex/core/cpp/world.cpp b/luprex/core/cpp/world.cpp index 93b1ac87..065e5006 100644 --- a/luprex/core/cpp/world.cpp +++ b/luprex/core/cpp/world.cpp @@ -30,7 +30,7 @@ World::World() { LS.rawset(LuaRegistry, "tangibles", LuaNewTable); // Initialize the SourceDB - source_db_.initialize(state()); + source_db_.init(state()); source_db_.rebuild(); LS.result();