Index: generic/xotcl.c =================================================================== diff -u -rd7b2898d74c2ff2158ae2cc4ca3f7a6d87533d45 -r9f8816ff85210d4b5a1dbc235f8518a0d3312909 --- generic/xotcl.c (.../xotcl.c) (revision d7b2898d74c2ff2158ae2cc4ca3f7a6d87533d45) +++ generic/xotcl.c (.../xotcl.c) (revision 9f8816ff85210d4b5a1dbc235f8518a0d3312909) @@ -204,8 +204,10 @@ static int isSubType(XOTclClass *subcl, XOTclClass *cl); static XOTclClass *DefaultSuperClass(Tcl_Interp *interp, XOTclClass *cl, XOTclClass *mcl, int isMeta); +XOTCLINLINE static void CscInit(XOTclCallStackContent *cscPtr, XOTclObject *object, XOTclClass *cl, + Tcl_Command cmd, int frameType); +XOTCLINLINE static void CscFinish(Tcl_Interp *interp, XOTclCallStackContent *cscPtr); static XOTclCallStackContent *CallStackGetFrame(Tcl_Interp *interp, Tcl_CallFrame **framePtrPtr); -XOTCLINLINE static void CallStackPop(Tcl_Interp *interp, XOTclCallStackContent *cscPtr); XOTCLINLINE static void CallStackDoDestroy(Tcl_Interp *interp, XOTclObject *object); static int XOTclCInvalidateObjectParameterMethod(Tcl_Interp *interp, XOTclClass *cl); @@ -2518,7 +2520,7 @@ } /* If the object is not referenced on the callstack anymore - we have to destroy it directly, because CallStackPop won't + we have to destroy it directly, because CscFinish won't find the object destroy */ if (object->activationCount == 0) { CallStackDoDestroy(interp, object); @@ -5348,7 +5350,7 @@ # if defined(TCL_STACK_ALLOC_TRACE) fprintf(stderr, "---- FinalizeProcMethod calls pop, csc free %p method %s\n", cscPtr, methodName); # endif - CallStackPop(interp, cscPtr); + CscFinish(interp, cscPtr); TclStackFree(interp, cscPtr); return result; @@ -5420,7 +5422,7 @@ # if defined(TCL_STACK_ALLOC_TRACE) fprintf(stderr, "---- GuardFailed calls pop, cscPtr free %p method %s\n", cscPtr, methodName); # endif - CallStackPop(interp, cscPtr); + CscFinish(interp, cscPtr); TclStackFree(interp, cscPtr); /* todo check mixin guards for same case? */ #endif @@ -5490,7 +5492,7 @@ # if defined(TCL_STACK_ALLOC_TRACE) fprintf(stderr, "---- ProcPrep fails and calls pop, cscPtr free %p method %s\n", cscPtr, methodName); # endif - CallStackPop(interp, cscPtr); + CscFinish(interp, cscPtr); TclStackFree(interp, cscPtr); #endif } @@ -5663,13 +5665,13 @@ #else cscPtr = &csc; #endif - CallStackPush(cscPtr, object, cl, cmd, frameType); + CscInit(cscPtr, object, cl, cmd, frameType); result = ProcMethodDispatch(cp, interp, objc, objv, methodName, object, cl, cmd, cscPtr); #if defined(NRE) - /* CallStackPop() is performed by the callbacks or in error case base ProcMethodDispatch */ + /* CscFinish() is performed by the callbacks or in error case base ProcMethodDispatch */ /*fprintf(stderr, "no pop for %s\n", methodName);*/ #else - CallStackPop(interp, cscPtr); + CscFinish(interp, cscPtr); #endif return result; @@ -5707,7 +5709,7 @@ cp = clientData; assert((CmdIsProc(cmd) == 0)); } - CallStackPush(cscPtr, object, cl, cmd, frameType); + CscInit(cscPtr, object, cl, cmd, frameType); } else { /* @@ -5721,7 +5723,7 @@ result = CmdMethodDispatch(cp, interp, objc, objv, methodName, object, cmd, cscPtr); /* make sure, that csc is still in the scope; therefore, csc is currently on the top scope of this function */ - CallStackPop(interp, cscPtr); + CscFinish(interp, cscPtr); return result; } @@ -12430,7 +12432,7 @@ */ Tcl_Interp_varFramePtr(interp) = varFramePtr->callerPtr; - CallStackPush(cscPtr, object, NULL /*cl*/, NULL/*cmd*/, XOTCL_CSC_TYPE_PLAIN); + CscInit(cscPtr, object, NULL /*cl*/, NULL/*cmd*/, XOTCL_CSC_TYPE_PLAIN); XOTcl_PushFrameCsc(interp, cscPtr, framePtr2); if (paramPtr->flags & XOTCL_ARG_INITCMD) { @@ -12456,7 +12458,7 @@ varFramePtr to the previous value. */ XOTcl_PopFrameCsc(interp, framePtr2); - CallStackPop(interp, cscPtr); + CscFinish(interp, cscPtr); Tcl_Interp_varFramePtr(interp) = varFramePtr; /*fprintf(stderr, "XOTclOConfigureMethod_ attribute %s evaluated %s => (%d)\n", Index: generic/xotclStack85.c =================================================================== diff -u -rd7b2898d74c2ff2158ae2cc4ca3f7a6d87533d45 -r9f8816ff85210d4b5a1dbc235f8518a0d3312909 --- generic/xotclStack85.c (.../xotclStack85.c) (revision d7b2898d74c2ff2158ae2cc4ca3f7a6d87533d45) +++ generic/xotclStack85.c (.../xotclStack85.c) (revision 9f8816ff85210d4b5a1dbc235f8518a0d3312909) @@ -1,5 +1,6 @@ static TclVarHashTable *VarHashTableCreate(); +static void XOTclCleanupObject(XOTclObject *object); void tcl85showStack(Tcl_Interp *interp) { Tcl_CallFrame *framePtr; @@ -342,7 +343,6 @@ return NULL; } -static void XOTclCleanupObject(XOTclObject *object); /* * Pop any callstack entry that is still alive (e.g. * if "exit" is called and we were jumping out of the @@ -364,7 +364,7 @@ if (frameFlags & (FRAME_IS_XOTCL_METHOD|FRAME_IS_XOTCL_CMETHOD)) { /* free the call stack content; we need this just for decr activation count */ XOTclCallStackContent *cscPtr = ((XOTclCallStackContent *)Tcl_CallFrame_clientData(framePtr)); - CallStackPop(interp, cscPtr); + CscFinish(interp, cscPtr); } else if (frameFlags & FRAME_IS_XOTCL_OBJECT) { Tcl_CallFrame_varTablePtr(framePtr) = NULL; } @@ -374,10 +374,35 @@ } } +/* + *---------------------------------------------------------------------- + * CscInit -- + * + * Initialize call stack content and track activation counts + * of involved objects and classes + * + * Results: + * None. + * + * Side effects: + * Initialized Csc, updated activation counts + * + *---------------------------------------------------------------------- + */ + XOTCLINLINE static void -CallStackPush(XOTclCallStackContent *cscPtr, XOTclObject *object, XOTclClass *cl, Tcl_Command cmd, int frameType) { +CscInit(XOTclCallStackContent *cscPtr, XOTclObject *object, XOTclClass *cl, Tcl_Command cmd, int frameType) { + + assert(cscPtr); + + /* + * track object activations + */ object->activationCount ++; -#if 1 + + /* + * track class activations + */ if (cl) { Namespace *nsPtr = ((Command *)cmd)->nsPtr; cl->object.activationCount ++; @@ -391,7 +416,7 @@ during the invocation */ nsPtr->refCount ++; } -#endif + /* fprintf(stderr, "incr activationCount for %s to %d\n", objectName(object), object->activationCount); */ cscPtr->self = object; cscPtr->cl = cl; @@ -411,8 +436,23 @@ #endif } +/* + *---------------------------------------------------------------------- + * CscFinish -- + * + * Counterpart of CscInit(). Decreament activation counts + * and delete objects/classes if necessary. + * + * Results: + * None. + * + * Side effects: + * potentially deletes objects, classes or namespaces. + * + *---------------------------------------------------------------------- + */ XOTCLINLINE static void -CallStackPop(Tcl_Interp *interp, XOTclCallStackContent *cscPtr) { +CscFinish(Tcl_Interp *interp, XOTclCallStackContent *cscPtr) { XOTclObject *object = cscPtr->self; int allowDestroy = RUNTIME_STATE(interp)->exitHandlerDestroyRound != XOTCL_EXITHANDLER_ON_SOFT_DESTROY; @@ -446,11 +486,11 @@ object = &cscPtr->cl->object; object->activationCount --; - /* fprintf(stderr, "CallStackPop cl=%p %s (%d) flags %.6x cl ns=%p cmd %p cmd ns %p\n", + /* fprintf(stderr, "CscFinish cl=%p %s (%d) flags %.6x cl ns=%p cmd %p cmd ns %p\n", object, objectName(object), object->activationCount, object->flags, cscPtr->cl->nsPtr, cscPtr->cmdPtr, ((Command *)cscPtr->cmdPtr)->nsPtr); */ - /*fprintf(stderr, "CallStackPop check ac %d flags %.6x\n", + /*fprintf(stderr, "CscFinish check ac %d flags %.6x\n", object->activationCount, object->flags & XOTCL_DESTROY_CALLED);*/ if (object->activationCount < 1 && object->flags & XOTCL_DESTROY_CALLED && allowDestroy) { @@ -464,7 +504,7 @@ if (nsPtr) { nsPtr->refCount--; - /*fprintf(stderr, "CallStackPop parent %s activationCount %d flags %.4x refCount %d\n", + /*fprintf(stderr, "CscFinish 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)) { @@ -478,7 +518,7 @@ } } - /*fprintf(stderr, "CallStackPop done\n");*/ + /*fprintf(stderr, "CscFinish done\n");*/ } }