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:
parent
d556364ecf
commit
2b9c8f6550
@ -1029,7 +1029,7 @@ struct Var<StackStrF> {
|
||||
///
|
||||
/// \param vm Target VM
|
||||
/// \param idx Index trying to be read
|
||||
/// \param idx Whether to mimmic a format function
|
||||
/// \param fmt Whether to mimmic a format function
|
||||
///
|
||||
/// \remarks
|
||||
/// This function MUST have its Error handled if it occurred.
|
||||
@ -1040,6 +1040,26 @@ struct Var<StackStrF> {
|
||||
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
|
||||
@ -1064,6 +1084,8 @@ template<>
|
||||
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) {}
|
||||
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> {
|
||||
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>::DropFuncPtrOverload /*fpsub*/)
|
||||
: Var<StackStrF>(vm, idx, fmt, Var<StackStrF>::DropFuncPtr) {}
|
||||
};
|
||||
|
||||
// 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) {}
|
||||
};
|
||||
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) {}
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1545,6 +1545,15 @@ private:
|
||||
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.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -1663,7 +1672,7 @@ struct StackStrF
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// 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 (mVM == nullptr)
|
||||
@ -1677,8 +1686,13 @@ struct StackStrF
|
||||
}
|
||||
// Reset the converted value object
|
||||
sq_resetobject(&mObj);
|
||||
// Grab the top of the stack
|
||||
const SQInteger top = sq_gettop(mVM);
|
||||
// Grab the top of the stack, if necessary
|
||||
if (top < 0)
|
||||
{
|
||||
top = sq_gettop(mVM);
|
||||
}
|
||||
// Make the stack index absolute
|
||||
mIdx = IndexAbs(top, mIdx);
|
||||
// Was the string or value specified?
|
||||
if (top <= (mIdx - 1))
|
||||
{
|
||||
@ -1766,7 +1780,7 @@ struct StackStrF
|
||||
/// \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
|
||||
sq_getlasterror(vm);
|
||||
// See if there's an actual error
|
||||
|
Loading…
x
Reference in New Issue
Block a user