summaryrefslogtreecommitdiffstats
path: root/generic/tclBasic.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclBasic.c')
-rw-r--r--generic/tclBasic.c57
1 files changed, 22 insertions, 35 deletions
diff --git a/generic/tclBasic.c b/generic/tclBasic.c
index dcfedc4..511258f 100644
--- a/generic/tclBasic.c
+++ b/generic/tclBasic.c
@@ -13,7 +13,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.192 2006/02/28 15:47:10 dgp Exp $
+ * RCS: @(#) $Id: tclBasic.c,v 1.193 2006/03/06 21:56:34 dgp Exp $
*/
#include "tclInt.h"
@@ -3244,6 +3244,7 @@ TclEvalObjvInternal(
int traceCode = TCL_OK;
int checkTraces = 1;
int cmdEpoch;
+ Namespace *savedNsPtr = NULL;
if (TclInterpReady(interp) == TCL_ERROR) {
return TCL_ERROR;
@@ -3253,6 +3254,15 @@ TclEvalObjvInternal(
return TCL_OK;
}
+ /* Configure evaluation context to match the requested flags */
+ savedVarFramePtr = iPtr->varFramePtr;
+ if (flags & TCL_EVAL_GLOBAL) {
+ iPtr->varFramePtr = NULL;
+ } else if ((flags & TCL_EVAL_INVOKE) && iPtr->varFramePtr) {
+ savedNsPtr = iPtr->varFramePtr->nsPtr;
+ iPtr->varFramePtr->nsPtr = iPtr->globalNsPtr;
+ }
+
/*
* Find the function to execute this command. If there isn't one, then see
* if there is an unknown command handler registered for this namespace.
@@ -3260,23 +3270,11 @@ TclEvalObjvInternal(
* the original command words as arguments. Then call ourselves
* recursively to execute it.
*
- * If caller requests, or if we're resolving the target end of an
- * interpeter alias (TCL_EVAL_INVOKE), be sure to do command name
- * resolution in the global namespace.
- *
* If any execution traces rename or delete the current command, we may
* need (at most) two passes here.
*/
reparseBecauseOfTraces:
- savedVarFramePtr = iPtr->varFramePtr;
- /*
- * Both INVOKE and GLOBAL flags dictate that command resolution
- * happens in an [uplevel #0] context. (iPtr->varFramePtr == NULL)
- */
- if (flags & (TCL_EVAL_INVOKE | TCL_EVAL_GLOBAL)) {
- iPtr->varFramePtr = NULL;
- }
cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, objv[0]);
if (cmdPtr == NULL) {
Namespace *currNsPtr = NULL; /* Used to check for and invoke any
@@ -3315,7 +3313,6 @@ TclEvalObjvInternal(
newObjv[i+handlerObjc] = objv[i];
}
cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, newObjv[0]);
- iPtr->varFramePtr = savedVarFramePtr;
if (cmdPtr == NULL) {
Tcl_AppendResult(interp, "invalid command name \"",
TclGetString(objv[0]), "\"", NULL);
@@ -3323,16 +3320,21 @@ TclEvalObjvInternal(
} else {
iPtr->numLevels++;
code = TclEvalObjvInternal(interp, newObjc, newObjv, command,
- length, flags);
+ length, 0);
iPtr->numLevels--;
}
for (i = 0; i < handlerObjc; ++i) {
Tcl_DecrRefCount(newObjv[i]);
}
ckfree((char *) newObjv);
- return code;
+ if (savedNsPtr) {
+ iPtr->varFramePtr->nsPtr = savedNsPtr;
+ }
+ goto done;
+ }
+ if (savedNsPtr) {
+ iPtr->varFramePtr->nsPtr = savedNsPtr;
}
- iPtr->varFramePtr = savedVarFramePtr;
/*
* Call trace functions if needed.
@@ -3348,9 +3350,6 @@ TclEvalObjvInternal(
* while loop one more time.
*/
- if (flags & TCL_EVAL_GLOBAL) {
- iPtr->varFramePtr = NULL;
- }
if (iPtr->tracePtr != NULL && traceCode == TCL_OK) {
traceCode = TclCheckInterpTraces(interp, command, length,
cmdPtr, code, TCL_TRACE_ENTER_EXEC, objc, objv);
@@ -3359,7 +3358,6 @@ TclEvalObjvInternal(
traceCode = TclCheckExecutionTraces(interp, command, length,
cmdPtr, code, TCL_TRACE_ENTER_EXEC, objc, objv);
}
- iPtr->varFramePtr = savedVarFramePtr;
cmdPtr->refCount--;
}
if (cmdEpoch != cmdPtr->cmdEpoch) {
@@ -3375,22 +3373,12 @@ TclEvalObjvInternal(
cmdPtr->refCount++;
iPtr->cmdCount++;
if (code == TCL_OK && traceCode == TCL_OK && !Tcl_LimitExceeded(interp)) {
- savedVarFramePtr = iPtr->varFramePtr;
- /*
- * Only the GLOBAL flag dictates command procedure exection (distinct
- * from command name resolution above) happens in an [uplevel #0]
- * context. (iPtr->varFramePtr == NULL)
- */
- if (flags & TCL_EVAL_GLOBAL) {
- iPtr->varFramePtr = NULL;
- }
if (!(flags & TCL_EVAL_INVOKE) &&
(iPtr->ensembleRewrite.sourceObjs != NULL) &&
!Tcl_IsEnsemble((Tcl_Command) cmdPtr)) {
iPtr->ensembleRewrite.sourceObjs = NULL;
}
code = (*cmdPtr->objProc)(cmdPtr->objClientData, interp, objc, objv);
- iPtr->varFramePtr = savedVarFramePtr;
}
if (Tcl_AsyncReady()) {
code = Tcl_AsyncInvoke(interp, code);
@@ -3404,9 +3392,6 @@ TclEvalObjvInternal(
*/
if (!(cmdPtr->flags & CMD_IS_DELETED)) {
- if (flags & TCL_EVAL_GLOBAL) {
- iPtr->varFramePtr = NULL;
- }
if ((cmdPtr->flags & CMD_HAS_EXEC_TRACES) && (traceCode == TCL_OK)) {
traceCode = TclCheckExecutionTraces(interp, command, length,
cmdPtr, code, TCL_TRACE_LEAVE_EXEC, objc, objv);
@@ -3415,7 +3400,6 @@ TclEvalObjvInternal(
traceCode = TclCheckInterpTraces(interp, command, length,
cmdPtr, code, TCL_TRACE_LEAVE_EXEC, objc, objv);
}
- iPtr->varFramePtr = savedVarFramePtr;
}
TclCleanupCommand(cmdPtr);
@@ -3439,6 +3423,9 @@ TclEvalObjvInternal(
if (*(iPtr->result) != 0) {
(void) Tcl_GetObjResult(interp);
}
+
+ done:
+ iPtr->varFramePtr = savedVarFramePtr;
return code;
}