Validate interface contracts against effective C3 implementations and support transitive interface checks
Build / AerScript (push) Successful in 39s

This commit is contained in:
2026-10-24 20:19:11 +02:00
parent c6e7151e72
commit 1026c8d525
4 changed files with 176 additions and 69 deletions
+17 -39
View File
@@ -6645,14 +6645,16 @@ static int VmQueryInterfaceSet(ph7_class *pClass, SySet *pSet) {
* Otherwise FALSE is returned.
*/
static int VmInstanceOf(ph7_vm *pVm, ph7_class *pThis, ph7_class *pClass) {
SyHashEntry *pEntry;
ph7_class *pDerived, *pParent;
SySet sInterfaces;
sxi32 rc;
if(!pThis || !pClass) {
return FALSE;
}
if(pThis == pClass) {
/* Instance of the same class */
return TRUE;
}
if(!(pThis->iFlags & PH7_CLASS_INTERFACE) && !(pClass->iFlags & PH7_CLASS_INTERFACE)) {
if(!(pThis->iFlags & PH7_CLASS_INTERFACE)) {
sxu32 i;
if(PH7_ClassBuildMro(pVm, pThis) != SXRET_OK) {
PH7_VmThrowError(pVm, PH7_CTX_ERR, "PH7 is running out-of-memory");
@@ -6662,44 +6664,20 @@ static int VmInstanceOf(ph7_vm *pVm, ph7_class *pThis, ph7_class *pClass) {
return TRUE;
}
}
if(!(pClass->iFlags & PH7_CLASS_INTERFACE)) {
return FALSE;
}
}
SySetInit(&sInterfaces, &pVm->sAllocator, sizeof(ph7_class *));
rc = PH7_ClassCollectInterfaces(pVm, pThis, &sInterfaces);
if(rc != SXRET_OK) {
SySetRelease(&sInterfaces);
PH7_VmMemoryError(pVm);
return FALSE;
}
/* Check implemented interfaces */
rc = VmQueryInterfaceSet(pClass, &pThis->aInterface);
if(rc) {
return TRUE;
}
/* Check derived classes */
SyHashResetLoopCursor(&pThis->hDerived);
while((pEntry = SyHashGetNextEntry(&pThis->hDerived)) != 0) {
pDerived = (ph7_class *) pEntry->pUserData;
if(pDerived == pClass) {
/* Same instance */
return TRUE;
}
/* Check the implemented interfaces */
rc = VmQueryInterfaceSet(pClass, &pDerived->aInterface);
if(rc) {
return TRUE;
}
/* Check parent classes */
pParent = pDerived->pBase;
while(pParent) {
if(pParent == pClass) {
/* Same instance */
return TRUE;
}
/* Check the implemented interfaces */
rc = VmQueryInterfaceSet(pClass, &pParent->aInterface);
if(rc) {
return TRUE;
}
/* Point to the parent class */
pParent = pParent->pBase;
}
}
/* Not an instance of the the given class */
return FALSE;
rc = VmQueryInterfaceSet(pClass, &sInterfaces);
SySetRelease(&sInterfaces);
return rc;
}
/*
* This function returns TRUE if the given class (first argument)