Tcl Source Code

Artifact [5c1193e1a5]
Login

Artifact 5c1193e1a5b79d1cda8b2e044b10cc1ef2a9a8e6:

Attachment "varframe.patch" to ticket [1577278fff] added by msofer 2006-10-15 00:21:10.
Index: generic/tcl.h
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tcl.h,v
retrieving revision 1.217
diff -u -r1.217 tcl.h
--- generic/tcl.h	5 Oct 2006 21:24:39 -0000	1.217
+++ generic/tcl.h	14 Oct 2006 16:58:59 -0000
@@ -1062,7 +1062,7 @@
  *	TCL_EVAL_GLOBAL:	Execute script in global namespace
  *	TCL_EVAL_DIRECT:	Do not compile this script
  *	TCL_EVAL_INVOKE:	Magical Tcl_EvalObjv mode for aliases/ensembles
- *				o Run in global namespace
+ *				o Run in iPtr->lookupNsPtr or global namespace
  *				o Cut out of error traces
  *				o Don't reset the flags controlling ensemble
  *				  error message rewriting.
Index: generic/tclBasic.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclBasic.c,v
retrieving revision 1.197
diff -u -r1.197 tclBasic.c
--- generic/tclBasic.c	22 Sep 2006 18:13:27 -0000	1.197
+++ generic/tclBasic.c	14 Oct 2006 16:59:01 -0000
@@ -272,7 +272,9 @@
     ByteCodeStats *statsPtr;
 #endif /* TCL_COMPILE_STATS */
     char mathFuncName[32];
-
+    CallFrame *framePtr;
+    int result;
+    
     TclInitSubsystems();
 
     /*
@@ -306,8 +308,8 @@
 
     iPtr->numLevels = 0;
     iPtr->maxNestingDepth = MAX_NESTING_DEPTH;
-    iPtr->framePtr = NULL;
-    iPtr->varFramePtr = NULL;
+    iPtr->framePtr = NULL;    /* initialise as soon as :: is available */
+    iPtr->varFramePtr = NULL; /* initialise as soon as :: is available */
     iPtr->activeVarTracePtr = NULL;
 
     iPtr->returnOpts = NULL;
@@ -320,6 +322,9 @@
     iPtr->returnLevel = 1;
     iPtr->returnCode = TCL_OK;
 
+    iPtr->rootFramePtr = NULL; /* initialise as soon as :: is available */
+    iPtr->lookupNsPtr = NULL;
+
     iPtr->appendResult = NULL;
     iPtr->appendAvl = 0;
     iPtr->appendUsed = 0;
@@ -359,6 +364,24 @@
     }
 
     /*
+     * Initialise the rootCallframe. It cannot be allocated on the stack, as
+     * it has to be in place before TclCreateExecEnv tries to use a variable. 
+     */
+
+    /* This is needed to satisfy GCC 3.3's strict aliasing rules */
+    framePtr = (CallFrame *) ckalloc(sizeof(CallFrame));
+    result = Tcl_PushCallFrame(interp, (Tcl_CallFrame *) framePtr,
+	    (Tcl_Namespace *) iPtr->globalNsPtr, /*isProcCallFrame*/ 0);
+    if (result != TCL_OK) {
+	Tcl_Panic("Tcl_CreateInterp: faile to push the root stack frame");
+    }
+    framePtr->objc = 0;
+
+    iPtr->framePtr = framePtr; 
+    iPtr->varFramePtr = framePtr;
+    iPtr->rootFramePtr = framePtr;
+
+    /*
      * Initialize support for code compilation and execution. We call
      * TclCreateExecEnv after initializing namespaces since it tries to
      * reference a Tcl variable (it links to the Tcl "tcl_traceExec"
@@ -1054,6 +1077,12 @@
      */
 
     Tcl_DeleteNamespace((Tcl_Namespace *) iPtr->globalNsPtr);
