From 43b74325b2b3533128702e7c72de712087e10345 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Wed, 28 Oct 2026 19:02:27 +0100 Subject: [PATCH] Remove method reference returns and obsolete VM support --- engine/compiler.c | 10 +-------- engine/oop.c | 12 ++++------- engine/vm.c | 54 ++++++----------------------------------------- include/ph7int.h | 3 +-- 4 files changed, 13 insertions(+), 66 deletions(-) diff --git a/engine/compiler.c b/engine/compiler.c index 16f5056..0a17272 100644 --- a/engine/compiler.c +++ b/engine/compiler.c @@ -3648,23 +3648,15 @@ static sxi32 PH7_GenStateCompileClassMethod( ) { sxu32 nLine = pGen->pIn->nLine; ph7_class_method *pMeth; - sxi32 iFuncFlags; SyString *pName; SyToken *pEnd; sxi32 rc; /* Extract visibility level */ iProtection = PH7_GetProtectionLevel(iProtection); - iFuncFlags = 0; if(pGen->pIn >= pGen->pEnd) { /* Invalid method name */ PH7_GenCompileError(pGen, E_ERROR, nLine, "Invalid method name '%z' in class '%z'", &pGen->pIn->sData, &pClass->sName); } - if(pGen->pIn < pGen->pEnd && (pGen->pIn->nType & PH7_TK_AMPER)) { - /* Return by reference,remember that */ - iFuncFlags |= VM_FUNC_REF_RETURN; - /* Jump the '&' token */ - pGen->pIn++; - } if(pGen->pIn >= pGen->pEnd || (pGen->pIn->nType & (PH7_TK_ID)) == 0) { /* Invalid method name */ PH7_GenCompileError(pGen, E_ERROR, nLine, "Invalid method name '%z' in class '%z'", &pGen->pIn->sData, &pClass->sName); @@ -3700,7 +3692,7 @@ static sxi32 PH7_GenStateCompileClassMethod( PH7_GenCompileError(pGen, E_ERROR, nLine, "Expected '(' after method name '%z::%z()'", &pClass->sName, pName); } /* Allocate a new class_method instance */ - pMeth = PH7_NewClassMethod(pGen->pVm, pClass, pName, nLine, iProtection, iFlags, iFuncFlags); + pMeth = PH7_NewClassMethod(pGen->pVm, pClass, pName, nLine, iProtection, iFlags); if(pMeth == 0) { PH7_GenCompileError(&(*pGen), E_ERROR, nLine, "PH7 is running out-of-memory"); } diff --git a/engine/oop.c b/engine/oop.c index 768add0..27127d6 100644 --- a/engine/oop.c +++ b/engine/oop.c @@ -102,7 +102,7 @@ PH7_PRIVATE ph7_class_attr *PH7_NewClassAttr(ph7_vm *pVm, ph7_class *pClass, con * random unique name. */ PH7_PRIVATE ph7_class_method *PH7_NewClassMethod(ph7_vm *pVm, ph7_class *pClass, const SyString *pName, sxu32 nLine, - sxi32 iProtection, sxi32 iFlags, sxi32 iFuncFlags) { + sxi32 iProtection, sxi32 iFlags) { ph7_class_method *pMeth; SyHashEntry *pEntry; SyString *pNamePtr; @@ -144,7 +144,7 @@ PH7_PRIVATE ph7_class_method *PH7_NewClassMethod(ph7_vm *pVm, ph7_class *pClass, pMeth->iFlags = iFlags; pMeth->nLine = nLine; PH7_VmInitFuncState(&(*pVm), &pMeth->sFunc, &zName[sizeof(char) * 4/*[__@*/ + SyStringLength(&pClass->sName)], - pName->nByte, iFuncFlags | VM_FUNC_CLASS_METHOD, pClass); + pName->nByte, VM_FUNC_CLASS_METHOD, pClass); return pMeth; } /* @@ -362,7 +362,6 @@ static sxi32 ClassValidateMethods(ph7_vm *pVm, ph7_class *pClass) { if((k < SySetUsed(&pMeth->sFunc.pClass->aMro) || ((pMeth->iFlags & pOther->iFlags) & PH7_CLASS_ATTR_VIRTUAL)) && (pMeth->sFunc.nType != pOther->sFunc.nType || - ((pMeth->sFunc.iFlags ^ pOther->sFunc.iFlags) & VM_FUNC_REF_RETURN) || ((pMeth->iFlags ^ pOther->iFlags) & PH7_CLASS_ATTR_STATIC))) { PH7_VmThrowError(pVm, PH7_CTX_ERR, "Incompatible method contract '%z::%z()' inside class '%z'", &pOther->sFunc.pClass->sName, &pOther->sFunc.sName, &pClass->sName); } @@ -386,7 +385,6 @@ static sxi32 ClassValidateMethods(ph7_vm *pVm, ph7_class *pClass) { /* Every requirement uses the same first concrete C3 declaration, not * a later implementation selected for its compatible contract. */ if(pImpl && (pImpl->sFunc.nType != pMeth->sFunc.nType || - ((pImpl->sFunc.iFlags ^ pMeth->sFunc.iFlags) & VM_FUNC_REF_RETURN) || ((pImpl->iFlags ^ pMeth->iFlags) & PH7_CLASS_ATTR_STATIC))) { PH7_VmThrowError(pVm, PH7_CTX_ERR, "Incompatible method contract '%z::%z()' inside class '%z'", &pMeth->sFunc.pClass->sName, &pMeth->sFunc.sName, &pClass->sName); } @@ -486,8 +484,7 @@ static sxi32 ClassValidateInterfaces(ph7_vm *pVm, ph7_class *pClass) { for(j = 0; j < i; j++) { pOther = *(ph7_class_method **)SySetAt(&sRequired, j); if(PH7_VmSameSignature(&pMeth->sFunc, &pOther->sFunc) && - (pMeth->sFunc.nType != pOther->sFunc.nType || - ((pMeth->sFunc.iFlags ^ pOther->sFunc.iFlags) & VM_FUNC_REF_RETURN))) { + pMeth->sFunc.nType != pOther->sFunc.nType) { PH7_VmThrowError(pVm, PH7_CTX_ERR, "Conflicting interface contract '%z::%z()' inside class '%z'", &pMeth->sFunc.pClass->sName, &pMeth->sFunc.sName, &pClass->sName); } } @@ -507,8 +504,7 @@ static sxi32 ClassValidateInterfaces(ph7_vm *pVm, ph7_class *pClass) { } if(!pImpl || (pOther->iFlags & PH7_CLASS_ATTR_VIRTUAL)) { if(pOther->iProtection != PH7_CLASS_PROT_PUBLIC || - (pOther->iFlags & PH7_CLASS_ATTR_STATIC) || pOther->sFunc.nType != pMeth->sFunc.nType || - ((pOther->sFunc.iFlags ^ pMeth->sFunc.iFlags) & VM_FUNC_REF_RETURN)) { + (pOther->iFlags & PH7_CLASS_ATTR_STATIC) || pOther->sFunc.nType != pMeth->sFunc.nType) { PH7_VmThrowError(pVm, PH7_CTX_ERR, "Incompatible interface implementation '%z::%z()' inside class '%z'", &pMeth->sFunc.pClass->sName, &pMeth->sFunc.sName, &pClass->sName); } if(!(pOther->iFlags & PH7_CLASS_ATTR_VIRTUAL)) { diff --git a/engine/vm.c b/engine/vm.c index a7380da..6f04e3a 100644 --- a/engine/vm.c +++ b/engine/vm.c @@ -2718,7 +2718,6 @@ static sxi32 VmByteCodeExec( ph7_value *pStack, /* Operand stack */ int nTos, /* Top entry in the operand stack (usually -1) */ ph7_value *pResult, /* Store program return value here. NULL otherwise */ - sxu32 *pLastRef, /* Last referenced ph7_value index */ int iExecFlags /* Callback (1), included statements or exception handler */ ) { VmInstr *pInstr; @@ -2785,12 +2784,7 @@ Resume: goto Abort; } PH7_MemObjStore(pTos, &sTransfer); - if(pLastRef) { - *pLastRef = pTos->nIdx; - } VmPopOperand(&pTos, 1); - } else if(pLastRef) { - *pLastRef = SXU32_HIGH; } iTransfer = VM_TRANSFER_RETURN; goto Unwind; @@ -2807,9 +2801,6 @@ Resume: if(pTos < pStack) { goto Abort; } - if(pLastRef) { - *pLastRef = pTos->nIdx; - } if((iExecFlags & VM_EXEC_INCLUDE) == 0 && (pVm->pFrame->iFlags & VM_FRAME_LOOP)) { /* An initializer can borrow an existing iteration frame. */ while(pVm->pFrame != pEntryFrame && pVm->pFrame->pParent && (pVm->pFrame->iFlags & (VM_FRAME_ACTIVE | VM_FRAME_CATCH | VM_FRAME_FINALLY)) == 0) { @@ -2821,9 +2812,6 @@ Resume: PH7_MemObjStore(pTos, pResult); } VmPopOperand(&pTos, 1); - } else if(pLastRef) { - /* Nothing referenced */ - *pLastRef = SXU32_HIGH; } goto Done; /* @@ -2837,9 +2825,6 @@ Resume: if(pTos < pStack) { goto Abort; } - if(pLastRef) { - *pLastRef = pTos->nIdx; - } if(pTos->nType & MEMOBJ_STRING) { if(SyBlobLength(&pTos->sBlob) > 0) { /* Output the exit message */ @@ -2852,9 +2837,6 @@ Resume: pVm->iExitStatus = (sxi32)pTos->x.iVal; } VmPopOperand(&pTos, 1); - } else if(pLastRef) { - /* Nothing referenced */ - *pLastRef = SXU32_HIGH; } goto Abort; /* @@ -6015,28 +5997,12 @@ Resume: SySetPut(&pVm->aSelf, (const void *)&pSelf); } /* Execute function body */ - rc = VmByteCodeExec(&(*pVm), (VmInstr *)SySetBasePtr(&pVmFunc->aByteCode), pFrameStack, -1, pTos, &n, FALSE); + rc = VmByteCodeExec(&(*pVm), (VmInstr *)SySetBasePtr(&pVmFunc->aByteCode), pFrameStack, -1, pTos, FALSE); if(pSelf) { /* Pop class name */ (void)SySetPop(&pVm->aSelf); } /* Cleanup the mess left behind */ - if((pVmFunc->iFlags & VM_FUNC_REF_RETURN) && rc == SXRET_OK) { - /* Return by reference,reflect that */ - if(n != SXU32_HIGH) { - VmSlot *aSlot = (VmSlot *)SySetBasePtr(&pFrame->sLocal); - sxu32 i; - /* Make sure the referenced object is not a local variable */ - for(i = 0 ; i < SySetUsed(&pFrame->sLocal) ; ++i) { - if(n == aSlot[i].nIdx) { - pObj = (ph7_value *)SySetAt(&pVm->aMemObj, n); - n = SXU32_HIGH; - break; - } - } - } - pTos->nIdx = n; - } /* Free the operand stack */ SyMemBackendFree(&pVm->sAllocator, pFrameStack); /* Leave the frame */ @@ -6161,9 +6127,6 @@ Unwind: (rc == VM_INCLUDE_RETURN || rc == VM_RETURN_VOID ? VM_TRANSFER_RETURN : VM_TRANSFER_NORMAL); bReturnValue = rc == VM_INCLUDE_RETURN; PH7_MemObjStore(&sHandler, &sTransfer); - if(pLastRef) { - *pLastRef = SXU32_HIGH; - } nTarget = sRegion.nEnd + 1; if(rc == VM_INCLUDE_JUMP) { iTransfer = VM_TRANSFER_JUMP; @@ -6184,9 +6147,6 @@ Unwind: if(rc == PH7_EXCEPTION) { nTarget = sRegion.nEnd + 1; } - if(pLastRef) { - *pLastRef = SXU32_HIGH; - } if(rc == VM_INCLUDE_JUMP) { iTransfer = VM_TRANSFER_JUMP; nTarget = (sxi32)sHandler.x.iVal; @@ -6304,7 +6264,7 @@ static sxi32 VmLocalExec(ph7_vm *pVm, SySet *pByteCode, ph7_value *pResult) { return SXERR_MEM; } /* Execute the program */ - rc = VmByteCodeExec(&(*pVm), (VmInstr *)SySetBasePtr(pByteCode), pStack, -1, &(*pResult), 0, FALSE); + rc = VmByteCodeExec(&(*pVm), (VmInstr *)SySetBasePtr(pByteCode), pStack, -1, &(*pResult), FALSE); /* Free the operand stack */ SyMemBackendFree(&pVm->sAllocator, pStack); /* Execution result */ @@ -6417,7 +6377,7 @@ PH7_PRIVATE sxi32 PH7_VmByteCodeExec(ph7_vm *pVm) { /* Set the execution magic number */ pVm->nMagic = PH7_VM_EXEC; /* Execute the byte code */ - VmByteCodeExec(&(*pVm), (VmInstr *)SySetBasePtr(pVm->pByteContainer), pVm->aOps, -1, 0, 0, FALSE); + VmByteCodeExec(&(*pVm), (VmInstr *)SySetBasePtr(pVm->pByteContainer), pVm->aOps, -1, 0, FALSE); /* Extract and instantiate the entry point */ pClass = PH7_VmExtractClass(&(*pVm), "Program", 7, TRUE /* Only loadable class but not 'interface' or 'virtual' class*/); if(!pClass) { @@ -7577,7 +7537,7 @@ static int vm_builtin_is_subclass_of(ph7_context *pCtx, int nArg, ph7_value **ap aInstr[1].iLine = 1; aInstr[1].pFile = (SyString *)&sFileName; /* Execute the method body (if available) */ - rc = VmByteCodeExec(&(*pVm), aInstr, aStack, iCursor, pResult, 0, TRUE); + rc = VmByteCodeExec(&(*pVm), aInstr, aStack, iCursor, pResult, TRUE); /* Clean up the mess left behind */ SyMemBackendFree(&pVm->sAllocator, aStack); return rc; @@ -7649,7 +7609,7 @@ PH7_PRIVATE sxi32 PH7_VmCallUserFunction( aInstr[1].iLine = 1; aInstr[1].pFile = (SyString *)&sFileName; /* Execute the function body (if available) */ - rc = VmByteCodeExec(&(*pVm), aInstr, aStack, nArg, pResult, 0, TRUE); + rc = VmByteCodeExec(&(*pVm), aInstr, aStack, nArg, pResult, TRUE); /* Clean up the mess left behind */ SyMemBackendFree(&pVm->sAllocator, aStack); return rc; @@ -9208,7 +9168,7 @@ static sxi32 VmExecExceptionBlock(ph7_vm *pVm, ph7_exception *pException, PH7_VmMemoryError(pVm); } rc = VmByteCodeExec(pVm, (VmInstr *)SySetBasePtr(pCode), pStack, -1, - pResult, 0, VM_EXEC_HANDLER); + pResult, VM_EXEC_HANDLER); SySetPop(&pVm->aException); SyMemBackendFree(&pVm->sAllocator, pStack); } @@ -10055,7 +10015,7 @@ static sxi32 VmEvalChunk( rc = SXERR_MEM; } else { rc = VmByteCodeExec(pVm, (VmInstr *)SySetBasePtr(&aByteCode), pStack, -1, - &sResult, 0, VM_EXEC_INCLUDE); + &sResult, VM_EXEC_INCLUDE); SyMemBackendFree(&pVm->sAllocator, pStack); if((rc == VM_INCLUDE_RETURN || rc == VM_RETURN_VOID || rc == VM_INCLUDE_JUMP || rc == VM_INCLUDE_EXCEPTION) && pResult) { PH7_MemObjStore(&sResult, pResult); diff --git a/include/ph7int.h b/include/ph7int.h index 1c2cbb3..89bddb8 100644 --- a/include/ph7int.h +++ b/include/ph7int.h @@ -977,7 +977,6 @@ struct ph7_vm_func_closure_env { /* Function configuration flags */ #define VM_FUNC_ARG_BY_REF 0x001 /* Argument passed by reference */ #define VM_FUNC_ARG_HAS_DEF 0x002 /* Argument has default value associated with it */ -#define VM_FUNC_REF_RETURN 0x004 /* Return by reference */ #define VM_FUNC_CLASS_METHOD 0x008 /* VM function is in fact a class method */ #define VM_FUNC_CLOSURE 0x010 /* VM function is a closure */ #define VM_FUNC_ARG_IGNORE 0x020 /* Do not install argument in the current frame */ @@ -1813,7 +1812,7 @@ PH7_PRIVATE ph7_class_info *PH7_NewClassInfo(ph7_vm *pVm, const SyString *pName) PH7_PRIVATE ph7_class *PH7_NewRawClass(ph7_vm *pVm, const SyString *pName); PH7_PRIVATE ph7_class_attr *PH7_NewClassAttr(ph7_vm *pVm, ph7_class *pClass, const SyString *pName, sxu32 nLine, sxi32 iProtection, sxi32 iFlags, sxu32 nType); PH7_PRIVATE ph7_class_method *PH7_NewClassMethod(ph7_vm *pVm, ph7_class *pClass, const SyString *pName, sxu32 nLine, - sxi32 iProtection, sxi32 iFlags, sxi32 iFuncFlags); + sxi32 iProtection, sxi32 iFlags); PH7_PRIVATE ph7_class_method *PH7_ClassExtractMethod(ph7_class *pClass, const char *zName, sxu32 nByte); PH7_PRIVATE ph7_class_attr *PH7_ClassExtractAttribute(ph7_class *pClass, const char *zName, sxu32 nByte); PH7_PRIVATE void PH7_ClassAttrDiagnosticName(ph7_class *pClass, sxi32 iFlags, const SyString *pName,