summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2016-03-17 12:15:52 (GMT)
committerdgp <dgp@users.sourceforge.net>2016-03-17 12:15:52 (GMT)
commitba96ade25a6b00ff4945834090a8de52b1147204 (patch)
tree7c8a5db98dd8fa327775dbed89e97c4220aa08a7 /generic
parent671e2228ac8024e945034191da52584381ce61ac (diff)
parent8ad967404ac779d2dff31836f295f22ed6fc130c (diff)
downloadtcl-ba96ade25a6b00ff4945834090a8de52b1147204.zip
tcl-ba96ade25a6b00ff4945834090a8de52b1147204.tar.gz
tcl-ba96ade25a6b00ff4945834090a8de52b1147204.tar.bz2
[b9b2079e6d] Unwind ExceptionAux data after failed compile.
Diffstat (limited to 'generic')
-rw-r--r--generic/tclEnsemble.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/generic/tclEnsemble.c b/generic/tclEnsemble.c
index 8f7d1a2..986a553 100644
--- a/generic/tclEnsemble.c
+++ b/generic/tclEnsemble.c
@@ -3082,6 +3082,11 @@ TclAttemptCompileProc(
Tcl_Token *saveTokenPtr = parsePtr->tokenPtr;
int savedStackDepth = envPtr->currStackDepth;
unsigned savedCodeNext = envPtr->codeNext - envPtr->codeStart;
+ int savedAuxDataArrayNext = envPtr->auxDataArrayNext;
+ int savedExceptArrayNext = envPtr->exceptArrayNext;
+#ifdef TCL_COMPILE_DEBUG
+ int savedExceptDepth = envPtr->exceptDepth;
+#endif
DefineLineInformation;
if (cmdPtr->compileProc == NULL) {
@@ -3130,7 +3135,45 @@ TclAttemptCompileProc(
* we avoid compiling subcommands that recursively call TclCompileScript().
*/
+#ifdef TCL_COMPILE_DEBUG
+ if (envPtr->exceptDepth != savedExceptDepth) {
+ Tcl_Panic("ExceptionRange Starts and Ends do not balance");
+ }
+#endif
+
if (result != TCL_OK) {
+ ExceptionAux *auxPtr = envPtr->exceptAuxArrayPtr;
+
+ for (i = 0; i < savedExceptArrayNext; i++) {
+ while (auxPtr->numBreakTargets > 0
+ && auxPtr->breakTargets[auxPtr->numBreakTargets - 1]
+ >= savedCodeNext) {
+ auxPtr->numBreakTargets--;
+ }
+ while (auxPtr->numContinueTargets > 0
+ && auxPtr->continueTargets[auxPtr->numContinueTargets - 1]
+ >= savedCodeNext) {
+ auxPtr->numContinueTargets--;
+ }
+ auxPtr++;
+ }
+ envPtr->exceptArrayNext = savedExceptArrayNext;
+
+ if (savedAuxDataArrayNext != envPtr->auxDataArrayNext) {
+ AuxData *auxDataPtr = envPtr->auxDataArrayPtr;
+ AuxData *auxDataEnd = auxDataPtr;
+
+ auxDataPtr += savedAuxDataArrayNext;
+ auxDataEnd += envPtr->auxDataArrayNext;
+
+ while (auxDataPtr < auxDataEnd) {
+ if (auxDataPtr->type->freeProc != NULL) {
+ auxDataPtr->type->freeProc(auxDataPtr->clientData);
+ }
+ auxDataPtr++;
+ }
+ envPtr->auxDataArrayNext = savedAuxDataArrayNext;
+ }
envPtr->currStackDepth = savedStackDepth;
envPtr->codeNext = envPtr->codeStart + savedCodeNext;
#ifdef TCL_COMPILE_DEBUG