Index: generic/nsf.c =================================================================== diff -u -r3e18b80be2883ba647c2110a2e8e2b1980940c30 -rf34be2f016a50e3f5fc8b1b021e28fb696bdb5de --- generic/nsf.c (.../nsf.c) (revision 3e18b80be2883ba647c2110a2e8e2b1980940c30) +++ generic/nsf.c (.../nsf.c) (revision f34be2f016a50e3f5fc8b1b021e28fb696bdb5de) @@ -4913,10 +4913,18 @@ * remove all command pointers from a list that have a bumped epoch */ static void -CmdListRemoveEpoched(INTERP_DECL NsfCmdList **cmdList, NsfFreeCmdListClientData *freeFct) { +CmdListRemoveDeleted(INTERP_DECL NsfCmdList **cmdList, NsfFreeCmdListClientData *freeFct) { NsfCmdList *f = *cmdList, *del; while (f) { - if (Tcl_Command_cmdEpoch(f->cmdPtr)) { + /* + * HIDDEN OBJECTS: For supporting hidden mixins, we cannot rely on the + * cmdEpoch as indicator of the deletion status of a cmd because the epoch + * counters of hidden and re-exposed commands are bumped. Despite of this, + * their object structures remain valid. We resort to the use of the + * per-cmd flag CMD_IS_DELETED, set upon processing a command in + * Tcl_DeleteCommandFromToken(). + */ + if (Tcl_Command_flags(f->cmdPtr) & CMD_IS_DELETED /* Tcl_Command_cmdEpoch(f->cmdPtr) */) { del = f; f = f->nextPtr; del = CmdListRemoveFromList(cmdList, del); @@ -4935,7 +4943,7 @@ NsfFreeCmdListClientData *freeFct) { NsfCmdList *c, *del = NULL; /* - CmdListRemoveEpoched(INTERP cmdList, freeFct); + CmdListRemoveDeleted(INTERP cmdList, freeFct); */ c = *cmdList; while (c && c->clorobj == clorobj) { @@ -5446,7 +5454,7 @@ NsfCmdList *m; NsfClasses *pl, **clPtr = mixinClasses; - CmdListRemoveEpoched(INTERP mixinList, GuardDel); + CmdListRemoveDeleted(INTERP mixinList, GuardDel); for (m = *mixinList; m; m = m->nextPtr) { NsfClass *mCl = NsfGetClassFromCmdPtr(m->cmdPtr); @@ -5511,7 +5519,7 @@ *---------------------------------------------------------------------- * NsfClassListAddPerClassMixins -- * - * Append the class mixins to the proivded list. CheckList is used to + * Append the class mixins to the provided list. CheckList is used to * eliminate potential duplicates. * * Results: @@ -6652,11 +6660,10 @@ *---------------------------------------------------------------------- * MixinSearchProc -- * - * Search for a methodname in the mixin list of the provided - * object. According to the state of the mixin stack it start the search - * from the beginning of from the last dispatched method shadowed method on - * the mixin path. If a class *cl and a *cmdPtr are provided, the function - * only succeeds, when the class is a mixin class. + * Search for a method name in the mixin list of the provided + * object. Depending on the state of the mixin stack, the search starts + * at the beginning or at the last dispatched, shadowed method on + * the mixin path. * * Results: * Tcl result code. @@ -6698,8 +6705,16 @@ for (; cmdList; cmdList = cmdList->nextPtr) { NsfClass *cl1; - - if (Tcl_Command_cmdEpoch(cmdList->cmdPtr)) { continue; } + + /* + * HIDDEN OBJECTS: For supporting hidden mixins, we cannot rely on the + * cmdEpoch as indicator of the deletion status of a cmd because the + * epoch counters of hidden and re-exposed commands are bumped. Despite + * of this, their object structures remain valid. + */ + if (Tcl_Command_flags(cmdList->cmdPtr) & CMD_IS_DELETED + /*Tcl_Command_cmdEpoch(cmdList->cmdPtr)*/) { continue; } + cl1 = NsfGetClassFromCmdPtr(cmdList->cmdPtr); assert(cl1); lastCmdPtr = cmdList->cmdPtr; @@ -6748,8 +6763,13 @@ } else { for (; cmdList; cmdList = cmdList->nextPtr) { - - if (Tcl_Command_cmdEpoch(cmdList->cmdPtr)) { + /* + * HIDDEN OBJECTS: For supporting hidden mixins, we cannot rely on the + * cmdEpoch as indicator of the deletion status of a cmd because the + * epoch counters of hidden and re-exposed commands are bumped. Despite + * of this, their object structures remain valid. + */ + if (Tcl_Command_flags(cmdList->cmdPtr) & CMD_IS_DELETED /*Tcl_Command_cmdEpoch(cmdList->cmdPtr)*/) { continue; } cl = NsfGetClassFromCmdPtr(cmdList->cmdPtr); @@ -7213,7 +7233,7 @@ NsfCmdList *cmdList, *del; NsfClass *cl = NULL; - CmdListRemoveEpoched(INTERP filters, GuardDel); + CmdListRemoveDeleted(INTERP filters, GuardDel); for (cmdList = *filters; cmdList; ) { simpleName = (char *) Tcl_GetCommandName(interp, cmdList->cmdPtr); cmd = FilterSearch(INTERP simpleName, startingObject, startingClass, &cl); @@ -7404,7 +7424,7 @@ /* * ensure that no epoched command is in the filters list */ - CmdListRemoveEpoched(INTERP filters, GuardDel); + CmdListRemoveDeleted(INTERP filters, GuardDel); for (f = *filters; f; f = f->nextPtr) { simpleName = (char *) Tcl_GetCommandName(interp, f->cmdPtr);