Execute the compiled 'finally' block.
The build was successful.
Details
The build was successful.
Details
This commit is contained in:
parent
ba43269b80
commit
101453950e
46
engine/vm.c
46
engine/vm.c
|
@ -6178,7 +6178,7 @@ static int VmClassMemberAccess(
|
|||
if(iProtection != PH7_CLASS_PROT_PUBLIC) {
|
||||
VmFrame *pFrame = pVm->pFrame;
|
||||
ph7_vm_func *pVmFunc;
|
||||
while(pFrame->pParent && (pFrame->iFlags & (VM_FRAME_EXCEPTION | VM_FRAME_CATCH))) {
|
||||
while(pFrame->pParent && (pFrame->iFlags & (VM_FRAME_EXCEPTION | VM_FRAME_CATCH | VM_FRAME_FINALLY))) {
|
||||
/* Safely ignore the exception frame */
|
||||
pFrame = pFrame->pParent;
|
||||
}
|
||||
|
@ -8149,6 +8149,8 @@ static sxi32 VmUncaughtException(
|
|||
if(pFrame->pParent) {
|
||||
if(pFrame->iFlags & VM_FRAME_CATCH) {
|
||||
SyStringInitFromBuf(&sFuncName, "Catch_block", sizeof("Catch_block") - 1);
|
||||
} else if(pFrame->iFlags & VM_FRAME_FINALLY) {
|
||||
SyStringInitFromBuf(&sFuncName, "Finally_block", sizeof("Finally_block") - 1);
|
||||
} else {
|
||||
ph7_vm_func *pFunc = (ph7_vm_func *)pFrame->pUserData;
|
||||
if(pFunc) {
|
||||
|
@ -8174,6 +8176,7 @@ static sxi32 VmThrowException(
|
|||
ph7_exception_block *pCatch; /* Catch block to execute */
|
||||
ph7_exception **apException;
|
||||
ph7_exception *pException;
|
||||
sxi32 rc;
|
||||
/* Point to the stack of loaded exceptions */
|
||||
apException = (ph7_exception **)SySetBasePtr(&pVm->aException);
|
||||
pException = 0;
|
||||
|
@ -8201,25 +8204,9 @@ static sxi32 VmThrowException(
|
|||
}
|
||||
}
|
||||
}
|
||||
/* Execute the cached block if available */
|
||||
if(pCatch == 0) {
|
||||
sxi32 rc;
|
||||
rc = VmUncaughtException(&(*pVm), pThis);
|
||||
if(rc == SXRET_OK && pException) {
|
||||
VmFrame *pFrame = pVm->pFrame;
|
||||
while(pFrame->pParent && (pFrame->iFlags & VM_FRAME_EXCEPTION)) {
|
||||
/* Safely ignore the exception frame */
|
||||
pFrame = pFrame->pParent;
|
||||
}
|
||||
if(pException->pFrame == pFrame) {
|
||||
/* Tell the upper layer that the exception was caught */
|
||||
pFrame->iFlags &= ~VM_FRAME_THROW;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
} else {
|
||||
/* Execute the 'catch' block if available */
|
||||
if(pCatch) {
|
||||
VmFrame *pFrame = pVm->pFrame;
|
||||
sxi32 rc;
|
||||
while(pFrame->pParent && (pFrame->iFlags & VM_FRAME_EXCEPTION)) {
|
||||
/* Safely ignore the exception frame */
|
||||
pFrame = pFrame->pParent;
|
||||
|
@ -8246,10 +8233,29 @@ static sxi32 VmThrowException(
|
|||
VmLeaveFrame(&(*pVm));
|
||||
}
|
||||
}
|
||||
/* Execute the 'finally' block if available */
|
||||
if(pException && SySetUsed(&pException->sFinally)) {
|
||||
rc = VmExecFinallyBlock(&(*pVm), pException);
|
||||
}
|
||||
/* No matching 'catch' block found */
|
||||
if(pCatch == 0) {
|
||||
rc = VmUncaughtException(&(*pVm), pThis);
|
||||
if(rc == SXRET_OK && pException) {
|
||||
VmFrame *pFrame = pVm->pFrame;
|
||||
while(pFrame->pParent && (pFrame->iFlags & VM_FRAME_EXCEPTION)) {
|
||||
/* Safely ignore the exception frame */
|
||||
pFrame = pFrame->pParent;
|
||||
}
|
||||
if(pException->pFrame == pFrame) {
|
||||
/* Tell the upper layer that the exception was caught */
|
||||
pFrame->iFlags &= ~VM_FRAME_THROW;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* TICKET 1433-60: Do not release the 'pException' pointer since it may
|
||||
* be used again if a 'goto' statement is executed.
|
||||
*/
|
||||
return SXRET_OK;
|
||||
return rc;
|
||||
}
|
||||
/*
|
||||
* Section:
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
Uncaught NewException, code: 1
|
||||
Message: Catch me once
|
||||
Called finally block 1
|
||||
Uncaught Exception, code: 2
|
||||
Message: Catch me twice
|
||||
|
|
Loading…
Reference in New Issue