This commit is contained in:
+1
-9
@@ -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");
|
||||
}
|
||||
|
||||
+4
-8
@@ -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)) {
|
||||
|
||||
+7
-47
@@ -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);
|
||||
|
||||
+1
-2
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user