Index: generic/xotcl.c =================================================================== diff -u -ra19d77bc89cdb0882d2cad69305be4e0e483cae3 -red8301802df5fc7427fc0e4dbd82c2cf880329de --- generic/xotcl.c (.../xotcl.c) (revision a19d77bc89cdb0882d2cad69305be4e0e483cae3) +++ generic/xotcl.c (.../xotcl.c) (revision ed8301802df5fc7427fc0e4dbd82c2cf880329de) @@ -195,7 +195,7 @@ Tcl_Obj *CONST objv[], int flags); static int XOTclNextMethod(XOTclObject *obj, Tcl_Interp *interp, XOTclClass *givenCl, char *givenMethod, int objc, Tcl_Obj *CONST objv[], - int useCSObjs); + int useCSObjs, XOTclCallStackContent *csc); static int XOTclForwardMethod(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]); @@ -2644,13 +2644,6 @@ return (RUNTIME_STATE(interp)->cs.top->destroyedCmd == NULL) ? 0 : 1; } -XOTCLINLINE static XOTclCallStackContent* -CallStackGetTopFrame(Tcl_Interp *interp) { - XOTclCallStack *cs = &RUNTIME_STATE(interp)->cs; - return cs->top; -} - - /* * cmd list handling */ @@ -5368,8 +5361,8 @@ #endif #if defined(TCL85STACK_TRACE) - fprintf(stderr, "+++ callProcCheck %s, isTclProc %d csc %p, teardown %p\n", - methodName,isTclProc,csc,obj->teardown); + fprintf(stderr, "+++ callProcCheck %s, isTclProc %d csc %p, frametype %d, teardown %p\n", + methodName, isTclProc, csc, frameType, obj->teardown); #endif if (!obj->teardown) { @@ -5437,8 +5430,6 @@ * if this is a filter, check whether its guard applies, * if not: just step forward to the next filter */ - /*fprintf(stderr,"calling proc %s isTclProc %d tearDown %p frameType %d\n", - methodName,isTclProc,obj->teardown,frameType);*/ if (frameType == XOTCL_CSC_TYPE_ACTIVE_FILTER) { XOTclCmdList *cmdList; @@ -5463,12 +5454,13 @@ * we may not be in a method, thus there may be wrong or * no callstackobjs */ - /*fprintf(stderr, "... calling nextmethod\n"); XOTclCallStackDump(interp);*/ + /*fprintf(stderr, "... calling nextmethod csc %p\n", csc); XOTclCallStackDump(interp);*/ + /* the call stack content is not jet pushed to the tcl + stack, so we pass it here explicitely */ rc = XOTclNextMethod(obj, interp, cl, methodName, - objc, objv, /*useCallStackObjs*/ 0); - /*fprintf(stderr, "... after nextmethod\n"); - XOTclCallStackDump(interp);*/ + objc, objv, /*useCallStackObjs*/ 0, csc); + /*fprintf(stderr, "... after nextmethod\n"); XOTclCallStackDump(interp);*/ } return rc; @@ -6961,8 +6953,7 @@ static int XOTclNextMethod(XOTclObject *obj, Tcl_Interp *interp, XOTclClass *givenCl, char *givenMethod, int objc, Tcl_Obj *CONST objv[], - int useCallstackObjs) { - XOTclCallStackContent *csc = CallStackGetTopFrame(interp); + int useCallstackObjs, XOTclCallStackContent *csc) { Tcl_Command cmd, currentCmd = NULL; int result = TCL_OK, frameType = XOTCL_CSC_TYPE_PLAIN, @@ -6972,6 +6963,10 @@ XOTclClass **cl = &givenCl; char **methodName = &givenMethod; + if (!csc) { + csc = CallStackGetTopFrame(interp); + } + #if !defined(NDEBUG) if (useCallstackObjs) { Tcl_CallFrame *cf = (Tcl_CallFrame *)Tcl_Interp_varFramePtr(interp); @@ -6990,8 +6985,8 @@ } #endif - /*fprintf(stderr,"givenMethod = %s, csc = %p, useCallstackObj %d, objc %d\n", - givenMethod, csc, useCallstackObjs, objc);*/ + /*fprintf(stderr,"XOTclNextMethod givenMethod = %s, csc = %p, useCallstackObj %d, objc %d cfp %p\n", + givenMethod, csc, useCallstackObjs, objc, csc->currentFramePtr);*/ /* if no args are given => use args from stack */ if (objc < 2 && useCallstackObjs && csc->currentFramePtr) { @@ -7108,7 +7103,7 @@ return XOTclNextMethod(csc->self, interp, csc->cl, (char *)Tcl_GetCommandName(interp, csc->cmdPtr), - objc, objv, 1); + objc, objv, 1, NULL); } @@ -10863,18 +10858,14 @@ /* method for calling e.g. $obj __next */ static int XOTclONextMethod(Tcl_Interp *interp, XOTclObject *obj, int objc, Tcl_Obj *CONST objv[]) { - XOTclCallStack *cs = &RUNTIME_STATE(interp)->cs; - XOTclCallStackContent *csc = CallStackGetTopFrame(interp); + XOTclCallStackContent *csc = CallStackGetObjectFrame(interp, obj); char *methodName; - for (; csc >= cs->content; csc--) { - if (csc->self == obj) break; - } - if (csccontent) + if (!csc) return XOTclVarErrMsg(interp, "__next: can't find object", objectName(obj), (char *) NULL); methodName = (char *)Tcl_GetCommandName(interp, csc->cmdPtr); - return XOTclNextMethod(obj, interp, csc->cl, methodName, objc-1, &objv[1], 0); + return XOTclNextMethod(obj, interp, csc->cl, methodName, objc-1, &objv[1], 0, NULL); } static int XOTclONoinitMethod(Tcl_Interp *interp, XOTclObject *obj) { Index: generic/xotclStack.c =================================================================== diff -u -ra19d77bc89cdb0882d2cad69305be4e0e483cae3 -red8301802df5fc7427fc0e4dbd82c2cf880329de --- generic/xotclStack.c (.../xotclStack.c) (revision a19d77bc89cdb0882d2cad69305be4e0e483cae3) +++ generic/xotclStack.c (.../xotclStack.c) (revision ed8301802df5fc7427fc0e4dbd82c2cf880329de) @@ -28,6 +28,12 @@ return top; } +XOTCLINLINE static XOTclCallStackContent* +CallStackGetTopFrame(Tcl_Interp *interp) { + XOTclCallStack *cs = &RUNTIME_STATE(interp)->cs; + return cs->top; +} + static void CallStackClearCmdReferences(Tcl_Interp *interp, Tcl_Command cmd) { XOTclCallStack *cs = &RUNTIME_STATE(interp)->cs; @@ -40,6 +46,19 @@ } } +static XOTclCallStackContent* +CallStackGetObjectFrame(Tcl_Interp *interp, XOTclObject *obj) { + XOTclCallStack *cs = &RUNTIME_STATE(interp)->cs; + XOTclCallStackContent *csc = CallStackGetTopFrame(interp); + + for (; csc >= cs->content; csc--) { + if (csc->self == obj) { + return csc; + } + } + return NULL; +} + static int CallStackMarkDestroyed(Tcl_Interp *interp, XOTclObject *obj) { XOTclCallStack *cs = &RUNTIME_STATE(interp)->cs; Index: generic/xotclStack85.c =================================================================== diff -u -ra19d77bc89cdb0882d2cad69305be4e0e483cae3 -red8301802df5fc7427fc0e4dbd82c2cf880329de --- generic/xotclStack85.c (.../xotclStack85.c) (revision a19d77bc89cdb0882d2cad69305be4e0e483cae3) +++ generic/xotclStack85.c (.../xotclStack85.c) (revision ed8301802df5fc7427fc0e4dbd82c2cf880329de) @@ -50,6 +50,30 @@ return NULL; } +#if 1 +XOTCLINLINE static XOTclCallStackContent* +CallStackGetTopFrame(Tcl_Interp *interp) { + return CallStackGetFrame(interp); +} +#else +XOTCLINLINE static XOTclCallStackContent* +CallStackGetTopFrameOld(Tcl_Interp *interp) { + XOTclCallStack *cs = &RUNTIME_STATE(interp)->cs; + return cs->top; +} + +XOTCLINLINE static XOTclCallStackContent* +CallStackGetTopFrame(Tcl_Interp *interp, int i) { + XOTclCallStack *cs = &RUNTIME_STATE(interp)->cs; + XOTclCallStackContent* csc = CallStackGetFrame(interp); + fprintf(stderr, "old csc %p, new %p ok %d (%d)\n",cs->top,csc,csc==cs->top,i); + if (csc != cs->top) { + tcl85showStack(interp); + } + return csc; +} +#endif + static void CallStackClearCmdReferences(Tcl_Interp *interp, Tcl_Command cmd) { register Tcl_CallFrame *varFramePtr = (Tcl_CallFrame *)Tcl_Interp_varFramePtr(interp); @@ -64,6 +88,21 @@ } } +static XOTclCallStackContent* +CallStackGetObjectFrame(Tcl_Interp *interp, XOTclObject *obj) { + register Tcl_CallFrame *varFramePtr = (Tcl_CallFrame *)Tcl_Interp_varFramePtr(interp); + + for (; varFramePtr; varFramePtr = Tcl_CallFrame_callerPtr(varFramePtr)) { + if (Tcl_CallFrame_isProcCallFrame(varFramePtr) & FRAME_IS_XOTCL_METHOD) { + XOTclCallStackContent *csc = (XOTclCallStackContent *)Tcl_CallFrame_clientData(varFramePtr); + if (csc->self == obj) { + return csc; + } + } + } + return NULL; +} + /* TODO: we have a small divergence in the test "filterGuards" due to different lifetime of stack entries, so we keep for reference and