Attachment "1444291.patch" to
ticket [1444291fff]
added by
dgp
2006-03-07 04:39:28.
Index: generic/tclBasic.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclBasic.c,v
retrieving revision 1.75.2.20
diff -u -r1.75.2.20 tclBasic.c
--- generic/tclBasic.c 28 Feb 2006 15:44:35 -0000 1.75.2.20
+++ generic/tclBasic.c 6 Mar 2006 21:37:11 -0000
@@ -2984,6 +2984,7 @@
int code = TCL_OK;
int traceCode = TCL_OK;
int checkTraces = 1;
+ Namespace *savedNsPtr = NULL;
if (TclInterpReady(interp) == TCL_ERROR) {
return TCL_ERROR;
@@ -2993,6 +2994,15 @@
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;
+ }
+
/*
* If any execution traces rename or delete the current command,
* we may need (at most) two passes here.
@@ -3005,19 +3015,8 @@
* word array with "unknown" as the first word and 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.
*/
-
- savedVarFramePtr = iPtr->varFramePtr;
- if (flags & (TCL_EVAL_INVOKE | TCL_EVAL_GLOBAL)) {
- iPtr->varFramePtr = NULL;
- }
cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, objv[0]);
- iPtr->varFramePtr = savedVarFramePtr;
-
if (cmdPtr == NULL) {
newObjv = (Tcl_Obj **) ckalloc((unsigned)
((objc + 1) * sizeof (Tcl_Obj *)));
@@ -3035,13 +3034,19 @@
} else {
iPtr->numLevels++;
code = TclEvalObjvInternal(interp, objc+1, newObjv,
- command, length, flags);
+ command, length, 0);
iPtr->numLevels--;
}
Tcl_DecrRefCount(newObjv[0]);
ckfree((char *) newObjv);
+ if (savedNsPtr) {
+ iPtr->varFramePtr->nsPtr = savedNsPtr;
+ }
goto done;
}
+ if (savedNsPtr) {
+ iPtr->varFramePtr->nsPtr = savedNsPtr;
+ }
/*
* Call trace procedures if needed.
@@ -3054,10 +3059,6 @@
* any existing traces, then the set checkTraces to 0 and
* go through this while loop one more time.
*/
- savedVarFramePtr = iPtr->varFramePtr;
- 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);
@@ -3067,7 +3068,6 @@
traceCode = TclCheckExecutionTraces(interp, command, length,
cmdPtr, code, TCL_TRACE_ENTER_EXEC, objc, objv);
}
- iPtr->varFramePtr = savedVarFramePtr;
cmdPtr->refCount--;
if (cmdEpoch != cmdPtr->cmdEpoch) {
/* The command has been modified in some way */
@@ -3084,12 +3084,7 @@
cmdPtr->refCount++;
iPtr->cmdCount++;
if ( code == TCL_OK && traceCode == TCL_OK) {
- savedVarFramePtr = iPtr->varFramePtr;
- if (flags & TCL_EVAL_GLOBAL) {
- iPtr->varFramePtr = NULL;
- }
code = (*cmdPtr->objProc)(cmdPtr->objClientData, interp, objc, objv);
- iPtr->varFramePtr = savedVarFramePtr;
}
if (Tcl_AsyncReady()) {
code = Tcl_AsyncInvoke(interp, code);
@@ -3101,10 +3096,6 @@
if (!(cmdPtr->flags & CMD_IS_DELETED)) {
int saveErrFlags = iPtr->flags
& (ERR_IN_PROGRESS | ERR_ALREADY_LOGGED | ERROR_CODE_SET);
- savedVarFramePtr = iPtr->varFramePtr;
- 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);
@@ -3113,7 +3104,6 @@
traceCode = TclCheckInterpTraces(interp, command, length,
cmdPtr, code, TCL_TRACE_LEAVE_EXEC, objc, objv);
}
- iPtr->varFramePtr = savedVarFramePtr;
if (traceCode == TCL_OK) {
iPtr->flags |= saveErrFlags;
}
@@ -3143,6 +3133,7 @@
}
done:
+ iPtr->varFramePtr = savedVarFramePtr;
return code;
}
Index: tests/parse.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/parse.test,v
retrieving revision 1.11.2.3
diff -u -r1.11.2.3 parse.test
--- tests/parse.test 28 Feb 2006 15:44:36 -0000 1.11.2.3
+++ tests/parse.test 6 Mar 2006 21:37:12 -0000
@@ -312,7 +312,27 @@
rename ::unknown {}
rename unknown.save ::unknown
set ::info
-} [subst {[set level 2; incr level [info level]] namespace 1 global 1 global}]
+} [subst {[set level 2; incr level [info level]] global 1 global 1 global}]
+test parse-8.12 {Tcl_EvalObjv procedure, TCL_EVAL_INVOKE} {
+ set ::auto_index(noSuchCommand) {
+ proc noSuchCommand {} {lappend ::info global}
+ }
+ set ::auto_index(::[string trimleft [namespace current]::test_ns_1::noSuchCommand :]) [list \
+ proc [namespace current]::test_ns_1::noSuchCommand {} {
+ lappend ::info ns
+ }]
+ catch {rename ::noSuchCommand {}}
+ set ::slave [interp create]
+ $::slave alias bar noSuchCommand
+ set ::info {}
+ namespace eval test_ns_1 {
+ $::slave eval bar
+ }
+ namespace delete test_ns_1
+ interp delete $::slave
+ catch {rename ::noSuchCommand {}}
+ set ::info
+} global
test parse-9.1 {Tcl_LogCommandInfo, line numbers} {
catch {unset x}