summaryrefslogtreecommitdiffstats
path: root/generic
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)
commit5beba35bfcc1c668ee6683550aff7299a6b2d3ac (patch)
tree298dbc46f7ca04ab3370021cc5dbb13208fbbdbf /generic
parente342f953c3661d6401a14dba8f85d4cfb48112a2 (diff)
downloadtcl-5beba35bfcc1c668ee6683550aff7299a6b2d3ac.zip
tcl-5beba35bfcc1c668ee6683550aff7299a6b2d3ac.tar.gz
tcl-5beba35bfcc1c668ee6683550aff7299a6b2d3ac.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')
-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 *