diff options
author | Miguel Sofer <miguel.sofer@gmail.com> | 2009-03-21 09:42:06 (GMT) |
---|---|---|
committer | Miguel Sofer <miguel.sofer@gmail.com> | 2009-03-21 09:42:06 (GMT) |
commit | 61861981e390fd931fe6af2bb3fa9b2d984eb307 (patch) | |
tree | e8e1c28643010bdcc4334464e09bcae493800483 /generic/tclExecute.c | |
parent | 0a098f986c82c3df2107386ae53a6e40da726c27 (diff) | |
download | tcl-61861981e390fd931fe6af2bb3fa9b2d984eb307.zip tcl-61861981e390fd931fe6af2bb3fa9b2d984eb307.tar.gz tcl-61861981e390fd931fe6af2bb3fa9b2d984eb307.tar.bz2 |
* generic/tclBasic.c: Fix for (among others) [Bug 2699087]
* generic/tclCmdAH.c: Tailcalls now perform properly even from
* generic/tclExecute.c: within [eval]ed scripts.
* generic/tclInt.h: More tests missing, as well as proper
exploration and testing of the interaction with "redirectors" like
interp-alias (suspect that it does not happen in constant space)
and pure-eval commands.
Diffstat (limited to 'generic/tclExecute.c')
-rw-r--r-- | generic/tclExecute.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 99bf84e..b00848a 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -14,7 +14,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclExecute.c,v 1.432 2009/03/21 06:55:31 msofer Exp $ + * RCS: @(#) $Id: tclExecute.c,v 1.433 2009/03/21 09:42:07 msofer Exp $ */ #include "tclInt.h" @@ -1871,18 +1871,15 @@ TclExecuteByteCode( fprintf(stdout, " Tailcall request received\n"); } #endif - TEOV_callback *tailcallPtr = param; - - iPtr->varFramePtr->tailcallPtr = tailcallPtr; - if (catchTop != initCatchTop) { - tailcallPtr->data[2] = INT2PTR(1); + TclClearTailcall(interp, param); result = TCL_ERROR; Tcl_SetResult(interp,"Tailcall called from within a catch environment", TCL_STATIC); pc--; goto checkForCatch; } + iPtr->varFramePtr->tailcallPtr = param; goto abnormalReturn; } case TCL_NR_YIELD_TYPE: { /*[yield] */ @@ -1995,6 +1992,15 @@ TclExecuteByteCode( */ if (iPtr->varFramePtr->tailcallPtr) { + if (catchTop != initCatchTop) { + TclClearTailcall(interp, iPtr->varFramePtr->tailcallPtr); + iPtr->varFramePtr->tailcallPtr = NULL; + result = TCL_ERROR; + Tcl_SetResult(interp,"Tailcall called from within a catch environment", + TCL_STATIC); + pc--; + goto checkForCatch; + } goto abnormalReturn; } @@ -7759,6 +7765,19 @@ TclExecuteByteCode( abnormalReturn: TCL_DTRACE_INST_LAST(); + + /* + * Winding down: insure that all pending cleanups are done before + * dropping out of this bytecode. + */ + if (TOP_CB(interp) != bottomPtr->rootPtr) { + result = TclNRRunCallbacks(interp, result, bottomPtr->rootPtr, 1); + + if (TOP_CB(interp) != bottomPtr->rootPtr) { + Tcl_Panic("Abnormal return with busy callback stack"); + } + } + /* * Clear all expansions and same-level NR calls. * |