Index: generic/xotcl.c =================================================================== diff -u -ra6f0c9f2a438c7dcbe003698032aefb6a77f0199 -rec939a7b02581cdfc2a0c6fdf9393b2c83030207 --- generic/xotcl.c (.../xotcl.c) (revision a6f0c9f2a438c7dcbe003698032aefb6a77f0199) +++ generic/xotcl.c (.../xotcl.c) (revision ec939a7b02581cdfc2a0c6fdf9393b2c83030207) @@ -104,6 +104,7 @@ static void MixinComputeDefined(Tcl_Interp *interp, XOTclObject *obj); static XOTclClass *DefaultSuperClass(Tcl_Interp *interp, XOTclClass *cl, XOTclClass *mcl, int isMeta); static XOTclCallStackContent *CallStackGetFrame(Tcl_Interp *interp, Tcl_CallFrame **framePtrPtr); +XOTCLINLINE static void CallStackPop(Tcl_Interp *interp); static Tcl_ObjType XOTclObjectType = { "XOTclObject", @@ -12745,7 +12746,6 @@ ExitHandler(ClientData clientData) { Tcl_Interp *interp = (Tcl_Interp *)clientData; int i, flags; - XOTclCallStack *cs = &RUNTIME_STATE(interp)->cs; /* * Don't use exit handler, if the interpreted is destroyed already @@ -12777,21 +12777,8 @@ XOTclFinalizeObjCmd(NULL, interp, 0, NULL); } - /* - * Pop any callstack entry that is still alive (e.g. - * if "exit" is called and we were jumping out of the - * callframe - */ - while (cs->top > cs->content) - CallStackPop(interp); + CallStackPopAll(interp); - while (1) { - Tcl_CallFrame *f = Tcl_Interp_framePtr(interp); - if (!f) break; - if (Tcl_CallFrame_level(f) == 0) break; - Tcl_PopCallFrame(interp); - } - /* must be before freeing of XOTclGlobalObjects */ XOTclShadowTclCommands(interp, SHADOW_UNLOAD); Index: generic/xotclStack.c =================================================================== diff -u -ra6f0c9f2a438c7dcbe003698032aefb6a77f0199 -rec939a7b02581cdfc2a0c6fdf9393b2c83030207 --- generic/xotclStack.c (.../xotclStack.c) (revision a6f0c9f2a438c7dcbe003698032aefb6a77f0199) +++ generic/xotclStack.c (.../xotclStack.c) (revision ec939a7b02581cdfc2a0c6fdf9393b2c83030207) @@ -243,4 +243,22 @@ obj->flags &= ~XOTCL_DESTROY_CALLED; } +/* + * Pop any callstack entry that is still alive (e.g. + * if "exit" is called and we were jumping out of the + * callframe + */ +void CallStackPopAll(Tcl_Interp *interp) { + XOTclCallStack *cs = &RUNTIME_STATE(interp)->cs; + + while (cs->top > cs->content) + CallStackPop(interp); + + while (1) { + Tcl_CallFrame *framePtr = Tcl_Interp_framePtr(interp); + if (!framePtr) break; + if (Tcl_CallFrame_level(framePtr) == 0) break; + Tcl_PopCallFrame(interp); + } +} #endif /* NOT TCL85STACK */ Index: generic/xotclStack85.c =================================================================== diff -u -rdc6c71950983c8fc6c220a751e3e0e3f79b5e10b -rec939a7b02581cdfc2a0c6fdf9393b2c83030207 --- generic/xotclStack85.c (.../xotclStack85.c) (revision dc6c71950983c8fc6c220a751e3e0e3f79b5e10b) +++ generic/xotclStack85.c (.../xotclStack85.c) (revision ec939a7b02581cdfc2a0c6fdf9393b2c83030207) @@ -360,6 +360,26 @@ */ obj->flags &= ~XOTCL_DESTROY_CALLED; } + +/* + * Pop any callstack entry that is still alive (e.g. + * if "exit" is called and we were jumping out of the + * callframe + */ +void CallStackPopAll(Tcl_Interp *interp) { + + while (1) { + Tcl_CallFrame *framePtr = Tcl_Interp_framePtr(interp); + if (!framePtr) break; + if (Tcl_CallFrame_level(framePtr) == 0) break; + if (Tcl_CallFrame_isProcCallFrame(framePtr) & (FRAME_IS_XOTCL_METHOD|FRAME_IS_XOTCL_CMETHOD)) { + /* free the call stack content; for now, we pop it from the allocation stack */ + CallStackPop(interp); + } + /* pop the Tcl frame */ + Tcl_PopCallFrame(interp); + } +} #endif /* TCL85STACK */