From a0dd23e63eae5df02c062737e2679e31cd304655 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Wed, 28 Oct 2026 17:29:24 +0100 Subject: [PATCH] Fix instance-call diagnostics and declaring scope for static methods --- engine/vm.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/engine/vm.c b/engine/vm.c index b534941..a7380da 100644 --- a/engine/vm.c +++ b/engine/vm.c @@ -1111,7 +1111,7 @@ static ph7_vm_func *VmOverload( sxi32 bInternal /* VM-invoked methods already have an access context */ ) { sxu32 iTarget, j, k, iArgs, nCandidates, nCompatible, nCols, nPassed; - sxi32 bDominated; + sxi32 bDominated, bInstanceOnly = 0; ph7_vm_func **apSet; ph7_vm_func *pLink; ph7_vm_func_arg *pFuncArg; @@ -1160,10 +1160,13 @@ static ph7_vm_func *VmOverload( for(pLink = pEntry ? (ph7_vm_func *)pEntry->pUserData : 0; pLink; pLink = pLink->pNextName) { pMeth = (ph7_class_method *)pLink; if((pMeth->iFlags & PH7_CLASS_ATTR_VIRTUAL) || - (bStatic && !(pMeth->iFlags & PH7_CLASS_ATTR_STATIC)) || (!bInternal && !VmClassMemberAccess(pVm, pLink->pClass, pMeth->iProtection))) { continue; } + if(bStatic && !(pMeth->iFlags & PH7_CLASS_ATTR_STATIC)) { + bInstanceOnly = 1; + continue; + } for(k = 0; k < SySetUsed(&sMethods); k++) { if(PH7_VmSameSignature(pLink, *(ph7_vm_func **)SySetAt(&sMethods, k))) { break; @@ -1181,6 +1184,11 @@ static ph7_vm_func *VmOverload( } } } + if(bInstanceOnly && SySetUsed(&sMethods) < 1) { + SySetRelease(&sMethods); + SySetRelease(&sSet); + PH7_VmThrowError(pVm, PH7_CTX_ERR, "Instance method '%z()' requires an object", &pList->sName); + } /* Put functions whose arguments are compatible with the current call */ for(iMethod = 0; iMethod < SySetUsed(&sMethods); iMethod++) { pLink = *(ph7_vm_func **)SySetAt(&sMethods, iMethod); @@ -5743,7 +5751,8 @@ Resume: } else { pVmFunc = (ph7_vm_func *)pInstr->p3; } - if(pThis && (pVmFunc->iFlags & VM_FUNC_CLASS_METHOD)) { + /* The selected declaration owns the scope, even without a receiver. */ + if(pVmFunc->iFlags & VM_FUNC_CLASS_METHOD) { pSelf = pVmFunc->pClass; } if(pVmFunc->iFlags & VM_FUNC_CLOSURE) {