summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiguel Sofer <miguel.sofer@gmail.com>2004-05-22 03:42:49 (GMT)
committerMiguel Sofer <miguel.sofer@gmail.com>2004-05-22 03:42:49 (GMT)
commit5391471ba68476e8ffa96b327d4e2bc09746d0f1 (patch)
tree309e81a45cfbd5249fac9ac609604e4be2bffee0
parent8dc91fd4313dc268bca4ad3d522914a3ad2bc6e8 (diff)
downloadtcl-5391471ba68476e8ffa96b327d4e2bc09746d0f1.zip
tcl-5391471ba68476e8ffa96b327d4e2bc09746d0f1.tar.gz
tcl-5391471ba68476e8ffa96b327d4e2bc09746d0f1.tar.bz2
* generic/tclVar.c: fix for [Bug 735335]. The use of
tclNsVarNameType objs is still disabled, pending resolution of [Bug 736729].
-rw-r--r--ChangeLog6
-rw-r--r--generic/tclVar.c45
2 files changed, 30 insertions, 21 deletions
diff --git a/ChangeLog b/ChangeLog
index 403f4c7..84caa5d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2004-05-22 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclVar.c: fix for [Bug 735335]. The use of
+ tclNsVarNameType objs is still disabled, pending resolution of
+ [Bug 736729].
+
2004-05-21 Miguel Sofer <msofer@users.sf.net>
* tests/namespace.test (namespace-41.3): removed the {knownBug}
diff --git a/generic/tclVar.c b/generic/tclVar.c
index b3dbbee..a177cf8 100644
--- a/generic/tclVar.c
+++ b/generic/tclVar.c
@@ -15,7 +15,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclVar.c,v 1.79 2004/04/28 13:11:33 msofer Exp $
+ * RCS: @(#) $Id: tclVar.c,v 1.80 2004/05/22 03:42:56 msofer Exp $
*/
#include "tclInt.h"
@@ -398,11 +398,15 @@ TclObjLookupVar(interp, part1Ptr, part2, flags, msg, createPart1, createPart2,
if (useLocal && (procPtr == varFramePtr->procPtr)) {
/*
* part1Ptr points to an indexed local variable of the
- * correct procedure: use the cached value.
+ * correct procedure: use the cached value if the names
+ * coincide.
*/
varPtr = &(varFramePtr->compiledLocals[localIndex]);
- goto donePart1;
+ if ((varPtr->name != NULL)
+ && (strcmp(part1, varPtr->name) == 0)) {
+ goto donePart1;
+ }
}
goto doneParsing;
} else if (typePtr == &tclNsVarNameType) {
@@ -542,11 +546,10 @@ TclObjLookupVar(interp, part1Ptr, part2, flags, msg, createPart1, createPart2,
/*
* TEMPORARYLY DISABLED tclNsVarNameType
*
- * This is a stop-gap fix for [Bug 735335]; it may not address the
- * real issue (which I haven't pinned down yet), but it avoids the
- * segfault in the test case.
+ * This is a stop-gap fix for [Bug 736729]; it may not address the
+ * real issue (which I haven't pinned down yet).
* This optimisation will hopefully be turned back on soon.
- * Miguel Sofer, 2003-05-12
+ * Miguel Sofer, 2004-05-22
*/
} else if (index > -3) {
@@ -2154,7 +2157,7 @@ TclObjUnsetVar2(interp, part1Ptr, part2, flags)
if (varPtr == NULL) {
return TCL_ERROR;
}
-
+
result = (TclIsVarUndefined(varPtr)? TCL_ERROR : TCL_OK);
if ((arrayPtr != NULL) && (arrayPtr->searchPtr != NULL)) {
@@ -2182,6 +2185,16 @@ TclObjUnsetVar2(interp, part1Ptr, part2, flags)
varPtr->searchPtr = NULL;
/*
+ * Keep the variable alive until we're done with it. We used to
+ * increase/decrease the refCount for each operation, making it
+ * hard to find [Bug 735335] - caused by unsetting the variable
+ * whose value was the variable's name.
+ */
+
+ varPtr->refCount++;
+
+
+ /*
* Call trace procedures for the variable being deleted. Then delete
* its traces. Be sure to abort any other traces for the variable
* that are still pending. Special tricks:
@@ -2193,7 +2206,6 @@ TclObjUnsetVar2(interp, part1Ptr, part2, flags)
if ((dummyVar.tracePtr != NULL)
|| ((arrayPtr != NULL) && (arrayPtr->tracePtr != NULL))) {
- varPtr->refCount++;
dummyVar.flags &= ~VAR_TRACE_ACTIVE;
TclCallVarTraces(iPtr, arrayPtr, &dummyVar, part1, part2,
(flags & (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY))
@@ -2209,7 +2221,6 @@ TclObjUnsetVar2(interp, part1Ptr, part2, flags)
activePtr->nextTracePtr = NULL;
}
}
- varPtr->refCount--;
}
/*
@@ -2233,12 +2244,10 @@ TclObjUnsetVar2(interp, part1Ptr, part2, flags)
* array are being deleted when the array still exists, but since the
* array is about to be removed anyway, that shouldn't really matter.
*/
- varPtr->refCount++;
DeleteArray(iPtr, part1, dummyVarPtr,
(flags & (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY))
| TCL_TRACE_UNSETS);
/* Decr ref count */
- varPtr->refCount--;
}
if (TclIsVarScalar(dummyVarPtr)
&& (dummyVarPtr->value.objPtr != NULL)) {
@@ -2273,6 +2282,7 @@ TclObjUnsetVar2(interp, part1Ptr, part2, flags)
* its value object, if any, was decremented above.
*/
+ varPtr->refCount--;
TclCleanupVar(varPtr, arrayPtr);
return result;
}
@@ -4617,16 +4627,9 @@ FreeNsVarName(objPtr)
Tcl_Obj *objPtr;
{
register Var *varPtr = (Var *) objPtr->internalRep.twoPtrValue.ptr2;
-
+
varPtr->refCount--;
- if (TclIsVarUndefined(varPtr) && (varPtr->refCount <= 0)) {
- if (TclIsVarLink(varPtr)) {
- Var *linkPtr = varPtr->value.linkPtr;
- linkPtr->refCount--;
- if (TclIsVarUndefined(linkPtr) && (linkPtr->refCount <= 0)) {
- TclCleanupVar(linkPtr, (Var *) NULL);
- }
- }
+ if (TclIsVarUndefined(varPtr) && (varPtr->refCount == 0)) {
TclCleanupVar(varPtr, NULL);
}
}