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

Fix StackStrF mistaking the free function variable containing the native function wrapper pointer as a user passed parameter.

Also fix StackStrF treating negative indexes as positive indexes.
Make ErrorToException inline instead of static in header.
This commit is contained in:
Sandu Liviu Catalin 2018-10-25 19:43:38 +03:00
parent d556364ecf
commit 2b9c8f6550
2 changed files with 44 additions and 6 deletions

View File

@ -1029,7 +1029,7 @@ struct Var<StackStrF> {
/// ///
/// \param vm Target VM /// \param vm Target VM
/// \param idx Index trying to be read /// \param idx Index trying to be read
/// \param idx Whether to mimmic a format function /// \param fmt Whether to mimmic a format function
/// ///
/// \remarks /// \remarks
/// This function MUST have its Error handled if it occurred. /// This function MUST have its Error handled if it occurred.
@ -1040,6 +1040,26 @@ struct Var<StackStrF> {
ErrorToException(vm); ErrorToException(vm);
} }
} }
// Quick and dirty way to subtract the function pointer from the stack top as to not confuse formatted functions
enum DropFuncPtrOverload { DropFuncPtr };
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// 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 fmt Whether to mimmic a format function
/// \param top Number of slots to ignore from the stack top
///
/// \remarks
/// This function MUST have its Error handled if it occurred.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Var(HSQUIRRELVM vm, SQInteger idx, bool fmt, DropFuncPtrOverload /*fpsub*/) : value(vm, idx) {
if (SQ_FAILED(value.Proc(fmt, sq_gettop(vm) - 1))) {
ErrorToException(vm);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Called by Sqrat::PushVar to put an StackStrF on the stack /// Called by Sqrat::PushVar to put an StackStrF on the stack
@ -1064,6 +1084,8 @@ template<>
struct Var<StackStrF&> : Var<StackStrF> { struct Var<StackStrF&> : Var<StackStrF> {
Var(HSQUIRRELVM vm, SQInteger idx) : Var<StackStrF>(vm, idx) {} Var(HSQUIRRELVM vm, SQInteger idx) : Var<StackStrF>(vm, idx) {}
Var(HSQUIRRELVM vm, SQInteger idx, bool fmt) : Var<StackStrF>(vm, idx, fmt) {} Var(HSQUIRRELVM vm, SQInteger idx, bool fmt) : Var<StackStrF>(vm, idx, fmt) {}
Var(HSQUIRRELVM vm, SQInteger idx, bool fmt, Var<StackStrF>::DropFuncPtrOverload /*fpsub*/)
: Var<StackStrF>(vm, idx, fmt, Var<StackStrF>::DropFuncPtr) {}
}; };
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -1073,6 +1095,8 @@ template<>
struct Var<const StackStrF&> : Var<StackStrF> { struct Var<const StackStrF&> : Var<StackStrF> {
Var(HSQUIRRELVM vm, SQInteger idx) : Var<StackStrF>(vm, idx) {} Var(HSQUIRRELVM vm, SQInteger idx) : Var<StackStrF>(vm, idx) {}
Var(HSQUIRRELVM vm, SQInteger idx, bool fmt) : Var<StackStrF>(vm, idx, fmt) {} Var(HSQUIRRELVM vm, SQInteger idx, bool fmt) : Var<StackStrF>(vm, idx, fmt) {}
Var(HSQUIRRELVM vm, SQInteger idx, bool fmt, Var<StackStrF>::DropFuncPtrOverload /*fpsub*/)
: Var<StackStrF>(vm, idx, fmt, Var<StackStrF>::DropFuncPtr) {}
}; };
// Non-referencable type definitions // Non-referencable type definitions
@ -1217,7 +1241,7 @@ template<class T, bool> struct ArgFwdFmtVar : Var<T> {
ArgFwdFmtVar(HSQUIRRELVM vm, SQInteger idx) : Var<T>(vm, idx) {} ArgFwdFmtVar(HSQUIRRELVM vm, SQInteger idx) : Var<T>(vm, idx) {}
}; };
template<class T> struct ArgFwdFmtVar<T, true> : Var<T> { template<class T> struct ArgFwdFmtVar<T, true> : Var<T> {
ArgFwdFmtVar(HSQUIRRELVM vm, SQInteger idx) : Var<T>(vm, idx, true) {} ArgFwdFmtVar(HSQUIRRELVM vm, SQInteger idx) : Var<T>(vm, idx, true, Var<T>::DropFuncPtr) {}
}; };
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -1545,6 +1545,15 @@ private:
SQInteger m_Top; ///< The top of the stack when this instance was created. SQInteger m_Top; ///< The top of the stack when this instance was created.
}; };
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Helper function to transform a negative index into a positive index.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
inline SQInteger IndexAbs(SQInteger top, SQInteger idx)
{
return (idx <= -1) ? (top + idx + 1) : idx;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Helper structure for retrieving a value from the stack as a string or a formatted string. /// Helper structure for retrieving a value from the stack as a string or a formatted string.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -1663,7 +1672,7 @@ struct StackStrF
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Actual implementation. /// Actual implementation.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
SQRESULT Proc(bool fmt = false) SQRESULT Proc(bool fmt = false, SQInteger top = -1)
{ {
// 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)
@ -1677,8 +1686,13 @@ struct StackStrF
} }
// Reset the converted value object // Reset the converted value object
sq_resetobject(&mObj); sq_resetobject(&mObj);
// Grab the top of the stack // Grab the top of the stack, if necessary
const SQInteger top = sq_gettop(mVM); if (top < 0)
{
top = sq_gettop(mVM);
}
// Make the stack index absolute
mIdx = IndexAbs(top, mIdx);
// Was the string or value specified? // Was the string or value specified?
if (top <= (mIdx - 1)) if (top <= (mIdx - 1))
{ {
@ -1766,7 +1780,7 @@ struct StackStrF
/// \param keep Whether to clear the error from the VM /// \param keep Whether to clear the error from the VM
/// ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static void ErrorToException(HSQUIRRELVM vm, bool keep = false) { inline void ErrorToException(HSQUIRRELVM vm, bool keep = false) {
// Get the error object on the stack // Get the error object on the stack
sq_getlasterror(vm); sq_getlasterror(vm);
// See if there's an actual error // See if there's an actual error