Index: generic/xotcl.c =================================================================== diff -u -r77531e5530970d3f46f6b7d9785d02e32df7ae96 -re2bce71b86e234dd095039949f8e7dbbb4a4620e --- generic/xotcl.c (.../xotcl.c) (revision 77531e5530970d3f46f6b7d9785d02e32df7ae96) +++ generic/xotcl.c (.../xotcl.c) (revision e2bce71b86e234dd095039949f8e7dbbb4a4620e) @@ -246,7 +246,7 @@ /* objv can be separately extended */ if (pcPtr->objv != &pcPtr->objv_static[1]) { - /*fprintf(stderr, "release free %p %p\n", pcPtr->full_objv, pcPtr->clientData);*/ + /*fprintf(stderr, "parseContextRelease free %p %p\n", pcPtr->full_objv, pcPtr->clientData);*/ ckfree((char *)pcPtr->full_objv); } /* if the parameter definition was extended, both clientData and flags are extended */ @@ -5536,6 +5536,8 @@ fprintf(stderr, "\tcmd=%s\n", Tcl_GetCommandName(interp, cmdPtr)); #endif rst->deallocCalled = 0; + /*fprintf(stderr, "CmdDispatch obj %p %p %s\n", obj, methodName, methodName);*/ + #if !defined(NRE) result = (*Tcl_Command_objProc(cmdPtr))(cp, interp, objc, objv); #else @@ -5551,7 +5553,7 @@ } #endif - /*fprintf(stderr, "CmdDispatch obj %p %s deallocCalled %d\n", + /*fprintf(stderr, "CmdDispatch obj %p %p deallocCalled %d\n", obj, methodName, rst->deallocCalled);*/ /* The order of the if-condition below is important, since obj might be already @@ -5696,6 +5698,7 @@ Tcl_Obj *cmdName = obj->cmdName, *methodObj, *cmdObj; assert(objc>0); + if (flags & XOTCL_CM_NO_SHIFT) { shift = 0; cmdObj = obj->cmdName; @@ -5720,7 +5723,10 @@ #endif objflags = obj->flags; /* avoid stalling */ + + /* make sure, cmdName and obj survive this method until the end */ INCR_REF_COUNT(cmdName); + obj->refCount ++; if (!(objflags & XOTCL_FILTER_ORDER_VALID)) { FilterComputeDefined(interp, obj); @@ -5855,9 +5861,10 @@ Tcl_Obj *unknownObj = XOTclGlobalObjects[XOTE_UNKNOWN]; if (/*XOTclObjectIsClass(obj) &&*/ (flags & XOTCL_CM_NO_UNKNOWN)) { - return XOTclVarErrMsg(interp, objectName(obj), - ": unable to dispatch method '", - methodName, "'", (char *) NULL); + result = XOTclVarErrMsg(interp, objectName(obj), + ": unable to dispatch method '", + methodName, "'", (char *) NULL); + goto exit_dispatch; } else if (methodObj != unknownObj) { /* * back off and try unknown; @@ -5882,9 +5889,10 @@ FREE_ON_STACK(tov); } else { /* unknown failed */ - return XOTclVarErrMsg(interp, objectName(obj), - ": unable to dispatch method '", - ObjStr(objv[shift+1]), "'", (char *) NULL); + result = XOTclVarErrMsg(interp, objectName(obj), + ": unable to dispatch method '", + ObjStr(objv[shift+1]), "'", (char *) NULL); + goto exit_dispatch; } } @@ -5898,13 +5906,13 @@ printExit(interp, "DISPATCH", objc, objv, result); #endif - /*!(obj->flags & XOTCL_DESTROY_CALLED)) */ if (mixinStackPushed && obj->mixinStack) MixinStackPop(obj); - + if (filterStackPushed && obj->filterStack) FilterStackPop(obj); - + + XOTclCleanupObject(obj); DECR_REF_COUNT(cmdName); /* must be after last dereferencing of obj */ return result; } Index: generic/xotclStack85.c =================================================================== diff -u -rf3cbadd6d76459cc00032877fa905bb618e9f780 -re2bce71b86e234dd095039949f8e7dbbb4a4620e --- generic/xotclStack85.c (.../xotclStack85.c) (revision f3cbadd6d76459cc00032877fa905bb618e9f780) +++ generic/xotclStack85.c (.../xotclStack85.c) (revision e2bce71b86e234dd095039949f8e7dbbb4a4620e) @@ -355,7 +355,7 @@ } #if 1 if (csc->cl) { - Namespace *nsPtr = ((Command *)(csc->cmdPtr))->nsPtr; + Namespace *nsPtr = csc->cmdPtr ? ((Command *)(csc->cmdPtr))->nsPtr : NULL; obj = &csc->cl->object; obj->activationCount --; @@ -373,18 +373,20 @@ CallStackDoDestroy(interp, obj); } - nsPtr->refCount--; - /*fprintf(stderr, "CallStackPop parent %s activationCount %d flags %.4x refCount %d\n", - nsPtr->fullName, nsPtr->activationCount, nsPtr->flags, nsPtr->refCount);*/ - - if ((nsPtr->refCount == 0) && (nsPtr->flags & NS_DEAD)) { - /* the namspace refcound has reached 0, we have to free - it. unfortunately, NamespaceFree() is not exported */ - fprintf(stderr, "HAVE TO FREE %p\n",nsPtr); - /*NamespaceFree(nsPtr);*/ - ckfree(nsPtr->fullName); - ckfree(nsPtr->name); - ckfree((char*)nsPtr); + if (nsPtr) { + nsPtr->refCount--; + /*fprintf(stderr, "CallStackPop parent %s activationCount %d flags %.4x refCount %d\n", + nsPtr->fullName, nsPtr->activationCount, nsPtr->flags, nsPtr->refCount);*/ + + if ((nsPtr->refCount == 0) && (nsPtr->flags & NS_DEAD)) { + /* the namspace refcound has reached 0, we have to free + it. unfortunately, NamespaceFree() is not exported */ + fprintf(stderr, "HAVE TO FREE %p\n",nsPtr); + /*NamespaceFree(nsPtr);*/ + ckfree(nsPtr->fullName); + ckfree(nsPtr->name); + ckfree((char*)nsPtr); + } } /*fprintf(stderr, "CallStackPop done\n");*/ Index: tests/testx.xotcl =================================================================== diff -u -rd56d2a8ee3f246c9891783abb09bd820dbc508e4 -re2bce71b86e234dd095039949f8e7dbbb4a4620e --- tests/testx.xotcl (.../testx.xotcl) (revision d56d2a8ee3f246c9891783abb09bd820dbc508e4) +++ tests/testx.xotcl (.../testx.xotcl) (revision e2bce71b86e234dd095039949f8e7dbbb4a4620e) @@ -2594,8 +2594,12 @@ # class hierarchy copy Class O X copy O::X + ::errorCheck "[::xotcl::is O::X object]" 1 "O::X is an object" + ::errorCheck "[::xotcl::is O::X::Y object]" 1 "O::X::Y is an object" + ::errorCheck "[::xotcl::is O::X::Y::Z object]" 1 "O::X::Y::Z is an object" O::X x1; O::X::Y y1; O::X::Y::Z z1 + ::errorCheck "[x1 q 1 2 3]--[y1 q 1 2 3]--[z1 q 1 2 3]" \ "::x1--::O::X--q------::y1--::O::X::Y--q------::z1--::O::X::Y::Z--q----"\ "class hierarchy copy" @@ -2614,13 +2618,23 @@ x copy x::a x copy x::a::z - + ::errorCheck "[::x::a::tclProc]--[::x::a::z::a::tclProc]" \ "tclProc--tclProc"\ "object hierarchy copy" +#todo REMOVE ME + Class DestroyWatch + DestroyWatch instproc destroy args { + puts stderr "[self] destroy" + next + } + ::xotcl::Class instmixin DestroyWatch +### until here + Class O O x + x invar {{7 > 5} { #a comment }}