diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | generic/tclLiteral.c | 56 |
2 files changed, 30 insertions, 32 deletions
@@ -1,3 +1,9 @@ +2001-10-11 Miguel Sofer <msofer@users.sourceforge.net> + + * generic/tclLiteral.c: (TclReleaseLiteral) insured that + self-referential bytecodes are properly cleaned up on interpreter + deletion [Bug 467523] (Ronnie Brunner) + 2001-10-10 David Gravereaux <davygrvy@pobox.com> * win/tclWinPort.h: #include <winsock2.h> needed to get moved diff --git a/generic/tclLiteral.c b/generic/tclLiteral.c index 976cb98..4814002 100644 --- a/generic/tclLiteral.c +++ b/generic/tclLiteral.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclLiteral.c,v 1.10 2001/10/09 17:18:56 msofer Exp $ + * RCS: @(#) $Id: tclLiteral.c,v 1.11 2001/10/11 22:28:01 msofer Exp $ */ #include "tclInt.h" @@ -696,31 +696,10 @@ TclReleaseLiteral(interp, objPtr) entryPtr->refCount--; /* - * We found the matching LiteralEntry. Check if it's only being - * kept alive only by a circular reference from a ByteCode - * stored as its internal rep. - */ - - if ((entryPtr->refCount == 1) - && (objPtr->typePtr == &tclByteCodeType)) { - codePtr = (ByteCode *) objPtr->internalRep.otherValuePtr; - if ((codePtr->numLitObjects == 1) - && (codePtr->objArrayPtr[0] == objPtr)) { - entryPtr->refCount = 0; - - /* - * Set the ByteCode object array entry NULL to signal - * to TclCleanupByteCode to not try to release this - * about to be freed literal again. - */ - - codePtr->objArrayPtr[0] = NULL; - } - } - - /* * If the literal is no longer being used by any ByteCode, - * delete the entry then decrement the ref count of its object. + * delete the entry then remove the reference corresponding + * to the global literal table entry (decrement the ref count + * of the object). */ if (entryPtr->refCount == 0) { @@ -729,27 +708,40 @@ TclReleaseLiteral(interp, objPtr) } else { prevPtr->nextPtr = entryPtr->nextPtr; } -#ifdef TCL_COMPILE_STATS - iPtr->stats.currentLitStringBytes -= (double) (length + 1); -#endif /*TCL_COMPILE_STATS*/ ckfree((char *) entryPtr); globalTablePtr->numEntries--; + TclDecrRefCount(objPtr); + /* - * Remove the reference corresponding to the global - * literal table entry. + * Check if the LiteralEntry is only being kept alive by + * a circular reference from a ByteCode stored as its + * internal rep. In that case, set the ByteCode object array + * entry NULL to signal to TclCleanupByteCode to not try to + * release this about to be freed literal again. */ + + if (objPtr->typePtr == &tclByteCodeType) { + codePtr = (ByteCode *) objPtr->internalRep.otherValuePtr; + if ((codePtr->numLitObjects == 1) + && (codePtr->objArrayPtr[0] == objPtr)) { + codePtr->objArrayPtr[0] = NULL; + } + } - TclDecrRefCount(objPtr); +#ifdef TCL_COMPILE_STATS + iPtr->stats.currentLitStringBytes -= (double) (length + 1); +#endif /*TCL_COMPILE_STATS*/ } break; } } - + /* * Remove the reference corresponding to the local literal table * entry. */ + Tcl_DecrRefCount(objPtr); } |