summaryrefslogtreecommitdiffstats
path: root/generic/tclCompile.c
diff options
context:
space:
mode:
authorandreas_kupries <akupries@shaw.ca>2010-02-11 19:51:48 (GMT)
committerandreas_kupries <akupries@shaw.ca>2010-02-11 19:51:48 (GMT)
commitd58785661f5df34462a865083b64842790ac0263 (patch)
treed247e38b48a5d8106ab86a908d4443288d527280 /generic/tclCompile.c
parent0a2eb75c6b7960ada46c0f31b72ac7a2a505eba6 (diff)
downloadtcl-d58785661f5df34462a865083b64842790ac0263.zip
tcl-d58785661f5df34462a865083b64842790ac0263.tar.gz
tcl-d58785661f5df34462a865083b64842790ac0263.tar.bz2
* generic/tclCompile.c: [Bug 2949302]: Fixed leak of support
structures for [info frame] which occured when bytecode compilation fails.
Diffstat (limited to 'generic/tclCompile.c')
-rw-r--r--generic/tclCompile.c65
1 files changed, 47 insertions, 18 deletions
diff --git a/generic/tclCompile.c b/generic/tclCompile.c
index 74688bd..b442c50 100644
--- a/generic/tclCompile.c
+++ b/generic/tclCompile.c
@@ -11,7 +11,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclCompile.c,v 1.43.2.17 2009/08/26 02:25:47 dgp Exp $
+ * RCS: @(#) $Id: tclCompile.c,v 1.43.2.18 2010/02/11 19:51:49 andreas_kupries Exp $
*/
#include "tclInt.h"
@@ -308,6 +308,7 @@ static void EnterCmdWordData _ANSI_ARGS_((
ExtCmdLoc *eclPtr, int srcOffset, Tcl_Token* tokenPtr,
CONST char* cmd, int len, int numWords, int line,
int* clNext, int** lines, CompileEnv* envPtr));
+static void ReleaseCmdWordData _ANSI_ARGS_((ExtCmdLoc* eclPtr));
#endif
@@ -721,22 +722,8 @@ TclCleanupByteCode(codePtr)
Tcl_HashEntry* hePtr = Tcl_FindHashEntry (iPtr->lineBCPtr, (char *) codePtr);
if (hePtr) {
ExtCmdLoc* eclPtr = (ExtCmdLoc*) Tcl_GetHashValue (hePtr);
- int i;
- if (eclPtr->type == TCL_LOCATION_SOURCE) {
- Tcl_DecrRefCount (eclPtr->path);
- }
- for (i=0; i < eclPtr->nuloc; i++) {
- ckfree ((char*) eclPtr->loc[i].line);
- }
-
- if (eclPtr->loc != NULL) {
- ckfree ((char*) eclPtr->loc);
- }
-
- Tcl_DeleteHashTable (&eclPtr->litInfo);
-
- ckfree ((char*) eclPtr);
+ ReleaseCmdWordData (eclPtr);
Tcl_DeleteHashEntry (hePtr);
}
}
@@ -745,6 +732,30 @@ TclCleanupByteCode(codePtr)
TclHandleRelease(codePtr->interpHandle);
ckfree((char *) codePtr);
}
+
+#ifdef TCL_TIP280
+static void
+ReleaseCmdWordData (eclPtr)
+ ExtCmdLoc* eclPtr;
+{
+ int i;
+
+ if (eclPtr->type == TCL_LOCATION_SOURCE) {
+ Tcl_DecrRefCount (eclPtr->path);
+ }
+ for (i=0; i < eclPtr->nuloc; i++) {
+ ckfree ((char*) eclPtr->loc[i].line);
+ }
+
+ if (eclPtr->loc != NULL) {
+ ckfree ((char*) eclPtr->loc);
+ }
+
+ Tcl_DeleteHashTable (&eclPtr->litInfo);
+
+ ckfree ((char*) eclPtr);
+}
+#endif
/*
*----------------------------------------------------------------------
@@ -960,6 +971,9 @@ TclFreeCompileEnv(envPtr)
if (envPtr->clLoc) {
Tcl_Release (envPtr->clLoc);
}
+ if (envPtr->extCmdMapPtr) {
+ ReleaseCmdWordData (envPtr->extCmdMapPtr);
+ }
#endif
}
@@ -1068,7 +1082,7 @@ TclCompileScript(interp, script, numBytes, nested, envPtr)
#ifdef TCL_TIP280
/* TIP #280 */
ExtCmdLoc* eclPtr = envPtr->extCmdMapPtr;
- int* wlines;
+ int* wlines = NULL;
int wlineat, cmdLine;
int* clNext;
#endif
@@ -1376,6 +1390,7 @@ TclCompileScript(interp, script, numBytes, nested, envPtr)
ckfree ((char*) eclPtr->loc [wlineat].next);
eclPtr->loc [wlineat].line = wlines;
eclPtr->loc [wlineat].next = NULL;
+ wlines = NULL;
#endif
} /* end if parse.numWords > 0 */
@@ -1449,7 +1464,21 @@ TclCompileScript(interp, script, numBytes, nested, envPtr)
commandLength -= 1;
}
- log:
+ log:
+#ifdef TCL_TIP280
+ /* TIP #280: Free the per-word line data left over from parsing an
+ * erroneous command, if any.
+ */
+ if (wlines) {
+ ckfree ((char*) eclPtr->loc [wlineat].line);
+ ckfree ((char*) eclPtr->loc [wlineat].next);
+ ckfree ((char*) wlines);
+ eclPtr->loc [wlineat].line = NULL;
+ eclPtr->loc [wlineat].next = NULL;
+ wlines = NULL;
+ }
+#endif
+
LogCompilationInfo(interp, script, parse.commandStart, commandLength);
if (gotParse) {
Tcl_FreeParse(&parse);