Index: TODO =================================================================== diff -u -r3cb6a6a8f1e33e63abeec25b3c36231702af6fe2 -r9d9ae3c8df6dacbb526362d371ad9b8fa2523673 --- TODO (.../TODO) (revision 3cb6a6a8f1e33e63abeec25b3c36231702af6fe2) +++ TODO (.../TODO) (revision 9d9ae3c8df6dacbb526362d371ad9b8fa2523673) @@ -1024,6 +1024,10 @@ - implemented parameter option "allowempty" - extended regression test +- commented out XOTCL_CMD_NOT_FOUND, since it seems to be obsolete by now +- extended regression test to avoid CallDirectly on dealloc (the last place, + where XOTCL_CMD_NOT_FOUND was used) + TODO: - nameing * self/current: Index: generic/xotcl.c =================================================================== diff -u -r3cb6a6a8f1e33e63abeec25b3c36231702af6fe2 -r9d9ae3c8df6dacbb526362d371ad9b8fa2523673 --- generic/xotcl.c (.../xotcl.c) (revision 3cb6a6a8f1e33e63abeec25b3c36231702af6fe2) +++ generic/xotcl.c (.../xotcl.c) (revision 9d9ae3c8df6dacbb526362d371ad9b8fa2523673) @@ -2611,7 +2611,8 @@ object, object->refCount, object->teardown);*/ PrimitiveDestroy((ClientData) object); - if (!(object->flags & XOTCL_TCL_DELETE) && !(object->flags & XOTCL_CMD_NOT_FOUND)) { +; + if (!(object->flags & XOTCL_TCL_DELETE) /*&& !(object->flags & XOTCL_CMD_NOT_FOUND)*/) { Tcl_Obj *savedObjResult = Tcl_GetObjResult(interp); INCR_REF_COUNT(savedObjResult); /*fprintf(stderr, " before DeleteCommandFromToken %p object flags %.6x\n", oid, object->flags);*/ @@ -12811,14 +12812,17 @@ if (CallDirectly(interp, &object->cl->object, XO_c_dealloc_idx, &methodObj)) { result = DoDealloc(interp, object); } else { + /*fprintf(stderr, "call dealloc\n");*/ result = XOTclCallMethodWithArgs((ClientData)object->cl, interp, methodObj, object->cmdName, 1, NULL, 0); if (result != TCL_OK) { - object->flags |= XOTCL_CMD_NOT_FOUND; - /*fprintf(stderr, "*** dealloc failed for %p %s flags %.6x, retry\n", object, objectName(object), object->flags);*/ - /* In case, the call of the dealloc method has failed above (e.g. NS_DYING), + /* + * In case, the call of the dealloc method has failed above (e.g. NS_DYING), * we have to call dealloc manually, otherwise we have a memory leak */ + /*object->flags |= XOTCL_CMD_NOT_FOUND;*/ + /*fprintf(stderr, "*** dealloc failed for %p %s flags %.6x, retry\n", + object, objectName(object), object->flags);*/ result = DoDealloc(interp, object); } } Index: generic/xotclInt.h =================================================================== diff -u -r3cb6a6a8f1e33e63abeec25b3c36231702af6fe2 -r9d9ae3c8df6dacbb526362d371ad9b8fa2523673 --- generic/xotclInt.h (.../xotclInt.h) (revision 3cb6a6a8f1e33e63abeec25b3c36231702af6fe2) +++ generic/xotclInt.h (.../xotclInt.h) (revision 9d9ae3c8df6dacbb526362d371ad9b8fa2523673) @@ -354,7 +354,7 @@ #define XOTCL_IS_ROOT_CLASS 0x0100 #define XOTCL_TCL_DELETE 0x0200 /* DESTROYED set, when object is physically destroyed with PrimitiveODestroy */ -#define XOTCL_CMD_NOT_FOUND 0x1000 +/*#define XOTCL_CMD_NOT_FOUND 0x1000*/ #define XOTCL_DURING_DELETE 0x2000 #define XOTCL_DELETED 0x4000 #define XOTCL_RECREATE 0x8000 Index: tests/destroytest.tcl =================================================================== diff -u -rf3cb5afe6aa1b6761b4a9909058f64ff7d64ab92 -r9d9ae3c8df6dacbb526362d371ad9b8fa2523673 --- tests/destroytest.tcl (.../destroytest.tcl) (revision f3cb5afe6aa1b6761b4a9909058f64ff7d64ab92) +++ tests/destroytest.tcl (.../destroytest.tcl) (revision 9d9ae3c8df6dacbb526362d371ad9b8fa2523673) @@ -5,6 +5,7 @@ ::nsf::alias ::nx::Object set -objscope ::set + Class create O -superclass Object { :method init {} { set ::ObjectDestroy 0 @@ -569,6 +570,42 @@ ::module destroy } +puts stderr XXXXXXXXXXXXXX +# to avoid CallDirectly, we could activate this line +::nx::Class create M {:method dealloc args {next}} +Test case delete-parent-namespace-dealloc +namespace eval ::test { + Class create C -superclass O + C method destroy {} {incr ::firstDestroy; puts stderr " *** [current] destroy"; next} + C method foo {} { + puts stderr "==== $::case [current]" + namespace delete ::test + puts stderr "AAAA [current] exists [::nsf::objectproperty [current] object]" + :set x 1 + # + # If the following line is commented in, the namespace is deleted + # here. Is there a bug with nsPtr->activationCount + # + #? "[current] set x" 1 "$::case can still access [current]" + puts stderr "BBB" + puts stderr "???? [current] exists [::nsf::objectproperty [current] object]" + ? "::nsf::objectproperty [current] object" 0 ;# WHY? + puts stderr "???? [current] exists [::nsf::objectproperty [current] object]" + ? "set ::firstDestroy" 0 "firstDestroy called" + ? "set ::ObjectDestroy" 0 "$::case destroy not yet called" + } +} +test::C create test::c1 +test::c1 foo +puts stderr ======[::nsf::objectproperty test::c1 object] +? {::nsf::objectproperty test::c1 object} 0 "object still exists after proc" +? "set ::firstDestroy" 1 "firstDestroy called" +? "set ::ObjectDestroy" 1 "destroy was called when poping stack frame" +? {::nsf::objectproperty ::test::C object} 0 "class still exists after proc" +? {namespace exists ::test::C} 0 "namespace ::test::C still exists after proc" +? {namespace exists ::test} 1 "parent ::test namespace still exists after proc" +? {namespace exists ::xotcl::classes::test::C} 0 "namespace ::xotcl::classes::test::C still exists after proc" + puts stderr "==== EXIT ====" exit