From 5256dda92296954e63cde7b9a9e82aac3b664af1 Mon Sep 17 00:00:00 2001 From: belliash Date: Fri, 10 May 2019 23:45:32 +0200 Subject: [PATCH] Attempt to fix '$this' and '$parent' constructs. --- engine/oop.c | 8 +++----- engine/vm.c | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/engine/oop.c b/engine/oop.c index b622a0f..0d47be1 100644 --- a/engine/oop.c +++ b/engine/oop.c @@ -260,11 +260,9 @@ PH7_PRIVATE sxi32 PH7_ClassInherit(ph7_vm *pVm, ph7_class *pSub, ph7_class *pBas continue; } /* Install the attribute */ - if(pAttr->iProtection != PH7_CLASS_PROT_PRIVATE) { - rc = SyHashInsert(&pSub->hAttr, (const void *)pName->zString, pName->nByte, pAttr); - if(rc != SXRET_OK) { - return rc; - } + rc = SyHashInsert(&pSub->hAttr, (const void *)pName->zString, pName->nByte, pAttr); + if(rc != SXRET_OK) { + return rc; } } SyHashResetLoopCursor(&pBase->hMethod); diff --git a/engine/vm.c b/engine/vm.c index c1d2e81..b4a0e3e 100644 --- a/engine/vm.c +++ b/engine/vm.c @@ -4548,6 +4548,7 @@ static sxi32 VmByteCodeExec( if(pEntry) { ph7_vm_func_arg *aFormalArg; ph7_class_instance *pThis; + ph7_class *pClass; ph7_value *pFrameStack; ph7_vm_func *pVmFunc; ph7_class *pSelf; @@ -4559,6 +4560,7 @@ static sxi32 VmByteCodeExec( pVmFunc = (ph7_vm_func *)pEntry->pUserData; pThis = 0; pSelf = 0; + pClass = 0; if(pVmFunc->iFlags & VM_FUNC_CLASS_METHOD) { ph7_class_method *pMeth; /* Class method call */ @@ -4569,6 +4571,16 @@ static sxi32 VmByteCodeExec( /* Instance already loaded */ pThis = (ph7_class_instance *)pTarget->x.pOther; pThis->iRef += 2; + pClass = pThis->pClass; + if(pTarget->iFlags & MEMOBJ_PARENTOBJ) { + /* Parent called */ + if(pThis->pClass->pBase == 0) { + PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, + "Attempt to call parent class from non-inheritance instance of class '%z'", &pClass->sName); + } + /* Swap to parent class */ + pThis->pClass = pThis->pClass->pBase; + } pSelf = pThis->pClass; } if(pSelf == 0) { @@ -4925,6 +4937,10 @@ static sxi32 VmByteCodeExec( SyMemBackendFree(&pVm->sAllocator, pFrameStack); /* Leave the frame */ VmLeaveFrame(&(*pVm)); + if(pClass != 0) { + /* Restore original class */ + pThis->pClass = pClass; + } if(rc == PH7_ABORT) { /* Abort processing immediately */ goto Abort;