1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-01-19 03:57:14 +01:00

Attempt to fix function binding to comply with changes to StackStrF.

Various other changes to fix other issues related to changes in StackStrF behavior.
This commit is contained in:
Sandu Liviu Catalin 2018-10-24 21:37:51 +03:00
parent 107ddea5fd
commit d556364ecf
4 changed files with 133 additions and 132 deletions

View File

@ -46,7 +46,7 @@ namespace Sqrat {
// //
template <class R> struct SqGlobalProxy { template <class R> struct SqGlobalProxy {
template <class... A> static SQInteger Run(HSQUIRRELVM vm, SQInteger idx) { template <class... A> static SQInteger Run(HSQUIRRELVM vm, SQInteger idx) {
ArgFwd<A...> a{SQ_OK}; ArgFwd<A...> a;
a.Call(vm, idx, [](HSQUIRRELVM vm, A... a) { a.Call(vm, idx, [](HSQUIRRELVM vm, A... a) {
typedef R(*M)(A...); typedef R(*M)(A...);
M* method; M* method;
@ -54,7 +54,7 @@ template <class R> struct SqGlobalProxy {
R ret = (*method)(a...); R ret = (*method)(a...);
PushVar(vm, ret); PushVar(vm, ret);
}); });
return SQ_FAILED(a.mRes) ? a.mRes : 1; return 1;
} }
}; };
@ -64,7 +64,7 @@ template <class R> struct SqGlobalProxy {
template <class R> struct SqGlobalProxy<R&> { template <class R> struct SqGlobalProxy<R&> {
template <class... A> static SQInteger Run(HSQUIRRELVM vm, SQInteger idx) { template <class... A> static SQInteger Run(HSQUIRRELVM vm, SQInteger idx) {
ArgFwd<A...> a{SQ_OK}; ArgFwd<A...> a;
a.Call(vm, idx, [](HSQUIRRELVM vm, A... a) { a.Call(vm, idx, [](HSQUIRRELVM vm, A... a) {
typedef R&(*M)(A...); typedef R&(*M)(A...);
M* method; M* method;
@ -72,7 +72,7 @@ template <class R> struct SqGlobalProxy<R&> {
R& ret = (*method)(a...); R& ret = (*method)(a...);
PushVarR(vm, ret); PushVarR(vm, ret);
}); });
return SQ_FAILED(a.mRes) ? a.mRes : 1; return 1;
} }
}; };
@ -82,14 +82,14 @@ template <class R> struct SqGlobalProxy<R&> {
template <> struct SqGlobalProxy<void> { template <> struct SqGlobalProxy<void> {
template <class... A> static SQInteger Run(HSQUIRRELVM vm, SQInteger idx) { template <class... A> static SQInteger Run(HSQUIRRELVM vm, SQInteger idx) {
ArgFwd<A...> a{SQ_OK}; ArgFwd<A...> a;
a.Call(vm, idx, [](HSQUIRRELVM vm, A... a) { a.Call(vm, idx, [](HSQUIRRELVM vm, A... a) {
typedef void(*M)(A...); typedef void(*M)(A...);
M* method; M* method;
sq_getuserdata(vm, -1, reinterpret_cast<SQUserPointer*>(&method), nullptr); sq_getuserdata(vm, -1, reinterpret_cast<SQUserPointer*>(&method), nullptr);
(*method)(a...); (*method)(a...);
}); });
return SQ_FAILED(a.mRes) ? a.mRes : 0; return 0;
} }
}; };

View File

@ -46,7 +46,7 @@ namespace Sqrat {
// //
template <class C,class R> struct SqMemberProxy { template <class C,class R> struct SqMemberProxy {
template <class... A> static SQInteger Run(HSQUIRRELVM vm) { template <class... A> static SQInteger Run(HSQUIRRELVM vm) {
ArgFwd<A...> a{SQ_OK}; ArgFwd<A...> a;
a.Call(vm, 2, [](HSQUIRRELVM vm, A... a) { a.Call(vm, 2, [](HSQUIRRELVM vm, A... a) {
typedef R(C::*M)(A...); typedef R(C::*M)(A...);
C* inst = Var<C*>(vm, 1).value; C* inst = Var<C*>(vm, 1).value;
@ -56,10 +56,10 @@ template <class C,class R> struct SqMemberProxy {
R ret = (inst->*method)(a...); R ret = (inst->*method)(a...);
PushVar(vm, ret); PushVar(vm, ret);
}); });
return SQ_FAILED(a.mRes) ? a.mRes : 1; return 1;
} }
template <class... A> static SQInteger RunC(HSQUIRRELVM vm) { template <class... A> static SQInteger RunC(HSQUIRRELVM vm) {
ArgFwd<A...> a{SQ_OK}; ArgFwd<A...> a;
a.Call(vm, 2, [](HSQUIRRELVM vm, A... a) { a.Call(vm, 2, [](HSQUIRRELVM vm, A... a) {
typedef R(C::*M)(A...) const; typedef R(C::*M)(A...) const;
C* inst = Var<C*>(vm, 1).value; C* inst = Var<C*>(vm, 1).value;
@ -69,7 +69,7 @@ template <class C,class R> struct SqMemberProxy {
R ret = (inst->*method)(a...); R ret = (inst->*method)(a...);
PushVar(vm, ret); PushVar(vm, ret);
}); });
return SQ_FAILED(a.mRes) ? a.mRes : 1; return 1;
} }
}; };
@ -79,7 +79,7 @@ template <class C,class R> struct SqMemberProxy {
template <class C, class R> struct SqMemberProxy<C,R&> { template <class C, class R> struct SqMemberProxy<C,R&> {
template <class... A> static SQInteger Run(HSQUIRRELVM vm) { template <class... A> static SQInteger Run(HSQUIRRELVM vm) {
ArgFwd<A...> a{SQ_OK}; ArgFwd<A...> a;
a.Call(vm, 2, [](HSQUIRRELVM vm, A... a) { a.Call(vm, 2, [](HSQUIRRELVM vm, A... a) {
typedef R&(C::*M)(A...); typedef R&(C::*M)(A...);
C* inst = Var<C*>(vm, 1).value; C* inst = Var<C*>(vm, 1).value;
@ -89,10 +89,10 @@ template <class C, class R> struct SqMemberProxy<C,R&> {
R& ret = (inst->*method)(a...); R& ret = (inst->*method)(a...);
PushVarR(vm, ret); PushVarR(vm, ret);
}); });
return SQ_FAILED(a.mRes) ? a.mRes : 1; return 1;
} }
template <class... A> static SQInteger RunC(HSQUIRRELVM vm) { template <class... A> static SQInteger RunC(HSQUIRRELVM vm) {
ArgFwd<A...> a{SQ_OK}; ArgFwd<A...> a;
a.Call(vm, 2, [](HSQUIRRELVM vm, A... a) { a.Call(vm, 2, [](HSQUIRRELVM vm, A... a) {
typedef R&(C::*M)(A...) const; typedef R&(C::*M)(A...) const;
C* inst = Var<C*>(vm, 1).value; C* inst = Var<C*>(vm, 1).value;
@ -102,7 +102,7 @@ template <class C, class R> struct SqMemberProxy<C,R&> {
R& ret = (inst->*method)(a...); R& ret = (inst->*method)(a...);
PushVarR(vm, ret); PushVarR(vm, ret);
}); });
return SQ_FAILED(a.mRes) ? a.mRes : 1; return 1;
} }
}; };
@ -112,7 +112,7 @@ template <class C, class R> struct SqMemberProxy<C,R&> {
template <class C> struct SqMemberProxy<C, void> { template <class C> struct SqMemberProxy<C, void> {
template <class... A> static SQInteger Run(HSQUIRRELVM vm) { template <class... A> static SQInteger Run(HSQUIRRELVM vm) {
ArgFwd<A...> a{SQ_OK}; ArgFwd<A...> a;
a.Call(vm, 2, [](HSQUIRRELVM vm, A... a) { a.Call(vm, 2, [](HSQUIRRELVM vm, A... a) {
typedef void(C::*M)(A...); typedef void(C::*M)(A...);
C* inst = Var<C*>(vm, 1).value; C* inst = Var<C*>(vm, 1).value;
@ -121,10 +121,10 @@ template <class C> struct SqMemberProxy<C, void> {
M method = *methodPtr; M method = *methodPtr;
(inst->*method)(a...); (inst->*method)(a...);
}); });
return SQ_FAILED(a.mRes) ? a.mRes : 0; return 0;
} }
template <class... A> static SQInteger RunC(HSQUIRRELVM vm) { template <class... A> static SQInteger RunC(HSQUIRRELVM vm) {
ArgFwd<A...> a{SQ_OK}; ArgFwd<A...> a;
a.Call(vm, 2, [](HSQUIRRELVM vm, A... a) { a.Call(vm, 2, [](HSQUIRRELVM vm, A... a) {
typedef void(C::*M)(A...) const; typedef void(C::*M)(A...) const;
C* inst = Var<C*>(vm, 1).value; C* inst = Var<C*>(vm, 1).value;
@ -133,7 +133,7 @@ template <class C> struct SqMemberProxy<C, void> {
M method = *methodPtr; M method = *methodPtr;
(inst->*method)(a...); (inst->*method)(a...);
}); });
return SQ_FAILED(a.mRes) ? a.mRes : 0; return 0;
} }
}; };

View File

@ -999,6 +999,7 @@ public:
}; };
#endif #endif
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Used to get and push StackStrF instances to and from the stack as references (StackStrF should not be a reference) /// 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<StackStrF> {
/// ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Var(HSQUIRRELVM vm, SQInteger idx) : value(vm, idx) { 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<StackStrF> {
/// Used to get and push StackStrF instances to and from the stack as references (StackStrF should not be a reference) /// Used to get and push StackStrF instances to and from the stack as references (StackStrF should not be a reference)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<> template<>
struct Var<StackStrF&> : Var<StackStrF> {Var(HSQUIRRELVM vm, SQInteger idx) : Var<StackStrF>(vm, idx) {}}; struct Var<StackStrF&> : Var<StackStrF> {
Var(HSQUIRRELVM vm, SQInteger idx) : Var<StackStrF>(vm, idx) {}
Var(HSQUIRRELVM vm, SQInteger idx, bool fmt) : Var<StackStrF>(vm, idx, fmt) {}
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Used to get and push StackStrF instances to and from the stack as references (StackStrF should not be a reference) /// Used to get and push StackStrF instances to and from the stack as references (StackStrF should not be a reference)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<> template<>
struct Var<const StackStrF&> : Var<StackStrF> {Var(HSQUIRRELVM vm, SQInteger idx) : Var<StackStrF>(vm, idx) {}}; struct Var<const StackStrF&> : Var<StackStrF> {
Var(HSQUIRRELVM vm, SQInteger idx) : Var<StackStrF>(vm, idx) {}
Var(HSQUIRRELVM vm, SQInteger idx, bool fmt) : Var<StackStrF>(vm, idx, fmt) {}
};
// Non-referencable type definitions // Non-referencable type definitions
template<class T> struct is_referencable {static const bool value = true;}; template<class T> struct is_referencable {static const bool value = true;};
@ -1186,13 +1213,11 @@ template<> struct ArgFwdHasFmt<const StackStrF&> { static constexpr bool value =
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Helper used to process formatted arguments when necessary. /// Helper used to process formatted arguments when necessary.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<bool> struct ArgFwdFmt { template<class T, bool> struct ArgFwdFmtVar : Var<T> {
template<class T> static inline SQInteger Proc(T &, bool) { return SQ_OK; } ArgFwdFmtVar(HSQUIRRELVM vm, SQInteger idx) : Var<T>(vm, idx) {}
template<class T> static inline SQInteger Get(T &) { return SQ_OK; }
}; };
template<> struct ArgFwdFmt<true> { template<class T> struct ArgFwdFmtVar<T, true> : Var<T> {
static inline SQInteger Proc(StackStrF & s, bool dummy = false) { return s.Proc(true, dummy); } ArgFwdFmtVar(HSQUIRRELVM vm, SQInteger idx) : Var<T>(vm, idx, true) {}
static inline SQInteger Get(StackStrF & s) { return s.mRes; }
}; };
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -1207,8 +1232,6 @@ template<>
struct ArgFwd<> { struct ArgFwd<> {
// Used to tell whether the last template parameter is a StackStrF type // Used to tell whether the last template parameter is a StackStrF type
static constexpr bool HASFMT = false; static constexpr bool HASFMT = false;
// Where Squirrel result codes can be stored
SQInteger mRes;
// Forward the arguments to a function object // Forward the arguments to a function object
template<class F> inline void Call(HSQUIRRELVM vm, SQInteger /*idx*/, F f) { template<class F> inline void Call(HSQUIRRELVM vm, SQInteger /*idx*/, F f) {
f(vm); f(vm);
@ -1222,14 +1245,10 @@ template<class T1>
struct ArgFwd<T1> { struct ArgFwd<T1> {
// Used to tell whether the last template parameter is a StackStrF type // Used to tell whether the last template parameter is a StackStrF type
static constexpr bool HASFMT = ArgFwdHasFmt<T1>::value; static constexpr bool HASFMT = ArgFwdHasFmt<T1>::value;
// Where Squirrel result codes can be stored
SQInteger mRes;
// Forward the arguments to a function object // Forward the arguments to a function object
template<class F> inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { template<class F> inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) {
Var<T1> a1(vm, idx); ArgFwdFmtVar<T1, HASFMT> a1(vm, idx);
mRes = ArgFwdFmt<HASFMT>::Proc(a1.value, sq_gettop(vm) <= idx); f(vm,a1.value);
if (SQ_SUCCEEDED(mRes))
f(vm,a1.value);
} }
}; };
@ -1237,15 +1256,11 @@ template<class T1,class T2>
struct ArgFwd<T1,T2> { struct ArgFwd<T1,T2> {
// Used to tell whether the last template parameter is a StackStrF type // Used to tell whether the last template parameter is a StackStrF type
static constexpr bool HASFMT = ArgFwdHasFmt<T2>::value; static constexpr bool HASFMT = ArgFwdHasFmt<T2>::value;
// Where Squirrel result codes can be stored
SQInteger mRes;
// Forward the arguments to a function object // Forward the arguments to a function object
template<class F> inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { template<class F> inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) {
Var<T1> a1(vm, idx++); Var<T1> a1(vm, idx++);
Var<T2> a2(vm, idx); ArgFwdFmtVar<T2, HASFMT> a2(vm, idx);
mRes = ArgFwdFmt<HASFMT>::Proc(a2.value, sq_gettop(vm) <= idx); f(vm,a1.value,a2.value);
if (SQ_SUCCEEDED(mRes))
f(vm,a1.value,a2.value);
} }
}; };
@ -1253,16 +1268,12 @@ template<class T1,class T2,class T3>
struct ArgFwd<T1,T2,T3> { struct ArgFwd<T1,T2,T3> {
// Used to tell whether the last template parameter is a StackStrF type // Used to tell whether the last template parameter is a StackStrF type
static constexpr bool HASFMT = ArgFwdHasFmt<T3>::value; static constexpr bool HASFMT = ArgFwdHasFmt<T3>::value;
// Where Squirrel result codes can be stored
SQInteger mRes;
// Forward the arguments to a function object // Forward the arguments to a function object
template<class F> inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { template<class F> inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) {
Var<T1> a1(vm, idx++); Var<T1> a1(vm, idx++);
Var<T2> a2(vm, idx++); Var<T2> a2(vm, idx++);
Var<T3> a3(vm, idx); ArgFwdFmtVar<T3, HASFMT> a3(vm, idx);
mRes = ArgFwdFmt<HASFMT>::Proc(a3.value, sq_gettop(vm) <= idx); f(vm,a1.value,a2.value,a3.value);
if (SQ_SUCCEEDED(mRes))
f(vm,a1.value,a2.value,a3.value);
} }
}; };
@ -1271,17 +1282,13 @@ template<class T1,class T2,class T3,class T4>
struct ArgFwd<T1,T2,T3,T4> { struct ArgFwd<T1,T2,T3,T4> {
// Used to tell whether the last template parameter is a StackStrF type // Used to tell whether the last template parameter is a StackStrF type
static constexpr bool HASFMT = ArgFwdHasFmt<T4>::value; static constexpr bool HASFMT = ArgFwdHasFmt<T4>::value;
// Where Squirrel result codes can be stored
SQInteger mRes;
// Forward the arguments to a function object // Forward the arguments to a function object
template<class F> inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { template<class F> inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) {
Var<T1> a1(vm, idx++); Var<T1> a1(vm, idx++);
Var<T2> a2(vm, idx++); Var<T2> a2(vm, idx++);
Var<T3> a3(vm, idx++); Var<T3> a3(vm, idx++);
Var<T4> a4(vm, idx); ArgFwdFmtVar<T4, HASFMT> a4(vm, idx);
mRes = ArgFwdFmt<HASFMT>::Proc(a4.value, sq_gettop(vm) <= idx); f(vm,a1.value,a2.value,a3.value,a4.value);
if (SQ_SUCCEEDED(mRes))
f(vm,a1.value,a2.value,a3.value,a4.value);
} }
}; };
@ -1289,18 +1296,14 @@ template<class T1,class T2,class T3,class T4,class T5>
struct ArgFwd<T1,T2,T3,T4,T5> { struct ArgFwd<T1,T2,T3,T4,T5> {
// Used to tell whether the last template parameter is a StackStrF type // Used to tell whether the last template parameter is a StackStrF type
static constexpr bool HASFMT = ArgFwdHasFmt<T5>::value; static constexpr bool HASFMT = ArgFwdHasFmt<T5>::value;
// Where Squirrel result codes can be stored
SQInteger mRes;
// Forward the arguments to a function object // Forward the arguments to a function object
template<class F> inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { template<class F> inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) {
Var<T1> a1(vm, idx++); Var<T1> a1(vm, idx++);
Var<T2> a2(vm, idx++); Var<T2> a2(vm, idx++);
Var<T3> a3(vm, idx++); Var<T3> a3(vm, idx++);
Var<T4> a4(vm, idx++); Var<T4> a4(vm, idx++);
Var<T5> a5(vm, idx); ArgFwdFmtVar<T5, HASFMT> a5(vm, idx);
mRes = ArgFwdFmt<HASFMT>::Proc(a5.value, sq_gettop(vm) <= idx); f(vm,a1.value,a2.value,a3.value,a4.value,a5.value);
if (SQ_SUCCEEDED(mRes))
f(vm,a1.value,a2.value,a3.value,a4.value,a5.value);
} }
}; };
@ -1308,8 +1311,6 @@ template<class T1,class T2,class T3,class T4,class T5,class T6>
struct ArgFwd<T1,T2,T3,T4,T5,T6> { struct ArgFwd<T1,T2,T3,T4,T5,T6> {
// Used to tell whether the last template parameter is a StackStrF type // Used to tell whether the last template parameter is a StackStrF type
static constexpr bool HASFMT = ArgFwdHasFmt<T6>::value; static constexpr bool HASFMT = ArgFwdHasFmt<T6>::value;
// Where Squirrel result codes can be stored
SQInteger mRes;
// Forward the arguments to a function object // Forward the arguments to a function object
template<class F> inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { template<class F> inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) {
Var<T1> a1(vm, idx++); Var<T1> a1(vm, idx++);
@ -1317,10 +1318,8 @@ struct ArgFwd<T1,T2,T3,T4,T5,T6> {
Var<T3> a3(vm, idx++); Var<T3> a3(vm, idx++);
Var<T4> a4(vm, idx++); Var<T4> a4(vm, idx++);
Var<T5> a5(vm, idx++); Var<T5> a5(vm, idx++);
Var<T6> a6(vm, idx); ArgFwdFmtVar<T6, HASFMT> a6(vm, idx);
mRes = ArgFwdFmt<HASFMT>::Proc(a6.value, sq_gettop(vm) <= idx); f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value);
if (SQ_SUCCEEDED(mRes))
f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value);
} }
}; };
@ -1328,8 +1327,6 @@ template<class T1,class T2,class T3,class T4,class T5,class T6,class T7>
struct ArgFwd<T1,T2,T3,T4,T5,T6,T7> { struct ArgFwd<T1,T2,T3,T4,T5,T6,T7> {
// Used to tell whether the last template parameter is a StackStrF type // Used to tell whether the last template parameter is a StackStrF type
static constexpr bool HASFMT = ArgFwdHasFmt<T7>::value; static constexpr bool HASFMT = ArgFwdHasFmt<T7>::value;
// Where Squirrel result codes can be stored
SQInteger mRes;
// Forward the arguments to a function object // Forward the arguments to a function object
template<class F> inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { template<class F> inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) {
Var<T1> a1(vm, idx++); Var<T1> a1(vm, idx++);
@ -1338,10 +1335,8 @@ struct ArgFwd<T1,T2,T3,T4,T5,T6,T7> {
Var<T4> a4(vm, idx++); Var<T4> a4(vm, idx++);
Var<T5> a5(vm, idx++); Var<T5> a5(vm, idx++);
Var<T6> a6(vm, idx++); Var<T6> a6(vm, idx++);
Var<T7> a7(vm, idx); ArgFwdFmtVar<T7, HASFMT> a7(vm, idx);
mRes = ArgFwdFmt<HASFMT>::Proc(a7.value, sq_gettop(vm) <= idx); f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value);
if (SQ_SUCCEEDED(mRes))
f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value);
} }
}; };
@ -1349,8 +1344,6 @@ template<class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8
struct ArgFwd<T1,T2,T3,T4,T5,T6,T7,T8> { struct ArgFwd<T1,T2,T3,T4,T5,T6,T7,T8> {
// Used to tell whether the last template parameter is a StackStrF type // Used to tell whether the last template parameter is a StackStrF type
static constexpr bool HASFMT = ArgFwdHasFmt<T8>::value; static constexpr bool HASFMT = ArgFwdHasFmt<T8>::value;
// Where Squirrel result codes can be stored
SQInteger mRes;
// Forward the arguments to a function object // Forward the arguments to a function object
template<class F> inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { template<class F> inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) {
Var<T1> a1(vm, idx++); Var<T1> a1(vm, idx++);
@ -1360,10 +1353,8 @@ struct ArgFwd<T1,T2,T3,T4,T5,T6,T7,T8> {
Var<T5> a5(vm, idx++); Var<T5> a5(vm, idx++);
Var<T6> a6(vm, idx++); Var<T6> a6(vm, idx++);
Var<T7> a7(vm, idx++); Var<T7> a7(vm, idx++);
Var<T8> a8(vm, idx); ArgFwdFmtVar<T8, HASFMT> a8(vm, idx);
mRes = ArgFwdFmt<HASFMT>::Proc(a8.value, sq_gettop(vm) <= idx); f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value,a8.value);
if (SQ_SUCCEEDED(mRes))
f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value,a8.value);
} }
}; };
@ -1371,8 +1362,6 @@ template<class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8
struct ArgFwd<T1,T2,T3,T4,T5,T6,T7,T8,T9> { struct ArgFwd<T1,T2,T3,T4,T5,T6,T7,T8,T9> {
// Used to tell whether the last template parameter is a StackStrF type // Used to tell whether the last template parameter is a StackStrF type
static constexpr bool HASFMT = ArgFwdHasFmt<T9>::value; static constexpr bool HASFMT = ArgFwdHasFmt<T9>::value;
// Where Squirrel result codes can be stored
SQInteger mRes;
// Forward the arguments to a function object // Forward the arguments to a function object
template<class F> inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { template<class F> inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) {
Var<T1> a1(vm, idx++); Var<T1> a1(vm, idx++);
@ -1383,10 +1372,8 @@ struct ArgFwd<T1,T2,T3,T4,T5,T6,T7,T8,T9> {
Var<T6> a6(vm, idx++); Var<T6> a6(vm, idx++);
Var<T7> a7(vm, idx++); Var<T7> a7(vm, idx++);
Var<T8> a8(vm, idx++); Var<T8> a8(vm, idx++);
Var<T9> a9(vm, idx); ArgFwdFmtVar<T9, HASFMT> a9(vm, idx);
mRes = ArgFwdFmt<HASFMT>::Proc(a9.value, sq_gettop(vm) <= idx); f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value,a8.value,a9.value);
if (SQ_SUCCEEDED(mRes))
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<class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8
struct ArgFwd<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10> { struct ArgFwd<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10> {
// Used to tell whether the last template parameter is a StackStrF type // Used to tell whether the last template parameter is a StackStrF type
static constexpr bool HASFMT = ArgFwdHasFmt<T10>::value; static constexpr bool HASFMT = ArgFwdHasFmt<T10>::value;
// Where Squirrel result codes can be stored
SQInteger mRes;
// Forward the arguments to a function object // Forward the arguments to a function object
template<class F> inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { template<class F> inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) {
Var<T1> a1(vm, idx++); Var<T1> a1(vm, idx++);
@ -1407,10 +1392,8 @@ struct ArgFwd<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10> {
Var<T7> a7(vm, idx++); Var<T7> a7(vm, idx++);
Var<T8> a8(vm, idx++); Var<T8> a8(vm, idx++);
Var<T9> a9(vm, idx++); Var<T9> a9(vm, idx++);
Var<T10> a10(vm, idx); ArgFwdFmtVar<T10, HASFMT> a10(vm, idx);
mRes = ArgFwdFmt<HASFMT>::Proc(a10.value, sq_gettop(vm) <= idx); f(vm,a1.value,a2.value,a3.value,a4.value,a5.value,a6.value,a7.value,a8.value,a9.value,a10.value);
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);
} }
}; };
@ -1418,8 +1401,6 @@ template<class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8
struct ArgFwd<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11> { struct ArgFwd<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11> {
// Used to tell whether the last template parameter is a StackStrF type // Used to tell whether the last template parameter is a StackStrF type
static constexpr bool HASFMT = ArgFwdHasFmt<T11>::value; static constexpr bool HASFMT = ArgFwdHasFmt<T11>::value;
// Where Squirrel result codes can be stored
SQInteger mRes;
// Forward the arguments to a function object // Forward the arguments to a function object
template<class F> inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { template<class F> inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) {
Var<T1> a1(vm, idx++); Var<T1> a1(vm, idx++);
@ -1432,10 +1413,8 @@ struct ArgFwd<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11> {
Var<T8> a8(vm, idx++); Var<T8> a8(vm, idx++);
Var<T9> a9(vm, idx++); Var<T9> a9(vm, idx++);
Var<T10> a10(vm, idx++); Var<T10> a10(vm, idx++);
Var<T11> a11(vm, idx); ArgFwdFmtVar<T11, HASFMT> a11(vm, idx);
mRes = ArgFwdFmt<HASFMT>::Proc(a11.value, sq_gettop(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);
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);
} }
}; };
@ -1443,8 +1422,6 @@ template<class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8
struct ArgFwd<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12> { struct ArgFwd<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12> {
// Used to tell whether the last template parameter is a StackStrF type // Used to tell whether the last template parameter is a StackStrF type
static constexpr bool HASFMT = ArgFwdHasFmt<T12>::value; static constexpr bool HASFMT = ArgFwdHasFmt<T12>::value;
// Where Squirrel result codes can be stored
SQInteger mRes;
// Forward the arguments to a function object // Forward the arguments to a function object
template<class F> inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { template<class F> inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) {
Var<T1> a1(vm, idx++); Var<T1> a1(vm, idx++);
@ -1458,10 +1435,8 @@ struct ArgFwd<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12> {
Var<T9> a9(vm, idx++); Var<T9> a9(vm, idx++);
Var<T10> a10(vm, idx++); Var<T10> a10(vm, idx++);
Var<T11> a11(vm, idx++); Var<T11> a11(vm, idx++);
Var<T12> a12(vm, idx); ArgFwdFmtVar<T12, HASFMT> a12(vm, idx);
mRes = ArgFwdFmt<HASFMT>::Proc(a12.value, sq_gettop(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);
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);
} }
}; };
@ -1469,8 +1444,6 @@ template<class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8
struct ArgFwd<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13> { struct ArgFwd<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13> {
// Used to tell whether the last template parameter is a StackStrF type // Used to tell whether the last template parameter is a StackStrF type
static constexpr bool HASFMT = ArgFwdHasFmt<T13>::value; static constexpr bool HASFMT = ArgFwdHasFmt<T13>::value;
// Where Squirrel result codes can be stored
SQInteger mRes;
// Forward the arguments to a function object // Forward the arguments to a function object
template<class F> inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { template<class F> inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) {
Var<T1> a1(vm, idx++); Var<T1> a1(vm, idx++);
@ -1485,10 +1458,8 @@ struct ArgFwd<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13> {
Var<T10> a10(vm, idx++); Var<T10> a10(vm, idx++);
Var<T11> a11(vm, idx++); Var<T11> a11(vm, idx++);
Var<T12> a12(vm, idx++); Var<T12> a12(vm, idx++);
Var<T13> a13(vm, idx); ArgFwdFmtVar<T13, HASFMT> a13(vm, idx);
mRes = ArgFwdFmt<HASFMT>::Proc(a13.value, sq_gettop(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);
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);
} }
}; };
@ -1496,8 +1467,6 @@ template<class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8
struct ArgFwd<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14> { struct ArgFwd<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14> {
// Used to tell whether the last template parameter is a StackStrF type // Used to tell whether the last template parameter is a StackStrF type
static constexpr bool HASFMT = ArgFwdHasFmt<T14>::value; static constexpr bool HASFMT = ArgFwdHasFmt<T14>::value;
// Where Squirrel result codes can be stored
SQInteger mRes;
// Forward the arguments to a function object // Forward the arguments to a function object
template<class F> inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) { template<class F> inline void Call(HSQUIRRELVM vm, SQInteger idx, F f) {
Var<T1> a1(vm, idx++); Var<T1> a1(vm, idx++);
@ -1513,10 +1482,8 @@ struct ArgFwd<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14> {
Var<T11> a11(vm, idx++); Var<T11> a11(vm, idx++);
Var<T12> a12(vm, idx++); Var<T12> a12(vm, idx++);
Var<T13> a13(vm, idx++); Var<T13> a13(vm, idx++);
Var<T14> a14(vm, idx); ArgFwdFmtVar<T14, HASFMT> a14(vm, idx);
mRes = ArgFwdFmt<HASFMT>::Proc(a14.value, sq_gettop(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);
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);
} }
}; };

View File

@ -402,6 +402,15 @@ public:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Exception(const SQChar * msg) : message(msg) {} 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 /// Constructs an exception
/// ///
@ -1503,7 +1512,7 @@ struct StackGuard
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
~StackGuard() ~StackGuard()
{ {
Restore(); Restore();
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -1520,15 +1529,15 @@ struct StackGuard
/// Restore the stack to what was known to be. /// Restore the stack to what was known to be.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Restore() const void Restore() const
{ {
// Retrieve the new stack top // Retrieve the new stack top
const SQInteger top = sq_gettop(m_VM); const SQInteger top = sq_gettop(m_VM);
// Did the stack size change? // Did the stack size change?
if (top > m_Top) 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: private:
@ -1654,25 +1663,20 @@ struct StackStrF
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Actual implementation. /// 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 there's no virtual machine, just ignore the request
if (mVM == nullptr) if (mVM == nullptr)
{ {
return SQ_OK; return SQ_OK;
} }
// Release the converted value object
else if (!sq_isnull(mObj))
{
sq_release(mVM, &mObj);
}
// Reset the converted value object // Reset the converted value object
sq_resetobject(&mObj); 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 // Grab the top of the stack
const SQInteger top = sq_gettop(mVM); const SQInteger top = sq_gettop(mVM);
// Was the string or value specified? // 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. /// RAII approach to make sure an instance is deleted regardless of what exceptions are thrown.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////