Index: generic/nsf.c =================================================================== diff -u -r3ebbf610e7283069e36fd24ab85a590a4b2fb67d -rc86c077585d0ea7664dc3791e21a577927655da8 --- generic/nsf.c (.../nsf.c) (revision 3ebbf610e7283069e36fd24ab85a590a4b2fb67d) +++ generic/nsf.c (.../nsf.c) (revision c86c077585d0ea7664dc3791e21a577927655da8) @@ -203,6 +203,9 @@ static Nsf_TypeConverter ConvertToNothing, ConvertViaCmd, ConvertToObjpattern; +static const char * autonamePrefix = "::nsf::__#"; +static const int autonamePrefixLength = 10; + /* * Tcl_Obj Types for Next Scripting Objects */ @@ -29103,7 +29106,7 @@ Tcl_DString ds, *dsPtr = &ds; Tcl_DStringInit(dsPtr); - Tcl_DStringAppend(dsPtr, "::nsf::__#", 10); + Tcl_DStringAppend(dsPtr, autonamePrefix, autonamePrefixLength); NewTclCommand(interp, dsPtr); @@ -32591,6 +32594,7 @@ NsfObject *newObject = NULL; Tcl_Obj *actualNameObj, *methodObj, *tmpObj = NULL; int result, nameLength; + bool autoNameCreate; const char *nameString; Tcl_Namespace *parentNsPtr; @@ -32619,6 +32623,7 @@ */ if (unlikely(NSValidObjectName(nameString, (size_t)nameLength) == 0)) { result = NsfPrintError(interp, "cannot allocate object - illegal name '%s'", nameString); + autoNameCreate = NSF_FALSE; goto create_method_exit; } @@ -32640,11 +32645,18 @@ /* fprintf(stderr, " **** fixed name is '%s'\n", nameString); */ INCR_REF_COUNT(tmpObj); actualNameObj = tmpObj; + autoNameCreate = NSF_FALSE; } else { parentNsPtr = NULL; actualNameObj = nameObj; /* fprintf(stderr, " **** used specified name is '%s'\n", nameString); */ + + /* + * Check for autname prefix string. This string is always an absolute path + * name, so it is sufficient to test here. + */ + autoNameCreate = (strncmp(autonamePrefix, nameString, autonamePrefixLength) == 0); } /* @@ -32770,6 +32782,10 @@ } create_method_exit: + if (autoNameCreate && result == TCL_OK) { + newObject->flags |= NSF_IS_AUTONAMED; + } + if (tmpObj != NULL) { DECR_REF_COUNT(tmpObj); } @@ -32957,7 +32973,7 @@ } Tcl_DStringAppend(dsPtr, "::__#", 5); } else { - Tcl_DStringAppend(dsPtr, "::nsf::__#", 10); + Tcl_DStringAppend(dsPtr, autonamePrefix, autonamePrefixLength); } NewTclCommand(interp, dsPtr); @@ -32990,16 +33006,6 @@ } } - { - Tcl_Obj *resultObj; - NsfObject *object; - - resultObj = Tcl_GetObjResult(interp); - if (GetObjectFromObj(interp, resultObj, &object) == TCL_OK) { - object->flags |= NSF_IS_AUTONAMED; - } - } - DECR_REF_COUNT(fullnameObj); Tcl_DStringFree(dsPtr); Index: library/xotcl/tests/speedtest.xotcl =================================================================== diff -u -re5df69942b2d9eb3944ef709803870f476886981 -rc86c077585d0ea7664dc3791e21a577927655da8 --- library/xotcl/tests/speedtest.xotcl (.../speedtest.xotcl) (revision e5df69942b2d9eb3944ef709803870f476886981) +++ library/xotcl/tests/speedtest.xotcl (.../speedtest.xotcl) (revision c86c077585d0ea7664dc3791e21a577927655da8) @@ -19,7 +19,7 @@ nx::test new -msg {test multiple dashed args o3} \ -cmd {Object create o3 -proc foo args {return 1} {-set -a -t1} {-set b "-b 1 -y 2"}} \ -expected ::o3 \ - -post {o3 destroy} + -post {o3 destroy} nx::test configure -count 1000 @@ -42,8 +42,8 @@ my instvar n v #for {set i 1} {$i<1000} {incr i} {set n($i) 1} #for {set i 1} {$i<1000} {incr i} {Object [self]::$i} - for {set i 0} {$i<$::ccount} {incr i} {set n($i) 1} - for {set i 0} {$i<$::ccount} {incr i} {Object [self]::$i} + for {set i 0} {$i<$::ccount} {incr i} {set n($i) 1} + for {set i 0} {$i<$::ccount} {incr i} {Object [self]::$i} set v 1 } @@ -58,23 +58,23 @@ } C instproc existsViaInstvar {} { - my instvar v + my instvar v info exists v } C instproc existsViaMyInstvar {} { - my instvar v + my instvar v info exists v } -C instproc existsViaExistsMethod {} { +C instproc existsViaExistsMethod {} { [self] exists v } -C instproc existsViaMyExistsMethod {} { +C instproc existsViaMyExistsMethod {} { my exists v } -C instproc existsViaDotExistsMethod {} { +C instproc existsViaDotExistsMethod {} { :exists v } -C instproc existsViaResolver {} { +C instproc existsViaResolver {} { info exists :v } C instproc notExistsViaInstvar {} { @@ -85,12 +85,12 @@ my exists xxx } -C instproc existsAndReturnValue1 {} { +C instproc existsAndReturnValue1 {} { if {[my exists v]} { my set v } } -C instproc existsAndReturnValue3 {} { +C instproc existsAndReturnValue3 {} { if {[my exists v]} { set x [my set v] } @@ -273,13 +273,13 @@ nx::test new -count 1 -cmd {llength [Object info instances]} -expected $ocount nx::test new -cmd {Object new -volatile} -expected ::nsf::__\#F9 -count 2000 \ - -post {foreach o [Object info instances ::nsf::__*] {$o destroy}} + -post {foreach o [Object info instances ::nsf::__*] {$o destroy}} # should be still the same number as above nx::test new -count 1 -cmd {llength [Object info instances]} -expected $ocount nx::test new -cmd {Object new} -expected ::nsf::__\#lQ -count 2000 \ - -post {foreach o [Object info instances ::nsf::__*] {$o destroy}} + -post {foreach o [Object info instances ::nsf::__*] {$o destroy}} # should be still the same number as above nx::test new -count 1 -cmd {llength [Object info instances]} -expected $ocount @@ -530,28 +530,28 @@ -cmd {o x self} -expected ::n::x -count $cnt \ -post {o destroy} nx::test new -msg {call obj with namespace via instforward and mixinclass} \ - -pre {Object n; Object n::x; Class M -instforward ::n::x; + -pre {Object n; Object n::x; Class M -instforward ::n::x; Class C -instmixin M; C create o } \ -cmd {o x self} -expected ::n::x -count $cnt \ -post {o destroy} nx::test new -msg {call obj with namespace via instforward and next from proc} \ -pre { - Object n; Object n::x; - Class C -instforward ::n::x; + Object n; Object n::x; + Class C -instforward ::n::x; C create o -proc x args {next} } \ -cmd {o x self} -expected ::n::x -count $cnt \ -post {o destroy} nx::test new -msg {call obj with namespace via instforward and next from instproc} \ -pre { - Object n; Object n::x; - Class C -instforward ::n::x; + Object n; Object n::x; + Class C -instforward ::n::x; Class D -superclass C -instproc x args {next}; D create o } \ -cmd {o x self} -expected ::n::x -count $cnt \ -post {o destroy} nx::test new -msg {call obj with namespace via mixin and instforward and next} \ - -pre {Object n; Object n::x; - Class M -instforward ::n::x; + -pre {Object n; Object n::x; + Class M -instforward ::n::x; Class N -superclass M -instproc x args {next}; Class C -instmixin N; C create o} \ -cmd {o x self} -expected ::n::x -count $cnt \ @@ -597,6 +597,27 @@ -cmd {foo; ::B info instances} -expected {} -count 2 \ -post {B destroy; A destroy; M destroy; MC destroy; rename foo ""} +# +# Check whether the setting of the autoname object property is already +# visible immediately after the object creation (e.g. in an overloaded +# "create" method. This is e.g. important for ttrace, catching object +# creates via instmixin. +# +nx::test new -msg {autonamed property + overloaded create} \ + -pre { + set ::_ {} + ::xotcl::Class create ::xotcl::_creator -instproc create {args} { + set r [next] + lappend ::_ [nsf::object::property $r autonamed] + return $r + } + ::xotcl::Class instmixin ::xotcl::_creator + } \ + -cmd {::xotcl::Object new; ::xotcl::Object a; ::xotcl::Object create a; ::xotcl::Object new; set ::_} \ + -expected {1 0 0 1} -count 1 \ + -post {::xotcl::Class instmixin ""; ::xotcl::_creator destroy; a destroy} + + nx::test run #