diff options
author | andreas_kupries <akupries@shaw.ca> | 2010-02-11 19:51:48 (GMT) |
---|---|---|
committer | andreas_kupries <akupries@shaw.ca> | 2010-02-11 19:51:48 (GMT) |
commit | eeb7c22b2a85cf74501a8b945643df576c24a395 (patch) | |
tree | d247e38b48a5d8106ab86a908d4443288d527280 | |
parent | d8aa3dc96ad63efdca37d4f340caa2060eee128b (diff) | |
download | tcl-eeb7c22b2a85cf74501a8b945643df576c24a395.zip tcl-eeb7c22b2a85cf74501a8b945643df576c24a395.tar.gz tcl-eeb7c22b2a85cf74501a8b945643df576c24a395.tar.bz2 |
* generic/tclCompile.c: [Bug 2949302]: Fixed leak of support
structures for [info frame] which occured when bytecode
compilation fails.
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | generic/tclCompile.c | 65 |
2 files changed, 53 insertions, 18 deletions
@@ -1,3 +1,9 @@ +2010-02-11 Andreas Kupries <andreask@activestate.com> + + * generic/tclCompile.c: [Bug 2949302]: Fixed leak of support + structures for [info frame] which occured when bytecode + compilation fails. + 2010-02-01 Donal K. Fellows <dkf@users.sf.net> * generic/regexec.c (ccondissect, crevdissect): [Bug 2942697]: Rework 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); |