Release ScriptVariant_t memory in all paths of squirrel function stubs

This commit is contained in:
Alexander 'z33ky' Hirsch 2024-11-18 15:09:55 +01:00
parent c0e12a2f58
commit 1ecaa44c49

View File

@ -1405,31 +1405,39 @@ SQInteger function_stub(HSQUIRRELVM vm)
instance = ((ClassInstanceData*)self)->instance; instance = ((ClassInstanceData*)self)->instance;
} }
ScriptVariant_t retval; ScriptVariant_t script_retval;
ScriptVariantTemporaryStorage_t retval_storage; ScriptVariantTemporaryStorage_t script_retval_storage;
SquirrelVM* pSquirrelVM = (SquirrelVM*)sq_getforeignptr(vm); SquirrelVM* pSquirrelVM = (SquirrelVM*)sq_getforeignptr(vm);
assert(pSquirrelVM); assert(pSquirrelVM);
sq_resetobject(&pSquirrelVM->lastError_); sq_resetobject(&pSquirrelVM->lastError_);
(*pFunc->m_pfnBinding)(pFunc->m_pFunction, instance, params.Base(), nargs, bool call_success = (*pFunc->m_pfnBinding)(pFunc->m_pFunction, instance, params.Base(), nargs,
pFunc->m_desc.m_ReturnType == FIELD_VOID ? nullptr : &retval, retval_storage); pFunc->m_desc.m_ReturnType == FIELD_VOID ? nullptr : &script_retval, script_retval_storage);
Assert(call_success);
(void)call_success;
SQInteger sq_retval;
if (!sq_isnull(pSquirrelVM->lastError_)) if (!sq_isnull(pSquirrelVM->lastError_))
{ {
sq_pushobject(vm, pSquirrelVM->lastError_); sq_pushobject(vm, pSquirrelVM->lastError_);
sq_resetobject(&pSquirrelVM->lastError_); sq_resetobject(&pSquirrelVM->lastError_);
return sq_throwobject(vm); sq_retval = sq_throwobject(vm);
} }
else
{
Assert(script_retval.m_type == pFunc->m_desc.m_ReturnType);
PushVariant(vm, retval); PushVariant(vm, script_retval);
sq_retval = 1;
}
// strings never get copied here, Vector and QAngle are stored in script_retval_storage // strings never get copied here, Vector and QAngle are stored in script_retval_storage
// everything else is stored inline, so there should be no memory to free // everything else is stored inline, so there should be no memory to free
Assert(!(retval.m_flags & SV_FREE)); Assert(!(script_retval.m_flags & SV_FREE));
return pFunc->m_desc.m_ReturnType != FIELD_VOID; return sq_retval;
} }
@ -1469,12 +1477,8 @@ SQInteger constructor_stub(HSQUIRRELVM vm)
void* instance = pClassDesc->m_pfnConstruct(); void* instance = pClassDesc->m_pfnConstruct();
if (!sq_isnull(pSquirrelVM->lastError_)) // expect construction to always succeed
{ Assert(sq_isnull(pSquirrelVM->lastError_));
sq_pushobject(vm, pSquirrelVM->lastError_);
sq_resetobject(&pSquirrelVM->lastError_);
return sq_throwobject(vm);
}
{ {
SQUserPointer p; SQUserPointer p;
@ -1531,19 +1535,22 @@ SQInteger get_stub(HSQUIRRELVM vm)
} }
ScriptVariant_t var; ScriptVariant_t var;
SQInteger sq_retval = 0;
if (classInstanceData && if (classInstanceData &&
classInstanceData->instance && classInstanceData->instance &&
classInstanceData->desc->pHelper && classInstanceData->desc->pHelper &&
classInstanceData->desc->pHelper->Get(classInstanceData->instance, key, var)) classInstanceData->desc->pHelper->Get(classInstanceData->instance, key, var))
{ {
PushVariant(vm, var); PushVariant(vm, var);
sq_retval = 1;
} }
else else
{ {
return sqstd_throwerrorf(vm, "the index '%.50s' does not exist", key); sq_retval = sqstd_throwerrorf(vm, "the index '%.50s' does not exist", key);
} }
return 1; var.Free();
return sq_retval;
} }
SQInteger set_stub(HSQUIRRELVM vm) SQInteger set_stub(HSQUIRRELVM vm)
@ -1560,22 +1567,22 @@ SQInteger set_stub(HSQUIRRELVM vm)
} }
ScriptVariant_t var; ScriptVariant_t var;
SQInteger sq_retval = 0;
getVariant( vm, -1, var ); getVariant( vm, -1, var );
if (classInstanceData && if (!(
classInstanceData &&
classInstanceData->instance && classInstanceData->instance &&
classInstanceData->desc->pHelper && classInstanceData->desc->pHelper &&
classInstanceData->desc->pHelper->Set(classInstanceData->instance, key, var)) classInstanceData->desc->pHelper->Set(classInstanceData->instance, key, var)
))
{ {
sq_pop(vm, 1); sq_retval = sqstd_throwerrorf(vm, "the index '%.50s' does not exist", key);
}
else
{
sq_pop(vm, 1);
return sqstd_throwerrorf(vm, "the index '%.50s' does not exist", key);
} }
return 0; var.Free();
sq_pop(vm, 1);
return sq_retval;
} }
SQInteger IsValid_stub(HSQUIRRELVM vm) SQInteger IsValid_stub(HSQUIRRELVM vm)
@ -2326,6 +2333,7 @@ void SquirrelVM::RegisterFunction(ScriptFunctionBinding_t* pScriptFunction)
return; return;
char typemask[64]; char typemask[64];
Assert(pScriptFunction->m_desc.m_Parameters.Count() < sizeof(typemask));
if (!CreateParamCheck(*pScriptFunction, typemask)) if (!CreateParamCheck(*pScriptFunction, typemask))
{ {
return; return;
@ -2429,6 +2437,7 @@ bool SquirrelVM::RegisterClass(ScriptClassDesc_t* pClassDesc)
auto& scriptFunction = pClassDesc->m_FunctionBindings[i]; auto& scriptFunction = pClassDesc->m_FunctionBindings[i];
char typemask[64]; char typemask[64];
Assert(scriptFunction.m_desc.m_Parameters.Count() < sizeof(typemask));
if (!CreateParamCheck(scriptFunction, typemask)) if (!CreateParamCheck(scriptFunction, typemask))
{ {
Warning("Unable to create param check for %s.%s\n", Warning("Unable to create param check for %s.%s\n",