Evaluate local constants once per declaration and invocation
Build / AerScript (push) Successful in 40s
Build / AerScript (push) Successful in 40s
This commit is contained in:
+42
-10
@@ -492,6 +492,17 @@ static void VmScopeSync(ph7_vm *pVm, VmScopeInfo *pTarget, void *pExec) {
|
|||||||
}
|
}
|
||||||
VmScopeEnter(pVm, pTarget, pExec);
|
VmScopeEnter(pVm, pTarget, pExec);
|
||||||
}
|
}
|
||||||
|
/* Stable, invocation-owned storage: neither bytecode nor moving VM arrays own
|
||||||
|
* local constant values. Scope exit removes only their visible bindings. */
|
||||||
|
typedef struct VmLocalConstant VmLocalConstant;
|
||||||
|
struct VmLocalConstant {
|
||||||
|
ph7_constant_info *pDecl;
|
||||||
|
ph7_value sValue;
|
||||||
|
};
|
||||||
|
static void VmExpandLocalConstant(ph7_value *pVal, void *pUserData) {
|
||||||
|
VmLocalConstant *pConst = (VmLocalConstant *)pUserData;
|
||||||
|
PH7_MemObjLoad(&pConst->sValue, pVal);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Allocate a new virtual machine frame.
|
* Allocate a new virtual machine frame.
|
||||||
*/
|
*/
|
||||||
@@ -517,7 +528,7 @@ static VmFrame *VmNewFrame(
|
|||||||
SySetInit(&pFrame->sArg, &pVm->sAllocator, sizeof(VmSlot));
|
SySetInit(&pFrame->sArg, &pVm->sAllocator, sizeof(VmSlot));
|
||||||
SySetInit(&pFrame->sLocal, &pVm->sAllocator, sizeof(VmSlot));
|
SySetInit(&pFrame->sLocal, &pVm->sAllocator, sizeof(VmSlot));
|
||||||
SySetInit(&pFrame->sRef, &pVm->sAllocator, sizeof(VmSlot));
|
SySetInit(&pFrame->sRef, &pVm->sAllocator, sizeof(VmSlot));
|
||||||
SySetInit(&pFrame->sConstDecl, &pVm->sAllocator, sizeof(void *));
|
SySetInit(&pFrame->sConstDecl, &pVm->sAllocator, sizeof(VmLocalConstant *));
|
||||||
return pFrame;
|
return pFrame;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@@ -576,6 +587,14 @@ static void VmLeaveFrame(ph7_vm *pVm) {
|
|||||||
SySetRelease(&pFrame->sArg);
|
SySetRelease(&pFrame->sArg);
|
||||||
SySetRelease(&pFrame->sLocal);
|
SySetRelease(&pFrame->sLocal);
|
||||||
SySetRelease(&pFrame->sRef);
|
SySetRelease(&pFrame->sRef);
|
||||||
|
{
|
||||||
|
VmLocalConstant **apConst = (VmLocalConstant **)SySetBasePtr(&pFrame->sConstDecl);
|
||||||
|
sxu32 n;
|
||||||
|
for(n = 0; n < SySetUsed(&pFrame->sConstDecl); n++) {
|
||||||
|
PH7_MemObjRelease(&apConst[n]->sValue);
|
||||||
|
SyMemBackendPoolFree(&pVm->sAllocator, apConst[n]);
|
||||||
|
}
|
||||||
|
}
|
||||||
SySetRelease(&pFrame->sConstDecl);
|
SySetRelease(&pFrame->sConstDecl);
|
||||||
/* Release the whole structure */
|
/* Release the whole structure */
|
||||||
SyMemBackendPoolFree(&pVm->sAllocator, pFrame);
|
SyMemBackendPoolFree(&pVm->sAllocator, pFrame);
|
||||||
@@ -3071,25 +3090,39 @@ Resume:
|
|||||||
/* Constant declaration */
|
/* Constant declaration */
|
||||||
ph7_constant_info *pConstInfo = (ph7_constant_info *) pInstr->p3;
|
ph7_constant_info *pConstInfo = (ph7_constant_info *) pInstr->p3;
|
||||||
VmFrame *pOwner = pVm->pFrame;
|
VmFrame *pOwner = pVm->pFrame;
|
||||||
void **apDecl;
|
VmLocalConstant **apDecl, *pConst;
|
||||||
sxu32 n;
|
sxu32 n;
|
||||||
while(pOwner->pParent && (pOwner->iFlags & VM_FRAME_ACTIVE) == 0) {
|
while(pOwner->pParent && (pOwner->iFlags & VM_FRAME_ACTIVE) == 0) {
|
||||||
pOwner = pOwner->pParent;
|
pOwner = pOwner->pParent;
|
||||||
}
|
}
|
||||||
apDecl = (void **)SySetBasePtr(&pOwner->sConstDecl);
|
apDecl = (VmLocalConstant **)SySetBasePtr(&pOwner->sConstDecl);
|
||||||
for(n = 0; n < SySetUsed(&pOwner->sConstDecl); n++) {
|
for(n = 0; n < SySetUsed(&pOwner->sConstDecl); n++) {
|
||||||
if(apDecl[n] == pConstInfo) {
|
if(apDecl[n]->pDecl == pConstInfo) {
|
||||||
PH7_VmThrowError(pVm, PH7_CTX_ERR, "Redeclaration of ‘%z’ constant", &pConstInfo->pName);
|
PH7_VmThrowError(pVm, PH7_CTX_ERR, "Redeclaration of ‘%z’ constant", &pConstInfo->pName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(SySetPut(&pOwner->sConstDecl, &pConstInfo) != SXRET_OK) {
|
pConst = (VmLocalConstant *)SyMemBackendPoolAlloc(&pVm->sAllocator, sizeof(VmLocalConstant));
|
||||||
|
if(pConst == 0) {
|
||||||
PH7_VmMemoryError(pVm);
|
PH7_VmMemoryError(pVm);
|
||||||
}
|
}
|
||||||
rc = PH7_VmRegisterConstant(&(*pVm), &pConstInfo->pName, PH7_VmExpandConstantValue, pConstInfo->pConsCode, FALSE);
|
pConst->pDecl = pConstInfo;
|
||||||
|
PH7_MemObjInit(pVm, &pConst->sValue);
|
||||||
|
if(SySetPut(&pOwner->sConstDecl, &pConst) != SXRET_OK) {
|
||||||
|
PH7_VmMemoryError(pVm);
|
||||||
|
}
|
||||||
|
rc = PH7_VmRegisterConstant(&(*pVm), &pConstInfo->pName, VmExpandLocalConstant, pConst, FALSE);
|
||||||
if(rc == SXERR_EXISTS) {
|
if(rc == SXERR_EXISTS) {
|
||||||
PH7_VmThrowError(&(*pVm), PH7_CTX_ERR,
|
PH7_VmThrowError(&(*pVm), PH7_CTX_ERR,
|
||||||
"Redeclaration of ‘%z’ constant", &pConstInfo->pName);
|
"Redeclaration of ‘%z’ constant", &pConstInfo->pName);
|
||||||
}
|
}
|
||||||
|
rc = VmLocalExec(pVm, pConstInfo->pConsCode, &pConst->sValue);
|
||||||
|
if(rc == SXERR_MEM) {
|
||||||
|
PH7_VmMemoryError(pVm);
|
||||||
|
} else if(rc == PH7_ABORT) {
|
||||||
|
goto Abort;
|
||||||
|
} else if(rc == PH7_EXCEPTION) {
|
||||||
|
goto Exception;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Variable declaration */
|
/* Variable declaration */
|
||||||
ph7_value *pObj;
|
ph7_value *pObj;
|
||||||
@@ -6123,10 +6156,9 @@ PH7_PRIVATE sxi32 PH7_VmOutputConsumeAp(
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Default constant expansion callback used by the 'const' statement if used
|
* Constant expansion callback used by global constants declared with 'define'.
|
||||||
* outside a class body [i.e: global or function scope].
|
* Refer to the implementation of [PH7_CompileDefine()] defined
|
||||||
* Refer to the implementation of [PH7_CompileConstant()] defined
|
* in 'compiler.c' for additional information.
|
||||||
* in 'compile.c' for additional information.
|
|
||||||
*/
|
*/
|
||||||
PH7_PRIVATE void PH7_VmExpandConstantValue(ph7_value *pVal, void *pUserData) {
|
PH7_PRIVATE void PH7_VmExpandConstantValue(ph7_value *pVal, void *pUserData) {
|
||||||
SySet *pByteCode = (SySet *)pUserData;
|
SySet *pByteCode = (SySet *)pUserData;
|
||||||
|
|||||||
Reference in New Issue
Block a user