summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2014-12-18 19:21:31 (GMT)
committerdgp <dgp@users.sourceforge.net>2014-12-18 19:21:31 (GMT)
commitf06d852f72d64565eab335c0aaab3fdc60927171 (patch)
tree80124aec81d19a23d8069c9ccf9d46f90e1d7312
parent648900ebca5832143f62cc4b8c654c7d6ee58f59 (diff)
downloadtcl-f06d852f72d64565eab335c0aaab3fdc60927171.zip
tcl-f06d852f72d64565eab335c0aaab3fdc60927171.tar.gz
tcl-f06d852f72d64565eab335c0aaab3fdc60927171.tar.bz2
Shift the allocation of AuxData earlier in the [foreach] compiler.
-rw-r--r--generic/tclCompCmds.c41
1 files changed, 25 insertions, 16 deletions
diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c
index a0f493c..f07b19f 100644
--- a/generic/tclCompCmds.c
+++ b/generic/tclCompCmds.c
@@ -1536,7 +1536,7 @@ TclCompileForeachCmd(
CompileEnv *envPtr) /* Holds resulting instructions. */
{
Proc *procPtr = envPtr->procPtr;
- ForeachInfo *infoPtr; /* Points to the structure describing this
+ ForeachInfo *infoPtr = NULL;/* Points to the structure describing this
* foreach command. Stored in a AuxData
* record in the ByteCode. */
int firstValueTemp; /* Index of the first temp var in the frame
@@ -1599,6 +1599,16 @@ TclCompileForeachCmd(
memset((char*) varvList, 0, numLists * sizeof(const char **));
/*
+ * Create and initialize the ForeachInfo and ForeachVarList data
+ * structures describing this command. Then create a AuxData record
+ * pointing to the ForeachInfo structure.
+ */
+
+ infoPtr = (ForeachInfo *) ckalloc((unsigned)
+ sizeof(ForeachInfo) + numLists*sizeof(ForeachVarList *));
+ infoPtr->numLists = 0; /* Count this up as we go */
+
+ /*
* Break up each var list and set the varcList and varvList arrays. Don't
* compile the foreach inline if any var name needs substitutions or isn't
* a scalar, or if any var list needs substitutions.
@@ -1609,6 +1619,7 @@ TclCompileForeachCmd(
i < numWords-1;
i++, tokenPtr = TokenAfter(tokenPtr)) {
Tcl_DString varList;
+ ForeachVarList *varListPtr;
if (i%2 != 1) {
continue;
@@ -1634,6 +1645,12 @@ TclCompileForeachCmd(
}
numVars = varcList[loopIndex];
+ varListPtr = (ForeachVarList *) ckalloc((unsigned)
+ sizeof(ForeachVarList) + numVars*sizeof(int));
+ varListPtr->numVars = numVars;
+ infoPtr->varLists[loopIndex] = varListPtr;
+ infoPtr->numLists++;
+
/*
* If the variable list is empty, we can enter an infinite loop when
* the interpreted version would not. Take care to ensure this does
@@ -1678,23 +1695,11 @@ TclCompileForeachCmd(
loopCtTemp = TclFindCompiledLocal(NULL, /*nameChars*/ 0,
/*create*/ 1, procPtr);
- /*
- * Create and initialize the ForeachInfo and ForeachVarList data
- * structures describing this command. Then create a AuxData record
- * pointing to the ForeachInfo structure.
- */
-
- infoPtr = (ForeachInfo *) ckalloc((unsigned)
- sizeof(ForeachInfo) + numLists*sizeof(ForeachVarList *));
- infoPtr->numLists = numLists;
infoPtr->firstValueTemp = firstValueTemp;
infoPtr->loopCtTemp = loopCtTemp;
for (loopIndex = 0; loopIndex < numLists; loopIndex++) {
- ForeachVarList *varListPtr;
- numVars = varcList[loopIndex];
- varListPtr = (ForeachVarList *) ckalloc((unsigned)
- sizeof(ForeachVarList) + numVars*sizeof(int));
- varListPtr->numVars = numVars;
+ ForeachVarList *varListPtr = infoPtr->varLists[loopIndex];
+ numVars = varListPtr->numVars;
for (j = 0; j < numVars; j++) {
const char *varName = varvList[loopIndex][j];
int nameChars = strlen(varName);
@@ -1702,7 +1707,6 @@ TclCompileForeachCmd(
varListPtr->varIndexes[j] = TclFindCompiledLocal(varName,
nameChars, /*create*/ 1, procPtr);
}
- infoPtr->varLists[loopIndex] = varListPtr;
}
infoIndex = TclCreateAuxData(infoPtr, &tclForeachInfoType, envPtr);
@@ -1816,6 +1820,11 @@ TclCompileForeachCmd(
envPtr->currStackDepth = savedStackDepth + 1;
done:
+ if (code == TCL_ERROR) {
+ if (infoPtr) {
+ FreeForeachInfo(infoPtr);
+ }
+ }
for (loopIndex = 0; loopIndex < numLists; loopIndex++) {
if (varvList[loopIndex] != NULL) {
ckfree((char *) varvList[loopIndex]);