From d556364ecf670ae6afb0edd5c79875cbc1e10d61 Mon Sep 17 00:00:00 2001 From: Sandu Liviu Catalin Date: Wed, 24 Oct 2018 21:37:51 +0300 Subject: [PATCH] Attempt to fix function binding to comply with changes to StackStrF. Various other changes to fix other issues related to changes in StackStrF behavior. --- include/sqrat/sqratGlobalMethods.h | 12 +-- include/sqrat/sqratMemberMethods.h | 24 ++--- include/sqrat/sqratTypes.h | 155 ++++++++++++----------------- include/sqrat/sqratUtil.h | 74 ++++++++++---- 4 files changed, 133 insertions(+), 132 deletions(-) diff --git a/include/sqrat/sqratGlobalMethods.h b/include/sqrat/sqratGlobalMethods.h index 0bdf2497..e8c030e9 100644 --- a/include/sqrat/sqratGlobalMethods.h +++ b/include/sqrat/sqratGlobalMethods.h @@ -46,7 +46,7 @@ namespace Sqrat { // template struct SqGlobalProxy { template static SQInteger Run(HSQUIRRELVM vm, SQInteger idx) { - ArgFwd a{SQ_OK}; + ArgFwd a; a.Call(vm, idx, [](HSQUIRRELVM vm, A... a) { typedef R(*M)(A...); M* method; @@ -54,7 +54,7 @@ template struct SqGlobalProxy { R ret = (*method)(a...); PushVar(vm, ret); }); - return SQ_FAILED(a.mRes) ? a.mRes : 1; + return 1; } }; @@ -64,7 +64,7 @@ template struct SqGlobalProxy { template struct SqGlobalProxy { template static SQInteger Run(HSQUIRRELVM vm, SQInteger idx) { - ArgFwd a{SQ_OK}; + ArgFwd a; a.Call(vm, idx, [](HSQUIRRELVM vm, A... a) { typedef R&(*M)(A...); M* method; @@ -72,7 +72,7 @@ template struct SqGlobalProxy { R& ret = (*method)(a...); PushVarR(vm, ret); }); - return SQ_FAILED(a.mRes) ? a.mRes : 1; + return 1; } }; @@ -82,14 +82,14 @@ template struct SqGlobalProxy { template <> struct SqGlobalProxy { template static SQInteger Run(HSQUIRRELVM vm, SQInteger idx) { - ArgFwd a{SQ_OK}; + ArgFwd a; a.Call(vm, idx, [](HSQUIRRELVM vm, A... a) { typedef void(*M)(A...); M* method; sq_getuserdata(vm, -1, reinterpret_cast(&method), nullptr); (*method)(a...); }); - return SQ_FAILED(a.mRes) ? a.mRes : 0; + return 0; } }; diff --git a/include/sqrat/sqratMemberMethods.h b/include/sqrat/sqratMemberMethods.h index 80ed7af0..e921f02e 100644 --- a/include/sqrat/sqratMemberMethods.h +++ b/include/sqrat/sqratMemberMethods.h @@ -46,7 +46,7 @@ namespace Sqrat { // template struct SqMemberProxy { template static SQInteger Run(HSQUIRRELVM vm) { - ArgFwd a{SQ_OK}; + ArgFwd a; a.Call(vm, 2, [](HSQUIRRELVM vm, A... a) { typedef R(C::*M)(A...); C* inst = Var(vm, 1).value; @@ -56,10 +56,10 @@ template struct SqMemberProxy { R ret = (inst->*method)(a...); PushVar(vm, ret); }); - return SQ_FAILED(a.mRes) ? a.mRes : 1; + return 1; } template static SQInteger RunC(HSQUIRRELVM vm) { - ArgFwd a{SQ_OK}; + ArgFwd a; a.Call(vm, 2, [](HSQUIRRELVM vm, A... a) { typedef R(C::*M)(A...) const; C* inst = Var(vm, 1).value; @@ -69,7 +69,7 @@ template struct SqMemberProxy { R ret = (inst->*method)(a...); PushVar(vm, ret); }); - return SQ_FAILED(a.mRes) ? a.mRes : 1; + return 1; } }; @@ -79,7 +79,7 @@ template struct SqMemberProxy { template struct SqMemberProxy { template static SQInteger Run(HSQUIRRELVM vm) { - ArgFwd a{SQ_OK}; + ArgFwd a; a.Call(vm, 2, [](HSQUIRRELVM vm, A... a) { typedef R&(C::*M)(A...); C* inst = Var(vm, 1).value; @@ -89,10 +89,10 @@ template struct SqMemberProxy { R& ret = (inst->*method)(a...); PushVarR(vm, ret); }); - return SQ_FAILED(a.mRes) ? a.mRes : 1; + return 1; } template static SQInteger RunC(HSQUIRRELVM vm) { - ArgFwd a{SQ_OK}; + ArgFwd a; a.Call(vm, 2, [](HSQUIRRELVM vm, A... a) { typedef R&(C::*M)(A...) const; C* inst = Var(vm, 1).value; @@ -102,7 +102,7 @@ template struct SqMemberProxy { R& ret = (inst->*method)(a...); PushVarR(vm, ret); }); - return SQ_FAILED(a.mRes) ? a.mRes : 1; + return 1; } }; @@ -112,7 +112,7 @@ template struct SqMemberProxy { template struct SqMemberProxy { template static SQInteger Run(HSQUIRRELVM vm) { - ArgFwd a{SQ_OK}; + ArgFwd a; a.Call(vm, 2, [](HSQUIRRELVM vm, A... a) { typedef void(C::*M)(A...); C* inst = Var(vm, 1).value; @@ -121,10 +121,10 @@ template struct SqMemberProxy { M method = *methodPtr; (inst->*method)(a...); }); - return SQ_FAILED(a.mRes) ? a.mRes : 0; + return 0; } template static SQInteger RunC(HSQUIRRELVM vm) { - ArgFwd a{SQ_OK}; + ArgFwd a; a.Call(vm, 2, [](HSQUIRRELVM vm, A... a) { typedef void(C::*M)(A...) const; C* inst = Var(vm, 1).value; @@ -133,7 +133,7 @@ template struct SqMemberProxy { M method = *methodPtr; (inst->*method)(a...); }); - return SQ_FAILED(a.mRes) ? a.mRes : 0; + return 0; } }; diff --git a/include/sqrat/sqratTypes.h b/include/sqrat/sqratTypes.h index 643e3c47..6a588a4a 100644 --- a/include/sqrat/sqratTypes.h +++ b/include/sqrat/sqratTypes.h @@ -999,6 +999,7 @@ public: }; #endif + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// Used to get and push StackStrF instances to and from the stack as references (StackStrF should not be a reference) ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1018,6 +1019,26 @@ struct Var { /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Var(HSQUIRRELVM vm, SQInteger idx) : value(vm, idx) { + if (SQ_FAILED(value.Proc())) { + ErrorToException(vm); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Attempts to get the value off the stack at idx as an StackStrF + /// + /// \param vm Target VM + /// \param idx Index trying to be read + /// \param idx Whether to mimmic a format function + /// + /// \remarks + /// This function MUST have its Error handled if it occurred. + /// + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + Var(HSQUIRRELVM vm, SQInteger idx, bool fmt) : value(vm, idx) { + if (SQ_FAILED(value.Proc(fmt))) { + ErrorToException(vm); + } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1040,13 +1061,19 @@ struct Var { /// Used to get and push StackStrF instances to and from the stack as references (StackStrF should not be a reference) ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// template<> -struct Var : Var {Var(HSQUIRRELVM vm, SQInteger idx) : Var(vm, idx) {}}; +struct Var : Var { + Var(HSQUIRRELVM vm, SQInteger idx) : Var(vm, idx) {} + Var(HSQUIRRELVM vm, SQInteger idx, bool fmt) : Var(vm, idx, fmt) {} +}; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// Used to get and push StackStrF instances to and from the stack as references (StackStrF should not be a reference) ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// template<> -struct Var : Var {Var(HSQUIRRELVM vm, SQInteger idx) : Var(vm, idx) {}}; +struct Var : Var { + Var(HSQUIRRELVM vm, SQInteger idx) : Var(vm, idx) {} + Var(HSQUIRRELVM vm, SQInteger idx, bool fmt) : Var(vm, idx, fmt) {} +}; // Non-referencable type definitions template struct is_referencable {static const bool value = true;}; @@ -1186,13 +1213,11 @@ template<> struct ArgFwdHasFmt { static constexpr bool value = ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// Helper used to process formatted arguments when necessary. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -template struct ArgFwdFmt { - template static inline SQInteger Proc(T &, bool) { return SQ_OK; } - template static inline SQInteger Get(T &) { return SQ_OK; } +template struct ArgFwdFmtVar : Var { + ArgFwdFmtVar(HSQUIRRELVM vm, SQInteger idx) : Var(vm, idx) {} }; -template<> struct ArgFwdFmt { - static inline SQInteger Proc(StackStrF & s, bool dummy = false) { return s.Proc(true, dummy); } - static inline SQInteger Get(StackStrF & s) { return s.mRes; } +template struct ArgFwdFmtVar : Var { + ArgFwdFmtVar(HSQUIRRELVM vm, SQInteger idx) : Var(vm, idx, true) {} }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1207,8 +1232,6 @@ template<> struct ArgFwd<> { // Used to tell whether the last template parameter is a StackStrF type static constexpr bool HASFMT = false; - // Where Squirrel result codes can be stored - SQInteger mRes; // Forward the arguments to a function object template inline void Call(HSQUIRRELVM vm, SQInteger /*idx*/, F f) { f(vm); @@ -1222,14 +1245,10 @@ template struct ArgFwd { // Used to tell whether the last template parameter is a StackStrF type static constexpr bool HASFMT = ArgFwdHasFmt::value; - // Where Squirrel result codes can be stored - SQInteger mRes; // Forward the arguments to a function object template inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { - Var a1(vm, idx); - mRes = ArgFwdFmt::Proc(a1.value, sq_gettop(vm) <= idx); - if (SQ_SUCCEEDED(mRes)) - f(vm,a1.value); + ArgFwdFmtVar a1(vm, idx); + f(vm,a1.value); } }; @@ -1237,15 +1256,11 @@ template struct ArgFwd { // Used to tell whether the last template parameter is a StackStrF type static constexpr bool HASFMT = ArgFwdHasFmt::value; - // Where Squirrel result codes can be stored - SQInteger mRes; // Forward the arguments to a function object template inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { Var a1(vm, idx++); - Var a2(vm, idx); - mRes = ArgFwdFmt::Proc(a2.value, sq_gettop(vm) <= idx); - if (SQ_SUCCEEDED(mRes)) - f(vm,a1.value,a2.value); + ArgFwdFmtVar a2(vm, idx); + f(vm,a1.value,a2.value); } }; @@ -1253,16 +1268,12 @@ template struct ArgFwd { // Used to tell whether the last template parameter is a StackStrF type static constexpr bool HASFMT = ArgFwdHasFmt::value; - // Where Squirrel result codes can be stored - SQInteger mRes; // Forward the arguments to a function object template inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { Var a1(vm, idx++); Var a2(vm, idx++); - Var a3(vm, idx); - mRes = ArgFwdFmt::Proc(a3.value, sq_gettop(vm) <= idx); - if (SQ_SUCCEEDED(mRes)) - f(vm,a1.value,a2.value,a3.value); + ArgFwdFmtVar a3(vm, idx); + f(vm,a1.value,a2.value,a3.value); } }; @@ -1271,17 +1282,13 @@ template struct ArgFwd { // Used to tell whether the last template parameter is a StackStrF type static constexpr bool HASFMT = ArgFwdHasFmt::value; - // Where Squirrel result codes can be stored - SQInteger mRes; // Forward the arguments to a function object template inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { Var a1(vm, idx++); Var a2(vm, idx++); Var a3(vm, idx++); - Var a4(vm, idx); - mRes = ArgFwdFmt::Proc(a4.value, sq_gettop(vm) <= idx); - if (SQ_SUCCEEDED(mRes)) - f(vm,a1.value,a2.value,a3.value,a4.value); + ArgFwdFmtVar a4(vm, idx); + f(vm,a1.value,a2.value,a3.value,a4.value); } }; @@ -1289,18 +1296,14 @@ template struct ArgFwd { // Used to tell whether the last template parameter is a StackStrF type static constexpr bool HASFMT = ArgFwdHasFmt::value; - // Where Squirrel result codes can be stored - SQInteger mRes; // Forward the arguments to a function object template inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { Var a1(vm, idx++); Var a2(vm, idx++); Var a3(vm, idx++); Var a4(vm, idx++); - Var a5(vm, idx); - mRes = ArgFwdFmt::Proc(a5.value, sq_gettop(vm) <= idx); - if (SQ_SUCCEEDED(mRes)) - f(vm,a1.value,a2.value,a3.value,a4.value,a5.value); + ArgFwdFmtVar a5(vm, idx); + f(vm,a1.value,a2.value,a3.value,a4.value,a5.value); } }; @@ -1308,8 +1311,6 @@ template struct ArgFwd { // Used to tell whether the last template parameter is a StackStrF type static constexpr bool HASFMT = ArgFwdHasFmt::value; - // Where Squirrel result codes can be stored - SQInteger mRes; // Forward the arguments to a function object template inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { Var a1(vm, idx++); @@ -1317,10 +1318,8 @@ struct ArgFwd { Var a3(vm, idx++); Var a4(vm, idx++); Var a5(vm, idx++); - Var a6(vm, idx); - mRes = ArgFwdFmt::Proc(a6.value, sq_gettop(vm) <= idx); - if (SQ_SUCCEEDED(mRes)) - f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value); + ArgFwdFmtVar a6(vm, idx); + f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value); } }; @@ -1328,8 +1327,6 @@ template struct ArgFwd { // Used to tell whether the last template parameter is a StackStrF type static constexpr bool HASFMT = ArgFwdHasFmt::value; - // Where Squirrel result codes can be stored - SQInteger mRes; // Forward the arguments to a function object template inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { Var a1(vm, idx++); @@ -1338,10 +1335,8 @@ struct ArgFwd { Var a4(vm, idx++); Var a5(vm, idx++); Var a6(vm, idx++); - Var a7(vm, idx); - mRes = ArgFwdFmt::Proc(a7.value, sq_gettop(vm) <= idx); - if (SQ_SUCCEEDED(mRes)) - f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value); + ArgFwdFmtVar a7(vm, idx); + f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value); } }; @@ -1349,8 +1344,6 @@ template { // Used to tell whether the last template parameter is a StackStrF type static constexpr bool HASFMT = ArgFwdHasFmt::value; - // Where Squirrel result codes can be stored - SQInteger mRes; // Forward the arguments to a function object template inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { Var a1(vm, idx++); @@ -1360,10 +1353,8 @@ struct ArgFwd { Var a5(vm, idx++); Var a6(vm, idx++); Var a7(vm, idx++); - Var a8(vm, idx); - mRes = ArgFwdFmt::Proc(a8.value, sq_gettop(vm) <= idx); - if (SQ_SUCCEEDED(mRes)) - f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value,a8.value); + ArgFwdFmtVar a8(vm, idx); + f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value,a8.value); } }; @@ -1371,8 +1362,6 @@ template { // Used to tell whether the last template parameter is a StackStrF type static constexpr bool HASFMT = ArgFwdHasFmt::value; - // Where Squirrel result codes can be stored - SQInteger mRes; // Forward the arguments to a function object template inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { Var a1(vm, idx++); @@ -1383,10 +1372,8 @@ struct ArgFwd { Var a6(vm, idx++); Var a7(vm, idx++); Var a8(vm, idx++); - Var a9(vm, idx); - mRes = ArgFwdFmt::Proc(a9.value, sq_gettop(vm) <= idx); - if (SQ_SUCCEEDED(mRes)) - f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value,a8.value,a9.value); + ArgFwdFmtVar a9(vm, idx); + f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value,a8.value,a9.value); } }; @@ -1394,8 +1381,6 @@ template { // Used to tell whether the last template parameter is a StackStrF type static constexpr bool HASFMT = ArgFwdHasFmt::value; - // Where Squirrel result codes can be stored - SQInteger mRes; // Forward the arguments to a function object template inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { Var a1(vm, idx++); @@ -1407,10 +1392,8 @@ struct ArgFwd { Var a7(vm, idx++); Var a8(vm, idx++); Var a9(vm, idx++); - Var a10(vm, idx); - mRes = ArgFwdFmt::Proc(a10.value, sq_gettop(vm) <= idx); - if (SQ_SUCCEEDED(mRes)) - f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value,a8.value,a9.value,a10.value); + ArgFwdFmtVar a10(vm, idx); + f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value,a8.value,a9.value,a10.value); } }; @@ -1418,8 +1401,6 @@ template { // Used to tell whether the last template parameter is a StackStrF type static constexpr bool HASFMT = ArgFwdHasFmt::value; - // Where Squirrel result codes can be stored - SQInteger mRes; // Forward the arguments to a function object template inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { Var a1(vm, idx++); @@ -1432,10 +1413,8 @@ struct ArgFwd { Var a8(vm, idx++); Var a9(vm, idx++); Var a10(vm, idx++); - Var a11(vm, idx); - mRes = ArgFwdFmt::Proc(a11.value, sq_gettop(vm) <= idx); - if (SQ_SUCCEEDED(mRes)) - f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value,a8.value,a9.value,a10.value,a11.value); + ArgFwdFmtVar a11(vm, idx); + f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value,a8.value,a9.value,a10.value,a11.value); } }; @@ -1443,8 +1422,6 @@ template { // Used to tell whether the last template parameter is a StackStrF type static constexpr bool HASFMT = ArgFwdHasFmt::value; - // Where Squirrel result codes can be stored - SQInteger mRes; // Forward the arguments to a function object template inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { Var a1(vm, idx++); @@ -1458,10 +1435,8 @@ struct ArgFwd { Var a9(vm, idx++); Var a10(vm, idx++); Var a11(vm, idx++); - Var a12(vm, idx); - mRes = ArgFwdFmt::Proc(a12.value, sq_gettop(vm) <= idx); - if (SQ_SUCCEEDED(mRes)) - f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value,a8.value,a9.value,a10.value,a11.value,a12.value); + ArgFwdFmtVar a12(vm, idx); + f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value,a8.value,a9.value,a10.value,a11.value,a12.value); } }; @@ -1469,8 +1444,6 @@ template { // Used to tell whether the last template parameter is a StackStrF type static constexpr bool HASFMT = ArgFwdHasFmt::value; - // Where Squirrel result codes can be stored - SQInteger mRes; // Forward the arguments to a function object template inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { Var a1(vm, idx++); @@ -1485,10 +1458,8 @@ struct ArgFwd { Var a10(vm, idx++); Var a11(vm, idx++); Var a12(vm, idx++); - Var a13(vm, idx); - mRes = ArgFwdFmt::Proc(a13.value, sq_gettop(vm) <= idx); - if (SQ_SUCCEEDED(mRes)) - f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value,a8.value,a9.value,a10.value,a11.value,a12.value,a13.value); + ArgFwdFmtVar a13(vm, idx); + f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value,a8.value,a9.value,a10.value,a11.value,a12.value,a13.value); } }; @@ -1496,8 +1467,6 @@ template { // Used to tell whether the last template parameter is a StackStrF type static constexpr bool HASFMT = ArgFwdHasFmt::value; - // Where Squirrel result codes can be stored - SQInteger mRes; // Forward the arguments to a function object template inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { Var a1(vm, idx++); @@ -1513,10 +1482,8 @@ struct ArgFwd { Var a11(vm, idx++); Var a12(vm, idx++); Var a13(vm, idx++); - Var a14(vm, idx); - mRes = ArgFwdFmt::Proc(a14.value, sq_gettop(vm) <= idx); - if (SQ_SUCCEEDED(mRes)) - f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value,a8.value,a9.value,a10.value,a11.value,a12.value,a13.value,a14.value); + ArgFwdFmtVar a14(vm, idx); + f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value,a8.value,a9.value,a10.value,a11.value,a12.value,a13.value,a14.value); } }; diff --git a/include/sqrat/sqratUtil.h b/include/sqrat/sqratUtil.h index 0dd533cb..53b1edf5 100644 --- a/include/sqrat/sqratUtil.h +++ b/include/sqrat/sqratUtil.h @@ -402,6 +402,15 @@ public: ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Exception(const SQChar * msg) : message(msg) {} + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Constructs an exception + /// + /// \param msg A nice error message + /// \param len Length of the message + /// + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + Exception(const SQChar * msg, SQInteger len) : message(msg, len > 0 ? len : 0) {} + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// Constructs an exception /// @@ -1503,7 +1512,7 @@ struct StackGuard ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ~StackGuard() { - Restore(); + Restore(); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1520,15 +1529,15 @@ struct StackGuard /// Restore the stack to what was known to be. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Restore() const - { - // Retrieve the new stack top - const SQInteger top = sq_gettop(m_VM); - // Did the stack size change? + { + // Retrieve the new stack top + const SQInteger top = sq_gettop(m_VM); + // Did the stack size change? if (top > m_Top) - { - sq_pop(m_VM, top - m_Top); // Trim the stack - } - } + { + sq_pop(m_VM, top - m_Top); // Trim the stack + } + } private: @@ -1654,25 +1663,20 @@ struct StackStrF ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// Actual implementation. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - SQRESULT Proc(bool fmt = false, bool dummy = false) + SQRESULT Proc(bool fmt = false) { // If there's no virtual machine, just ignore the request if (mVM == nullptr) { return SQ_OK; } + // Release the converted value object + else if (!sq_isnull(mObj)) + { + sq_release(mVM, &mObj); + } // Reset the converted value object sq_resetobject(&mObj); - // is this a dummy request? - if (dummy) - { - // Since this is a dummy then avoid making it look like a failure - mPtr = _SC(""); - mLen = 0; - mRes = SQ_OK; - // We're not supposed to proceed with this! - return mRes; - } // Grab the top of the stack const SQInteger top = sq_gettop(mVM); // Was the string or value specified? @@ -1755,6 +1759,36 @@ struct StackStrF } }; +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/// Throws the current error in a given VM as a program exception. +/// +/// \param vm Target VM +/// \param keep Whether to clear the error from the VM +/// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +static void ErrorToException(HSQUIRRELVM vm, bool keep = false) { + // Get the error object on the stack + sq_getlasterror(vm); + // See if there's an actual error + if (sq_gettype(vm, -1) == OT_NULL) { + sq_poptop(vm); // Pop the object from the stack + return; // Done here! + } + StackStrF s(vm, -1); + // Attempt to the the object as a string + if (SQ_FAILED(s.Proc(false))) { + sq_poptop(vm); // Pop the object from the stack + throw ::Sqrat::Exception(_SC("Unidentifiable script object used as error.")); + } + sq_poptop(vm); // Pop the object from the stack + // Should the error be kept in the VM? + if (!keep) { + sq_reseterror(vm); + } + // Throw the error message + throw ::Sqrat::Exception(s.mPtr, s.mLen); +} + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// RAII approach to make sure an instance is deleted regardless of what exceptions are thrown. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////