diff --git a/sp/src/public/vscript/ivscript.h b/sp/src/public/vscript/ivscript.h index c0a0cf08..1eba404c 100644 --- a/sp/src/public/vscript/ivscript.h +++ b/sp/src/public/vscript/ivscript.h @@ -263,6 +263,8 @@ inline const char * ScriptFieldTypeName( int16 eType) //--------------------------------------------------------- +struct ScriptClassDesc_t; + struct ScriptFuncDescriptor_t { ScriptFuncDescriptor_t() @@ -270,11 +272,13 @@ struct ScriptFuncDescriptor_t m_pszFunction = NULL; m_ReturnType = FIELD_TYPEUNKNOWN; m_pszDescription = NULL; + m_pScriptClassDesc = NULL; } const char *m_pszScriptName; const char *m_pszFunction; const char *m_pszDescription; + ScriptClassDesc_t *m_pScriptClassDesc; ScriptDataType_t m_ReturnType; CUtlVector m_Parameters; }; diff --git a/sp/src/public/vscript/vscript_templates.h b/sp/src/public/vscript/vscript_templates.h index 9f2054cc..bda6bc9e 100644 --- a/sp/src/public/vscript/vscript_templates.h +++ b/sp/src/public/vscript/vscript_templates.h @@ -61,7 +61,7 @@ FUNC_GENERATE_ALL( DEFINE_MEMBER_FUNC_TYPE_DEDUCER ); FUNC_GENERATE_ALL( DEFINE_CONST_MEMBER_FUNC_TYPE_DEDUCER ); -#define ScriptInitMemberFuncDescriptor_( pDesc, class, func, scriptName ) if ( 0 ) {} else { (pDesc)->m_pszScriptName = scriptName; (pDesc)->m_pszFunction = #func; ScriptDeduceFunctionSignature( pDesc, (class *)(0), &class::func ); } +#define ScriptInitMemberFuncDescriptor_( pDesc, class, func, scriptName ) if ( 0 ) {} else { (pDesc)->m_pszScriptName = scriptName; (pDesc)->m_pszFunction = #func; ScriptDeduceFunctionSignature( pDesc, (class *)(0), &class::func ); (pDesc)->m_pScriptClassDesc = GetScriptDesc(nullptr); } #define ScriptInitFuncDescriptorNamed( pDesc, func, scriptName ) if ( 0 ) {} else { (pDesc)->m_pszScriptName = scriptName; (pDesc)->m_pszFunction = #func; ScriptDeduceFunctionSignature( pDesc, &func ); } #define ScriptInitFuncDescriptor( pDesc, func ) ScriptInitFuncDescriptorNamed( pDesc, func, #func ) diff --git a/sp/src/vscript/vscript_squirrel.cpp b/sp/src/vscript/vscript_squirrel.cpp index 584402a1..39139fec 100644 --- a/sp/src/vscript/vscript_squirrel.cpp +++ b/sp/src/vscript/vscript_squirrel.cpp @@ -1427,18 +1427,30 @@ SQInteger function_stub(HSQUIRRELVM vm) if (pFunc->m_flags & SF_MEMBER_FUNC) { - SQUserPointer self; - if (SQ_FAILED(sq_getinstanceup(vm, 1, &self, 0))) + ClassInstanceData* classInstanceData; + if (SQ_FAILED(sq_getinstanceup(vm, 1, (SQUserPointer*)&classInstanceData, 0))) { - return sq_throwerror(vm, "Expected class userpointer"); + return SQ_ERROR; } - if (!self) + if (!classInstanceData) { return sq_throwerror(vm, "Accessed null instance"); } - instance = ((ClassInstanceData*)self)->instance; + // check that the type of self, or any basetype, matches the function description + ScriptClassDesc_t *selfType = classInstanceData->desc; + while (selfType != pFunc->m_desc.m_pScriptClassDesc) + { + if (!selfType) + { + return sq_throwerror(vm, "Mismatched instance type"); + } + selfType = selfType->m_pBaseDesc; + Assert(selfType != classInstanceData->desc); // there should be no infinite loop + } + + instance = classInstanceData->instance; } ScriptVariant_t script_retval;