Implement __invoke dispatch and fix VM cleanup and allocator alignment
This commit is contained in:
+20
-9
@@ -5563,7 +5563,24 @@ Resume:
|
||||
SyString sName;
|
||||
/* Extract function name */
|
||||
/* Synthetic calls have no preceding instruction at pc == 0. */
|
||||
if(pTos->nType & MEMOBJ_STRING && pc > 0 && aInstr[pc - 1].iOp == PH7_OP_LOADV) {
|
||||
if((pTos->nType & (MEMOBJ_OBJ | MEMOBJ_HASHMAP)) == MEMOBJ_OBJ) {
|
||||
ph7_class_instance *pThis = (ph7_class_instance *)pTos->x.pOther;
|
||||
ph7_class_method *pMeth;
|
||||
if(pThis == 0) {
|
||||
PH7_VmThrowError(pVm, PH7_CTX_ERR, "Call to non-instantiated object");
|
||||
}
|
||||
SyStringInitFromBuf(&sName, "__invoke", sizeof("__invoke") - 1);
|
||||
pMeth = VmMethodSeed(pVm, pThis->pClass, &sName, 0, FALSE);
|
||||
if(pMeth == 0) {
|
||||
PH7_VmThrowError(pVm, PH7_CTX_ERR, "Call to undefined method '%z->%z()'",
|
||||
&pThis->pClass->sName, &sName);
|
||||
}
|
||||
/* Keep arguments and receiver intact for ordinary method dispatch. */
|
||||
pTos++;
|
||||
SyBlobAppend(&pTos->sBlob, SyStringData(&pMeth->sVmName), SyStringLength(&pMeth->sVmName));
|
||||
MemObjSetType(pTos, MEMOBJ_STRING);
|
||||
pTos->nIdx = SXU32_HIGH;
|
||||
} else if(pTos->nType & MEMOBJ_STRING && pc > 0 && aInstr[pc - 1].iOp == PH7_OP_LOADV) {
|
||||
PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, "Calling a non-callable object");
|
||||
} else if((pTos->nType & (MEMOBJ_CALL | MEMOBJ_STRING)) == 0) {
|
||||
if(pTos->nType & MEMOBJ_HASHMAP) {
|
||||
@@ -5585,14 +5602,8 @@ Resume:
|
||||
PH7_MemObjStore(&sResult, pTos);
|
||||
PH7_MemObjRelease(&sResult);
|
||||
} else {
|
||||
if(pTos->nType & MEMOBJ_OBJ) {
|
||||
ph7_class_instance *pThis = (ph7_class_instance *)pTos->x.pOther;
|
||||
/* Call the magic method '__invoke' if available */
|
||||
PH7_ClassInstanceCallMagicMethod(&(*pVm), pThis->pClass, pThis, "__invoke", sizeof("__invoke") - 1, 0);
|
||||
} else {
|
||||
/* Raise exception: Invalid function name */
|
||||
PH7_VmThrowError(&(*pVm), PH7_CTX_WARNING, "Invalid function name");
|
||||
}
|
||||
/* Raise exception: Invalid function name */
|
||||
PH7_VmThrowError(&(*pVm), PH7_CTX_WARNING, "Invalid function name");
|
||||
/* Pop given arguments */
|
||||
if(pInstr->iP1 > 0) {
|
||||
VmPopOperand(&pTos, pInstr->iP1);
|
||||
|
||||
Reference in New Issue
Block a user