Index: generic/nsf.c =================================================================== diff -u -r3cc93845be8bba214f09b9c6ec29e48de99175ff -r7d197d8e8a9ad6229c2aa8a11111118f5cab26b6 --- generic/nsf.c (.../nsf.c) (revision 3cc93845be8bba214f09b9c6ec29e48de99175ff) +++ generic/nsf.c (.../nsf.c) (revision 7d197d8e8a9ad6229c2aa8a11111118f5cab26b6) @@ -17629,10 +17629,11 @@ Tcl_ObjCmdProc *objProc, *newObjProc = NULL; Tcl_CmdDeleteProc *deleteProc = NULL; AliasCmdClientData *tcd = NULL; /* make compiler happy */ - Tcl_Command cmd, newCmd = NULL; + Tcl_Command cmd, oldCmd, newCmd = NULL; Tcl_Namespace *nsPtr; int flags, result; NsfClass *cl = (withPer_object || ! NsfObjectIsClass(object)) ? NULL : (NsfClass *)object; + NsfObject *oldTargetObject, *newTargetObject; cmd = Tcl_GetCommandFromObj(interp, cmdName); if (cmd == NULL) { @@ -17665,26 +17666,50 @@ newObjProc = NsfObjscopedMethod; } - if (CmdIsNsfObject(cmd)) { - Tcl_Command oldCmd; - Tcl_Namespace *lookupNsPtr; - NsfObject *oldTargetObject, *newTargetObject; - - newTargetObject = (NsfObject *)Tcl_Command_objClientData(cmd); - assert(newTargetObject); + /* + * We need to perform a defensive lookup of a previously defined + * object-alias under the given methodName. + */ + nsPtr = cl ? cl->nsPtr : object->nsPtr; + oldCmd = nsPtr ? FindMethod(nsPtr, methodName) : NULL; + newTargetObject = NsfGetObjectFromCmdPtr(cmd); + if (oldCmd != NULL) { + oldTargetObject = NsfGetObjectFromCmdPtr(oldCmd); + /*fprintf(stderr, "oldTargetObject %p flags %.6x newTargetObject %p\n", + oldTargetObject, oldTargetObject ? oldTargetObject->flags : 0, newTargetObject);*/ /* - * We need to perform a defensive lookup of a previously defined - * object-alias under the given methodName. + * The old target object might be already stale (i.e. destroyed, but kept + * alive by the reference counter). In this case, we have to decrement the + * object reference counter and release this object here. + * + * nx::Object create ::x + * nx::Object create ::o {:alias X ::x} + * + * Destroy the object and create it new + * + * x destroy + * nx::Object create ::x + * + * The recreation of the alias has to decrement the reference counter on + * the old object ::x + * + * o alias X ::x + * + * The test below is exactly the same as for invokes on destroyed aliased + * objects in ObjectDispatchCsc(). */ - lookupNsPtr = cl ? cl->nsPtr : object->nsPtr; - oldCmd = lookupNsPtr ? FindMethod(lookupNsPtr, methodName) : NULL; - if (oldCmd != NULL) { - oldTargetObject = NsfGetObjectFromCmdPtr(oldCmd); - } else { - oldTargetObject = NULL; + if (oldTargetObject != NULL && oldTargetObject != newTargetObject) { + assert(oldTargetObject->refCount > 0); + /*fprintf(stderr, "--- releasing old target object %p refCount %d\n", + oldTargetObject, oldTargetObject->refCount);*/ + AliasDeleteObjectReference(interp, oldCmd); } + } else { + oldTargetObject = NULL; + } + if (newTargetObject) { /* * Bump the object reference counter when the new target object is * different from the old one. Note, that the old target object might be @@ -17707,34 +17732,6 @@ /*fprintf(stderr, "--- don't incr refcount on obj %p %s\n", newTargetObject, ObjectName(newTargetObject));*/ } - - /* - * The old target object might be already stale (i.e. destroyed, but kept - * alive by the reference counter). In this case, we have to decrement the - * object reference counter and release this object here. - * - * nx::Object create ::x - * nx::Object create ::o {:alias X ::x} - * - * Destroy the object and create it new - * - * x destroy - * nx::Object create ::x - * - * The recreation of the alias has to decrement the reference counter on - * the old object ::x - * - * o alias X ::x - * - * The test below is exactly the same as for invokes on destroyed aliased - * objects in ObjectDispatchCsc(). - */ - if (oldTargetObject != NULL && oldTargetObject->flags & NSF_DELETED) { - /*fprintf(stderr, "--- releasing destroyed object %p refCount %d\n", - oldTargetObject, oldTargetObject->refCount);*/ - assert(oldTargetObject->refCount > 0); - AliasDeleteObjectReference(interp, oldCmd); - } } else if (CmdIsProc(cmd)) { /*