summaryrefslogtreecommitdiffstats
path: root/generic/tclBasic.c
diff options
context:
space:
mode:
authorKevin B Kenny <kennykb@acm.org>2010-12-01 16:42:33 (GMT)
committerKevin B Kenny <kennykb@acm.org>2010-12-01 16:42:33 (GMT)
commit921c2612861d68b7b4eee66736379431ac081f30 (patch)
tree47091361dfd1c093c24bb1dc06082c6dc469eaad /generic/tclBasic.c
parent86b28e0c4b2444435a30d345b3fe26daaf9de126 (diff)
downloadtcl-921c2612861d68b7b4eee66736379431ac081f30.zip
tcl-921c2612861d68b7b4eee66736379431ac081f30.tar.gz
tcl-921c2612861d68b7b4eee66736379431ac081f30.tar.bz2
merge
Diffstat (limited to 'generic/tclBasic.c')
-rw-r--r--generic/tclBasic.c64
1 files changed, 61 insertions, 3 deletions
diff --git a/generic/tclBasic.c b/generic/tclBasic.c
index 954426c..90d5460 100644
--- a/generic/tclBasic.c
+++ b/generic/tclBasic.c
@@ -16,7 +16,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclBasic.c,v 1.465.2.4 2010/10/23 15:49:54 kennykb Exp $
+ * RCS: @(#) $Id: tclBasic.c,v 1.465.2.5 2010/12/01 16:42:34 kennykb Exp $
*/
#include "tclInt.h"
@@ -168,6 +168,7 @@ static Tcl_NRPostProc YieldToCallback;
static void ClearTailcall(Tcl_Interp *interp,
struct TEOV_callback *tailcallPtr);
+static Tcl_ObjCmdProc NRCoroInjectObjCmd;
MODULE_SCOPE const TclStubs tclStubs;
@@ -596,6 +597,15 @@ Tcl_CreateInterp(void)
iPtr->resultSpace[0] = 0;
iPtr->threadId = Tcl_GetCurrentThread();
+ /* TIP #378 */
+#ifdef TCL_INTERP_DEBUG_FRAME
+ iPtr->flags |= INTERP_DEBUG_FRAME;
+#else
+ if (getenv("TCL_INTERP_DEBUG_FRAME") != NULL) {
+ iPtr->flags |= INTERP_DEBUG_FRAME;
+ }
+#endif
+
/*
* Initialise the tables for variable traces and searches *before*
* creating the global ns - so that the trace on errorInfo can be
@@ -826,7 +836,9 @@ Tcl_CreateInterp(void)
TclNRYieldToObjCmd, NULL, NULL);
Tcl_NRCreateCommand(interp, "::tcl::unsupported::yieldm", NULL,
TclNRYieldObjCmd, INT2PTR(CORO_ACTIVATE_YIELDM), NULL);
-
+ Tcl_NRCreateCommand(interp, "::tcl::unsupported::inject", NULL,
+ NRCoroInjectObjCmd, NULL, NULL);
+
#ifdef USE_DTRACE
/*
* Register the tcl::dtrace command.
@@ -7697,7 +7709,7 @@ ExprRandFunc(
* to insure different seeds in different threads (bug #416643)
*/
- iPtr->randSeed = TclpGetClicks() + ((long)Tcl_GetCurrentThread()<<12);
+ iPtr->randSeed = TclpGetClicks() + (PTR2INT(Tcl_GetCurrentThread())<<12);
/*
* Make sure 1 <= randSeed <= (2^31) - 2. See below.
@@ -8754,6 +8766,52 @@ NRCoroutineActivateCallback(
}
}
+
+static int
+NRCoroInjectObjCmd(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *const objv[])
+{
+ Command *cmdPtr;
+ CoroutineData *corPtr;
+ ExecEnv *savedEEPtr = iPtr->execEnvPtr;
+
+ /*
+ * Usage more or less like tailcall:
+ * inject coroName cmd ?arg1 arg2 ...?
+ */
+
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "coroName cmd ?arg1 arg2 ...?");
+ return TCL_ERROR;
+ }
+
+ cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, objv[1]);
+ if ((!cmdPtr) || (cmdPtr->nreProc != NRInterpCoroutine)) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("can only inject a command into a coroutine", -1));
+ return TCL_ERROR;
+ }
+
+ corPtr = (CoroutineData *) cmdPtr->objClientData;
+ if (!COR_IS_SUSPENDED(corPtr)) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("can only inject a command into a suspended coroutine", -1));
+ return TCL_ERROR;
+ }
+
+ /*
+ * Add the callback to the coro's execEnv, so that it is the first thing
+ * to happen when the coro is resumed
+ */
+
+ iPtr->execEnvPtr = corPtr->eePtr;
+ Tcl_NREvalObj(interp, Tcl_NewListObj(objc-2, objv+2), 0);
+ iPtr->execEnvPtr = savedEEPtr;
+
+ return TCL_OK;
+}
+
int
NRInterpCoroutine(
ClientData clientData,