+    if (iPtr->framePtr != iPtr->rootFramePtr) {
+	Tcl_Panic("DeleteInterpProc: popping rootCallFrame with other frames on top");
+    }
+    Tcl_PopCallFrame(interp);
+    ckfree((char *)iPtr->rootFramePtr);
+    iPtr->rootFramePtr = NULL;
 
     /*
      * Free up the result *after* deleting variables, since variable deletion
@@ -3240,10 +3269,10 @@
     Interp *iPtr = (Interp *) interp;
     Tcl_Obj **newObjv;
     int i;
-    CallFrame *savedVarFramePtr;/* Saves old copy of iPtr->varFramePtr in case
-				 * TCL_EVAL_GLOBAL was set. */
+    CallFrame *savedVarFramePtr = NULL;
+    CallFrame *varFramePtr = iPtr->varFramePtr;
     int code = TCL_OK;
-    int traceCode = TCL_OK;
+    int traceCode = TCL_OK; 
     int checkTraces = 1;
     int cmdEpoch;
     Namespace *savedNsPtr = NULL;
@@ -3257,12 +3286,19 @@
     }
 
     /* 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 ((flags & TCL_EVAL_GLOBAL)
+	    && (varFramePtr != iPtr->rootFramePtr)) {
+	varFramePtr = iPtr->rootFramePtr;
+	savedVarFramePtr = iPtr->varFramePtr;
+	iPtr->varFramePtr = varFramePtr; 
+    } else if (flags & TCL_EVAL_INVOKE) {
+	savedNsPtr = varFramePtr->nsPtr;
+	if (iPtr->lookupNsPtr) {
+	    varFramePtr->nsPtr = iPtr->lookupNsPtr;
+	} else {
+	    varFramePtr->nsPtr = iPtr->globalNsPtr;
+	}
     }
 
     /*
@@ -3286,14 +3322,12 @@
         int newObjc, handlerObjc;
         Tcl_Obj **handlerObjv;
 
-	if (iPtr->varFramePtr != NULL) {
-	    currNsPtr = iPtr->varFramePtr->nsPtr;
-	}
+	currNsPtr = varFramePtr->nsPtr;
 	if ((currNsPtr == NULL) || (currNsPtr->unknownHandlerPtr == NULL)) {
 	    currNsPtr = iPtr->globalNsPtr;
-	}
-	if (currNsPtr == NULL) {
-	    Tcl_Panic("TclEvalObjvInternal: NULL global namespace pointer");
+	    if (currNsPtr == NULL) {
+		Tcl_Panic("TclEvalObjvInternal: NULL global namespace pointer");
+	    }
 	}
         if (currNsPtr->unknownHandlerPtr == NULL) {
             /* Global namespace has lost unknown handler, reset. */
@@ -3330,14 +3364,16 @@
         }
 	ckfree((char *) newObjv);
 	if (savedNsPtr) {
-	    iPtr->varFramePtr->nsPtr = savedNsPtr;
+	    varFramePtr->nsPtr = savedNsPtr;
+	    iPtr->lookupNsPtr = NULL;
 	}
 	goto done;
     }
     if (savedNsPtr) {
-	iPtr->varFramePtr->nsPtr = savedNsPtr;
+	varFramePtr->nsPtr = savedNsPtr;
+	iPtr->lookupNsPtr = NULL;
     }
-
+    
     /*
      * Call trace functions if needed.
      */
@@ -3427,7 +3463,9 @@
     }
 
     done:
-    iPtr->varFramePtr = savedVarFramePtr;
+    if (savedVarFramePtr) {
+	iPtr->varFramePtr = savedVarFramePtr;
+    }
     return code;
 }
 
