From 2a4e47e782bc8e8fb9c08b20d26399e0966f9438 Mon Sep 17 00:00:00 2001 From: belliash Date: Wed, 10 Apr 2019 18:32:53 +0200 Subject: [PATCH] I hope this finally fixes the default argument value. --- engine/compiler.c | 4 +++- engine/vm.c | 55 +++++++++++++++++++++++++++++++++++------------ 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/engine/compiler.c b/engine/compiler.c index 68088bf..0190b05 100644 --- a/engine/compiler.c +++ b/engine/compiler.c @@ -2891,8 +2891,10 @@ static sxi32 PH7_GenStateCollectFuncArgs(ph7_vm_func *pFunc, ph7_gen_state *pGen if(zDup) { sArg.nType = SXU32_HIGH; /* 0xFFFFFFFF as sentinel */ SyStringInitFromBuf(&sArg.sClass, zDup, pName->nByte); + } else { + /* This should not happen, but fallback to object anyway */ + sArg.nType = MEMOBJ_OBJ; } - sArg.nType = MEMOBJ_OBJ; } pIn++; if((pIn->nType & PH7_TK_OSB) && &pIn[1] < pEnd && (pIn[1].nType & PH7_TK_CSB)) { diff --git a/engine/vm.c b/engine/vm.c index bc0dd4a..e782d6f 100644 --- a/engine/vm.c +++ b/engine/vm.c @@ -4886,7 +4886,7 @@ static sxi32 VmByteCodeExec( } else { ph7_class_instance *pThis = (ph7_class_instance *)pArg->x.pOther; /* Make sure the object is an instance of the given class */ - if(! VmInstanceOf(pThis->pClass, pClass)) { + if(pThis == 0 || !VmInstanceOf(pThis->pClass, pClass)) { PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, "Argument %u passed to function '%z()' must be an object of type '%z'", n+1, &pVmFunc->sName, pName); @@ -4986,20 +4986,47 @@ static sxi32 VmByteCodeExec( if(rc == PH7_ABORT) { goto Abort; } - ph7_value *pTmp = PH7_ReserveMemObj(&(*pVm)); - pTmp->iFlags = aFormalArg[n].nType; - rc = PH7_MemObjSafeStore(pObj, pTmp); - if(rc != SXRET_OK) { - PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, - "Default value for argument %u of '%z()' does not match the data type", n + 1, &pVmFunc->sName); + if(aFormalArg[n].nType == SXU32_HIGH) { + /* Argument must be a class instance [i.e: object] */ + SyString *pName = &aFormalArg[n].sClass; + ph7_class *pClass; + /* Try to extract the desired class */ + pClass = PH7_VmExtractClass(&(*pVm), pName->zString, pName->nByte, TRUE, 0); + if(pClass) { + if((pObj->iFlags & MEMOBJ_OBJ) == 0) { + if((pObj->iFlags & MEMOBJ_NULL) == 0) { + PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, + "Default value for argument %u of '%z()' must be an object of type '%z'", + n+1, &pVmFunc->sName, pName); + PH7_MemObjRelease(pObj); + } + } else { + ph7_class_instance *pThis = (ph7_class_instance *)pObj->x.pOther; + /* Make sure the object is an instance of the given class */ + if(pThis == 0 || !VmInstanceOf(pThis->pClass, pClass)) { + PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, + "Default value for argument %u of '%z()' must be an object of type '%z'", + n+1, &pVmFunc->sName, pName); + PH7_MemObjRelease(pObj); + } + } + } + } else { + ph7_value *pTmp = PH7_ReserveMemObj(&(*pVm)); + pTmp->iFlags = aFormalArg[n].nType; + /* Make sure the default argument is of the correct type */ + rc = PH7_MemObjSafeStore(pObj, pTmp); + if(rc != SXRET_OK) { + PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, + "Default value for argument %u of '%z()' does not match the data type", n + 1, &pVmFunc->sName); + } + pObj->iFlags = pTmp->iFlags; + PH7_MemObjRelease(pTmp); + /* Insert argument index */ + sArg.nIdx = pObj->nIdx; + sArg.pUserData = 0; + SySetPut(&pFrame->sArg, (const void *)&sArg); } - pObj->iFlags = pTmp->iFlags; - PH7_MemObjRelease(pTmp); - /* Insert argument index */ - sArg.nIdx = pObj->nIdx; - sArg.pUserData = 0; - SySetPut(&pFrame->sArg, (const void *)&sArg); - /* Make sure the default argument is of the correct type */ } } ++n;