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);
|
||||
}
|
||||
/* 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.
|
||||
*/
|
||||
@@ -517,7 +528,7 @@ static VmFrame *VmNewFrame(
|
||||
SySetInit(&pFrame->sArg, &pVm->sAllocator, sizeof(VmSlot));
|
||||
SySetInit(&pFrame->sLocal, &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;
|
||||
}
|
||||
/*
|
||||
@@ -576,6 +587,14 @@ static void VmLeaveFrame(ph7_vm *pVm) {
|
||||
SySetRelease(&pFrame->sArg);
|
||||
SySetRelease(&pFrame->sLocal);
|
||||
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);
|
||||
/* Release the whole structure */
|
||||
SyMemBackendPoolFree(&pVm->sAllocator, pFrame);
|
||||
@@ -3071,25 +3090,39 @@ Resume:
|
||||
/* Constant declaration */
|
||||
ph7_constant_info *pConstInfo = (ph7_constant_info *) pInstr->p3;
|
||||
VmFrame *pOwner = pVm->pFrame;
|
||||
void **apDecl;
|
||||
VmLocalConstant **apDecl, *pConst;
|
||||
sxu32 n;
|
||||
while(pOwner->pParent && (pOwner->iFlags & VM_FRAME_ACTIVE) == 0) {
|
||||
pOwner = pOwner->pParent;
|
||||
}
|
||||
apDecl = (void **)SySetBasePtr(&pOwner->sConstDecl);
|
||||
apDecl = (VmLocalConstant **)SySetBasePtr(&pOwner->sConstDecl);
|
||||
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);
|
||||
}
|
||||
}
|
||||
if(SySetPut(&pOwner->sConstDecl, &pConstInfo) != SXRET_OK) {
|
||||
pConst = (VmLocalConstant *)SyMemBackendPoolAlloc(&pVm->sAllocator, sizeof(VmLocalConstant));
|
||||
if(pConst == 0) {
|
||||
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) {
|
||||
PH7_VmThrowError(&(*pVm), PH7_CTX_ERR,
|
||||
"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 {
|
||||
/* Variable declaration */
|
||||
ph7_value *pObj;
|
||||
@@ -6123,10 +6156,9 @@ PH7_PRIVATE sxi32 PH7_VmOutputConsumeAp(
|
||||
return rc;
|
||||
}
|
||||
/*
|
||||
* Default constant expansion callback used by the 'const' statement if used
|
||||
* outside a class body [i.e: global or function scope].
|
||||
* Refer to the implementation of [PH7_CompileConstant()] defined
|
||||
* in 'compile.c' for additional information.
|
||||
* Constant expansion callback used by global constants declared with 'define'.
|
||||
* Refer to the implementation of [PH7_CompileDefine()] defined
|
||||
* in 'compiler.c' for additional information.
|
||||
*/
|
||||
PH7_PRIVATE void PH7_VmExpandConstantValue(ph7_value *pVal, void *pUserData) {
|
||||
SySet *pByteCode = (SySet *)pUserData;
|
||||
|
||||
Reference in New Issue
Block a user