From 4f0713c9cb649c780d0122a85e6099d9f76f65e8 Mon Sep 17 00:00:00 2001 From: jyelon Date: Fri, 7 Apr 2023 14:20:45 -0400 Subject: [PATCH] At this point, most functions have been LuaStack refactored --- luprex/cpp/core/luaconsole.cpp | 2 +- luprex/cpp/core/luasnap.cpp | 4 +- luprex/cpp/core/luastack.hpp | 265 +++++++++++++++++++---------- luprex/cpp/core/planemap.cpp | 2 +- luprex/cpp/core/pprint.cpp | 27 ++- luprex/cpp/core/serializelua.cpp | 17 +- luprex/cpp/core/source.cpp | 15 +- luprex/cpp/core/world-accessor.cpp | 67 ++++---- luprex/cpp/core/world.hpp | 2 +- 9 files changed, 240 insertions(+), 161 deletions(-) diff --git a/luprex/cpp/core/luaconsole.cpp b/luprex/cpp/core/luaconsole.cpp index 228aa953..7d1e44b2 100644 --- a/luprex/cpp/core/luaconsole.cpp +++ b/luprex/cpp/core/luaconsole.cpp @@ -9,7 +9,7 @@ #include LuaConsole::LuaConsole() { - lua_state_ = LuaOldStack::newstate(eng::l_alloc); + lua_state_ = LuaCoreStack::newstate(eng::l_alloc); clear_raw_input(); } diff --git a/luprex/cpp/core/luasnap.cpp b/luprex/cpp/core/luasnap.cpp index f7b70087..1502cf83 100644 --- a/luprex/cpp/core/luasnap.cpp +++ b/luprex/cpp/core/luasnap.cpp @@ -10,8 +10,8 @@ LuaSnap::LuaSnap() { - state_ = LuaOldStack::newstate(eng::l_alloc); - LuaOldStack LS(state_); + state_ = LuaCoreStack::newstate(eng::l_alloc); + LuaExtStack LS(state_); // Create the persist table and the unpersist table. // diff --git a/luprex/cpp/core/luastack.hpp b/luprex/cpp/core/luastack.hpp index 0683412d..255cf21f 100644 --- a/luprex/cpp/core/luastack.hpp +++ b/luprex/cpp/core/luastack.hpp @@ -1,28 +1,28 @@ ///////////////////////////////////////////////////////// // // -// LuaOldStack +// LuaStack // // The standard lua C API asks you to work with a stack machine. You're supposed // to manually push and pop values on the lua stack. I find this difficult, I // find it hard to remember what stack position contains what value. // -// To make it easier, I've created this module, "LuaOldStack." This module -// creates the illusion that you're working with local variables that contain -// lua values. +// To make it easier, I've created this module, "LuaStack." This module creates +// the illusion that you're working with local variables that contain lua +// values. // -// Of course, this is all using the lua stack under the covers. Lua -// local variables are actually just lua stack addresses. But that's -// all kept fairly well hidden. When you use Lua local variables, and -// the accessors inside class LuaOldStack, it appears that you're -// manipulating data using local variables instead of using a stack. -// For people like me, that's easier to think about. +// Of course, this is all using the lua stack under the covers. Lua local +// variables are actually just lua stack addresses. But that's all kept fairly +// well hidden. When you use Lua local variables, and the accessors inside +// class LuaStack, it appears that you're manipulating data using local +// variables instead of using a stack. For people like me, that's easier to +// think about. // // Here's an example. // -// let's say you have a function that takes two arguments -// ARG1 and ARG2, has a single return value RET1, and needs two local -// variables LOC1 and LOC2. We would declare it like this: +// let's say you have a function that takes two arguments ARG1 and ARG2, has a +// single return value RET1, and needs two local variables LOC1 and LOC2. We +// would declare it like this: // // int myfunc(lua_State *L) { // @@ -31,128 +31,117 @@ // LuaVar loc1, loc2, loc3; // Declare local variables for other purposes. // // // Assign every local var a stack index. -// LuaOldStack LS(L, arg1, arg2, ret1, loc1, loc2, loc3); +// LuaDefStack LS(L, arg1, arg2, ret1, loc1, loc2, loc3); // // // manipulate the data in the lua local variables... // LS.rawget(loc1, arg1, arg2); // ... etc ... // } // -// Class LuaArg, LuaRet, and LuaVar are all lua local variables. -// The LuaOldStack constructor assigns each one of them a position on -// the lua stack. It also makes sure that the arguments are in -// the LuaArg variables, and it makes sure that the LuaRet values -// are the only thing left on the stack at return time. +// Class LuaArg, LuaRet, and LuaVar are all lua local variables. The LuaDefStack +// constructor assigns each one of them a position on the lua stack. It also +// makes sure that the arguments are in the LuaArg variables, and it makes sure +// that the LuaRet values are the only thing left on the stack at return time. // -// Class LuaOldStack provides a complete catalog of accessors -// like 'rawget' - roughly speaking, it provides equivalents to -// every major accessor in the lua API. However, the accessors -// provided by LuaOldStack take input and output from lua locals, not -// from the stack. For example, consider this: +// Class LuaDefStack provides a complete catalog of accessors like 'rawget' - +// roughly speaking, it provides equivalents to every major accessor in the lua +// API. However, the accessors provided by LuaDefStack take input and output +// from lua locals, not from the stack. For example, consider this: // // LS.rawget(value, tab, key); // -// In the above, value, tab, and key should be lua local variables. -// This does a rawget on 'table', with the specified 'key', and -// stores the result in 'value'. Nothing is added to or removed -// from the lua stack. In general, none of the accessors in class -// LuaOldStack add anything to the stack, or pop anything from the -// stack. +// In the above, value, tab, and key should be lua local variables. This does a +// rawget on 'table', with the specified 'key', and stores the result in +// 'value'. Nothing is added to or removed from the lua stack. In general, +// none of the accessors in class LuaDefStack add anything to the stack, or pop +// anything from the stack. // -// Class LuaOldStack can also do automatic type conversions. For -// example, suppose you do this: +// Class LuaDefStack can also do automatic type conversions. For example, +// suppose you do this: // // LS.rawget(value, tab, key); // -// Nominally, you would expect value, tab, and key to be lua local -// variables. But if you pass a eng::string for key, then LuaOldStack will -// automatically convert it. In general, class LuaOldStack can -// convert lua_Integer, lua_Number, eng::string, bool, and LuaNil. +// Nominally, you would expect value, tab, and key to be lua local variables. +// But if you pass a eng::string for key, then LuaDefStack will automatically +// convert it. // -// On output, LuaOldStack can convert lua_Integers, lua_Numbers, and -// eng::strings. In this case, strict type checking is done. If -// there is a type mismatch, a lua error is thrown. +// On output, LuaDefStack can convert lua_Integers, lua_Numbers, and +// eng::strings. In this case, strict type checking is done. If there is a +// type mismatch, a lua error is thrown. // -// You can use the operator 'set' to assign a value to a lua local -// variable: +// You can use the operator 'set' to assign a value to a lua local variable: // // LS.set(val1, val2); // -// This is actually a copy operation that copies from one lua local -// variable to another. But using type conversions, it can also be -// used to assign arbitrary values to lua local variables, or to -// get values from lua local variables. -// -// Passing LuaNewTable as an input will cause a new table to be -// created before calling the specified operation. +// This is actually a copy operation that copies from one lua local variable to +// another. But using type conversions, it can also be used to assign arbitrary +// values to lua local variables, or to get values from lua local variables. +// +// Passing LuaNewTable as an input will cause a new table to be created before +// calling the specified operation. // // ///////////////////////////////////////////////////////// // // -// LuaOldStack type checking +// LuaDefStack type checking // -// LuaOldStack contains accessors for type checking. These include: +// LuaDefStack contains accessors for type checking. These include: // -// bool LuaOldStack::isnumber(LuaSlot s) -// bool LuaOldStack::isinteger(LuaSlot s) -// bool LuaOldStack::isstring(LuaSlot s) +// bool LuaDefStack::isnumber(LuaSlot s) +// bool LuaDefStack::isinteger(LuaSlot s) +// bool LuaDefStack::isstring(LuaSlot s) // etc... // // And it also contains operations that throw errors: // -// void LuaOldStack::checknumber(LuaSlot s) -// void LuaOldStack::checkinteger(LuaSlot s) -// void LuaOldStack::checkstring(LuaSlot s) +// void LuaDefStack::checknumber(LuaSlot s) +// void LuaDefStack::checkinteger(LuaSlot s) +// void LuaDefStack::checkstring(LuaSlot s) // etc... // -// These are different from the lua builtins in that they are strict. -// For example, 'isnumber' only returns true if the value in the -// lua local variable is already a number. No conversions are done. +// These are different from the lua builtins in that they are strict. For +// example, 'isnumber' only returns true if the value in the lua local variable +// is already a number. No conversions are done. // // These functions do checking and also conversion at the same time: // -// lua_Integer LuaOldStack::ckinteger(LuaSlot s) -// lua_Number LuaOldStack::cknumber(LuaSlot s) -// eng::string LuaOldStack::ckstring(LuaSlot s) -// lua_State *LuaOldStack::ckthread(LuaSlot s) +// lua_Integer LuaDefStack::ckinteger(LuaSlot s) +// lua_Number LuaDefStack::cknumber(LuaSlot s) +// eng::string LuaDefStack::ckstring(LuaSlot s) +// lua_State *LuaDefStack::ckthread(LuaSlot s) // // Like the other operations, they are strict. // // // LUADEFINE // -// LuaDefine is a macro that defines a C function which is -// exposed to lua. It creates a global registry of functions -// created with LuaDefine. You use it like so: +// LuaDefine is a macro that defines a C function which is exposed to lua. It +// creates a global registry of functions created with LuaDefine. You use it +// like so: // // LuaDefine(function_name, "arguments", "documentation") { // ... // } // -// This macroexpands into a function definition and a function -// registration. The function definition looks like this: +// This macroexpands into a function definition and a function registration. +// The function definition looks like this: // // int function_name(lua_State *L) { // ... // } // -// The macro expansion generates this function definition, but it -// also generates a "registration object" whose constructor puts -// this function into a global registry of lua-callable C functions. -// This global registry is later used to inject these C functions -// into the lua intepreter. The mode is a string that contain -// the following characters: -// -// c - create a class, and put a function into it. -// f - create a global function not inside a class. +// The macro expansion generates this function definition, but it also generates +// a "registration object" whose constructor puts this function into a global +// registry of lua-callable C functions. This global registry is later used to +// inject these C functions into the lua intepreter. // // ///////////////////////////////////////////////////////// -#ifndef LuaOldStack_HPP -#define LuaOldStack_HPP +#ifndef LUASTACK_HPP +#define LUASTACK_HPP #include "wrap-string.hpp" #include "wrap-set.hpp" @@ -272,12 +261,22 @@ public: eng::string str() const; }; +//////////////////////////////////////////////////////////////////// +// +// LuaCoreStack +// +// This class is not meant to be used directly: it doesn't contain any code to +// allocate a stack frame on the lua stack and allocate slots within the frame +// to lua local variables. That code is in derived classes, below. The only +// time this class is used directly is in the extremely rare case that you want +// to manually allocate stack slots yourself. +// +//////////////////////////////////////////////////////////////////// + class LuaCoreStack : public eng::nevernew { protected: lua_State *L_; - - LuaCoreStack(lua_State *L) : L_(L) {} - + private: // Push any value on the stack, by type. void push_any_value(LuaNewTableMarker s) const { lua_newtable(L_); } @@ -306,6 +305,8 @@ private: void argerr(const char *arg, const char *tp) const; public: + LuaCoreStack(lua_State *L) : L_(L) {} + lua_State *state() const { return L_; } // This is the largest integer that can be stored in a lua_Number. @@ -479,6 +480,17 @@ public: static bool int64_storable(int64_t v) { return (v <= MAXINT) && (v >= -MAXINT); } }; +//////////////////////////////////////////////////////////////////// +// +// LuaOldStack +// +// This class is deprecated, we're phasing it out. This was the first piece of +// code we wrote to allocate stack slots, and it has issues. It is +// still in use in the difference transmitter and the source database, +// and a few other small spots. +// +//////////////////////////////////////////////////////////////////// + class LuaOldStack : public LuaCoreStack { private: int narg_; @@ -578,6 +590,33 @@ public: ~LuaOldStack() {}; }; +//////////////////////////////////////////////////////////////////// +// +// LuaDefStack +// +// This version of LuaStack is meant to be used at the top level of a LuaDefine. +// It can assign stack slots to LuaArg, LuaRet, and LuaVar locals. It arranges +// for the arguments to be in the LuaArg variables, and it arranges for the +// LuaRet variables to be returned. It also makes sure that the function has +// the correct number of arguments. +// +// At the end of the LuaDefine function, you're supposed to return LS.result(). +// LS.result causes the allocated stack slots to be freed except for the LuaRet +// values, which have to stay on the stack in order to pass them back as return +// values. LS.result returns the number of LuaRet variables left on the stack. +// +// If you terminate a LuaDefine by calling lua_error or lua_yield, then +// obviously, you don't get a chance to call LS.result. That's not a problem. +// The lua interpreter will clean up after an error or yield. +// +// Implementation note: LuaDefStack doesn't have a destructor to deallocate +// stack slots. That's deliberate: you shouldn't expect this class to clean +// up its stack frame, because after all, it has to leave return values on +// the stack. It would be deceptive to put a destructor, which then doesn't +// actually clean up anyway. Better to just let it be known that this +// class doesn't clean up its stack frame. +// +//////////////////////////////////////////////////////////////////// class LuaDefStack : public LuaCoreStack { private: @@ -651,6 +690,26 @@ public: ~LuaDefStack() { } }; +//////////////////////////////////////////////////////////////////// +// +// LuaExtStack +// +// This version of LuaStack is meant to be used in any context where +// you want to assign stack slots to some LuaVars, and then you want +// to automatically deallocate those LuaVars when the LuaExtStack +// goes out of scope. +// +// Unlike LuaDefStack, this version of LuaStack is meant to fully +// deallocate its stack frame when it goes out of scope, so it does +// have a destructor to do that. There is a special case in the +// destructor: if lua is throwing an error, the destructor leaves +// the stack alone, in order to preserve the error message that's +// on the stack. After an error throw, the lua interpreter will +// clean up the stack. +// +//////////////////////////////////////////////////////////////////// + + class LuaExtStack : public LuaCoreStack { private: int oldtop_; @@ -700,14 +759,28 @@ public: if (!lua_isthrowing(L_)) { lua_settop(L_, oldtop_); } - } - - void forcediscard() { - lua_settop(L_, oldtop_); } }; +//////////////////////////////////////////////////////////////////// +// +// LuaKeywordParser +// // This is a helper class to help parse tables full of keywords. +// It is meant to make it easier to write LuaDefine functions that +// accept keyword arguments. It helps with the following tasks: +// +// * It makes sure the keyword table actually is a table. +// +// * It makes sure that you didn't put an unrecognized keyword +// into the keyword table. Unrecognized keywords are defined +// as keywords that are never checked using 'parse'. +// +// * It makes sure that you didn't put anything that isn't a +// keyword into the keyword table. +// +//////////////////////////////////////////////////////////////////// + class LuaKeywordParser { struct cmp_char { bool operator () (const char *s1, const char *s2) const { @@ -742,6 +815,12 @@ public: lua_State *state() const { return L_; } }; +//////////////////////////////////////////////////////////////////// +// +// The Lua Constant Registry +// +//////////////////////////////////////////////////////////////////// + class LuaConstantReg : public eng::nevernew { private: const char *name_; @@ -761,6 +840,12 @@ public: LuaConstantReg *next() const { return next_; } }; +//////////////////////////////////////////////////////////////////// +// +// The Lua Function Registry +// +//////////////////////////////////////////////////////////////////// + class LuaFunctionReg : public eng::nevernew { private: const char *name_; @@ -784,6 +869,12 @@ public: void set_func(lua_CFunction fn) { func_ = fn; } }; +//////////////////////////////////////////////////////////////////// +// +// LuaDefine and friends. +// +//////////////////////////////////////////////////////////////////// + #define LuaTokenConstant(name, tvalue, docs) \ LuaToken ltoken_##name(tvalue); \ LuaConstantReg reg_##name(#name, docs, LuaToken(tvalue), 0); @@ -812,4 +903,4 @@ public: #define LuaAssert(L, x) if (!(x)) { luaL_error((L), "Assert failed: %s (file %s line %d)", LuaStringify(x), __FILE__, __LINE__); } #define LuaAssertStrEq(L, x, y) { eng::string _s1_(x); eng::string _s2_(y); if (_s1_ != _s2_) luaL_error((L), "Assert failed: value=%s (file %s line %d)", _s1_.c_str(), __FILE__, __LINE__); } -#endif // LuaOldStack_HPP +#endif // LUASTACK_HPP diff --git a/luprex/cpp/core/planemap.cpp b/luprex/cpp/core/planemap.cpp index f564243e..7012f386 100644 --- a/luprex/cpp/core/planemap.cpp +++ b/luprex/cpp/core/planemap.cpp @@ -830,7 +830,7 @@ void PlaneMap::untrack_all() { void PlaneScan::configure(LuaKeywordParser &kp) { lua_State *L = kp.state(); LuaVar val, vx, vy, vz; - LuaOldStack LS(L, val, vx, vy, vz); + LuaExtStack LS(L, val, vx, vy, vz); bool have_plane = false; bool have_center = false; diff --git a/luprex/cpp/core/pprint.cpp b/luprex/cpp/core/pprint.cpp index 8b3a8b6f..57a2a340 100644 --- a/luprex/cpp/core/pprint.cpp +++ b/luprex/cpp/core/pprint.cpp @@ -10,7 +10,7 @@ class PrintMachine { public: LuaVar tabchpos_; - LuaOldStack LS_; + LuaExtStack LS_; int next_id_; bool indent_; std::ostream *output_; @@ -103,7 +103,7 @@ public: lua_State *L = LS_.state(); lua_checkstack(L, 20); LuaVar loffset, pairs, key, val, lchpos, nextseq; - LuaOldStack LS(L, loffset, pairs, key, val, lchpos, nextseq); + LuaExtStack LS(L, loffset, pairs, key, val, lchpos, nextseq); // Determine the extended type of the object. If the // expand flag is true, try to coerce it to a general table. @@ -113,7 +113,6 @@ public: if (xtype != LUA_TT_GENERAL) { atomic_print(xtype, value, true); if ((xtype < LUA_TT_GENERAL) || (!expand)) { - LS.result(); return; } } @@ -207,8 +206,6 @@ public: (*output_) << " "; } (*output_) << "}"; - - LS.result(); } // Atomic print interface. @@ -216,7 +213,6 @@ public: LS_(LS0.state(), tabchpos_) { output_ = os; atomic_print(LS_.xtype(root), root, quote); - LS_.result(); } // Pretty print interface. @@ -242,13 +238,12 @@ public: } (*os).put(pre[i]); } - LS_.result(); } }; void PrettyPrintOptions::parse(LuaKeywordParser &kp) { LuaVar option; - LuaOldStack LS(kp.state(), option); + LuaExtStack LS(kp.state(), option); if (kp.parse(option, "indent")) { indent = LS.ckboolean(option); } @@ -258,7 +253,6 @@ void PrettyPrintOptions::parse(LuaKeywordParser &kp) { if (kp.parse(option, "expand")) { expand = LS.ckboolean(option); } - LS.result(); } void atomic_print(LuaCoreStack &LS, LuaSlot val, bool quote, std::ostream *os) { @@ -278,8 +272,7 @@ LuaDefine(string_pprint, "obj1, obj2, ...", "|top-level table." "|") { int n = lua_gettop(L); - LuaRet result; - LuaOldStack LS(L, result); + LuaCoreStack LS(L); util::ostringstream oss; for (int i = 1; i <= n; i++) { LuaSpecial root(i); @@ -287,8 +280,10 @@ LuaDefine(string_pprint, "obj1, obj2, ...", if (i < n) oss << "\n"; } oss << std::endl; + lua_settop(L, 1); + LuaSpecial result(1); LS.set(result, oss.view()); - return LS.result(); + return 1; } LuaDefine(string_pprintx, "options", @@ -310,7 +305,7 @@ LuaDefine(string_pprintx, "options", LuaArg loptions; LuaRet result; LuaVar value; - LuaOldStack LS(L, loptions, result, value); + LuaDefStack LS(L, loptions, result, value); PrettyPrintOptions options; LuaKeywordParser kp(LS, loptions); options.parse(kp); @@ -333,7 +328,7 @@ LuaDefine(string_print, "obj", "|") { LuaArg val; LuaRet result; - LuaOldStack LS(L, val, result); + LuaDefStack LS(L, val, result); eng::ostringstream oss; atomic_print(LS, val, false, &oss); LS.set(result, oss.str()); @@ -350,7 +345,7 @@ LuaDefine(tostring, "obj", "|") { LuaArg val; LuaRet result; - LuaOldStack LS(L, val, result); + LuaDefStack LS(L, val, result); eng::ostringstream oss; atomic_print(LS, val, false, &oss); LS.set(result, oss.str()); @@ -360,7 +355,7 @@ LuaDefine(tostring, "obj", LuaDefine(string_isidentifier, "str", "return true if the string is a valid lua identifier") { LuaArg str; LuaRet result; - LuaOldStack LS(L, str, result); + LuaDefStack LS(L, str, result); if (LS.isstring(str)) { eng::string s = LS.ckstring(str); LS.set(result, sv::is_lua_id(s)); diff --git a/luprex/cpp/core/serializelua.cpp b/luprex/cpp/core/serializelua.cpp index 07142d7c..ef6b577a 100644 --- a/luprex/cpp/core/serializelua.cpp +++ b/luprex/cpp/core/serializelua.cpp @@ -12,14 +12,14 @@ class DeserializeError { class Deserializer { LuaVar id_to_value_; - LuaOldStack LS_; + LuaExtStack LS_; eng::string &error_; StreamBuffer *sb_; int next_id_; void deserialize_table_r(LuaSlot target) { LuaVar key, val; - LuaOldStack LS(LS_.state(), key, val); + LuaExtStack LS(LS_.state(), key, val); LS.newtable(target); LS.rawset(id_to_value_, next_id_++, target); bool hasmeta = sb_->read_bool(); @@ -124,7 +124,6 @@ public: lua_settop(LS_.state(), top); LS_.set(val, LuaNil); } - LS_.result(); } }; @@ -137,14 +136,14 @@ public: class Serializer { LuaVar lookup_; LuaVar value_to_id_; - LuaOldStack LS_; + LuaExtStack LS_; eng::string &error_; StreamBuffer *sb_; int next_id_; void serialize_table_r(LuaSlot tab) { LuaVar key, val; - LuaOldStack SLS(LS_.state(), key, val); + LuaExtStack SLS(LS_.state(), key, val); sb_->write_uint8(LUA_TT_GENERAL); SLS.getmetatable(val, tab); if (SLS.isnil(val)) { @@ -157,17 +156,14 @@ class Serializer { while (SLS.next(tab, key, val)) { serialize_r(key); if (!error_.empty()) { - SLS.result(); return; } serialize_r(val); if (!error_.empty()) { - SLS.result(); return; } } sb_->write_uint8(LUA_PK_ENDTABLE); - SLS.result(); } void serialize_r(LuaSlot val) { @@ -270,7 +266,6 @@ public: LS_.newtable(value_to_id_); sb_->write_uint16(0xD096); serialize_r(val); - LS_.result(); } }; @@ -328,7 +323,7 @@ LuaDefine(table_serialize, "value", "|") { LuaArg value; LuaRet str; - LuaOldStack LS(L, value, str); + LuaDefStack LS(L, value, str); StreamBuffer sb; eng::string error = serialize_lua(LS, value, &sb); if (!error.empty()) { @@ -347,7 +342,7 @@ LuaDefine(table_deserialize, "binary", "|") { LuaArg str; LuaRet value; - LuaOldStack LS(L, value, str); + LuaDefStack LS(L, value, str); std::string_view s = LS.ckstringview(str); StreamBuffer sb(s); eng::string error = deserialize_lua(LS, value, &sb); diff --git a/luprex/cpp/core/source.cpp b/luprex/cpp/core/source.cpp index 54e07ad7..f13a8ac2 100644 --- a/luprex/cpp/core/source.cpp +++ b/luprex/cpp/core/source.cpp @@ -21,7 +21,7 @@ LuaDefine(makeclass, "classname", "create a class if it doesn't already exist") { LuaArg classname; LuaRet classtab; - LuaOldStack LS(L, classname, classtab); + LuaDefStack LS(L, classname, classtab); if (!LS.isstring(classname)) { luaL_error(L, "class name must be a string"); } @@ -35,7 +35,7 @@ LuaDefine(makeclass, "classname", "create a class if it doesn't already exist") LuaDefine(getclass, "classname", "get the classtab with the specified name") { LuaArg classname; LuaRet classtab; - LuaOldStack LS(L, classname, classtab); + LuaDefStack LS(L, classname, classtab); eng::string err = LS.getclass(classtab, classname); if (err != "") { luaL_error(L, "%s", err.c_str()); @@ -46,7 +46,7 @@ LuaDefine(getclass, "classname", "get the classtab with the specified name") { LuaDefine(classname, "classtable", "get the class name from a class table") { LuaArg table; LuaRet result; - LuaOldStack LS(L, table, result); + LuaDefStack LS(L, table, result); eng::string rstr = LS.classname(table); if (rstr == "") { LS.set(result, LuaNil); @@ -78,7 +78,7 @@ static void get_info_table(LuaCoreStack &LS, LuaSlot db, LuaSlot info, const eng static void calculate_loadresult(LuaCoreStack &LS0, LuaSlot info, const eng::string &fn, const eng::string &code) { LuaVar loadresult; - LuaOldStack LS(LS0.state(), loadresult); + LuaExtStack LS(LS0.state(), loadresult); if (code == "") { LS.rawset(info, "loadresult", "missing or empty source file"); } else { @@ -250,7 +250,7 @@ void SourceDB::update(const util::LuaSourceVec &source) { // static void source_clear_globals(lua_State *L) { LuaVar classname, classtab, key, globtab, classes; - LuaOldStack LS(L, classname, classtab, key, globtab, classes); + LuaExtStack LS(L, classname, classtab, key, globtab, classes); LS.getglobaltable(globtab); LS.cleartable(globtab, true); @@ -263,7 +263,6 @@ static void source_clear_globals(lua_State *L) { assert(LS.istable(classtab)); LS.cleartable(classtab, true); } - LS.result(); } @@ -470,7 +469,7 @@ void SourceDB::deserialize_source(util::LuaSourceVec *sv, StreamBuffer *sb) { // This function should not touch the dlmalloc heap. void SourceDB::register_lua_builtins() { - lua_State *L = LuaOldStack::newstate(nullptr); + lua_State *L = LuaCoreStack::newstate(nullptr); luaL_openlibs(L); LuaVar globals, lclassname, lfuncname, classtab, func; LuaOldStack LS(L, globals, lclassname, lfuncname, classtab, func); @@ -766,7 +765,7 @@ LuaSandboxBuiltin(math_log10, "", ""); LuaNumberConstant(math_pi, M_PI, ""); LuaNumberConstant(math_huge, HUGE_VAL, ""); LuaNumberConstant(math_nan, NAN, ""); -LuaNumberConstant(math_maxint, LuaOldStack::MAXINT, ""); +LuaNumberConstant(math_maxint, LuaCoreStack::MAXINT, ""); // math.random and math.randomseed are in world-accessor.cpp, because // generating random numbers must manipulate global state which is diff --git a/luprex/cpp/core/world-accessor.cpp b/luprex/cpp/core/world-accessor.cpp index 19157bb1..c987590a 100644 --- a/luprex/cpp/core/world-accessor.cpp +++ b/luprex/cpp/core/world-accessor.cpp @@ -7,7 +7,7 @@ static void tangible_getall(LuaCoreStack &LS0, LuaSlot list, const util::IdVector &idv) { LuaVar tangibles, tan; - LuaOldStack LS(LS0.state(), tangibles, tan); + LuaExtStack LS(LS0.state(), tangibles, tan); LS.rawget(tangibles, LuaRegistry, "tangibles"); assert(LS.istable(tangibles)); LS.set(list, LuaNewTable); @@ -17,7 +17,6 @@ static void tangible_getall(LuaCoreStack &LS0, LuaSlot list, const util::IdVecto assert(LS.istable(tan)); LS.rawset(list, index++, tan); } - LS.result(); } LuaDefine(tangible_animstate, "tan", @@ -25,7 +24,7 @@ LuaDefine(tangible_animstate, "tan", "|Returns six values: graphic,plane,x,y,z,facing.") { LuaArg tanobj; LuaRet graphic, plane, x, y, z, facing; - LuaOldStack LS(L, tanobj, graphic, plane, x, y, z, facing); + LuaDefStack LS(L, tanobj, graphic, plane, x, y, z, facing); World *w = World::fetch_global_pointer(L); Tangible *tan = w->tangible_get(LS, tanobj, false); const AnimStep &aqback = tan->anim_queue_.back(); @@ -43,7 +42,7 @@ LuaDefine(tangible_xyz, "tan", "|Returns three values: x, y, z") { LuaArg tanobj; LuaRet x, y, z; - LuaOldStack LS(L, tanobj, x, y, z); + LuaDefStack LS(L, tanobj, x, y, z); World *w = World::fetch_global_pointer(L); Tangible *tan = w->tangible_get(LS, tanobj, false); const AnimStep &aqback = tan->anim_queue_.back(); @@ -58,7 +57,7 @@ LuaDefine(tangible_animate, "tan,configtable", "|The configtable is a table containing any of the following:" "|action,graphic,plane,x,y,z,facing") { LuaArg tanobj, config; - LuaOldStack LS(L, tanobj, config); + LuaDefStack LS(L, tanobj, config); LuaKeywordParser kp(LS, config); World *w = World::fetch_global_pointer(L); Tangible *tan = w->tangible_get(LS, tanobj, false); @@ -81,7 +80,7 @@ LuaDefine(tangible_setclass, "tan,class", "|given an __index metamethod that points at the class table.") { LuaArg tanobj, classname; LuaVar classtab, mt; - LuaOldStack LS(L, tanobj, classname, classtab, mt); + LuaDefStack LS(L, tanobj, classname, classtab, mt); World *w = World::fetch_global_pointer(L); w->tangible_get(LS, tanobj, false); eng::string err = LS.getclass(classtab, classname); @@ -100,7 +99,7 @@ LuaDefine(tangible_getclass, "tan", LuaArg tanobj; LuaVar mt, classtab; LuaRet classname; - LuaOldStack LS(L, tanobj, mt, classtab, classname); + LuaDefStack LS(L, tanobj, mt, classtab, classname); World *w = World::fetch_global_pointer(L); w->tangible_get(LS, tanobj, false); LS.getmetatable(mt, tanobj); @@ -119,7 +118,7 @@ LuaDefine(tangible_delete, "tan", "|This cannot be used to delete player tangibles," "|To delete a player, use tangible.redirect") { LuaArg tanobj; - LuaOldStack LS(L, tanobj); + LuaDefStack LS(L, tanobj); World *w = World::fetch_global_pointer(L); Tangible *tan = w->tangible_get(LS, tanobj, true); if (tan == nullptr) { @@ -140,7 +139,7 @@ LuaDefine(tangible_build, "config", LuaArg config; LuaVar classname, classtab, mt; LuaRet database; - LuaOldStack LS(L, config, classname, classtab, database, mt); + LuaDefStack LS(L, config, classname, classtab, database, mt); LuaKeywordParser kp(LS, config); // Get the class of the new tangible. @@ -192,7 +191,7 @@ LuaDefine(tangible_get, "id", LuaArg id; LuaVar tangibles; LuaRet database; - LuaOldStack LS(L, id, tangibles, database); + LuaDefStack LS(L, id, tangibles, database); int64_t nid = LS.ckinteger(id); LS.rawget(tangibles, LuaRegistry, "tangibles"); LS.rawget(database, tangibles, id); @@ -205,7 +204,7 @@ LuaDefine(tangible_get, "id", LuaDefine(tangible_redirect, "tan1,tan2,bulldozetan1", "|Redirect is not working yet") { LuaArg actor1, actor2, bldz; - LuaOldStack LS(L, actor1, actor2, bldz); + LuaDefStack LS(L, actor1, actor2, bldz); World *w = World::fetch_global_pointer(L); bool bulldoze = LS.ckboolean(bldz); Tangible *tan1 = w->tangible_get(LS, actor1, false); @@ -231,7 +230,7 @@ LuaDefine(tangible_id, "tan", "|in the released version.") { LuaArg tanobj; LuaRet id; - LuaOldStack LS(L, tanobj, id); + LuaDefStack LS(L, tanobj, id); int64_t tid = LS.tanid(tanobj); if (tid == 0) { luaL_error(L, "Not a tangible"); @@ -244,7 +243,7 @@ LuaDefine(tangible_actor, "", "|Return the current actor.") { LuaRet actor; LuaVar tangibles; - LuaOldStack LS(L, tangibles, actor); + LuaDefStack LS(L, tangibles, actor); World *w = World::fetch_global_pointer(L); LS.rawget(tangibles, LuaRegistry, "tangibles"); LS.rawget(actor, tangibles, w->lthread_actor_id_); @@ -255,7 +254,7 @@ LuaDefine(tangible_place, "", "|Return the current place.") { LuaRet place; LuaVar tangibles; - LuaOldStack LS(L, tangibles, place); + LuaDefStack LS(L, tangibles, place); World *w = World::fetch_global_pointer(L); LS.rawget(tangibles, LuaRegistry, "tangibles"); LS.rawget(place, tangibles, w->lthread_place_id_); @@ -269,7 +268,7 @@ LuaDefine(tangible_near, "tan,radius,omit_nowhere,omit_self", "|tangible passed in is omitted from the results.") { LuaArg ltan, lradius, lomit_nowhere, lomit_self; LuaRet list; - LuaOldStack LS(L, ltan, lradius, lomit_nowhere, lomit_self, list); + LuaDefStack LS(L, ltan, lradius, lomit_nowhere, lomit_self, list); World *w = World::fetch_global_pointer(L); Tangible *tan = w->tangible_get(LS, ltan, false); const AnimStep &aqback = tan->anim_queue_.back(); @@ -293,7 +292,7 @@ LuaDefine(tangible_scan, "plane,x,y,radius,omit_nowhere", "|the scan returns empty.") { LuaArg lplane, lx, ly, lradius, lomit_nowhere; LuaRet list; - LuaOldStack LS(L, lplane, lx, ly, lradius, lomit_nowhere, list); + LuaDefStack LS(L, lplane, lx, ly, lradius, lomit_nowhere, list); World *w = World::fetch_global_pointer(L); PlaneScan scan; @@ -367,7 +366,7 @@ LuaDefine(tangible_find, "config", "|") { LuaArg config; LuaRet result; - LuaOldStack LS(L, config, result); + LuaDefStack LS(L, config, result); LuaKeywordParser kw(LS, config); PlaneScan scan; scan.configure(kw); @@ -446,7 +445,7 @@ LuaDefine(tangible_start, "tangible,function,arg1,arg2...", w->guard_blockable(L, "tangible.start"); LuaVar mt, classtab, plthreads, thread, thinfo, func, tanlist; - LuaOldStack LS(L, mt, classtab, plthreads, thread, thinfo, func, tanlist); + LuaDefStack LS(L, mt, classtab, plthreads, thread, thinfo, func, tanlist); LuaSpecial place(1); LuaSpecial fname(2); @@ -537,7 +536,7 @@ LuaDefine(wait, "nticks", // Parse the argument. LuaArg seconds; - LuaOldStack LS(L, seconds); + LuaDefStack LS(L, seconds); int64_t n = LS.ckinteger(seconds); if ((n < 0) || (n > 1000000)) { luaL_error(L, "Argument to wait must be between 0 and 1000000"); @@ -603,7 +602,7 @@ LuaDefine(math_random, "(args...)", highf = std::floor(lua_tonumber(L, arg)); arg += 1; } - if ((lowf < -LuaOldStack::MAXINT) || (highf > LuaOldStack::MAXINT)) { + if ((lowf < -LuaCoreStack::MAXINT) || (highf > LuaCoreStack::MAXINT)) { luaL_error(L, "math.random range exceeds MAXINT"); return 0; } @@ -636,8 +635,8 @@ LuaDefine(math_random, "(args...)", } double dseed = lua_tonumber(L, -2); double dcount = lua_tonumber(L, -1); - seed = uint64_t(dseed) & LuaOldStack::MAXINT; - count = uint64_t(dcount) & LuaOldStack::MAXINT; + seed = uint64_t(dseed) & LuaCoreStack::MAXINT; + count = uint64_t(dcount) & LuaCoreStack::MAXINT; if (dseed < 0) { salt = 0x35c9a6082a097ade; } else { @@ -645,7 +644,7 @@ LuaDefine(math_random, "(args...)", } lua_pop(L, 2); lua_pushstring(L, "count"); - lua_pushnumber(L, double((count + 1) & LuaOldStack::MAXINT)); + lua_pushnumber(L, double((count + 1) & LuaCoreStack::MAXINT)); lua_rawset(L, 1); } else { World *w = World::fetch_global_pointer(L); @@ -692,7 +691,7 @@ LuaDefine(math_randomstate, "seed", double seed; if (lua_gettop(L) == 0) { World *w = World::fetch_global_pointer(L); - int64_t iseed = (w->id_global_pool_.get_seqno() & LuaOldStack::MAXINT) + 1; + int64_t iseed = (w->id_global_pool_.get_seqno() & LuaCoreStack::MAXINT) + 1; seed = -iseed; } else if (lua_gettop(L) == 1) { if (lua_type(L, 1) != LUA_TNUMBER) { @@ -700,7 +699,7 @@ LuaDefine(math_randomstate, "seed", return 0; } seed = lua_tonumber(L, 1); - if ((seed < 0.0) || (seed > LuaOldStack::MAXINT) || (std::floor(seed) != seed)) { + if ((seed < 0.0) || (seed > LuaCoreStack::MAXINT) || (std::floor(seed) != seed)) { luaL_error(L, "math.randomstate seed must be an integer 0-MAXINT"); return 0; } @@ -732,7 +731,7 @@ LuaDefine(pprint, "obj1, obj2, ...", World *w = World::fetch_global_pointer(L); std::ostream *ostream = w->lthread_print_stream(); int n = lua_gettop(L); - LuaOldStack LS(L); + LuaDefStack LS(L); for (int i = 1; i <= n; i++) { LuaSpecial root(i); pprint(LS, root, PrettyPrintOptions(), ostream); @@ -763,7 +762,7 @@ LuaDefine(pprintx, "options", std::ostream *ostream = w->lthread_print_stream(); LuaArg loptions; LuaVar value; - LuaOldStack LS(L, loptions, value); + LuaDefStack LS(L, loptions, value); PrettyPrintOptions options; LuaKeywordParser kp(LS, loptions); options.parse(kp); @@ -779,7 +778,7 @@ LuaDefine(print, "obj1, obj2, ...", "|Print object or objects.") { World *w = World::fetch_global_pointer(L); std::ostream *ostream = w->lthread_print_stream(); - LuaOldStack LS(L); + LuaCoreStack LS(L); int n = lua_gettop(L); for (int i = 1; i <= n; i++) { LuaSpecial root(i); @@ -787,7 +786,7 @@ LuaDefine(print, "obj1, obj2, ...", if (i < n) (*ostream) << " "; } (*ostream) << std::endl; - return LS.result(); + return 0; } LuaDefine(doc, "function", @@ -795,7 +794,7 @@ LuaDefine(doc, "function", World *w = World::fetch_global_pointer(L); std::ostream *ostream = w->lthread_print_stream(); LuaArg func; - LuaOldStack LS(L, func); + LuaDefStack LS(L, func); eng::string doc = SourceDB::function_docs(LS, func); if (doc == "") { (*ostream) << "no doc found" << std::endl; @@ -936,7 +935,7 @@ LuaDefine(global_set, "varname, value", "|") { LuaArg varname; LuaArg value; - LuaOldStack LS(L, varname, value); + LuaDefStack LS(L, varname, value); // Check the varname argument. eng::string gvar = LS.ckstring(varname); @@ -961,7 +960,7 @@ LuaDefine(global_get, "varname", LuaArg varname; LuaRet value; LuaVar globaldb; - LuaOldStack LS(L, varname, value, globaldb); + LuaDefStack LS(L, varname, value, globaldb); LS.rawget(globaldb, LuaRegistry, "globaldb"); LS.rawget(value, globaldb, varname); return LS.result(); @@ -977,7 +976,7 @@ LuaDefine(global_once, "varname", LuaArg varname; LuaRet result; LuaVar globaldb, flag; - LuaOldStack LS(L, varname, flag, result, globaldb); + LuaDefStack LS(L, varname, flag, result, globaldb); // Check the varname argument. eng::string gvar = LS.ckstring(varname); @@ -1009,7 +1008,7 @@ LuaDefine(global_clearonce, "varname", "|") { LuaArg varname; LuaVar null; - LuaOldStack LS(L, varname, null); + LuaDefStack LS(L, varname, null); // Check the varname argument. eng::string gvar = LS.ckstring(varname); diff --git a/luprex/cpp/core/world.hpp b/luprex/cpp/core/world.hpp index 108da3bc..894c895e 100644 --- a/luprex/cpp/core/world.hpp +++ b/luprex/cpp/core/world.hpp @@ -240,7 +240,7 @@ public: // Check if the world is authoritative. // - bool is_authoritative() const { return LuaOldStack::is_authoritative(world_type_); } + bool is_authoritative() const { return LuaCoreStack::is_authoritative(world_type_); } // Get a table showing all outstanding HTTP requests. //