Subject: Revise TclReleaseLiteral() to tolerate a NULL interp argument. Update callers and revise mistaken comments.

From: dgp <[email-masked]>
Date: Thu, 28 Feb 2013 17:08:43 +0000

---
 ChangeLog            |  8 ++++++++
 generic/tclCompile.c | 16 ++++------------
 generic/tclLiteral.c |  8 +++++++-
 generic/tclProc.c    | 12 ++----------
 4 files changed, 21 insertions(+), 23 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 7bffb3e..696c2a1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2013-02-28  Don Porter  <[email-masked]>
+
+	* generic/tclLiteral.c:	Revise TclReleaseLiteral() to tolerate a
+	NULL interp argument.
+
+	* generic/tclCompile.c:	Update callers and revise mistaken comments.
+	* generic/tclProc.c:
+
 2013-02-27  Jan Nijtmans  <[email-masked]>
 
 	* generic/regcomp.c:	[Bug 3606139]: missing error check allows
diff --git a/generic/tclCompile.c b/generic/tclCompile.c
index 91eab6e..cf165f6 100644
--- a/generic/tclCompile.c
+++ b/generic/tclCompile.c
@@ -918,7 +918,7 @@ TclCleanupByteCode(
      * released.
      */
 
-    if ((codePtr->flags & TCL_BYTECODE_PRECOMPILED) || (interp == NULL)) {
+    if (codePtr->flags & TCL_BYTECODE_PRECOMPILED) {
 
 	objArrayPtr = codePtr->objArrayPtr;
 	for (i = 0;  i < numLitObjects;  i++) {
@@ -931,17 +931,9 @@ TclCleanupByteCode(
 	codePtr->numLitObjects = 0;
     } else {
 	objArrayPtr = codePtr->objArrayPtr;
-	for (i = 0;  i < numLitObjects;  i++) {
-	    /*
-	     * TclReleaseLiteral sets a ByteCode's object array entry NULL to
-	     * indicate that it has already freed the literal.
-	     */
-
-	    objPtr = *objArrayPtr;
-	    if (objPtr != NULL) {
-		TclReleaseLiteral(interp, objPtr);
-	    }
-	    objArrayPtr++;
+	while (numLitObjects--) {
+	    /* TclReleaseLiteral calls Tcl_DecrRefCount() for us */
+	    TclReleaseLiteral(interp, *objArrayPtr++);
 	}
     }
 
diff --git a/generic/tclLiteral.c b/generic/tclLiteral.c
index 441ea91..2cba18d 100644
--- a/generic/tclLiteral.c
+++ b/generic/tclLiteral.c
@@ -750,11 +750,16 @@ TclReleaseLiteral(
 				 * TclRegisterLiteral. */
 {
     Interp *iPtr = (Interp *) interp;
-    LiteralTable *globalTablePtr = &iPtr->literalTable;
+    LiteralTable *globalTablePtr;
     register LiteralEntry *entryPtr, *prevPtr;
     const char *bytes;
     int length, index;
 
+    if (iPtr == NULL) {
+	goto done;
+    }
+
+    globalTablePtr = &iPtr->literalTable;
     bytes = TclGetStringFromObj(objPtr, &length);
     index = (HashString(bytes, length) & globalTablePtr->mask);
 
@@ -798,6 +803,7 @@ TclReleaseLiteral(
      * Remove the reference corresponding to the local literal table entry.
      */
 
+    done:
     Tcl_DecrRefCount(objPtr);
 }
 
diff --git a/generic/tclProc.c b/generic/tclProc.c
index e66b8ea..13f6f8a 100644
--- a/generic/tclProc.c
+++ b/generic/tclProc.c
@@ -1347,17 +1347,9 @@ TclFreeLocalCache(
     for (i = 0; i < localCachePtr->numVars; i++, namePtrPtr++) {
 	register Tcl_Obj *objPtr = *namePtrPtr;
 
-	/*
-	 * Note that this can be called with interp==NULL, on interp deletion.
-	 * In that case, the literal table and objects go away on their own.
-	 */
-
 	if (objPtr) {
-	    if (interp) {
-		TclReleaseLiteral(interp, objPtr);
-	    } else {
-		Tcl_DecrRefCount(objPtr);
-	    }
+	    /* TclReleaseLiteral calls Tcl_DecrRefCount for us */
+	    TclReleaseLiteral(interp, objPtr);
 	}
     }
     ckfree(localCachePtr);
-- 
cgit v0.12