Tcl Source Code

Artifact [95fb335ff0]
Login

Artifact 95fb335ff060d72f77cb4471c119046032ea6448:

Attachment "history.patch" to ticket [1190441fff] added by msofer 2006-10-01 00:59:43.
Index: generic/tclCompile.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclCompile.c,v
retrieving revision 1.97
diff -u -r1.97 tclCompile.c
--- generic/tclCompile.c	29 Aug 2006 06:28:38 -0000	1.97
+++ generic/tclCompile.c	30 Sep 2006 17:42:50 -0000
@@ -1636,6 +1636,51 @@
 /*
  *----------------------------------------------------------------------
  *
+ * TclCompileNoOp --
+ *
+ *	Function called to compile no-op's
+ *
+ * Results:
+ *	The return value is TCL_OK, indicating successful compilation.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute a no-op at runtime. No
+ *      result is pushed onto the stack: the compiler has to take care of this
+ *      itself if the last compiled command is a NoOp. 
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileNoOp(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *tokenPtr;
+    int i;
+    int savedStackDepth = envPtr->currStackDepth;
+
+    tokenPtr = parsePtr->tokenPtr;
+    for(i = 1; i < parsePtr->numWords; i++) {
+	tokenPtr = tokenPtr + tokenPtr->numComponents + 1;
+	envPtr->currStackDepth = savedStackDepth;
+
+	if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+	    TclCompileTokens(interp, tokenPtr+1, tokenPtr->numComponents,
+		    envPtr);
+	    TclEmitOpcode(INST_POP, envPtr);
+	}
+    }
+    envPtr->currStackDepth = savedStackDepth;
+    TclEmitPush(TclRegisterNewLiteral(envPtr, "", 0), envPtr);    
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
  * TclInitByteCodeObj --
  *
  *	Create a ByteCode structure and initialize it from a CompileEnv
Index: generic/tclHistory.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclHistory.c,v
retrieving revision 1.8
diff -u -r1.8 tclHistory.c
--- generic/tclHistory.c	18 Oct 2005 14:34:41 -0000	1.8
+++ generic/tclHistory.c	30 Sep 2006 17:42:50 -0000
@@ -112,29 +112,44 @@
 				 * in global variable context instead of the
 				 * current procedure. */
 {
-    int result;
+    int result, call = 1;
     Tcl_Obj *list[3];
     register Tcl_Obj *objPtr;
+    Tcl_CmdInfo info;
 
     /*
-     * Do recording by eval'ing a tcl history command: history add $cmd.
+     * Do not call [history] if it has been replaced by an empty proc
      */
 
-    list[0] = Tcl_NewStringObj("history", -1);
-    list[1] = Tcl_NewStringObj("add", -1);
-    list[2] = cmdPtr;
-
-    objPtr = Tcl_NewListObj(3, list);
-    Tcl_IncrRefCount(objPtr);
-    (void) Tcl_EvalObjEx(interp, objPtr, TCL_EVAL_GLOBAL);
-    Tcl_DecrRefCount(objPtr);
+    result = Tcl_GetCommandInfo(interp, "history", &info);
 
-    /*
-     * One possible failure mode above: exceeding a resource limit.
-     */
+    if (result && (info.objProc == TclObjInterpProc)) {
+	Proc *procPtr = (Proc *)(info.objClientData);
+	call = (procPtr->cmdPtr->compileProc != TclCompileNoOp);
+    }
+
+    if (call) {
 
-    if (Tcl_LimitExceeded(interp)) {
-	return TCL_ERROR;
+	/*
+	 * Do recording by eval'ing a tcl history command: history add $cmd. 
+	 */
+
+	list[0] = Tcl_NewStringObj("history", -1);
+	list[1] = Tcl_NewStringObj("add", -1);
+	list[2] = cmdPtr;
+	
+	objPtr = Tcl_NewListObj(3, list);
+	Tcl_IncrRefCount(objPtr);
+	(void) Tcl_EvalObjEx(interp, objPtr, TCL_EVAL_GLOBAL);
+	Tcl_DecrRefCount(objPtr);
+	
+	/*
+	 * One possible failure mode above: exceeding a resource limit.
+	 */
+	
+	if (Tcl_LimitExceeded(interp)) {
+	    return TCL_ERROR;
+	}
     }
 
     /*
Index: generic/tclInt.h
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclInt.h,v
retrieving revision 1.277
diff -u -r1.277 tclInt.h
--- generic/tclInt.h	22 Sep 2006 22:32:07 -0000	1.277
+++ generic/tclInt.h	30 Sep 2006 17:42:51 -0000
@@ -2554,6 +2554,8 @@
 			    Tcl_Parse *parsePtr, struct CompileEnv *envPtr);
 MODULE_SCOPE int	TclCompileLsetCmd(Tcl_Interp* interp,
 			    Tcl_Parse* parsePtr, struct CompileEnv* envPtr);
+MODULE_SCOPE int	TclCompileNoOp(Tcl_Interp *interp, Tcl_Parse *parsePtr,
+			    struct CompileEnv *envPtr);
 MODULE_SCOPE int	TclCompileRegexpCmd(Tcl_Interp* interp,
 			    Tcl_Parse* parsePtr, struct CompileEnv* envPtr);
 MODULE_SCOPE int	TclCompileReturnCmd(Tcl_Interp *interp,
Index: generic/tclProc.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclProc.c,v
retrieving revision 1.91
diff -u -r1.91 tclProc.c
--- generic/tclProc.c	15 May 2006 16:07:47 -0000	1.91
+++ generic/tclProc.c	30 Sep 2006 17:42:53 -0000
@@ -35,8 +35,6 @@
 static int		ProcessProcResultCode(Tcl_Interp *interp,
 			    char *procName, int nameLen, int returnCode);
 static int		SetLambdaFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
-static int		TclCompileNoOp(Tcl_Interp *interp, Tcl_Parse *parsePtr,
-			    struct CompileEnv *envPtr);
 static int		ProcCompileProc (Tcl_Interp *interp, Proc *procPtr,
 			    Tcl_Obj *bodyPtr, Namespace *nsPtr, 
 			    CONST char *description, CONST char *procName,
@@ -1962,49 +1960,6 @@
 }
 
 /*
- *----------------------------------------------------------------------
- *
- * TclCompileNoOp --
- *
- *	Function called to compile no-op's
- *
- * Results:
- *	The return value is TCL_OK, indicating successful compilation.
- *
- * Side effects:
- *	Instructions are added to envPtr to execute a no-op at runtime.
- *
- *----------------------------------------------------------------------
- */
-
-static int
-TclCompileNoOp(
-    Tcl_Interp *interp,		/* Used for error reporting. */
-    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
-				 * created by Tcl_ParseCommand. */
-    CompileEnv *envPtr)		/* Holds resulting instructions. */
-{
-    Tcl_Token *tokenPtr;
-    int i;
-    int savedStackDepth = envPtr->currStackDepth;
-
-    tokenPtr = parsePtr->tokenPtr;
-    for(i = 1; i < parsePtr->numWords; i++) {
-	tokenPtr = tokenPtr + tokenPtr->numComponents + 1;
-	envPtr->currStackDepth = savedStackDepth;
-
-	if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
-	    TclCompileTokens(interp, tokenPtr+1, tokenPtr->numComponents,
-		    envPtr);
-	    TclEmitOpcode(INST_POP, envPtr);
-	}
-    }
-    envPtr->currStackDepth = savedStackDepth;
-    TclEmitPush(TclRegisterNewLiteral(envPtr, "", 0), envPtr);
-    return TCL_OK;
-}
-
-/*
  * LAMBDA and APPLY implementation. [TIP#194]
  */