Index: generic/nsfStack.c =================================================================== diff -u -r86caad4d5db5f26fcf0d5b2fe009eefef554282c -r6671e05d628c0ecec739c584d997c11da73dbd19 --- generic/nsfStack.c (.../nsfStack.c) (revision 86caad4d5db5f26fcf0d5b2fe009eefef554282c) +++ generic/nsfStack.c (.../nsfStack.c) (revision 6671e05d628c0ecec739c584d997c11da73dbd19) @@ -77,12 +77,6 @@ NSF_INLINE static NsfCallStackContent* CallStackGetTopFrame0(const Tcl_Interp *interp) nonnull(1) pure; -/* static NsfCallStackContent* NsfCallStackFindLastInvocation( - const Tcl_Interp *interp, - int offset, - Tcl_CallFrame **framePtrPtr - ) nonnull(1);*/ - static NsfCallStackContent* NsfCallStackFindCallingContext( const Tcl_Interp *interp, int offset, @@ -646,22 +640,27 @@ nonnull_assert(interp != NULL); - // NsfShowStack((Tcl_Interp *)interp); - for (; likely(varFramePtr != NULL); varFramePtr = Tcl_CallFrame_callerVarPtr(varFramePtr)) { - - if (((unsigned int)Tcl_CallFrame_isProcCallFrame(varFramePtr) & - (FRAME_IS_NSF_METHOD|FRAME_IS_NSF_CMETHOD)) != 0u) { - NsfCallStackContent *cscPtr = (NsfCallStackContent *)Tcl_CallFrame_clientData(varFramePtr); - + register unsigned int flags = (unsigned int)Tcl_CallFrame_isProcCallFrame(varFramePtr); + + if (flags != 0u) { /* - * An NSF method frame. + * A proc frame */ - if ((cscPtr->flags & (NSF_CSC_CALL_IS_NEXT|NSF_CSC_CALL_IS_ENSEMBLE)) - || (cscPtr->frameType & NSF_CSC_TYPE_INACTIVE)) { - continue; + NsfCallStackContent *cscPtr = + (flags & (FRAME_IS_NSF_METHOD|FRAME_IS_NSF_CMETHOD)) ? + ((NsfCallStackContent *)Tcl_CallFrame_clientData(varFramePtr)) : NULL; + + if (cscPtr != NULL) { + /* + * An NSF method frame. + */ + if ((cscPtr->flags & (NSF_CSC_CALL_IS_NEXT|NSF_CSC_CALL_IS_ENSEMBLE)) + || (cscPtr->frameType & NSF_CSC_TYPE_INACTIVE)) { + continue; + } } - + if (offset != 0) { offset--; } else if (Tcl_CallFrame_level(varFramePtr) < lvl) { @@ -670,30 +669,11 @@ } return cscPtr; } - } else if (Tcl_CallFrame_isProcCallFrame(varFramePtr)) { - - /* - * A Tcl proc frame. - */ - if (offset != 0) { - offset--; - } else if (Tcl_CallFrame_level(varFramePtr) < lvl) { - if (callingProcFramePtrPtr != NULL) { - *callingProcFramePtrPtr = varFramePtr; - } - return NULL; - } - } else { - /* some other frame */ - if (offset != 0) { - offset--; - } else if (callingFramePtrPtr != NULL && - *callingFramePtrPtr == NULL && - Tcl_CallFrame_level(varFramePtr) < lvl) { - /* fprintf(stderr, "firstFramePtr %p lvl %d\n", - varFramePtr, Tcl_CallFrame_level(varFramePtr));*/ - *callingFramePtrPtr = varFramePtr; - } + + } else if (callingFramePtrPtr != NULL && + *callingFramePtrPtr == NULL && + Tcl_CallFrame_level(varFramePtr) < lvl) { + *callingFramePtrPtr = varFramePtr; } } @@ -705,88 +685,6 @@ /* *---------------------------------------------------------------------- - * NsfCallStackFindLastInvocation -- - * - * Find last invocation of a (scripted or non-leaf) method with a - * specified offset. - * - * Results: - * Call stack content or NULL. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -#if 0 - static NsfCallStackContent * -NsfCallStackFindLastInvocation(const Tcl_Interp *interp, int offset, Tcl_CallFrame **framePtrPtr) { - register Tcl_CallFrame *varFramePtr = (Tcl_CallFrame *)Tcl_Interp_varFramePtr(interp); - int lvl = Tcl_CallFrame_level(varFramePtr); - Tcl_CallFrame *firstFramePtr = NULL; - - nonnull_assert(interp != NULL); - - NsfShowStack((Tcl_Interp *)interp); - - for (; likely(varFramePtr != NULL); varFramePtr = Tcl_CallFrame_callerVarPtr(varFramePtr)) { - - if (((unsigned int)Tcl_CallFrame_isProcCallFrame(varFramePtr) & (FRAME_IS_NSF_METHOD|FRAME_IS_NSF_CMETHOD)) != 0u) { - NsfCallStackContent *cscPtr = (NsfCallStackContent *)Tcl_CallFrame_clientData(varFramePtr); - - /* - * A NSF method frame. - */ - if ((cscPtr->flags & (NSF_CSC_CALL_IS_NEXT|NSF_CSC_CALL_IS_ENSEMBLE)) - || (cscPtr->frameType & NSF_CSC_TYPE_INACTIVE)) { - continue; - } - - if (offset != 0) { - offset--; - } else if (Tcl_CallFrame_level(varFramePtr) < lvl) { - if (framePtrPtr != NULL) { - *framePtrPtr = varFramePtr; - } - return cscPtr; - } - } else if (Tcl_CallFrame_isProcCallFrame(varFramePtr)) { - - /* - * A Tcl proc frame. - */ - if (offset != 0) { - offset--; - } else if (Tcl_CallFrame_level(varFramePtr) < lvl) { - if (framePtrPtr != NULL) { - *framePtrPtr = varFramePtr; - } - return NULL; - } - } else { - /* some other frame */ - fprintf(stderr, "RUN\n"); - if (offset != 0) { - offset--; - } else if (firstFramePtr == NULL && - Tcl_CallFrame_level(varFramePtr) < lvl) { - fprintf(stderr, "firstFramePtr %p lvl %d\n", - varFramePtr, Tcl_CallFrame_level(varFramePtr)); - firstFramePtr = varFramePtr; - } - } - } - - if (framePtrPtr != NULL) { - *framePtrPtr = NULL; - } - return NULL; -} -#endif - -/* - *---------------------------------------------------------------------- * NsfCallStackFindActiveFrame -- * * Search for the first active frame on the call-stack. Index: tests/methods.test =================================================================== diff -u -r86caad4d5db5f26fcf0d5b2fe009eefef554282c -r6671e05d628c0ecec739c584d997c11da73dbd19 --- tests/methods.test (.../methods.test) (revision 86caad4d5db5f26fcf0d5b2fe009eefef554282c) +++ tests/methods.test (.../methods.test) (revision 6671e05d628c0ecec739c584d997c11da73dbd19) @@ -1637,7 +1637,7 @@ objekt public object method intercept args { list [current method] {*}[next] } - objekt object filters add intercept + objekt object filters set intercept ? {uplevel #0 {objekt foo}} "intercept #0" ? {uplevel #0 { @@ -1694,6 +1694,155 @@ } ? {uplevel #0 {objekt foo}} "#0" + ? {uplevel #0 { + namespace eval ::ns1 { + namespace eval ns2 { + objekt foo + } + } + }} "#2" + namespace delete ::ns1 + + ? {uplevel #0 {apply {{} {objekt foo}}}} "#1" + ? {uplevel #0 { apply {{} { + namespace eval ::ns1 { + namespace eval ns2 { + objekt foo + } + } + }}}} "#1" + namespace delete ::ns1 + + objekt public object method intercept args { + if {[current calledmethod] eq "foo"} { + list [current method] {*}[next] + } else { + next + } + } + objekt object filters set intercept + + ? {uplevel #0 {objekt foo}} "intercept #0" + ? {uplevel #0 { + namespace eval ::ns1 { + namespace eval ns2 { + objekt foo + } + } + }} "intercept #2" + namespace delete ::ns1 + + ? {uplevel #0 {apply {{} {objekt foo}}}} "intercept #1" + ? {uplevel #0 { apply {{} { + namespace eval ::ns1 { + namespace eval ns2 { + objekt foo + } + } + }}}} "intercept #1" + namespace delete ::ns1 + + objekt object mixins add [nx::Class new { + :public method foo {args} { + list [current method] {*}[next] + } + }] + + ? {uplevel #0 {objekt foo}} "intercept foo #0" + ? {uplevel #0 { + namespace eval ::ns1 { + namespace eval ns2 { + objekt foo + } + } + }} "intercept foo #2" + namespace delete ::ns1 + + ? {uplevel #0 {apply {{} {objekt foo}}}} "intercept foo #1" + ? {uplevel #0 { apply {{} { + namespace eval ::ns1 { + namespace eval ns2 { + objekt foo + } + } + }}}} "intercept foo #1" + namespace delete ::ns1 + + set filters [objekt object filters clear] + set mixins [objekt object mixins clear] + unset -nocomplain ::_ + + objekt public object method foo {} { + :uplevel {set FOO 1} + } + + ? {uplevel #0 { + lappend _ [info exists FOO]; + objekt foo; + lappend _ [info exists FOO][unset FOO]} + } "0 1" + + unset -nocomplain ::_ + + ? {uplevel #0 { + namespace eval ::ns1 { + namespace eval ns2 { + lappend _ [info exists FOO]; + objekt foo; + lappend _ [info exists FOO][unset FOO]; + } + } + }} "0 1" + namespace delete ::ns1 + + ? {uplevel #0 { + namespace eval ::ns1 { + apply {{} { + lappend _ [info exists FOO]; + namespace eval ns2 { + objekt foo; + } + lappend _ [info exists FOO][unset FOO]; + }} + } + }} "0 1" + namespace delete ::ns1 + + objekt object filters set $filters + objekt object mixins set $mixins + + ? {uplevel #0 { + lappend _ [info exists FOO]; + objekt foo; + lappend _ [info exists FOO][unset FOO]} + } "0 1" + + unset -nocomplain ::_ + + ? {uplevel #0 { + namespace eval ::ns1 { + namespace eval ns2 { + lappend _ [info exists FOO]; + objekt foo; + lappend _ [info exists FOO][unset FOO]; + } + } + }} "0 1" + namespace delete ::ns1 + + ? {uplevel #0 { + namespace eval ::ns1 { + apply {{} { + lappend _ [info exists FOO]; + namespace eval ns2 { + objekt foo; + } + lappend _ [info exists FOO][unset FOO]; + }} + } + }} "0 1" + namespace delete ::ns1 + }