Mark method/closure call frame as active.
The build was successful. Details

It is impossible to dump the frame during its initialization, as it does not contain all necessary information. Such frame should be skipped. After initialization is done, the frame has to be marked as active just before
evaluating a function body.
This commit is contained in:
Rafal Kupiec 2018-09-16 19:52:24 +02:00
parent 3a16eced8a
commit 58103ea5fe
Signed by: belliash
GPG Key ID: 4E829243E0CFE6B4
2 changed files with 41 additions and 36 deletions

View File

@ -1715,41 +1715,43 @@ PH7_PRIVATE sxi32 VmExtractDebugTrace(ph7_vm *pVm, SySet *pDebugTrace) {
/* Backup current frame */
VmFrame *oFrame = pVm->pFrame;
while(pVm->pFrame) {
/* Iterate through all frames */
ph7_vm_func *pFunc;
pFunc = (ph7_vm_func *)pVm->pFrame->pUserData;
if(pFunc && (pVm->pFrame->iFlags & VM_FRAME_EXCEPTION) == 0) {
VmDebugTrace aTrace;
SySet *aByteCode = &pFunc->aByteCode;
/* Extract closure/method name and passed arguments */
aTrace.pFuncName = &pFunc->sName;
aTrace.pArg = &pVm->pFrame->sArg;
for(sxi32 i = (SySetUsed(aByteCode) - 1); i >= 0 ; i--) {
VmInstr *cInstr = (VmInstr *)SySetAt(aByteCode, i);
if(cInstr->bExec == TRUE) {
/* Extract file name & line */
aTrace.pFile = cInstr->pFile;
aTrace.nLine = cInstr->iLine;
break;
}
}
if(aTrace.pFile) {
aTrace.pClassName = NULL;
aTrace.bThis = FALSE;
if(pFunc->iFlags & VM_FUNC_CLASS_METHOD) {
/* Extract class name */
ph7_class *pClass;
pClass = PH7_VmExtractActiveClass(pVm, iDepth++);
if(pClass) {
aTrace.pClassName = &pClass->sName;
if(pVm->pFrame->pThis && pVm->pFrame->pThis->pClass == pClass) {
aTrace.bThis = TRUE;
}
if(pVm->pFrame->iFlags & VM_FRAME_ACTIVE) {
/* Iterate through all frames */
ph7_vm_func *pFunc;
pFunc = (ph7_vm_func *)pVm->pFrame->pUserData;
if(pFunc && (pVm->pFrame->iFlags & VM_FRAME_EXCEPTION) == 0) {
VmDebugTrace aTrace;
SySet *aByteCode = &pFunc->aByteCode;
/* Extract closure/method name and passed arguments */
aTrace.pFuncName = &pFunc->sName;
aTrace.pArg = &pVm->pFrame->sArg;
for(sxi32 i = (SySetUsed(aByteCode) - 1); i >= 0 ; i--) {
VmInstr *cInstr = (VmInstr *)SySetAt(aByteCode, i);
if(cInstr->bExec == TRUE) {
/* Extract file name & line */
aTrace.pFile = cInstr->pFile;
aTrace.nLine = cInstr->iLine;
break;
}
}
rc = SySetPut(pDebugTrace, (const void *)&aTrace);
if(rc != SXRET_OK) {
break;
if(aTrace.pFile) {
aTrace.pClassName = NULL;
aTrace.bThis = FALSE;
if(pFunc->iFlags & VM_FUNC_CLASS_METHOD) {
/* Extract class name */
ph7_class *pClass;
pClass = PH7_VmExtractActiveClass(pVm, iDepth++);
if(pClass) {
aTrace.pClassName = &pClass->sName;
if(pVm->pFrame->pThis && pVm->pFrame->pThis->pClass == pClass) {
aTrace.bThis = TRUE;
}
}
}
rc = SySetPut(pDebugTrace, (const void *)&aTrace);
if(rc != SXRET_OK) {
break;
}
}
}
}
@ -5085,6 +5087,8 @@ static sxi32 VmByteCodeExec(
*/
PH7_MemObjRelease(pTos);
pTos = &pTos[-pInstr->iP1];
/* Mark current frame as active */
pFrame->iFlags |= VM_FRAME_ACTIVE;
/* Allocate a new operand stack and evaluate the function body */
pFrameStack = VmNewOperandStack(&(*pVm), SySetUsed(&pVmFunc->aByteCode));
if(pFrameStack == 0) {

View File

@ -1261,9 +1261,10 @@ struct VmFrame {
sxi32 iFlags; /* Frame configuration flags (See below) */
sxu32 iExceptionJump; /* Exception jump destination */
};
#define VM_FRAME_EXCEPTION 0x01 /* Special Exception frame */
#define VM_FRAME_THROW 0x02 /* An exception was thrown */
#define VM_FRAME_CATCH 0x04 /* Catch frame */
#define VM_FRAME_ACTIVE 0x01 /* Active call frame */
#define VM_FRAME_EXCEPTION 0x02 /* Special Exception frame */
#define VM_FRAME_THROW 0x04 /* An exception was thrown */
#define VM_FRAME_CATCH 0x08 /* Catch frame */
/*
* When a debug stacktrace is extracted from Virtual Machine, all information about
* calls (file, line, class, method, arguments) are stored in this structure.