diff --git a/src/common/Variant.cpp b/src/common/Variant.cpp index 7b33ee80b..8fd893f3f 100644 --- a/src/common/Variant.cpp +++ b/src/common/Variant.cpp @@ -160,7 +160,7 @@ Variant &Variant::operator = (const Variant &v) return *this; } -bool Variant::fromLua(lua_State *L, int n, Variant *v, bool allowTables) +Variant Variant::fromLua(lua_State *L, int n, bool allowTables) { size_t len; const char *str; @@ -171,30 +171,23 @@ bool Variant::fromLua(lua_State *L, int n, Variant *v, bool allowTables) switch (lua_type(L, n)) { case LUA_TBOOLEAN: - *v = Variant(luax_toboolean(L, n)); - return true; + return Variant(luax_toboolean(L, n)); case LUA_TNUMBER: - *v = Variant(lua_tonumber(L, n)); - return true; + return Variant(lua_tonumber(L, n)); case LUA_TSTRING: str = lua_tolstring(L, n, &len); - *v = Variant(str, len); - return true; + return Variant(str, len); case LUA_TLIGHTUSERDATA: - *v = Variant(lua_touserdata(L, n)); - return true; + return Variant(lua_touserdata(L, n)); case LUA_TUSERDATA: - *v = Variant(extractudatatype(L, n), lua_touserdata(L, n)); - return true; + return Variant(extractudatatype(L, n), lua_touserdata(L, n)); case LUA_TNIL: - *v = Variant(); - return true; + return Variant(); case LUA_TTABLE: if (allowTables) { bool success = true; std::vector> *table = new std::vector>(); - std::pair pair; size_t len = luax_objlen(L, -1); if (len > 0) @@ -204,29 +197,28 @@ bool Variant::fromLua(lua_State *L, int n, Variant *v, bool allowTables) while (lua_next(L, n)) { - if (!fromLua(L, -2, &pair.first, false) || !fromLua(L, -1, &pair.second, false)) + table->emplace_back(fromLua(L, -2), fromLua(L, -1)); + lua_pop(L, 1); + + const auto &p = table->back(); + if (p.first.getType() == UNKNOWN || p.second.getType() == UNKNOWN) { success = false; - lua_pop(L, 2); break; } - - table->push_back(pair); - lua_pop(L, 1); } if (success) - { - *v = Variant(table); - return true; - } + return Variant(table); else delete table; } break; } - return false; + Variant v; + v.type = UNKNOWN; + return v; } void Variant::toLua(lua_State *L) const @@ -260,11 +252,13 @@ void Variant::toLua(lua_State *L) const case TABLE: { std::vector> *table = data.table->table; - lua_createtable(L, 0, (int) table->size()); + int tsize = (int) table->size(); - for (size_t i = 0; i < table->size(); ++i) + lua_createtable(L, 0, tsize); + + for (int i = 0; i < tsize; ++i) { - std::pair &kv = table->at(i); + std::pair &kv = (*table)[i]; kv.first.toLua(L); kv.second.toLua(L); lua_settable(L, -3); diff --git a/src/common/Variant.h b/src/common/Variant.h index 3c4b9c5a3..87e5d3575 100644 --- a/src/common/Variant.h +++ b/src/common/Variant.h @@ -35,6 +35,19 @@ class Variant { public: + enum Type + { + UNKNOWN = 0, + BOOLEAN, + NUMBER, + STRING, + SMALLSTRING, + LUSERDATA, + FUSERDATA, + NIL, + TABLE + }; + Variant(); Variant(bool boolean); Variant(double number); @@ -48,7 +61,9 @@ public: Variant &operator = (const Variant &v); - static bool fromLua(lua_State *L, int n, Variant *v, bool allowTables = true); + Type getType() const { return type; } + + static Variant fromLua(lua_State *L, int n, bool allowTables = true); void toLua(lua_State *L) const; private: @@ -83,19 +98,6 @@ private: std::vector> *table; }; - enum Type - { - UNKNOWN = 0, - BOOLEAN, - NUMBER, - STRING, - SMALLSTRING, - LUSERDATA, - FUSERDATA, - NIL, - TABLE - }; - static const int MAX_SMALL_STRING_LENGTH = 15; Type type; diff --git a/src/modules/event/Event.cpp b/src/modules/event/Event.cpp index af5d86b08..960a39a08 100644 --- a/src/modules/event/Event.cpp +++ b/src/modules/event/Event.cpp @@ -63,14 +63,14 @@ Message *Message::fromLua(lua_State *L, int n) if (lua_isnoneornil(L, n+i)) break; - if (!Variant::fromLua(L, n+i, &varg)) + vargs.push_back(Variant::fromLua(L, n+i)); + + if (vargs.back().getType() == Variant::UNKNOWN) { vargs.clear(); luaL_error(L, "Argument %d can't be stored safely\nExpected boolean, number, string or userdata.", n+i); return nullptr; } - - vargs.push_back(varg); } return new Message(name, vargs); diff --git a/src/modules/event/wrap_Event.cpp b/src/modules/event/wrap_Event.cpp index de486bf61..06b9686f6 100644 --- a/src/modules/event/wrap_Event.cpp +++ b/src/modules/event/wrap_Event.cpp @@ -93,11 +93,7 @@ int w_clear(lua_State *) int w_quit(lua_State *L) { - std::vector args; - - Variant v; - if (Variant::fromLua(L, 1, &v)) - args.push_back(v); + std::vector args = {Variant::fromLua(L, 1)}; StrongRef m(new Message("quit", args), Acquire::NORETAIN); instance()->push(m); diff --git a/src/modules/thread/wrap_Channel.cpp b/src/modules/thread/wrap_Channel.cpp index 8fd30656f..813ca02cc 100644 --- a/src/modules/thread/wrap_Channel.cpp +++ b/src/modules/thread/wrap_Channel.cpp @@ -33,8 +33,8 @@ Channel *luax_checkchannel(lua_State *L, int idx) int w_Channel_push(lua_State *L) { Channel *c = luax_checkchannel(L, 1); - Variant var; - if (!Variant::fromLua(L, 2, &var)) + Variant var = Variant::fromLua(L, 2); + if (var.getType() == Variant::UNKNOWN) return luaL_argerror(L, 2, "boolean, number, string, love type, or flat table expected"); uint64 id = c->push(var); lua_pushnumber(L, (lua_Number) id); @@ -44,8 +44,8 @@ int w_Channel_push(lua_State *L) int w_Channel_supply(lua_State *L) { Channel *c = luax_checkchannel(L, 1); - Variant var; - if (!Variant::fromLua(L, 2, &var)) + Variant var = Variant::fromLua(L, 2); + if (var.getType() == Variant::UNKNOWN) return luaL_argerror(L, 2, "boolean, number, string, love type, or flat table expected"); c->supply(var); return 0; diff --git a/src/modules/thread/wrap_LuaThread.cpp b/src/modules/thread/wrap_LuaThread.cpp index 9fe432047..fefe06f1a 100644 --- a/src/modules/thread/wrap_LuaThread.cpp +++ b/src/modules/thread/wrap_LuaThread.cpp @@ -36,16 +36,15 @@ int w_Thread_start(lua_State *L) std::vector args; int nargs = lua_gettop(L) - 1; - Variant v; for (int i = 0; i < nargs; ++i) { - if (!Variant::fromLua(L, i+2, &v)) + args.push_back(Variant::fromLua(L, i+2)); + + if (args.back().getType() == Variant::UNKNOWN) { args.clear(); return luaL_argerror(L, i+2, "boolean, number, string, love type, or flat table expected"); } - - args.push_back(v); } luax_pushboolean(L, t->start(args));