summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--generic/tclBasic.c8
-rw-r--r--generic/tclLiteral.c34
3 files changed, 32 insertions, 20 deletions
diff --git a/ChangeLog b/ChangeLog
index 6e06fb2..848f22a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2004-07-05 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclBasic.c (DeleteInterpProc): fix for [Bug 983660],
+ found by pspjuth. Tear down the global namespace before freeing
+ the interp handle, to allow the bytecodes to free their non-shared
+ literals.
+ * generic/tclLiteral.c (TclReleaseLiteral): moved special code for
+ self-ref so that it is also used for non-shared literals. Possible
+ bug found by inspection.
+
2004-07-03 Miguel Sofer <msofer@users.sf.net>
* generic/tclExecute.c (ExprRoundFunc):
diff --git a/generic/tclBasic.c b/generic/tclBasic.c
index 6b9058b..aec8a18 100644
--- a/generic/tclBasic.c
+++ b/generic/tclBasic.c
@@ -13,7 +13,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclBasic.c,v 1.106 2004/06/14 22:14:11 kennykb Exp $
+ * RCS: @(#) $Id: tclBasic.c,v 1.107 2004/07/05 22:41:01 msofer Exp $
*/
#include "tclInt.h"
@@ -980,8 +980,6 @@ DeleteInterpProc(interp)
Tcl_Panic("DeleteInterpProc called on interpreter not marked deleted");
}
- TclHandleFree(iPtr->handle);
-
/*
* Shut down all limit handler callback scripts that call back
* into this interpreter. Then eliminate all limit handlers for
@@ -998,9 +996,13 @@ DeleteInterpProc(interp)
*
* Dismantle the namespace here, before we clear the assocData. If any
* background errors occur here, they will be deleted below.
+ *
+ * Dismantle the namespace before freeing the iPtr->handle, to insure
+ * that non-shared literals are freed properly [Bug 983660].
*/
TclTeardownNamespace(iPtr->globalNsPtr);
+ TclHandleFree(iPtr->handle);
/*
* Delete all the hidden commands.
diff --git a/generic/tclLiteral.c b/generic/tclLiteral.c
index 9250413..2dfe37f 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.14 2004/04/06 22:25:54 dgp Exp $
+ * RCS: @(#) $Id: tclLiteral.c,v 1.15 2004/07/05 22:41:02 msofer Exp $
*/
#include "tclInt.h"
@@ -712,22 +712,6 @@ TclReleaseLiteral(interp, objPtr)
TclDecrRefCount(objPtr);
- /*
- * 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;
- }
- }
-
#ifdef TCL_COMPILE_STATS
iPtr->stats.currentLitStringBytes -= (double) (length + 1);
#endif /*TCL_COMPILE_STATS*/
@@ -735,6 +719,22 @@ TclReleaseLiteral(interp, objPtr)
break;
}
}
+
+ /*
+ * 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;
+ }
+ }
/*
* Remove the reference corresponding to the local literal table