From eb15d5b60d298079a384b538aa00c53ece4309b6 Mon Sep 17 00:00:00 2001 From: Miguel Sofer Date: Tue, 25 May 2004 19:45:14 +0000 Subject: * generic/tclNamesp.c (Tcl_FindNamespaceVar): * tests/namespace.test (namespace-17.10-12): reverted commit of 2004-05-23 and removed the tests, as it interferes with the varname resolver and there are apps that break (AlphaTk). A fix will have to wait for Tcl9. * generic/tclVar.c: Caching of namespace variables disabled: no simple way was found to avoid interfering with the resolver's idea of variable existence. A cached varName may keep a variable's name in the namespace's hash table, which is the resolver's criterion for existence. * tests/namespace.c (namespace-17.10): testing for interference between varname caching and name resolver. --- ChangeLog | 21 +++++++++++++++++++-- generic/tclNamesp.c | 16 +--------------- generic/tclVar.c | 23 +++++++++++++++++++++-- tests/namespace.test | 38 ++++++++++++++------------------------ 4 files changed, 55 insertions(+), 43 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2d83a91..63f91d1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2004-05-25 Miguel Sofer + + * generic/tclNamesp.c (Tcl_FindNamespaceVar): + * tests/namespace.test (namespace-17.10-12): reverted commit of + 2004-05-23 and removed the tests, as it interferes with the + varname resolver and there are apps that break (AlphaTk). A fix + will have to wait for Tcl9. + + * generic/tclVar.c: Caching of namespace variables disabled: no + simple way was found to avoid interfering with the resolver's idea + of variable existence. A cached varName may keep a variable's name + in the namespace's hash table, which is the resolver's criterion + for existence. + + * tests/namespace.c (namespace-17.10): testing for interference + between varname caching and name resolver. + 2004-05-25 Kevin Kenny * tests/winFCmd.test: Correct test for the presence of a CD-ROM so @@ -61,8 +78,7 @@ * generic/tclVar.c (TclLookupSimpleVar): comments re [Bug 736729] (predecessor of [Bug 959052]) removed. * tests/namespace.test: added tests 17.10-12 - - ***POTENTIAL INCOMPATIBILITY*** + The patch modifies non-documented behaviour, and passes every test in the testsuite. However, scripts relying on the old behaviour may break. @@ -73,6 +89,7 @@ the namespace resolution process deems a variable to exist exactly when [info vars] finds it - ie, either it has value, or else it was "fixed" by a call to [variable]. + Note: this patch was removed on 2002-05-25. 2004-05-22 Miguel Sofer diff --git a/generic/tclNamesp.c b/generic/tclNamesp.c index 89dfbab..88ad3bb 100644 --- a/generic/tclNamesp.c +++ b/generic/tclNamesp.c @@ -21,7 +21,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclNamesp.c,v 1.39 2004/05/23 22:58:23 msofer Exp $ + * RCS: @(#) $Id: tclNamesp.c,v 1.40 2004/05/25 19:45:14 msofer Exp $ */ #include "tclInt.h" @@ -2324,20 +2324,6 @@ Tcl_FindNamespaceVar(interp, name, contextNsPtr, flags) simpleName); if (entryPtr != NULL) { varPtr = (Var *) Tcl_GetHashValue(entryPtr); - - /* Fix for [Bug 959052]. - * We might have found a "zombie" variable: it is in the hash - * table, but the variable is unset and it was not fixed with - * a call to [variable]. In particular, zombies created by - * [trace], [upvar], [global] or a reference in a - * tclNsVarNameType obj should never be found. - */ - - if (TclIsVarUndefined(varPtr) - && !(varPtr->flags & VAR_NAMESPACE_VAR) - && !(flags & (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY))) { - varPtr = NULL; - } } } } diff --git a/generic/tclVar.c b/generic/tclVar.c index e84ce8f..667c206 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.82 2004/05/23 22:53:20 msofer Exp $ + * RCS: @(#) $Id: tclVar.c,v 1.83 2004/05/25 19:45:16 msofer Exp $ */ #include "tclInt.h" @@ -101,10 +101,21 @@ Tcl_ObjType tclLocalVarNameType = { FreeLocalVarName, DupLocalVarName, UpdateLocalVarName, NULL }; +/* + * Caching of namespace variables disabled: no simple way was found to + * avoid interfering with the resolver's idea of variable existence. + * A cached varName may keep a variable's name in the namespace's hash + * table, which is the resolver's criterion for existence (see test + * namespace-17.10). + */ +#define ENABLE_NS_VARNAME_CACHING 0 + +#if ENABLE_NS_VARNAME_CACHING Tcl_ObjType tclNsVarNameType = { "namespaceVarName", FreeNsVarName, DupNsVarName, NULL, NULL }; +#endif Tcl_ObjType tclParsedVarNameType = { "parsedVarName", @@ -409,6 +420,7 @@ TclObjLookupVar(interp, part1Ptr, part2, flags, msg, createPart1, createPart2, } } goto doneParsing; +#if ENABLE_NS_VARNAME_CACHING } else if (typePtr == &tclNsVarNameType) { Namespace *cachedNsPtr; int useGlobal, useReference; @@ -444,6 +456,7 @@ TclObjLookupVar(interp, part1Ptr, part2, flags, msg, createPart1, createPart2, goto donePart1; } goto doneParsing; +#endif } doParse: @@ -542,6 +555,7 @@ TclObjLookupVar(interp, part1Ptr, part2, flags, msg, createPart1, createPart2, procPtr->refCount++; part1Ptr->internalRep.twoPtrValue.ptr1 = (VOID *) procPtr; part1Ptr->internalRep.twoPtrValue.ptr2 = (VOID *) index; +#if ENABLE_NS_VARNAME_CACHING } else if (index > -3) { /* * A cacheable namespace or global variable. @@ -553,6 +567,7 @@ TclObjLookupVar(interp, part1Ptr, part2, flags, msg, createPart1, createPart2, part1Ptr->typePtr = &tclNsVarNameType; part1Ptr->internalRep.twoPtrValue.ptr1 = (VOID *) nsPtr; part1Ptr->internalRep.twoPtrValue.ptr2 = (VOID *) varPtr; +#endif } else { /* * At least mark part1Ptr as already parsed. @@ -2271,6 +2286,7 @@ TclObjUnsetVar2(interp, part1Ptr, part2, flags) } } +#if ENABLE_NS_VARNAME_CACHING /* * Try to avoid keeping the Var struct allocated due to a tclNsVarNameType * keeping a reference. This removes some additional exteriorisations of @@ -2281,7 +2297,8 @@ TclObjUnsetVar2(interp, part1Ptr, part2, flags) part1Ptr->typePtr->freeIntRepProc(part1Ptr); part1Ptr->typePtr = NULL; } - +#endif + /* * Finally, if the variable is truly not in use then free up its Var * structure and remove it from its hash table, if any. The ref count of @@ -4619,6 +4636,7 @@ UpdateLocalVarName(objPtr) objPtr->length = 0; } +#if ENABLE_NS_VARNAME_CACHING /* * nsVarName - * @@ -4653,6 +4671,7 @@ DupNsVarName(srcPtr, dupPtr) varPtr->refCount++; dupPtr->typePtr = &tclNsVarNameType; } +#endif /* * parsedVarName - diff --git a/tests/namespace.test b/tests/namespace.test index 3193761..e22eb13 100644 --- a/tests/namespace.test +++ b/tests/namespace.test @@ -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: namespace.test,v 1.27 2004/05/25 18:58:04 dgp Exp $ +# RCS: @(#) $Id: namespace.test,v 1.28 2004/05/25 19:45:17 msofer Exp $ if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 @@ -560,30 +560,20 @@ test namespace-17.9 {Tcl_FindNamespaceVar, relative name and TCL_GLOBAL_ONLY} { } set test_ns_1::a } {hello} -test namespace-17.10 {Tcl_FindNamespaceVar, do not find zombies (Bug 959052)} { - catch {unset x} - catch {namespace delete test_ns_1 } - catch {namespace delete test_ns_2} - namespace eval test_ns_1 upvar x q - namespace eval test_ns_2 set x 1 - catch {set ::x} -} 1 -test namespace-17.11 {Tcl_FindNamespaceVar, do not find zombies (Bug 959052)} { - catch {unset x} - catch {namespace delete test_ns_1} - trace add variable x write {;#} - namespace eval test_ns_1 set x 1 - catch {set ::x} -} 1 -test namespace-17.12 {Tcl_FindNamespaceVar, do not find zombies (Bug 959052)} { - catch {unset x} - catch {namespace delete test_ns_1} - namespace eval test_ns_1 {trace add variable x write {;#}} - set ::x 0 - namespace eval test_ns_1 set x 1 - set ::x +test namespace-17.10 {Tcl_FindNamespaceVar, interference with cached varNames} { + namespace eval test_ns_1 {} + proc test_ns {} { + set ::test_ns_1::a 0 + } + test_ns + rename test_ns {} + namespace eval test_ns_1 unset a + set a 0 + namespace eval test_ns_1 set a 1 + namespace delete test_ns_1 + set a } 1 - +catch {unset a} catch {unset x} catch {unset l} -- cgit v0.12