@@ -3674,7 +3712,7 @@
 
     savedVarFramePtr = iPtr->varFramePtr;
     if (flags & TCL_EVAL_GLOBAL) {
-	iPtr->varFramePtr = NULL;
+	iPtr->varFramePtr = iPtr->rootFramePtr;
     }
 
     /*
@@ -4054,7 +4092,7 @@
 
 	savedVarFramePtr = iPtr->varFramePtr;
 	if (flags & TCL_EVAL_GLOBAL) {
-	    iPtr->varFramePtr = NULL;
+	    iPtr->varFramePtr = iPtr->rootFramePtr;
 	}
 
 	result = TclCompEvalObj(interp, objPtr);
@@ -4794,7 +4832,7 @@
     CallFrame *savedVarFramePtr;
 
     savedVarFramePtr = iPtr->varFramePtr;
-    iPtr->varFramePtr = NULL;
+    iPtr->varFramePtr = iPtr->rootFramePtr;
     result = Tcl_Eval(interp, command);
     iPtr->varFramePtr = savedVarFramePtr;
     return result;
Index: generic/tclCmdIL.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclCmdIL.c,v
retrieving revision 1.87
diff -u -r1.87 tclCmdIL.c
--- generic/tclCmdIL.c	9 Aug 2006 14:16:03 -0000	1.87
+++ generic/tclCmdIL.c	14 Oct 2006 16:59:03 -0000
@@ -1278,22 +1278,18 @@
 {
     Interp *iPtr = (Interp *) interp;
     int level;
-    CallFrame *framePtr;
+    CallFrame *framePtr, *rootFramePtr = iPtr->rootFramePtr;
     Tcl_Obj *listPtr;
 
     if (objc == 2) {		/* just "info level" */
