diff --git a/src/common/Variant.cpp b/src/common/Variant.cpp index df5ac0a17..1915561c4 100644 --- a/src/common/Variant.cpp +++ b/src/common/Variant.cpp @@ -26,7 +26,7 @@ namespace love { -static love::Type *extractudatatype(lua_State *L, int idx) +static Proxy *tryextractproxy(lua_State *L, int idx) { Proxy *u = (Proxy *)lua_touserdata(L, idx); @@ -36,7 +36,7 @@ static love::Type *extractudatatype(lua_State *L, int idx) // We could get rid of the dynamic_cast for more performance, but it would // be less safe... if (dynamic_cast(u->object) != nullptr) - return u->type; + return u; return nullptr; } @@ -73,25 +73,20 @@ Variant::Variant(const char *string, size_t len) } } -Variant::Variant(void *userdata) +Variant::Variant(void *lightuserdata) : type(LUSERDATA) { - data.userdata = userdata; + data.userdata = lightuserdata; } -Variant::Variant(love::Type *udatatype, void *userdata) - : type(FUSERDATA) - , udatatype(udatatype) +Variant::Variant(love::Type *lovetype, love::Object *object) + : type(LOVEOBJECT) { - if (udatatype != nullptr) - { - love::Object *o = (love::Object *) userdata; - data.userdata = o; - if (o != nullptr) - o->retain(); - } - else - data.userdata = userdata; + data.objectproxy.type = lovetype; + data.objectproxy.object = object; + + if (data.objectproxy.object != nullptr) + data.objectproxy.object->retain(); } // Variant gets ownership of the vector. @@ -103,20 +98,18 @@ Variant::Variant(std::vector> *table) Variant::Variant(const Variant &v) : type(v.type) - , udatatype(v.udatatype) , data(v.data) { if (type == STRING) data.string->retain(); - else if (type == FUSERDATA && udatatype != nullptr && data.userdata != nullptr) - ((love::Object *) data.userdata)->retain(); + else if (type == LOVEOBJECT && data.objectproxy.object != nullptr) + data.objectproxy.object->retain(); else if (type == TABLE) data.table->retain(); } Variant::Variant(Variant &&v) : type(std::move(v.type)) - , udatatype(std::move(v.udatatype)) , data(std::move(v.data)) { v.type = NIL; @@ -124,42 +117,32 @@ Variant::Variant(Variant &&v) Variant::~Variant() { - switch (type) - { - case STRING: + if (type == STRING) data.string->release(); - break; - case FUSERDATA: - if (udatatype != nullptr && data.userdata != nullptr) - ((love::Object *) data.userdata)->release(); - break; - case TABLE: + else if (type == LOVEOBJECT && data.objectproxy.object != nullptr) + data.objectproxy.object->release(); + else if (type == TABLE) data.table->release(); - break; - default: - break; - } } Variant &Variant::operator = (const Variant &v) { if (v.type == STRING) v.data.string->retain(); - else if (v.type == FUSERDATA && v.udatatype != nullptr && v.data.userdata != nullptr) - ((love::Object *) v.data.userdata)->retain(); + else if (v.type == LOVEOBJECT && v.data.objectproxy.object != nullptr) + v.data.objectproxy.object->retain(); else if (v.type == TABLE) v.data.table->retain(); if (type == STRING) data.string->release(); - else if (type == FUSERDATA && udatatype != nullptr && data.userdata != nullptr) - ((love::Object *) data.userdata)->release(); + else if (type == LOVEOBJECT && data.objectproxy.object != nullptr) + data.objectproxy.object->release(); else if (type == TABLE) data.table->release(); type = v.type; data = v.data; - udatatype = v.udatatype; return *this; } @@ -168,6 +151,7 @@ Variant Variant::fromLua(lua_State *L, int n, std::set *tableSet) { size_t len; const char *str; + Proxy *p = nullptr; if (n < 0) // Fix the stack position, we might modify it later n += lua_gettop(L) + 1; @@ -184,7 +168,14 @@ Variant Variant::fromLua(lua_State *L, int n, std::set *tableSet) case LUA_TLIGHTUSERDATA: return Variant(lua_touserdata(L, n)); case LUA_TUSERDATA: - return Variant(extractudatatype(L, n), lua_touserdata(L, n)); + p = tryextractproxy(L, n); + if (p != nullptr) + return Variant(p->type, p->object); + else + { + luax_typerror(L, n, "love type"); + return Variant(); + } case LUA_TNIL: return Variant(); case LUA_TTABLE: @@ -259,14 +250,8 @@ void Variant::toLua(lua_State *L) const case LUSERDATA: lua_pushlightuserdata(L, data.userdata); break; - case FUSERDATA: - if (udatatype != nullptr) - luax_pushtype(L, *udatatype, (love::Object *) data.userdata); - else - lua_pushlightuserdata(L, data.userdata); - // I know this is not the same - // sadly, however, it's the most - // I can do (at the moment). + case LOVEOBJECT: + luax_pushtype(L, *data.objectproxy.type, data.objectproxy.object); break; case TABLE: { diff --git a/src/common/Variant.h b/src/common/Variant.h index 9c1494590..8ad2944a7 100644 --- a/src/common/Variant.h +++ b/src/common/Variant.h @@ -44,7 +44,7 @@ public: STRING, SMALLSTRING, LUSERDATA, - FUSERDATA, + LOVEOBJECT, NIL, TABLE }; @@ -53,8 +53,8 @@ public: Variant(bool boolean); Variant(double number); Variant(const char *string, size_t len); - Variant(void *userdata); - Variant(love::Type *udatatype, void *userdata); + Variant(void *lightuserdata); + Variant(love::Type *type, love::Object *object); Variant(std::vector> *table); Variant(const Variant &v); Variant(Variant &&v); @@ -102,7 +102,6 @@ private: static const int MAX_SMALL_STRING_LENGTH = 15; Type type; - love::Type *udatatype; union Data { @@ -110,6 +109,7 @@ private: double number; SharedString *string; void *userdata; + Proxy objectproxy; SharedTable *table; struct { diff --git a/src/modules/event/wrap_Event.cpp b/src/modules/event/wrap_Event.cpp index 2578ce27f..3b484db55 100644 --- a/src/modules/event/wrap_Event.cpp +++ b/src/modules/event/wrap_Event.cpp @@ -74,7 +74,8 @@ int w_wait(lua_State *L) int w_push(lua_State *L) { - StrongRef m(Message::fromLua(L, 1), Acquire::NORETAIN); + StrongRef m; + luax_catchexcept(L, [&]() { m.set(Message::fromLua(L, 1), Acquire::NORETAIN); }); luax_pushboolean(L, m.get() != nullptr);