Index: generic/nsf.c =================================================================== diff -u -rf69e0909fcb180e1cbcdd316f0a20de1b254af3d -rfbf70aa67bec4deec1078074787aafb8b66b2dde --- generic/nsf.c (.../nsf.c) (revision f69e0909fcb180e1cbcdd316f0a20de1b254af3d) +++ generic/nsf.c (.../nsf.c) (revision fbf70aa67bec4deec1078074787aafb8b66b2dde) @@ -218,7 +218,7 @@ static void GetAllInstances(Tcl_Interp *interp, Tcl_HashTable *destTablePtr, NsfClass *startClass); NSF_INLINE static Tcl_Command FindMethod(Tcl_Namespace *nsPtr, CONST char *methodName); -/* prototypes for namespace specific calls*/ +/* prototypes for namespace specific calls */ static Tcl_Obj *NameInNamespaceObj(Tcl_Interp *interp, CONST char *name, Tcl_Namespace *ns); static Tcl_Namespace *CallingNameSpace(Tcl_Interp *interp); NSF_INLINE static Tcl_Command NSFindCommand(Tcl_Interp *interp, CONST char *name, Tcl_Namespace *ns); @@ -262,6 +262,10 @@ static Tcl_Obj *AliasGet(Tcl_Interp *interp, Tcl_Obj *cmdName, CONST char *methodName, int withPer_object); static int AliasDeleteObjectReference(Tcl_Interp *interp, Tcl_Command cmd); +/* prototypes for (class) list handling */ +extern NsfClasses ** NsfClassListAdd(NsfClasses **firstPtrPtr, NsfClass *cl, ClientData clientData); +extern void NsfClassListFree(NsfClasses *firstPtr); + /* misc prototypes */ static int NsfDeprecatedCmd(Tcl_Interp *interp, CONST char *what, CONST char *oldCmd, CONST char *newCmd); static int SetInstVar(Tcl_Interp *interp, NsfObject *object, Tcl_Obj *nameObj, Tcl_Obj *valueObj); @@ -754,16 +758,20 @@ return objPtr; } -extern void -NsfClassListFree(NsfClasses *sl) { - NsfClasses *n; - for (; sl; sl = n) { - n = sl->nextPtr; - FREE(NsfClasses, sl); - } -} - -/* reverse class list, caller is responsible for freeing data */ +/* + *---------------------------------------------------------------------- + * NsfReverseClasses -- + * + * Reverse class list. Caller is responsible for freeing data. + * + * Results: + * Pointer to start of the reversed list + * + * Side effects: + * Allocates fresh copies of list elements + * + *---------------------------------------------------------------------- + */ static NsfClasses * NsfReverseClasses(NsfClasses *sl) { NsfClasses *firstPtr = NULL; @@ -777,9 +785,48 @@ return firstPtr; } +/* + *---------------------------------------------------------------------- + * NsfClassListFree -- + * + * Frees all elements of the provided + * + * Results: + * None. + * + * Side effects: + * Frees memory. + * + *---------------------------------------------------------------------- + */ +extern void +NsfClassListFree(NsfClasses *sl) { + NsfClasses *n; + for (; sl; sl = n) { + n = sl->nextPtr; + FREE(NsfClasses, sl); + } +} + +/* + *---------------------------------------------------------------------- + * NsfClassListAdd -- + * + * Add class list entry to the specified list. In case the initial + * list is empty, *firstPtrPtr is updated as well. + * + * Results: + * Returns address of next pointer. + * + * Side effects: + * New list element is allocated. + * + *---------------------------------------------------------------------- + */ + extern NsfClasses ** -NsfClassListAdd(NsfClasses **cList, NsfClass *cl, ClientData clientData) { - NsfClasses *l = *cList, *element = NEW(NsfClasses); +NsfClassListAdd(NsfClasses **firstPtrPtr, NsfClass *cl, ClientData clientData) { + NsfClasses *l = *firstPtrPtr, *element = NEW(NsfClasses); element->cl = cl; element->clientData = clientData; element->nextPtr = NULL; @@ -788,10 +835,54 @@ while (l->nextPtr) l = l->nextPtr; l->nextPtr = element; } else - *cList = element; + *firstPtrPtr = element; return &(element->nextPtr); } +#if defined(CHECK_ACTIVATION_COUNTS) +/* + *---------------------------------------------------------------------- + * NsfClassListUnlink -- + * + * Return removed item with matching key form nsfClasses. + * Key is void to allow not only class pointers as keys. + * + * Results: + * unlinked element or NULL. + * In case the first element is unlinked, *firstPtrPtr + * is updated. + * + * Side effects: + * none. + * + *---------------------------------------------------------------------- + */ + +static NsfClasses * +NsfClassListUnlink(NsfClasses **firstPtrPtr, void *key) { + NsfClasses *entryPtr = NULL, *prevPtr = NULL; + + if (*firstPtrPtr != NULL) { + /* list is non-empty */ + for (entryPtr = *firstPtrPtr; entryPtr; prevPtr = entryPtr, entryPtr = entryPtr->nextPtr) { + if ((void *)entryPtr->cl == key) { + /* found entry */ + if (prevPtr) { + /* later item */ + prevPtr->nextPtr = entryPtr->nextPtr; + } else { + /* first item */ + *firstPtrPtr = entryPtr->nextPtr; + } + break; + } + } + } + + return entryPtr; +} +#endif + void NsfObjectListFree(NsfObjects *sl) { NsfObjects *n; @@ -3160,8 +3251,9 @@ static NsfCmdList * CmdListRemoveFromList(NsfCmdList **cmdList, NsfCmdList *delCL) { register NsfCmdList *c = *cmdList, *del = NULL; - if (c == NULL) + if (c == NULL) { return NULL; + } if (c == delCL) { *cmdList = c->nextPtr; del = c; @@ -6275,7 +6367,7 @@ * NRE-case, we need a CscFinish for all return codes. */ #if defined(NRE) - CscListRemove(interp, cscPtr); + //CscListRemove(interp, cscPtr); CscFinish(interp, cscPtr, "guard failed"); #endif return result; @@ -6687,12 +6779,13 @@ result = MethodDispatchCsc(clientData, interp, objc, objv, cscPtr, methodName); - CscListRemove(interp, cscPtr); #if defined(NRE) if ((cscPtr->flags & NSF_CSC_CALL_IS_NRE) == 0) { + CscListRemove(interp, cscPtr); CscFinish(interp, cscPtr, "csc cleanup"); } #else + CscListRemove(interp, cscPtr); CscFinish(interp, cscPtr, "csc cleanup"); #endif @@ -12264,7 +12357,10 @@ assert(object); assert(object->refCount>0); assert(object->cmdName->refCount>0); + assert(object->activationCount >= 0); + +#if defined(CHECK_ACTIVATION_COUNTS) if (object->activationCount > 0) { Tcl_CallFrame *framePtr; int count = 0; @@ -12302,13 +12398,9 @@ /* return NsfVarErrMsg(interp, "wrong activation count for object ", objectName(object), (char *) NULL);*/ } - } else { - if (object->activationCount != 0) { - fprintf(stderr, "DEBUG obj %p %s activationcount %d\n", - object, objectName(object), object->activationCount); - } - assert(object->activationCount == 0); } +#endif + } /*fprintf(stderr, "all assertions passed\n");*/ Tcl_DeleteHashTable(tablePtr); @@ -12893,6 +12985,9 @@ ObjectSystemsCleanup(interp); #ifdef DO_CLEANUP +# if defined(CHECK_ACTIVATION_COUNTS) + assert(RUNTIME_STATE(interp)->cscList == NULL); +# endif /*fprintf(stderr, "CLEANUP TOP NS\n");*/ Tcl_Export(interp, RUNTIME_STATE(interp)->NsfNS, "", 1); Tcl_DeleteNamespace(RUNTIME_STATE(interp)->NsfClassesNS);