summaryrefslogtreecommitdiffstats
path: root/generic/tclInt.h
diff options
context:
space:
mode:
authorMiguel Sofer <miguel.sofer@gmail.com>2009-03-19 23:31:36 (GMT)
committerMiguel Sofer <miguel.sofer@gmail.com>2009-03-19 23:31:36 (GMT)
commite6e54e79e2d7333a81f91a9525ed518f9d96a0cd (patch)
tree72f27d85c68739eb5710cc682cb2fd79c500452f /generic/tclInt.h
parente77ab61acdd95f64d2222c71c72f2b2db1a39f65 (diff)
downloadtcl-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.h49
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))