Tcl Source Code

Artifact [c383b79ee0]
Login

Artifact c383b79ee02bfacd640ee9917b7053ca9fe07bbf:

Attachment "result.diff" to ticket [1830184fff] added by msofer 2007-11-12 10:37:12.
Index: generic/tclBasic.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclBasic.c,v
retrieving revision 1.279
diff -u -r1.279 tclBasic.c
--- generic/tclBasic.c	11 Nov 2007 19:32:13 -0000	1.279
+++ generic/tclBasic.c	12 Nov 2007 03:18:23 -0000
@@ -3426,7 +3426,7 @@
      * any previous error information.
      */
 
-    Tcl_ResetResult(interp);
+    TclResetResult(iPtr);
 
     /*
      * If the interpreter has been deleted, return an error.
@@ -5398,6 +5398,7 @@
 	}
 	Tcl_AppendToObj(iPtr->errorInfo, message, length);
     }
+    ((Interp *) interp)->flags |= INTERP_RESULT_UNCLEAN;    
 }
 
 /*
Index: generic/tclExecute.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclExecute.c,v
retrieving revision 1.345
diff -u -r1.345 tclExecute.c
--- generic/tclExecute.c	11 Nov 2007 19:32:14 -0000	1.345
+++ generic/tclExecute.c	12 Nov 2007 03:18:25 -0000
@@ -1218,7 +1218,7 @@
 
     saveObjPtr = Tcl_GetObjResult(interp);
     Tcl_IncrRefCount(saveObjPtr);
-    Tcl_ResetResult(interp);
+    TclResetResult(interp);
 
     /*
      * Increment the code's ref count while it is being executed. If
@@ -6303,7 +6302,7 @@
 
     case INST_END_CATCH:
 	catchTop--;
-	Tcl_ResetResult(interp);
+	TclResetResult(interp);
 	result = TCL_OK;
 	TRACE(("=> catchTop=%d\n", (catchTop - initCatchTop - 1)));
 	NEXT_INST_F(1, 0, 0);
Index: generic/tclInt.h
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclInt.h,v
retrieving revision 1.342
diff -u -r1.342 tclInt.h
--- generic/tclInt.h	11 Nov 2007 19:32:16 -0000	1.342
+++ generic/tclInt.h	12 Nov 2007 03:18:26 -0000
@@ -1973,6 +1973,39 @@
 #define INTERP_TRACE_IN_PROGRESS	0x200
 #define INTERP_ALTERNATE_WRONG_ARGS	0x400
 #define ERR_LEGACY_COPY			0x800
+#define INTERP_RESULT_UNCLEAN           0x1000
+
+/*
+ * The following macro resets the interp's obj result and returns 1 if a call
+ * to the full Tcl_ResetResult is needed. TclResetResult macro uses it.
+ */
+
+#define ResetObjResultM(iPtr) \
+    {								\
+	register Tcl_Obj *objResultPtr = (iPtr)->objResultPtr;	\
+	\
+	if (Tcl_IsShared(objResultPtr)) {\
+	    TclDecrRefCount(objResultPtr);\
+	    TclNewObj(objResultPtr);\
+	    Tcl_IncrRefCount(objResultPtr);\
+	    (iPtr)->objResultPtr = objResultPtr;		\
+	} else if (objResultPtr->bytes != tclEmptyStringRep) {	\
+	    if (objResultPtr->bytes != NULL) {\
+		ckfree((char *) objResultPtr->bytes);	\
+	    }\
+	    objResultPtr->bytes = tclEmptyStringRep;\
+	    objResultPtr->length = 0;\
+	    TclFreeIntRep(objResultPtr);\
+	    objResultPtr->typePtr = NULL;\
+	}\
+    } 
+
+#define TclResetResult(iPtr)			\
+    {\
+	ResetObjResultM((Interp *)(iPtr));		\
+	if (((Interp *)(iPtr))->flags & INTERP_RESULT_UNCLEAN)	\
+	    TclCleanResult((Interp *)(iPtr));			\
+    }\
 
 /*
  * Maximum number of levels of nesting permitted in Tcl commands (used to
@@ -2416,6 +2449,7 @@
 			    Tcl_Channel chan);
 MODULE_SCOPE void	TclCleanupLiteralTable(Tcl_Interp *interp,
 			    LiteralTable *tablePtr);
+MODULE_SCOPE void       TclCleanResult(Interp *iPtr);
 MODULE_SCOPE int	TclDoubleDigits(char *buf, double value, int *signum);
 MODULE_SCOPE void       TclDeleteNamespaceVars(Namespace *nsPtr);
 /* TIP #280 - Modified token based evulation, with line information */
