Index: generic/nsf.c =================================================================== diff -u -r70090ae5f0348466a89053c5587fa0f9eb7f7c24 -rba7fd2903fd9cdb1f5a56b4457863633a3f72273 --- generic/nsf.c (.../nsf.c) (revision 70090ae5f0348466a89053c5587fa0f9eb7f7c24) +++ generic/nsf.c (.../nsf.c) (revision ba7fd2903fd9cdb1f5a56b4457863633a3f72273) @@ -2321,10 +2321,10 @@ NsfLog(sc->object.teardown, NSF_LOG_WARN, "cycle in the mixin graph list detected for class %s", ClassName(sc)); //cl->color = WHITE; //if (cl == baseClass) { - // register NsfClasses *pc; - // for (pc = cl->order; pc; pc = pc->nextPtr) { pc->cl->color = WHITE; } + //register NsfClasses *pc; + //for (pc = cl->order; pc; pc = pc->nextPtr) { pc->cl->color = WHITE; } //} - //return 0; + //return 0; } } } @@ -2869,6 +2869,7 @@ order = NULL; } + // TODO: if this holds, we can change the fn to returns_nonnull and the else-branch is not needed assert(order); AssertOrderIsWhite(order); @@ -2910,11 +2911,12 @@ if (likely(TopoSort(cl, cl, SUB_CLASSES, 1))) { order = cl->order; } else { - fprintf(stderr, "DependentSubClasses %s failed\n", ClassName(cl)); if (cl->order) NsfClassListFree(cl->order); order = NULL; } + // TODO: if this holds, we can change the fn to returns_nonnull and the else-branch is not needed + assert(order); AssertOrderIsWhite(order); @@ -25507,8 +25509,6 @@ */ static int NsfParameterCacheClassInvalidateCmd(Tcl_Interp *interp, NsfClass *cl) { - NsfClasses *dependentSubClasses; - NsfClasses *clPtr; assert(interp); assert(cl); @@ -25524,25 +25524,33 @@ #endif /* - * Clear the cached parsedParam of the class and all its subclasses (the - * result of DependentSubClasses() contains the starting class). Furthermore, - * make a quick check, if any of the subclasses is a class mixin of some - * other class. + * During shutdown, no new objects are created, therefore we do not need to + * to invalidate the cached parsedParamPtr of the classes. */ + if (unlikely(RUNTIME_STATE(interp)->exitHandlerDestroyRound != NSF_EXITHANDLER_OFF)) { + NsfClasses *dependentSubClasses; + NsfClasses *clPtr; - dependentSubClasses = DependentSubClasses(cl); + /* + * Clear the cached parsedParam of the class and all its subclasses (the + * result of DependentSubClasses() contains the starting class). Furthermore, + * make a quick check, if any of the subclasses is a class mixin of some + * other class. + */ - for (clPtr = dependentSubClasses; clPtr; clPtr = clPtr->nextPtr) { - NsfClass *subClass = clPtr->cl; + dependentSubClasses = DependentSubClasses(cl); - if (subClass->parsedParamPtr) { - ParsedParamFree(subClass->parsedParamPtr); - subClass->parsedParamPtr = NULL; + for (clPtr = dependentSubClasses; clPtr; clPtr = clPtr->nextPtr) { + NsfClass *subClass = clPtr->cl; + + if (subClass->parsedParamPtr) { + ParsedParamFree(subClass->parsedParamPtr); + subClass->parsedParamPtr = NULL; + } } - } - NsfClassListFree(dependentSubClasses); - + NsfClassListFree(dependentSubClasses); + } return TCL_OK; } @@ -26032,7 +26040,7 @@ break; } - case RelationtypeClass_mixinIdx: + case RelationtypeClass_mixinIdx: if (NsfRelationClassMixinsSet(interp, cl, valueObj, oc, ov) != TCL_OK) { return TCL_ERROR; }