diff options
author | msofer <msofer@noemail.net> | 2011-03-05 17:54:16 (GMT) |
---|---|---|
committer | msofer <msofer@noemail.net> | 2011-03-05 17:54:16 (GMT) |
commit | 5cc13f99f7400d7515eda09d8539882b5cdd9e22 (patch) | |
tree | 298dbc46f7ca04ab3370021cc5dbb13208fbbdbf | |
parent | 551de988907d1dd44ea218118ffeed1ca2b79eb8 (diff) | |
download | tcl-5cc13f99f7400d7515eda09d8539882b5cdd9e22.zip tcl-5cc13f99f7400d7515eda09d8539882b5cdd9e22.tar.gz tcl-5cc13f99f7400d7515eda09d8539882b5cdd9e22.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.
FossilOrigin-Name: 02580251b51ea2185168a1348628d495987fe98b
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | generic/tclExecute.c | 25 |
2 files changed, 23 insertions, 8 deletions
@@ -1,3 +1,9 @@ +2011-03-05 Miguel Sofer <msofer@users.sf.net> + + * 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. + 2011-03-05 Kevin B. Kenny <kennykb@acm.org> * generic/tclAssembly.c (new file): 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 * |