diff options
author | Miguel Sofer <miguel.sofer@gmail.com> | 2009-03-19 23:31:36 (GMT) |
---|---|---|
committer | Miguel Sofer <miguel.sofer@gmail.com> | 2009-03-19 23:31:36 (GMT) |
commit | e6e54e79e2d7333a81f91a9525ed518f9d96a0cd (patch) | |
tree | 72f27d85c68739eb5710cc682cb2fd79c500452f /generic/tclInt.h | |
parent | e77ab61acdd95f64d2222c71c72f2b2db1a39f65 (diff) | |
download | tcl-e6e54e79e2d7333a81f91a9525ed518f9d96a0cd.zip tcl-e6e54e79e2d7333a81f91a9525ed518f9d96a0cd.tar.gz tcl-e6e54e79e2d7333a81f91a9525ed518f9d96a0cd.tar.bz2 |
* generic/tcl.h:
* generic/tclInt.h:
* generic/tclBasic.c:
* generic/tclExecute.c:
* generic/tclNamesp.c (Tcl_PopCallFrame): Rewritten tailcall
implementation, ::unsupported::atProcExit is (temporarily?)
gone. The new approach is much simpler, and also closer to being
correct. This commit fixes [Bug 2649975] and [Bug 2695587].
* tests/coroutine.test: Moved the tests to their own files,
* tests/tailcall.test: removed the unsupported.test. Added
* tests/unsupported.test: tests for the fixed bugs.
Diffstat (limited to 'generic/tclInt.h')
-rw-r--r-- | generic/tclInt.h | 49 |
1 files changed, 43 insertions, 6 deletions
diff --git a/generic/tclInt.h b/generic/tclInt.h index 3f7a2dc..48473bd 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -15,7 +15,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclInt.h,v 1.418 2009/03/09 09:12:39 dkf Exp $ + * RCS: @(#) $Id: tclInt.h,v 1.419 2009/03/19 23:31:37 msofer Exp $ */ #ifndef _TCLINT @@ -1056,6 +1056,13 @@ typedef struct CallFrame { * meaning of the value is, which we do not * specify. */ LocalCache *localCachePtr; + struct TEOV_callback *tailcallPtr; + /* The callback implementing the call to be + * executed by the command that pushed this + * frame. It can be TAILCALL_NONE to signal + * that we are tailcalling a frame further up + * the stack. + */ } CallFrame; #define FRAME_IS_PROC 0x1 @@ -2006,10 +2013,13 @@ typedef struct Interp { * tclOOInt.h and tclOO.c for real definition * and setup. */ - struct TEOV_callback *atExitPtr; - /* Callbacks to be run after a command exited; - * this is only set for atProcExirt or - * tailcalls that fall back out of tebc. */ + struct TEOV_callback *deferredCallbacks; + /* Callbacks that are set previous to a call + * to some Eval function but that actually + * belong to the command that is about to be + * called - ie, they should be run *before* + * any tailcall is invoked. + */ #ifdef TCL_COMPILE_STATS /* @@ -2589,7 +2599,7 @@ MODULE_SCOPE Tcl_ObjCmdProc TclNRTryObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclNRWhileObjCmd; MODULE_SCOPE Tcl_NRPostProc TclNRForIterCallback; -MODULE_SCOPE Tcl_ObjCmdProc TclNRAtProcExitObjCmd; +MODULE_SCOPE Tcl_ObjCmdProc TclNRTailcallObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclNRCoroutineObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldObjCmd; @@ -4208,6 +4218,33 @@ typedef struct TEOV_callback { TOP_CB(interp) = callbackPtr; \ } +#define TclNRDeferCallback(interp,postProcPtr,data0,data1,data2,data3) { \ + TEOV_callback *callbackPtr; \ + TCLNR_ALLOC((interp), (callbackPtr)); \ + callbackPtr->procPtr = (postProcPtr); \ + callbackPtr->data[0] = (ClientData)(data0); \ + callbackPtr->data[1] = (ClientData)(data1); \ + callbackPtr->data[2] = (ClientData)(data2); \ + callbackPtr->data[3] = (ClientData)(data3); \ + callbackPtr->nextPtr = ((Interp *)interp)->deferredCallbacks; \ + ((Interp *)interp)->deferredCallbacks = callbackPtr; \ + } + +#define TclNRSpliceCallbacks(interp,topPtr) { \ + TEOV_callback *bottomPtr = topPtr; \ + while (bottomPtr->nextPtr) { \ + bottomPtr = bottomPtr->nextPtr; \ + } \ + bottomPtr->nextPtr = TOP_CB(interp); \ + TOP_CB(interp) = topPtr; \ + } + +#define TclNRSpliceDeferred(interp) \ + if (((Interp *)interp)->deferredCallbacks) { \ + TclNRSpliceCallbacks(interp, ((Interp *)interp)->deferredCallbacks); \ + ((Interp *)interp)->deferredCallbacks = NULL; \ + } + #if NRE_USE_SMALL_ALLOC #define TCLNR_ALLOC(interp, ptr) \ TclSmallAllocEx(interp, sizeof(TEOV_callback), (ptr)) |