Index: generic/nsf.c =================================================================== diff -u -r2c338821c949f8eb468c54a537d96a1d90b55805 -radedd712d56344175e1036b7b908e62054cb8c76 --- generic/nsf.c (.../nsf.c) (revision 2c338821c949f8eb468c54a537d96a1d90b55805) +++ generic/nsf.c (.../nsf.c) (revision adedd712d56344175e1036b7b908e62054cb8c76) @@ -27880,11 +27880,17 @@ break; case CurrentoptionIsnextcallIdx: { - (void)CallStackGetTopFrame(interp, &framePtr); + + cscPtr = CallStackGetTopFrame(interp, &framePtr); + + if ((cscPtr->frameType & NSF_CSC_TYPE_ENSEMBLE) != 0u) { + (void)CallStackFindEnsembleCsc(framePtr, &framePtr); + } + framePtr = CallStackNextFrameOfType(Tcl_CallFrame_callerPtr(framePtr), FRAME_IS_NSF_METHOD|FRAME_IS_NSF_CMETHOD); cscPtr = (framePtr != NULL) ? Tcl_CallFrame_clientData(framePtr) : NULL; - + Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (cscPtr != NULL && ((cscPtr->flags & NSF_CSC_CALL_IS_NEXT) != 0u))); break; Index: generic/nsfStack.c =================================================================== diff -u -r16324e94fee054ff57d403e5b51cf96117317ea0 -radedd712d56344175e1036b7b908e62054cb8c76 --- generic/nsfStack.c (.../nsfStack.c) (revision 16324e94fee054ff57d403e5b51cf96117317ea0) +++ generic/nsfStack.c (.../nsfStack.c) (revision adedd712d56344175e1036b7b908e62054cb8c76) @@ -318,37 +318,6 @@ /* *---------------------------------------------------------------------- - * CallStackNextFrameOfType -- - * - * Return the next frame with a specified type from the call stack. - * The type is specified by a bit mask passed as flags. - * - * Results: - * Tcl_CallFrame - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ -static Tcl_CallFrame * CallStackNextFrameOfType(Tcl_CallFrame *framePtr, unsigned int flags) nonnull(1); - -static Tcl_CallFrame * -CallStackNextFrameOfType(Tcl_CallFrame *framePtr, unsigned int flags) { - nonnull_assert(framePtr != NULL); - - do { - if (((unsigned int)Tcl_CallFrame_isProcCallFrame(framePtr) & flags) != 0u) { - return framePtr; - } - framePtr = Tcl_CallFrame_callerPtr(framePtr); - } while (framePtr != NULL); - - return framePtr; -} - -/* - *---------------------------------------------------------------------- * GetSelfObj -- * * Return the currently active object from a method or object frame. @@ -808,6 +777,48 @@ /* *---------------------------------------------------------------------- + * CallStackNextFrameOfType -- + * + * Return the next frame on the call stack being of a specified type. The + * type is specified by a bitmask passed as flags. + * + * Results: + * Tcl_CallFrame + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static Tcl_CallFrame * CallStackNextFrameOfType(Tcl_CallFrame *framePtr, unsigned int flags) nonnull(1); + +static Tcl_CallFrame * +CallStackNextFrameOfType(Tcl_CallFrame *framePtr, unsigned int flags) { + NsfCallStackContent *cscPtr; + nonnull_assert(framePtr != NULL); + + do { + + cscPtr = Tcl_CallFrame_clientData(framePtr); + + if (cscPtr != NULL && (cscPtr->frameType & NSF_CSC_TYPE_ENSEMBLE) != 0u) { + (void)CallStackFindEnsembleCsc(framePtr, &framePtr); + } + + if (((unsigned int)Tcl_CallFrame_isProcCallFrame(framePtr) & flags) != 0u) { + return framePtr; + } + + framePtr = Tcl_CallFrame_callerPtr(framePtr); + + } while (framePtr != NULL); + + return framePtr; +} + +/* + *---------------------------------------------------------------------- * CallStackMethodPath -- * * Return the method path of the current ensemble in a Tcl_Obj with Index: tests/submethods.test =================================================================== diff -u -r2c338821c949f8eb468c54a537d96a1d90b55805 -radedd712d56344175e1036b7b908e62054cb8c76 --- tests/submethods.test (.../submethods.test) (revision 2c338821c949f8eb468c54a537d96a1d90b55805) +++ tests/submethods.test (.../submethods.test) (revision adedd712d56344175e1036b7b908e62054cb8c76) @@ -913,26 +913,29 @@ nx::test case ensemble-callstack-introspection { set ::body { - return [list [current nextmethod] {*}[next]] + return [list [current nextmethod] [current isnextcall] {*}[next]] } nx::Class create A { set ::handle [:method "i s" args $::body] + :create a } nx::Class create B -superclasses A { :public method "i s" args $::body :create b } - ? {b eval { :i s }} {{::nsf::classes::A::i s} {}} + ? {b eval { :i s }} {{::nsf::classes::A::i s} 0 {} 1} ? {::nsf::cmd::info args [lindex [b eval { :i s }] 0]} "args" ? {::nsf::cmd::info definitionhandle [lindex [b eval { :i s }] 0]} $::handle ? {::nsf::cmd::info body [lindex [b eval { :i s }] 0]} $::body - ? {b i s} {{::nsf::classes::A::i s} {}}; + ? {b i s} {{::nsf::classes::A::i s} 0 {} 1}; ? {::nsf::cmd::info args [lindex [b i s] 0]} "args" ? {::nsf::cmd::info definitionhandle [lindex [b i s] 0]} $::handle ? {::nsf::cmd::info body [lindex [b i s] 0]} $::body + ? {a eval { :i s }} {{} 0} + ? {a i s} {{} 0} unset -nocomplain ::handle unset -nocomplain ::body