summaryrefslogtreecommitdiffstats
path: root/generic/tclBasic.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclBasic.c')
-rw-r--r--generic/tclBasic.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/generic/tclBasic.c b/generic/tclBasic.c
index a7dce89..6f695af 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.456 2010/05/03 14:36:41 nijtmans Exp $
+ * RCS: @(#) $Id: tclBasic.c,v 1.457 2010/06/05 16:24:26 msofer Exp $
*/
#include "tclInt.h"
@@ -8710,6 +8710,7 @@ NRCoroutineExitCallback(
TclCleanupCommandMacro(cmdPtr);
corPtr->eePtr->corPtr = NULL;
+ TclPopStackFrame(interp);
TclDeleteExecEnv(corPtr->eePtr);
corPtr->eePtr = NULL;
@@ -8790,6 +8791,7 @@ NRInterpCoroutine(
*/
SAVE_CONTEXT(corPtr->caller);
+ corPtr->base.framePtr->callerPtr = iPtr->framePtr;
RESTORE_CONTEXT(corPtr->running);
corPtr->auxNumLevels = iPtr->numLevels;
iPtr->numLevels += nestNumLevels;
@@ -8819,6 +8821,8 @@ TclNRCoroutineObjCmd(
const char *procName;
Namespace *nsPtr, *altNsPtr, *cxtNsPtr;
Tcl_DString ds;
+ Tcl_CallFrame *framePtr;
+
if (objc < 3) {
Tcl_WrongNumArgs(interp, 1, objv, "name cmd ?arg ...?");
@@ -8922,11 +8926,31 @@ TclNRCoroutineObjCmd(
}
/*
+ * Create the coro's execEnv and switch to it so that any CallFrames or
+ * callbacks refer to the new execEnv's stack.
+ */
+
+ corPtr->eePtr = TclCreateExecEnv(interp, CORO_STACK_INITIAL_SIZE);
+ corPtr->callerEEPtr = iPtr->execEnvPtr;
+ corPtr->eePtr->corPtr = corPtr;
+ iPtr->execEnvPtr = corPtr->eePtr;
+
+ /* push a base call frame; save the current namespace to do a correct
+ * command lookup.
+ */
+
+ nsPtr = iPtr->varFramePtr->nsPtr;
+ TclPushStackFrame(interp, &framePtr,
+ (Tcl_Namespace *) iPtr->globalNsPtr, 0);
+ iPtr->varFramePtr = iPtr->rootFramePtr;
+
+ /*
* Save the base context. The base cmdFramePtr is unknown at this time: it
* will be allocated in the Tcl stack. So signal TEBC that it has to
* initialize the base cmdFramePtr by setting it to NULL.
*/
+ SAVE_CONTEXT(corPtr->base);
corPtr->base.cmdFramePtr = NULL;
corPtr->running = NULL_CONTEXT;
corPtr->stackLevel = NULL;
@@ -8944,20 +8968,13 @@ TclNRCoroutineObjCmd(
cmdObjPtr->typePtr = NULL;
/*
- * Create the coro's execEnv and switch to it so that any CallFrames or
- * callbacks refer to the new execEnv's stack. Add the exit callback, then
- * the callback to eval the coro body.
+ * Add the exit callback, then the callback to eval the coro body
*/
- corPtr->eePtr = TclCreateExecEnv(interp, CORO_STACK_INITIAL_SIZE);
- corPtr->callerEEPtr = iPtr->execEnvPtr;
- corPtr->eePtr->corPtr = corPtr;
- iPtr->execEnvPtr = corPtr->eePtr;
-
TclNRAddCallback(interp, NRCoroutineExitCallback, corPtr,
NULL, NULL, NULL);
iPtr->evalFlags |= TCL_EVAL_REDIRECT;
- iPtr->lookupNsPtr = iPtr->varFramePtr->nsPtr;
+ iPtr->lookupNsPtr = nsPtr;
TclNREvalObjEx(interp, cmdObjPtr, 0, NULL, 0);
return TCL_OK;