summaryrefslogtreecommitdiffstats
path: root/generic/tclExecute.c
diff options
context:
space:
mode:
authorMiguel Sofer <miguel.sofer@gmail.com>2011-03-05 17:54:16 (GMT)
committerMiguel Sofer <miguel.sofer@gmail.com>2011-03-05 17:54:16 (GMT)
commitdd8df7deae958a8c13a42dda408334f1ce2e81c6 (patch)
tree298dbc46f7ca04ab3370021cc5dbb13208fbbdbf /generic/tclExecute.c
parent7c0907c17ee4b04124e931902bd620fc918463db (diff)
downloadtcl-dd8df7deae958a8c13a42dda408334f1ce2e81c6.zip
tcl-dd8df7deae958a8c13a42dda408334f1ce2e81c6.tar.gz
tcl-dd8df7deae958a8c13a42dda408334f1ce2e81c6.tar.bz2
* generic/tclExecute.c (TclStackFree): insure that the execStack satisfies
"at most one free stack after the current one" when consecutive reallocs caused the creation of intervening stacks.
Diffstat (limited to 'generic/tclExecute.c')
-rw-r--r--generic/tclExecute.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index 5cffc90..ece8a8c 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -1235,19 +1235,28 @@ TclStackFree(
}
/*
- * Return to previous stack.
+ * Return to previous active stack. Note that repeated expansions or
+ * reallocs could have generated several unused intervening stacks: free
+ * them too.
*/
- esPtr->tosPtr = &esPtr->stackWords[-1];
- if (esPtr->prevPtr) {
- eePtr->execStackPtr = esPtr->prevPtr;
+ while (esPtr->nextPtr) {
+ esPtr = esPtr->nextPtr;
}
- if (esPtr->nextPtr) {
- if (!esPtr->prevPtr) {
- eePtr->execStackPtr = esPtr->nextPtr;
+ esPtr->tosPtr = &esPtr->stackWords[-1];
+ while (esPtr->prevPtr) {
+ ExecStack *tmpPtr = esPtr->prevPtr;
+ if (tmpPtr->tosPtr == &tmpPtr->stackWords[-1]) {
+ DeleteExecStack(tmpPtr);
+ } else {
+ break;
}
- DeleteExecStack(esPtr);
}
+ if (esPtr->prevPtr) {
+ eePtr->execStackPtr = esPtr->prevPtr;
+ } else {
+ eePtr->execStackPtr = esPtr;
+ }
}
void *