Get rid of OP_UNUSED and implement additional context frame to resolve scope issue
Some checks failed
Build / AerScript (push) Failing after 28s
Some checks failed
Build / AerScript (push) Failing after 28s
This commit is contained in:
@@ -1860,8 +1860,6 @@ static sxi32 PH7_CompileFor(ph7_gen_state *pGen) {
|
|||||||
sxu32 nLine;
|
sxu32 nLine;
|
||||||
sxi32 rc;
|
sxi32 rc;
|
||||||
nLine = pGen->pIn->nLine;
|
nLine = pGen->pIn->nLine;
|
||||||
SyString *pName = NULL;
|
|
||||||
char *zName = NULL;
|
|
||||||
|
|
||||||
/* Jump the 'for' keyword */
|
/* Jump the 'for' keyword */
|
||||||
pGen->pIn++;
|
pGen->pIn++;
|
||||||
@@ -1881,13 +1879,9 @@ static sxi32 PH7_CompileFor(ph7_gen_state *pGen) {
|
|||||||
pTmp = pGen->pEnd;
|
pTmp = pGen->pEnd;
|
||||||
pGen->pEnd = pEnd;
|
pGen->pEnd = pEnd;
|
||||||
sxu32 nKey = (sxu32)(SX_PTR_TO_INT(pGen->pIn->pUserData));
|
sxu32 nKey = (sxu32)(SX_PTR_TO_INT(pGen->pIn->pUserData));
|
||||||
|
/* Emit the OP_CF_START instruction to enter a context frame */
|
||||||
|
PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_CF_START, 0, 0, 0, 0);
|
||||||
if(nKey & (PH7_KEYWORD_AUTO | PH7_KEYWORD_TYPEDEF)) {
|
if(nKey & (PH7_KEYWORD_AUTO | PH7_KEYWORD_TYPEDEF)) {
|
||||||
/* Local for variable, store its name */
|
|
||||||
pName = &pGen->pIn[2].sData;
|
|
||||||
zName = SyMemBackendStrDup(&pGen->pVm->sAllocator, pName->zString, pName->nByte);
|
|
||||||
if(zName == 0) {
|
|
||||||
PH7_GenCompileError(pGen, E_ERROR, nLine, "PH7 engine is running out-of-memory");
|
|
||||||
}
|
|
||||||
/* Compile variable */
|
/* Compile variable */
|
||||||
PH7_CompileVar(&(*pGen));
|
PH7_CompileVar(&(*pGen));
|
||||||
}
|
}
|
||||||
@@ -1943,6 +1937,10 @@ static sxi32 PH7_CompileFor(ph7_gen_state *pGen) {
|
|||||||
if(rc == SXERR_ABORT) {
|
if(rc == SXERR_ABORT) {
|
||||||
return SXERR_ABORT;
|
return SXERR_ABORT;
|
||||||
}
|
}
|
||||||
|
/* compile the post-expressions if available */
|
||||||
|
while(pPostStart < pEnd && (pPostStart->nType & PH7_TK_SEMI)) {
|
||||||
|
pPostStart++;
|
||||||
|
}
|
||||||
/* Fix post-continue jumps */
|
/* Fix post-continue jumps */
|
||||||
if(SySetUsed(&pForBlock->aPostContFix) > 0) {
|
if(SySetUsed(&pForBlock->aPostContFix) > 0) {
|
||||||
JumpFixup *aPost;
|
JumpFixup *aPost;
|
||||||
@@ -1959,10 +1957,6 @@ static sxi32 PH7_CompileFor(ph7_gen_state *pGen) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* compile the post-expressions if available */
|
|
||||||
while(pPostStart < pEnd && (pPostStart->nType & PH7_TK_SEMI)) {
|
|
||||||
pPostStart++;
|
|
||||||
}
|
|
||||||
if(pPostStart < pEnd) {
|
if(pPostStart < pEnd) {
|
||||||
SyToken *pTmpIn, *pTmpEnd;
|
SyToken *pTmpIn, *pTmpEnd;
|
||||||
SWAP_DELIMITER(pGen, pPostStart, pEnd);
|
SWAP_DELIMITER(pGen, pPostStart, pEnd);
|
||||||
@@ -1986,13 +1980,10 @@ static sxi32 PH7_CompileFor(ph7_gen_state *pGen) {
|
|||||||
PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMP, 0, pForBlock->nFirstInstr, 0, 0);
|
PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_JMP, 0, pForBlock->nFirstInstr, 0, 0);
|
||||||
/* Fix all jumps now the destination is resolved */
|
/* Fix all jumps now the destination is resolved */
|
||||||
PH7_GenStateFixJumps(pForBlock, -1, PH7_VmInstrLength(pGen->pVm));
|
PH7_GenStateFixJumps(pForBlock, -1, PH7_VmInstrLength(pGen->pVm));
|
||||||
/* If local for loop variable, unset it */
|
|
||||||
if(zName != NULL) {
|
|
||||||
/* Emit instruction to unset the variable after its initialization */
|
|
||||||
PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_UNSET, 0, 0, (void*)zName, 0);
|
|
||||||
}
|
|
||||||
/* Release the loop block */
|
/* Release the loop block */
|
||||||
PH7_GenStateLeaveBlock(pGen, 0);
|
PH7_GenStateLeaveBlock(pGen, 0);
|
||||||
|
/* Emit the OP_CF_STOP instruction to leave the context frame */
|
||||||
|
PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_CF_STOP, 0, 0, 0, 0);
|
||||||
/* Statement successfully compiled */
|
/* Statement successfully compiled */
|
||||||
return SXRET_OK;
|
return SXRET_OK;
|
||||||
}
|
}
|
||||||
@@ -2352,7 +2343,7 @@ static sxi32 PH7_CompileReturn(ph7_gen_state *pGen) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Emit the done instruction */
|
/* Emit the done instruction */
|
||||||
PH7_VmEmitInstr(pGen->pVm, pGen->pIn->nLine, PH7_OP_DONE, nRet, 0, 0, 0);
|
PH7_VmEmitInstr(pGen->pVm, pGen->pIn->nLine, PH7_OP_DONE, nRet, 0, (void *)1, 0);
|
||||||
return SXRET_OK;
|
return SXRET_OK;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@@ -19,7 +19,7 @@ PH7_PRIVATE sxi32 VmExtractDebugTrace(ph7_vm *pVm, SySet *pDebugTrace) {
|
|||||||
/* Backup current frame */
|
/* Backup current frame */
|
||||||
VmFrame *oFrame = pVm->pFrame;
|
VmFrame *oFrame = pVm->pFrame;
|
||||||
while(pVm->pFrame) {
|
while(pVm->pFrame) {
|
||||||
if(pVm->pFrame->iFlags & VM_FRAME_ACTIVE) {
|
if(pVm->pFrame->iFlags & (VM_FRAME_ACTIVE | VM_FRAME_CONTEXT)) {
|
||||||
/* Iterate through all frames */
|
/* Iterate through all frames */
|
||||||
ph7_vm_func *pFunc;
|
ph7_vm_func *pFunc;
|
||||||
pFunc = (ph7_vm_func *)pVm->pFrame->pUserData;
|
pFunc = (ph7_vm_func *)pVm->pFrame->pUserData;
|
||||||
@@ -116,6 +116,12 @@ static const char *VmInstrToString(sxi32 nOp) {
|
|||||||
case PH7_OP_JMPNZ:
|
case PH7_OP_JMPNZ:
|
||||||
zOp = "JMPNZ";
|
zOp = "JMPNZ";
|
||||||
break;
|
break;
|
||||||
|
case PH7_OP_CF_START:
|
||||||
|
zOp = "CF_START";
|
||||||
|
break;
|
||||||
|
case PH7_OP_CF_STOP:
|
||||||
|
zOp = "CF_STOP";
|
||||||
|
break;
|
||||||
case PH7_OP_LF_START:
|
case PH7_OP_LF_START:
|
||||||
zOp = "LF_START";
|
zOp = "LF_START";
|
||||||
break;
|
break;
|
||||||
|
69
engine/vm.c
69
engine/vm.c
@@ -1393,7 +1393,7 @@ static ph7_value *VmExtractMemObj(
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(pFrame->pParent && pFrame->iFlags & (VM_FRAME_LOOP | VM_FRAME_EXCEPTION | VM_FRAME_CATCH | VM_FRAME_FINALLY)) {
|
if(pFrame->pParent && pFrame->iFlags & (VM_FRAME_CONTEXT | VM_FRAME_LOOP | VM_FRAME_EXCEPTION | VM_FRAME_CATCH | VM_FRAME_FINALLY)) {
|
||||||
pFrame = pFrame->pParent;
|
pFrame = pFrame->pParent;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
@@ -1888,7 +1888,7 @@ static sxi32 VmByteCodeExec(
|
|||||||
*/
|
*/
|
||||||
switch(pInstr->iOp) {
|
switch(pInstr->iOp) {
|
||||||
/*
|
/*
|
||||||
* DONE: P1 P2 *
|
* DONE: P1 P2 P3
|
||||||
*
|
*
|
||||||
* Program execution completed: Clean up the mess left behind
|
* Program execution completed: Clean up the mess left behind
|
||||||
* and return immediately.
|
* and return immediately.
|
||||||
@@ -1901,16 +1901,20 @@ static sxi32 VmByteCodeExec(
|
|||||||
if(pLastRef) {
|
if(pLastRef) {
|
||||||
*pLastRef = pTos->nIdx;
|
*pLastRef = pTos->nIdx;
|
||||||
}
|
}
|
||||||
/* Ensure we are in active loop. Force abort all loops */
|
/* Ensure we are in active or context frame. Force abort all loops */
|
||||||
if(pVm->pFrame->iFlags & VM_FRAME_LOOP) {
|
if(pInstr->p3) { /* Called from a return statement */
|
||||||
while((pVm->pFrame->iFlags & VM_FRAME_ACTIVE) == 0) {
|
while(pVm->pFrame->pParent && (pVm->pFrame->iFlags & VM_FRAME_ACTIVE) == 0) {
|
||||||
|
VmLeaveFrame(&(*pVm));
|
||||||
|
}
|
||||||
|
} else if(pVm->pFrame->iFlags & VM_FRAME_LOOP) {
|
||||||
|
while(pVm->pFrame->pParent && (pVm->pFrame->iFlags & (VM_FRAME_ACTIVE | VM_FRAME_CONTEXT)) == 0) {
|
||||||
VmLeaveFrame(&(*pVm));
|
VmLeaveFrame(&(*pVm));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(pResult) {
|
if(pResult) {
|
||||||
/* Execution result */
|
/* Execution result */
|
||||||
PH7_MemObjStore(pTos, pResult);
|
PH7_MemObjStore(pTos, pResult);
|
||||||
if(!pInstr->iP2 && pVm->pFrame->iFlags & VM_FRAME_ACTIVE) {
|
if(!pInstr->iP2 && pVm->pFrame->iFlags & (VM_FRAME_ACTIVE | VM_FRAME_CONTEXT)) {
|
||||||
ph7_vm_func *pFunc = (ph7_vm_func *)pVm->pFrame->pUserData;
|
ph7_vm_func *pFunc = (ph7_vm_func *)pVm->pFrame->pUserData;
|
||||||
if(pFunc->nType) {
|
if(pFunc->nType) {
|
||||||
if((pFunc->nType & MEMOBJ_MIXED) == 0) {
|
if((pFunc->nType & MEMOBJ_MIXED) == 0) {
|
||||||
@@ -2022,6 +2026,33 @@ static sxi32 VmByteCodeExec(
|
|||||||
VmPopOperand(&pTos, 1);
|
VmPopOperand(&pTos, 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
/*
|
||||||
|
* CF_START: * * *
|
||||||
|
*
|
||||||
|
* Creates and enters the active context frame.
|
||||||
|
*/
|
||||||
|
case PH7_OP_CF_START: {
|
||||||
|
VmFrame *pFrame = 0;
|
||||||
|
/* Enter the context frame */
|
||||||
|
rc = VmEnterFrame(&(*pVm), pVm->pFrame->pUserData, pVm->pFrame->pThis, &pFrame);
|
||||||
|
if(rc != SXRET_OK) {
|
||||||
|
PH7_VmMemoryError(&(*pVm));
|
||||||
|
}
|
||||||
|
pFrame->iFlags = VM_FRAME_CONTEXT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* CF_STOP: * * *
|
||||||
|
*
|
||||||
|
* Leaves and destroys the active context frame.
|
||||||
|
*/
|
||||||
|
case PH7_OP_CF_STOP: {
|
||||||
|
/* Leave the context frame */
|
||||||
|
if(pVm->pFrame->iFlags & VM_FRAME_CONTEXT) {
|
||||||
|
VmLeaveFrame(&(*pVm));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* LF_START: * * *
|
* LF_START: * * *
|
||||||
*
|
*
|
||||||
@@ -2292,28 +2323,6 @@ static sxi32 VmByteCodeExec(
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* UNSET: * * P3
|
|
||||||
*
|
|
||||||
* Unset a variable. It takes the variable name indexed at P3 operand.
|
|
||||||
*/
|
|
||||||
case PH7_OP_UNSET: {
|
|
||||||
SyString sName;
|
|
||||||
VmFrame *pFrame = pVm->pFrame;
|
|
||||||
SyHashEntry *pEntry;
|
|
||||||
sxu32 nIdx;
|
|
||||||
SyStringInitFromBuf(&sName, pInstr->p3, SyStrlen((const char *)pInstr->p3));
|
|
||||||
/* Find variable in local frame */
|
|
||||||
pEntry = SyHashGet(&pFrame->hVar, (const void *)sName.zString, sName.nByte);
|
|
||||||
if(pEntry) {
|
|
||||||
nIdx = (sxu32)SX_PTR_TO_INT(pEntry->pUserData);
|
|
||||||
/* Delete variable from local frame */
|
|
||||||
SyHashDeleteEntry(&pFrame->hVar, (const void *)sName.zString, sName.nByte, 0);
|
|
||||||
/* Call PH7_VmUnsetMemObj to release the variable */
|
|
||||||
PH7_VmUnsetMemObj(&(*pVm), nIdx, FALSE);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* LOADC P1 P2 *
|
* LOADC P1 P2 *
|
||||||
*
|
*
|
||||||
@@ -2336,8 +2345,8 @@ static sxi32 VmByteCodeExec(
|
|||||||
SyHashEntry *pEntry;
|
SyHashEntry *pEntry;
|
||||||
/* Candidate for expansion via user defined callbacks */
|
/* Candidate for expansion via user defined callbacks */
|
||||||
for(;;) {
|
for(;;) {
|
||||||
pEntry = SyHashGet(&pVm->pFrame->hConst, SyBlobData(&pObj->sBlob), SyBlobLength(&pObj->sBlob));
|
pEntry = SyHashGet(&pFrame->hConst, SyBlobData(&pObj->sBlob), SyBlobLength(&pObj->sBlob));
|
||||||
if(pEntry == 0 && pFrame->iFlags & VM_FRAME_LOOP && pFrame->pParent) {
|
if(pEntry == 0 && pFrame->iFlags & (VM_FRAME_CONTEXT | VM_FRAME_LOOP) && pFrame->pParent) {
|
||||||
pFrame = pFrame->pParent;
|
pFrame = pFrame->pParent;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
@@ -1249,11 +1249,12 @@ struct VmFrame {
|
|||||||
sxu32 iExceptionJump; /* Exception jump destination */
|
sxu32 iExceptionJump; /* Exception jump destination */
|
||||||
};
|
};
|
||||||
#define VM_FRAME_ACTIVE 0x01 /* Active call frame */
|
#define VM_FRAME_ACTIVE 0x01 /* Active call frame */
|
||||||
#define VM_FRAME_LOOP 0x02 /* Active loop frame */
|
#define VM_FRAME_CONTEXT 0x02 /* Active context frame */
|
||||||
#define VM_FRAME_EXCEPTION 0x04 /* Special Exception frame */
|
#define VM_FRAME_LOOP 0x04 /* Active loop frame */
|
||||||
#define VM_FRAME_THROW 0x08 /* An exception was thrown */
|
#define VM_FRAME_EXCEPTION 0x08 /* Special Exception frame */
|
||||||
#define VM_FRAME_CATCH 0x10 /* Catch frame */
|
#define VM_FRAME_THROW 0x10 /* An exception was thrown */
|
||||||
#define VM_FRAME_FINALLY 0x20 /* Finally frame */
|
#define VM_FRAME_CATCH 0x20 /* Catch frame */
|
||||||
|
#define VM_FRAME_FINALLY 0x40 /* Finally frame */
|
||||||
/*
|
/*
|
||||||
* When a debug stacktrace is extracted from Virtual Machine, all information about
|
* When a debug stacktrace is extracted from Virtual Machine, all information about
|
||||||
* calls (file, line, class, method, arguments) are stored in this structure.
|
* calls (file, line, class, method, arguments) are stored in this structure.
|
||||||
@@ -1379,7 +1380,6 @@ enum ph7_vm_op {
|
|||||||
PH7_OP_IMPORT, /* Import AerScript module */
|
PH7_OP_IMPORT, /* Import AerScript module */
|
||||||
PH7_OP_INCLUDE, /* Include another source file */
|
PH7_OP_INCLUDE, /* Include another source file */
|
||||||
PH7_OP_DECLARE, /* Declare a variable */
|
PH7_OP_DECLARE, /* Declare a variable */
|
||||||
PH7_OP_UNSET, /* Unset variable */
|
|
||||||
PH7_OP_LOADV, /* Load variable */
|
PH7_OP_LOADV, /* Load variable */
|
||||||
PH7_OP_LOADC, /* Load constant */
|
PH7_OP_LOADC, /* Load constant */
|
||||||
PH7_OP_LOAD_IDX, /* Load array entry */
|
PH7_OP_LOAD_IDX, /* Load array entry */
|
||||||
@@ -1389,6 +1389,8 @@ enum ph7_vm_op {
|
|||||||
PH7_OP_JMP, /* Unconditional jump */
|
PH7_OP_JMP, /* Unconditional jump */
|
||||||
PH7_OP_JMPZ, /* Jump on zero (FALSE jump) */
|
PH7_OP_JMPZ, /* Jump on zero (FALSE jump) */
|
||||||
PH7_OP_JMPNZ, /* Jump on non-zero (TRUE jump) */
|
PH7_OP_JMPNZ, /* Jump on non-zero (TRUE jump) */
|
||||||
|
PH7_OP_CF_START, /* Context frame start */
|
||||||
|
PH7_OP_CF_STOP, /* Context frame stop */
|
||||||
PH7_OP_LF_START, /* Loop frame start */
|
PH7_OP_LF_START, /* Loop frame start */
|
||||||
PH7_OP_LF_STOP, /* Loop frame stop */
|
PH7_OP_LF_STOP, /* Loop frame stop */
|
||||||
PH7_OP_POP, /* Stack POP */
|
PH7_OP_POP, /* Stack POP */
|
||||||
|
Reference in New Issue
Block a user