diff options
author | dgp <dgp@users.sourceforge.net> | 2016-03-17 12:15:52 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2016-03-17 12:15:52 (GMT) |
commit | ba96ade25a6b00ff4945834090a8de52b1147204 (patch) | |
tree | 7c8a5db98dd8fa327775dbed89e97c4220aa08a7 /generic | |
parent | 671e2228ac8024e945034191da52584381ce61ac (diff) | |
parent | 8ad967404ac779d2dff31836f295f22ed6fc130c (diff) | |
download | tcl-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.c | 43 |
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 |