Index: TODO =================================================================== diff -u -r88ce4132aeb39289918426aa2c285c354a102a1e -r1e20304eae1c4ca141334902bfef6a1789ad0c41 --- TODO (.../TODO) (revision 88ce4132aeb39289918426aa2c285c354a102a1e) +++ TODO (.../TODO) (revision 1e20304eae1c4ca141334902bfef6a1789ad0c41) @@ -1314,6 +1314,11 @@ - added "info callable slots" with functionality of "info slotobjects" - removed "info slotobjects" +- handle aliases to (sub)ensemble objects during final + cleanup to improve sharing of logic. +- share definition of "info callable" and "info has" ensemble + between object info and class info + TODO: - check equivalence of the following two commands Index: generic/nsf.c =================================================================== diff -u -r88ce4132aeb39289918426aa2c285c354a102a1e -r1e20304eae1c4ca141334902bfef6a1789ad0c41 --- generic/nsf.c (.../nsf.c) (revision 88ce4132aeb39289918426aa2c285c354a102a1e) +++ generic/nsf.c (.../nsf.c) (revision 1e20304eae1c4ca141334902bfef6a1789ad0c41) @@ -2576,8 +2576,9 @@ if (object->flags & NSF_DURING_DELETE) { return; } - /*fprintf(stderr, "CallStackDoDestroy %p flags %.6x activation %d cmd %p \n", - object, object->flags, object->activationCount, object->id);*/ + /*fprintf(stderr, "CallStackDoDestroy %p flags %.6x activation %d rc %d cmd %p \n", + object, object->flags, object->activationCount, object->refCount, object->id);*/ + object->flags |= NSF_DURING_DELETE; oid = object->id; /* oid might be freed already, we can't even use (((Command*)oid)->flags & CMD_IS_DELETED) */ @@ -2596,7 +2597,7 @@ object, object->refCount, object->teardown);*/ PrimitiveDestroy((ClientData) object); -; + if (!(object->flags & NSF_TCL_DELETE) /*&& !(object->flags & NSF_CMD_NOT_FOUND)*/) { Tcl_Obj *savedObjResult = Tcl_GetObjResult(interp); INCR_REF_COUNT(savedObjResult); @@ -14971,8 +14972,8 @@ static void FinalObjectDeletion(Tcl_Interp *interp, NsfObject *object) { /* If a call to exit happens from a higher stack frame, the - obejct refcount might not be decremented corectly. If we are - in the phyical destroy round, we can set the counter to an + object refcount might not be decremented correctly. If we are + in the physical destroy round, we can set the counter to an appropriate value to ensure deletion. todo: remove debug line @@ -15019,9 +15020,28 @@ for (hPtr2 = Tcl_FirstHashEntry(Tcl_Namespace_cmdTable(object->nsPtr), &hSrch2); hPtr2; hPtr2 = Tcl_NextHashEntry(&hSrch2)) { Tcl_Command cmd = Tcl_GetHashValue(hPtr2); - if (cmd && Tcl_Command_objProc(cmd) != NsfObjDispatch) { - Tcl_DeleteCommandFromToken(interp, cmd); - deleted ++; + if (cmd) { + if (Tcl_Command_objProc(cmd) == NsfObjDispatch) { + NsfObject *referencedObject = NsfGetObjectFromCmdPtr(cmd); + if (referencedObject->refCount < 2) { + /* never delete the final "real" object, just references (aliases) zzzzz */ + continue; + } + fprintf(stderr, "referencedObject '%s' refCount %d cmd %p id %p\n", + objectName(referencedObject),referencedObject->refCount, + cmd, referencedObject->id); + if (cmd != referencedObject->id) { + /* + * cmd is an aliased object, reduce the refcount + */ + NsfCleanupObject(referencedObject); + Nsf_DeleteCommandFromToken(interp, cmd); + fprintf(stderr, "remove alias\n"); + } + continue; + } + Tcl_DeleteCommandFromToken(interp, cmd); + deleted ++; } } } @@ -15040,6 +15060,7 @@ } } } + } /*fprintf(stderr, "deleted %d cmds\n", deleted);*/ Index: library/nx/nx.tcl =================================================================== diff -u -r88ce4132aeb39289918426aa2c285c354a102a1e -r1e20304eae1c4ca141334902bfef6a1789ad0c41 --- library/nx/nx.tcl (.../nx.tcl) (revision 88ce4132aeb39289918426aa2c285c354a102a1e) +++ library/nx/nx.tcl (.../nx.tcl) (revision 1e20304eae1c4ca141334902bfef6a1789ad0c41) @@ -498,21 +498,22 @@ } Class eval { - :alias "info callable filter" ::nsf::cmd::ObjectInfo::callablefilter - :alias "info callable method" ::nsf::cmd::ObjectInfo::callablemethod - :alias "info callable methods" ::nsf::cmd::ObjectInfo::callablemethods - :method "info callable slots" {} { - ::nsf::dispatch [::nsf::current object] \ - ::nsf::cmd::ObjectInfo::callableslots -type ::nx::Slot - } - #:alias "info callable" ::nx::Object::slot::__info::callable - + #:alias "info callable filter" ::nsf::cmd::ObjectInfo::callablefilter + #:alias "info callable method" ::nsf::cmd::ObjectInfo::callablemethod + #:alias "info callable methods" ::nsf::cmd::ObjectInfo::callablemethods + #:method "info callable slots" {} { + # ::nsf::dispatch [::nsf::current object] \ +# ::nsf::cmd::ObjectInfo::callableslots -type ::nx::Slot + #} + :alias "info callable" ::nx::Object::slot::__info::callable :alias "info filter guard" ::nsf::cmd::ClassInfo::filterguard - :alias "info has mixin" ::nsf::cmd::ObjectInfo::hasmixin - :alias "info has namespace" ::nsf::cmd::ObjectInfo::hasnamespace - :alias "info has type" ::nsf::cmd::ObjectInfo::hastype :alias "info filter methods" ::nsf::cmd::ClassInfo::filtermethods :alias "info forward" ::nsf::cmd::ClassInfo::forward + # todo: maybe share "has"? + #:alias "info has mixin" ::nsf::cmd::ObjectInfo::hasmixin + #:alias "info has namespace" ::nsf::cmd::ObjectInfo::hasnamespace + #:alias "info has type" ::nsf::cmd::ObjectInfo::hastype + :alias "info has" ::nx::Object::slot::__info::has :alias "info heritage" ::nsf::cmd::ClassInfo::heritage :alias "info instances" ::nsf::cmd::ClassInfo::instances :alias "info methods" ::nsf::cmd::ClassInfo::methods