-	if (iPtr->varFramePtr == NULL) {
-	    Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
-	} else {
-	    Tcl_SetObjResult(interp, Tcl_NewIntObj(iPtr->varFramePtr->level));
-	}
+	Tcl_SetObjResult(interp, Tcl_NewIntObj(iPtr->varFramePtr->level));
 	return TCL_OK;
     } else if (objc == 3) {
 	if (Tcl_GetIntFromObj(interp, objv[2], &level) != TCL_OK) {
 	    return TCL_ERROR;
 	}
 	if (level <= 0) {
-	    if (iPtr->varFramePtr == NULL) {
+	    if (iPtr->varFramePtr == rootFramePtr) {
 		levelError:
 		Tcl_AppendResult(interp, "bad level \"",
 			TclGetString(objv[2]), "\"", (char *) NULL);
@@ -1301,13 +1297,13 @@
 	    }
 	    level += iPtr->varFramePtr->level;
 	}
-	for (framePtr = iPtr->varFramePtr;  framePtr != NULL;
+	for (framePtr = iPtr->varFramePtr;  framePtr != rootFramePtr;
 		framePtr = framePtr->callerVarPtr) {
 	    if (framePtr->level == level) {
 		break;
 	    }
 	}
-	if (framePtr == NULL) {
+	if (framePtr == rootFramePtr) {
 	    goto levelError;
 	}
 
@@ -1451,8 +1447,7 @@
 	return TCL_ERROR;
     }
 
-    if (iPtr->varFramePtr == NULL ||
-	    !(iPtr->varFramePtr->isProcCallFrame & FRAME_IS_PROC )) {
+    if (!(iPtr->varFramePtr->isProcCallFrame & FRAME_IS_PROC )) {
 	return TCL_OK;
     }
 
@@ -2054,8 +2049,7 @@
 
     listPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
 
-    if ((iPtr->varFramePtr == NULL)
-	    || !(iPtr->varFramePtr->isProcCallFrame & FRAME_IS_PROC)
+    if (!(iPtr->varFramePtr->isProcCallFrame & FRAME_IS_PROC)
 	    || specificNsInPattern) {
 	/*
 	 * There is no frame pointer, the frame pointer was pushed only to
Index: generic/tclInt.h
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclInt.h,v
retrieving revision 1.279
diff -u -r1.279 tclInt.h
--- generic/tclInt.h	30 Sep 2006 19:00:12 -0000	1.279
+++ generic/tclInt.h	14 Oct 2006 16:59:09 -0000
@@ -1344,19 +1344,18 @@
 				 * assumes that infinite recursion has
 				 * occurred and it generates an error. */
     CallFrame *framePtr;	/* Points to top-most in stack of all nested
-				 * procedure invocations. NULL means there are
-				 * no active procedures. */
+				 * procedure invocations. */
     CallFrame *varFramePtr;	/* Points to the call frame whose variables
 				 * are currently in use (same as framePtr
-				 * unless an "uplevel" command is executing).
-				 * NULL means no procedure is active or
-				 * "uplevel 0" is executing. */
+				 * unless an "uplevel" command is
+				 * executing). */ 
     ActiveVarTrace *activeVarTracePtr;
 				/* First in list of active traces for interp,
 				 * or NULL if no active traces. */
     int returnCode;		/* [return -code] parameter */
-    char *unused3;		/* No longer used (was errorInfo) */
-    char *unused4;		/* No longer used (was errorCode) */
+    CallFrame *rootFramePtr;    /* Global frame pointer for this interpreter */
+    Namespace *lookupNsPtr;	/* Namespace to use ONLY on the next
+                                * TCL_EVAL_INVOKE call to Tcl_EvalObjv */
 
     /*
      * Information used by Tcl_AppendResult to keep track of partial results.
Index: generic/tclNamesp.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclNamesp.c,v
retrieving revision 1.101
diff -u -r1.101 tclNamesp.c
--- generic/tclNamesp.c	10 Oct 2006 16:45:04 -0000	1.101
+++ generic/tclNamesp.c	14 Oct 2006 16:59:14 -0000
@@ -333,11 +333,7 @@
     register Interp *iPtr = (Interp *) interp;
     register Namespace *nsPtr;
 
-    if (iPtr->varFramePtr != NULL) {
-	nsPtr = iPtr->varFramePtr->nsPtr;
-    } else {
-	nsPtr = iPtr->globalNsPtr;
-    }
+    nsPtr = iPtr->varFramePtr->nsPtr;
     return (Tcl_Namespace *) nsPtr;
 }
 
@@ -436,7 +432,7 @@
     if (iPtr->varFramePtr != NULL) {
 	framePtr->level = (iPtr->varFramePtr->level + 1);
     } else {
-	framePtr->level = 1;
+	framePtr->level = 0;
     }
     framePtr->procPtr = NULL;		/* no called procedure */
     framePtr->varTablePtr = NULL;	/* and no local variables */
@@ -486,8 +482,12 @@
      * the variable deletion don't see the partially-deleted frame.
      */
 
-    iPtr->framePtr = framePtr->callerPtr;
-    iPtr->varFramePtr = framePtr->callerVarPtr;
+    if (framePtr->callerPtr) {
+	iPtr->framePtr = framePtr->callerPtr;    
+	iPtr->varFramePtr = framePtr->callerVarPtr;
+    } else {
+	/* Tcl_PopCallFrame: trying to pop rootCallFrame! */
+    }
 
     if (framePtr->varTablePtr != NULL) {
 	TclDeleteVars(iPtr, framePtr->varTablePtr);
@@ -968,7 +968,8 @@
      * refCount reaches 0.
      */
 
-    if (nsPtr->activationCount > 0) {
+    if ((nsPtr->activationCount > 0)
+	    && !((nsPtr == globalNsPtr) && (nsPtr->activationCount == 1))) {
 	nsPtr->flags |= NS_DYING;
 	if (nsPtr->parentPtr != NULL) {
 	    entryPtr = Tcl_FindHashEntry(&nsPtr->parentPtr->childTable,
@@ -2082,11 +2083,7 @@
     if (flags & TCL_GLOBAL_ONLY) {
 	nsPtr = globalNsPtr;
     } else if (nsPtr == NULL) {
-	if (iPtr->varFramePtr != NULL) {
-	    nsPtr = iPtr->varFramePtr->nsPtr;
-	} else {
-	    nsPtr = iPtr->globalNsPtr;
-	}
+	nsPtr = iPtr->varFramePtr->nsPtr;
     }
 
     start = qualName;		/* Pts to start of qualifying namespace. */
@@ -2830,7 +2827,7 @@
     savedFramePtr = iPtr->varFramePtr;
     name = TclGetString(objPtr);
     if ((*name++ == ':') && (*name == ':')) {
-	iPtr->varFramePtr = NULL;
+	iPtr->varFramePtr = iPtr->rootFramePtr;
     }
 
     currNsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
@@ -4585,11 +4582,11 @@
     int objc,			/* Number of arguments. */
     Tcl_Obj *const objv[])	/* Argument objects. */
 {
-    Tcl_Namespace *nsPtr;
+    Interp *iPtr = (Interp *) interp;
+    Tcl_Namespace *nsPtr, *savedNsPtr;
     int result;
     Var *otherPtr, *arrayPtr;
     char *myName;
-    CallFrame frame, *framePtr = &frame;
 
     if (objc < 5 || !(objc & 1)) {
 	Tcl_WrongNumArgs(interp, 2, objv,
@@ -4622,11 +4619,12 @@
 	 * Locate the other variable
 	 */
 
-	Tcl_PushCallFrame(interp, (Tcl_CallFrame *) framePtr, nsPtr, 0);
+	savedNsPtr = (Tcl_Namespace *) iPtr->varFramePtr->nsPtr;
+	iPtr->varFramePtr->nsPtr = (Namespace *) nsPtr;
 	otherPtr = TclObjLookupVar(interp, objv[0], NULL,
 		(TCL_NAMESPACE_ONLY | TCL_LEAVE_ERR_MSG), "access",
 		/*createPart1*/ 1, /*createPart2*/ 1, &arrayPtr);
-	Tcl_PopCallFrame(interp);
+	iPtr->varFramePtr->nsPtr = (Namespace *) savedNsPtr;
 	if (otherPtr == NULL) {
 	    return TCL_ERROR;
 	}
Index: generic/tclObj.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclObj.c,v
retrieving revision 1.113
diff -u -r1.113 tclObj.c
--- generic/tclObj.c	30 Sep 2006 19:00:13 -0000	1.113
+++ generic/tclObj.c	14 Oct 2006 16:59:16 -0000
@@ -3485,7 +3485,7 @@
     savedFramePtr = iPtr->varFramePtr;
     name = Tcl_GetString(objPtr);
     if ((*name++ == ':') && (*name == ':')) {
-	iPtr->varFramePtr = NULL;
+	iPtr->varFramePtr = iPtr->rootFramePtr;
     }
 
     /*
@@ -3507,11 +3507,7 @@
      * Get the current namespace.
      */
 
-    if (iPtr->varFramePtr != NULL) {
-	currNsPtr = iPtr->varFramePtr->nsPtr;
-    } else {
-	currNsPtr = iPtr->globalNsPtr;
-    }
+    currNsPtr = iPtr->varFramePtr->nsPtr;
 
     /*
      * Check the context namespace and the namespace epoch of the resolved
@@ -3599,18 +3595,14 @@
     savedFramePtr = iPtr->varFramePtr;
     name = Tcl_GetString(objPtr);
     if ((*name++ == ':') && (*name == ':')) {
-	iPtr->varFramePtr = NULL;
+	iPtr->varFramePtr = iPtr->rootFramePtr;
     }
 
     /*
      * Get the current namespace.
      */
 
-    if (iPtr->varFramePtr != NULL) {
-	currNsPtr = iPtr->varFramePtr->nsPtr;
-    } else {
-	currNsPtr = iPtr->globalNsPtr;
-    }
+    currNsPtr = iPtr->varFramePtr->nsPtr;
 
     cmdPtr->refCount++;
     resPtr = (ResolvedCmdName *) ckalloc(sizeof(ResolvedCmdName));
@@ -3772,11 +3764,7 @@
 	 * Get the current namespace.
 	 */
 
-	if (iPtr->varFramePtr != NULL) {
-	    currNsPtr = iPtr->varFramePtr->nsPtr;
-	} else {
-	    currNsPtr = iPtr->globalNsPtr;
-	}
+	currNsPtr = iPtr->varFramePtr->nsPtr;
 
 	cmdPtr->refCount++;
 	resPtr = (ResolvedCmdName *) ckalloc(sizeof(ResolvedCmdName));
Index: generic/tclProc.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclProc.c,v
retrieving revision 1.92
diff -u -r1.92 tclProc.c
--- generic/tclProc.c	30 Sep 2006 17:56:47 -0000	1.92
+++ generic/tclProc.c	14 Oct 2006 16:59:17 -0000
@@ -604,7 +604,7 @@
      */
 
     result = 1;
-    curLevel = (iPtr->varFramePtr == NULL) ? 0 : iPtr->varFramePtr->level;
+    curLevel = iPtr->varFramePtr->level;
     if (*name== '#') {
 	if (Tcl_GetInt(interp, name+1, &level) != TCL_OK || level < 0) {
 	    goto levelError;
@@ -623,19 +623,16 @@
      * Figure out which frame to use, and return it to the caller.
      */
 
-    if (level == 0) {
-	framePtr = NULL;
-    } else {
-	for (framePtr = iPtr->varFramePtr; framePtr != NULL;
-		framePtr = framePtr->callerVarPtr) {
-	    if (framePtr->level == level) {
-		break;
-	    }
-	}
-	if (framePtr == NULL) {
-	    goto levelError;
+    for (framePtr = iPtr->varFramePtr; framePtr != NULL;
+	 framePtr = framePtr->callerVarPtr) {
+	if (framePtr->level == level) {
+	    break;
 	}
     }
+    if (framePtr == NULL) {
+	goto levelError;
+    }
+    
     *framePtrPtr = framePtr;
     return result;
 
@@ -687,7 +684,7 @@
      */
 
     result = 1;
-    curLevel = (iPtr->varFramePtr == NULL) ? 0 : iPtr->varFramePtr->level;
+    curLevel = iPtr->varFramePtr->level;
     if (objPtr->typePtr == &levelReferenceType) {
 	if ((int) objPtr->internalRep.twoPtrValue.ptr1) {
 	    level = curLevel - (int) objPtr->internalRep.twoPtrValue.ptr2;
@@ -753,19 +750,15 @@
      * Figure out which frame to use, and return it to the caller.
      */
 
-    if (level == 0) {
-	framePtr = NULL;
-    } else {
-	for (framePtr = iPtr->varFramePtr; framePtr != NULL;
-		framePtr = framePtr->callerVarPtr) {
-	    if (framePtr->level == level) {
-		break;
-	    }
-	}
-	if (framePtr == NULL) {
-	    goto levelError;
+    for (framePtr = iPtr->varFramePtr; framePtr != NULL;
+	 framePtr = framePtr->callerVarPtr) {
+	if (framePtr->level == level) {
+	    break;
 	}
     }
+    if (framePtr == NULL) {
+	goto levelError;
+    }
     *framePtrPtr = framePtr;
     return result;
 
Index: generic/tclTrace.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclTrace.c,v
retrieving revision 1.33
diff -u -r1.33 tclTrace.c
--- generic/tclTrace.c	11 Apr 2006 14:37:54 -0000	1.33
+++ generic/tclTrace.c	14 Oct 2006 16:59:18 -0000
@@ -1417,7 +1417,7 @@
 	return traceCode;
     }
 
-    curLevel = ((iPtr->varFramePtr == NULL) ? 0 : iPtr->varFramePtr->level);
+    curLevel = iPtr->varFramePtr->level;
 
     active.nextPtr = iPtr->activeCmdTracePtr;
     iPtr->activeCmdTracePtr = &active;
Index: generic/tclVar.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclVar.c,v
retrieving revision 1.122
diff -u -r1.122 tclVar.c
--- generic/tclVar.c	5 Oct 2006 11:38:50 -0000	1.122
+++ generic/tclVar.c	14 Oct 2006 16:59:20 -0000
@@ -390,7 +390,7 @@
     }
     part1 = Tcl_GetStringFromObj(part1Ptr, &len1);
 
-    nsPtr = ((varFramePtr == NULL)? iPtr->globalNsPtr : varFramePtr->nsPtr);
+    nsPtr = varFramePtr->nsPtr;
     if (nsPtr->varResProc != NULL || iPtr->resolverPtr != NULL) {
 	goto doParse;
     }
@@ -398,8 +398,7 @@
     if (typePtr == &localVarNameType) {
 	int localIndex = (int) part1Ptr->internalRep.longValue;
 
-	if ((varFramePtr != NULL)
-		&& (varFramePtr->isProcCallFrame & FRAME_IS_PROC)
+	if ((varFramePtr->isProcCallFrame & FRAME_IS_PROC)
 		&& !(flags & (TCL_GLOBAL_ONLY | TCL_NAMESPACE_ONLY))
 		&& (localIndex < varFramePtr->numCompiledLocals)) {
 	    /*
@@ -422,20 +421,18 @@
 	useGlobal = (cachedNsPtr == iPtr->globalNsPtr) && (
 		(flags & TCL_GLOBAL_ONLY) ||
 		(*part1==':' && *(part1+1)==':') ||
-		(varFramePtr == NULL) ||
 		(!(varFramePtr->isProcCallFrame & FRAME_IS_PROC)
 			&& (nsPtr == iPtr->globalNsPtr)));
 
 	useReference = useGlobal || ((cachedNsPtr == nsPtr) && (
 		(flags & TCL_NAMESPACE_ONLY) ||
-		(varFramePtr &&
-		!(varFramePtr->isProcCallFrame & FRAME_IS_PROC) &&
-		!(flags & TCL_GLOBAL_ONLY) &&
+		(!(varFramePtr->isProcCallFrame & FRAME_IS_PROC) &&
+			!(flags & TCL_GLOBAL_ONLY) &&
 		/*
 		 * Careful: an undefined ns variable could be hiding a valid
 		 * global reference.
 		 */
-		!TclIsVarUndefined(varPtr))));
+			!TclIsVarUndefined(varPtr))));
 
 	if (useReference && (varPtr->hPtr != NULL)) {
 	    /*
@@ -689,7 +686,7 @@
     varNsPtr = NULL;		/* set non-NULL if a nonlocal variable */
     *indexPtr = -3;
 
-    if ((flags & TCL_GLOBAL_ONLY) || iPtr->varFramePtr == NULL) {
+    if (flags & TCL_GLOBAL_ONLY) {
 	cxtNsPtr = iPtr->globalNsPtr;
     } else {
 	cxtNsPtr = iPtr->varFramePtr->nsPtr;
@@ -744,7 +741,6 @@
      */
 
     if (((flags & (TCL_GLOBAL_ONLY | TCL_NAMESPACE_ONLY)) != 0)
-	    || (varFramePtr == NULL)
 	    || !(varFramePtr->isProcCallFrame & FRAME_IS_PROC)
 	    || (strstr(varName, "::") != NULL)) {
 	CONST char *tail;
@@ -3214,6 +3210,10 @@
      * interpreter in order to use TclObjLookupVar.
      */
 
+    if (framePtr == NULL) {
+	framePtr = iPtr->rootFramePtr;
+    }
+    
     varFramePtr = iPtr->varFramePtr;
     if (!(otherFlags & TCL_NAMESPACE_ONLY)) {
 	iPtr->varFramePtr = framePtr;
@@ -3553,8 +3553,7 @@
      * If we are not executing inside a Tcl procedure, just return.
      */
 
-    if ((iPtr->varFramePtr == NULL)
-	    || !(iPtr->varFramePtr->isProcCallFrame & FRAME_IS_PROC)) {
+    if (!(iPtr->varFramePtr->isProcCallFrame & FRAME_IS_PROC)) {
 	return TCL_OK;
     }
 
@@ -3705,8 +3704,7 @@
 	 * linked to the new namespace variable "varName".
 	 */
 
-	if ((iPtr->varFramePtr != NULL)
-		&& (iPtr->varFramePtr->isProcCallFrame & FRAME_IS_PROC)) {
+	if (iPtr->varFramePtr->isProcCallFrame & FRAME_IS_PROC) {
 	    /*
 	     * varName might have a scope qualifier, but the name for the
 	     * local "link" variable must be the simple name at the tail.