From 58103ea5fef369250a262bebe97842f95401bed0 Mon Sep 17 00:00:00 2001 From: belliash Date: Sun, 16 Sep 2018 19:52:24 +0200 Subject: [PATCH] Mark method/closure call frame as active. 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. --- engine/vm.c | 70 +++++++++++++++++++++++++----------------------- include/ph7int.h | 7 ++--- 2 files changed, 41 insertions(+), 36 deletions(-) diff --git a/engine/vm.c b/engine/vm.c index 13749a2..f863794 100644 --- a/engine/vm.c +++ b/engine/vm.c @@ -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) { diff --git a/include/ph7int.h b/include/ph7int.h index b60de17..f03d29e 100644 --- a/include/ph7int.h +++ b/include/ph7int.h @@ -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.