Index: generic/tclProc.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclProc.c,v
retrieving revision 1.136
diff -u -r1.136 tclProc.c
--- generic/tclProc.c	11 Nov 2007 19:32:17 -0000	1.136
+++ generic/tclProc.c	12 Nov 2007 03:18:27 -0000
@@ -2218,6 +2218,7 @@
 	    iPtr->flags |= ERR_LEGACY_COPY;
 	}
     }
+    iPtr->flags |= INTERP_RESULT_UNCLEAN;
     return code;
 }
 
Index: generic/tclResult.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclResult.c,v
retrieving revision 1.42
diff -u -r1.42 tclResult.c
--- generic/tclResult.c	11 Nov 2007 19:53:20 -0000	1.42
+++ generic/tclResult.c	12 Nov 2007 03:18:27 -0000
@@ -336,6 +336,7 @@
 
     Tcl_DecrRefCount(iPtr->objResultPtr);
     iPtr->objResultPtr = statePtr->objResultPtr;
+    iPtr->flags |= INTERP_RESULT_UNCLEAN;
 }
 
 /*
@@ -443,6 +444,7 @@
      */
 
     ResetObjResult(iPtr);
+    iPtr->flags |= INTERP_RESULT_UNCLEAN;
 }
 
 /*
@@ -475,6 +477,7 @@
 	Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),
 		TCL_VOLATILE);
     }
+    ((Interp *)interp)->flags |= INTERP_RESULT_UNCLEAN;
     return interp->result;
 }
 
@@ -584,6 +587,7 @@
 	}
 	iPtr->result = iPtr->resultSpace;
 	iPtr->resultSpace[0] = 0;
+	iPtr->flags &= ~INTERP_RESULT_UNCLEAN;	
     }
     return iPtr->objResultPtr;
 }
@@ -826,6 +830,7 @@
 
     Tcl_FreeResult((Tcl_Interp *) iPtr);
     iPtr->result = iPtr->appendResult;
+    iPtr->flags |= INTERP_RESULT_UNCLEAN;    
 }
 
 /*
@@ -866,6 +871,7 @@
     }
 
     ResetObjResult(iPtr);
+    iPtr->flags &= ~INTERP_RESULT_UNCLEAN;    
 }
 
 /*
@@ -891,9 +897,17 @@
 Tcl_ResetResult(
     register Tcl_Interp *interp)/* Interpreter for which to clear result. */
 {
-    register Interp *iPtr = (Interp *) interp;
+    /*
+     * This function is defined in a macro in tclInt.h
+     */
 
-    ResetObjResult(iPtr);
+    TclResetResult((Interp *) interp);
+}
+
+void
+TclCleanResult(
+    Interp *iPtr)
+{
     if (iPtr->freeProc != NULL) {
 	if (iPtr->freeProc == TCL_DYNAMIC) {
 	    ckfree(iPtr->result);
@@ -907,8 +921,8 @@
     if (iPtr->errorCode) {
 	/* Legacy support */
 	if (iPtr->flags & ERR_LEGACY_COPY) {
-	    Tcl_ObjSetVar2(interp, iPtr->ecVar, NULL,
-		    iPtr->errorCode, TCL_GLOBAL_ONLY);
+	    Tcl_ObjSetVar2((Tcl_Interp *)iPtr, iPtr->ecVar,
+		    NULL, iPtr->errorCode, TCL_GLOBAL_ONLY);
 	}
 	Tcl_DecrRefCount(iPtr->errorCode);
 	iPtr->errorCode = NULL;
@@ -916,8 +930,8 @@
     if (iPtr->errorInfo) {
 	/* Legacy support */
 	if (iPtr->flags & ERR_LEGACY_COPY) {
-	    Tcl_ObjSetVar2(interp, iPtr->eiVar, NULL,
-		    iPtr->errorInfo, TCL_GLOBAL_ONLY);
+	    Tcl_ObjSetVar2((Tcl_Interp *) iPtr, iPtr->eiVar,
+		    NULL, iPtr->errorInfo, TCL_GLOBAL_ONLY);
 	}
 	Tcl_DecrRefCount(iPtr->errorInfo);
 	iPtr->errorInfo = NULL;
@@ -928,7 +942,7 @@
 	Tcl_DecrRefCount(iPtr->returnOpts);
 	iPtr->returnOpts = NULL;
     }
-    iPtr->flags &= ~(ERR_ALREADY_LOGGED | ERR_LEGACY_COPY);
+    iPtr->flags &= ~(ERR_ALREADY_LOGGED | ERR_LEGACY_COPY | INTERP_RESULT_UNCLEAN);
 }
 
 /*
@@ -954,22 +968,11 @@
     register Interp *iPtr)	/* Points to the interpreter whose result
 				 * object should be reset. */
 {
-    register Tcl_Obj *objResultPtr = iPtr->objResultPtr;
-
-    if (Tcl_IsShared(objResultPtr)) {
-	TclDecrRefCount(objResultPtr);
-	TclNewObj(objResultPtr);
-	Tcl_IncrRefCount(objResultPtr);
-	iPtr->objResultPtr = objResultPtr;
-    } else if (objResultPtr->bytes != tclEmptyStringRep) {
-	if (objResultPtr->bytes != NULL) {
-	    ckfree((char *) objResultPtr->bytes);
-	}
-	objResultPtr->bytes = tclEmptyStringRep;
-	objResultPtr->length = 0;
-	TclFreeIntRep(objResultPtr);
-	objResultPtr->typePtr = NULL;
-    }
+    /*
+     * This function is defined in a macro in tclInt.h
+     */
+    
+    ResetObjResultM(iPtr);
 }
 
 /*
@@ -1078,6 +1081,7 @@
     }
     iPtr->errorCode = errorObjPtr;
     Tcl_IncrRefCount(iPtr->errorCode);
+    iPtr->flags |= INTERP_RESULT_UNCLEAN;
 }
 
 /*
@@ -1205,6 +1209,7 @@
 	}
 	iPtr->returnOpts = returnOpts;
 	Tcl_IncrRefCount(iPtr->returnOpts);
+	iPtr->flags |= INTERP_RESULT_UNCLEAN;	
     }
 
     if (code == TCL_ERROR) {
@@ -1234,14 +1239,16 @@
 	if (valuePtr != NULL) {
 	    TclGetIntFromObj(NULL, valuePtr, &iPtr->errorLine);
 	}
+	iPtr->flags |= INTERP_RESULT_UNCLEAN;	
     }
     if (level != 0) {
 	iPtr->returnLevel = level;
 	iPtr->returnCode = code;
+	iPtr->flags |= INTERP_RESULT_UNCLEAN;	
 	return TCL_RETURN;
     }
     if (code == TCL_ERROR) {
-	iPtr->flags |= ERR_LEGACY_COPY;
+	iPtr->flags |= (ERR_LEGACY_COPY | INTERP_RESULT_UNCLEAN);
     }
     return code;
 }
@@ -1402,6 +1409,7 @@
     } else {
 	*optionsPtrPtr = returnOpts;
     }
+    ((Interp *)interp)->flags |= INTERP_RESULT_UNCLEAN;
     return TCL_OK;
 
   error:
@@ -1508,6 +1516,7 @@
     }
 
     Tcl_DecrRefCount(options);
+    ((Interp *)interp)->flags |= INTERP_RESULT_UNCLEAN;
     return code;
 }
 
Index: generic/tclStubLib.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclStubLib.c,v
retrieving revision 1.18
diff -u -r1.18 tclStubLib.c
--- generic/tclStubLib.c	19 Sep 2007 10:53:25 -0000	1.18
+++ generic/tclStubLib.c	12 Nov 2007 03:18:27 -0000
@@ -50,6 +50,7 @@
     interp->result =
 	    "This interpreter does not support stubs-enabled extensions.";
     interp->freeProc = TCL_STATIC;
+    ((Interp *)interp)->flags |= INTERP_RESULT_UNCLEAN;
     return NULL;
 }
 
Index: generic/tclUtil.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclUtil.c,v
retrieving revision 1.87
diff -u -r1.87 tclUtil.c
--- generic/tclUtil.c	11 Nov 2007 19:32:17 -0000	1.87
+++ generic/tclUtil.c	12 Nov 2007 03:18:28 -0000
@@ -2024,6 +2024,7 @@
     } else {
 	Tcl_SetResult(interp, dsPtr->string, TCL_VOLATILE);
     }
+    ((Interp *) interp)->flags |= INTERP_RESULT_UNCLEAN;
 
     dsPtr->string = dsPtr->staticSpace;
     dsPtr->length = 0;