Tcl Source Code

Artifact [9b61ca8db9]
Login

Artifact 9b61ca8db918a33f49e02d810539bbb794643780:

Attachment "NaN.patch2" to ticket [761471ffff] added by msofer 2004-11-02 02:34:49.
Index: generic/tclExecute.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclExecute.c,v
retrieving revision 1.165
diff -u -r1.165 tclExecute.c
--- generic/tclExecute.c	1 Nov 2004 14:41:16 -0000	1.165
+++ generic/tclExecute.c	1 Nov 2004 19:29:28 -0000
@@ -3242,10 +3242,62 @@
 	valuePtr  = *(tosPtr - 1);
 
 	/*
-	 * Can't optimize the equal-object case; 'NaN' isn't supposed
-	 * to be equal to even itself. [Bug 761471]
+	 * If both objects are actually the same, avoid converting it
+	 * if at all possible, taking care of NaN [Bug 761471]
 	 */
+	
+	if (valuePtr == value2Ptr) {
+	    t1Ptr = valuePtr->typePtr;
+	    if (!IS_NUMERIC_TYPE(t1Ptr) && (t1Ptr != &tclDictType)) {
+		/*
+		 * Any other types that can never be NaN and may be very
+		 * expensive to parse?
+		 */
+		
+		length = 1;
+		if (t1Ptr == &tclListType) {
+		    /*
+		     * Only a list of length 1 can be NaN or such things ...
+		     */
+		    Tcl_ListObjLength(interp, valuePtr, &length);
+		}
+		if (length == 1) {
+		    /*
+		     * Too bad, we'll have to compute the string and
+		     * try the conversion
+		     */
 
+		    s1 = Tcl_GetStringFromObj(valuePtr, &length);
+		    if (TclLooksLikeInt(s1, length)) {
+			GET_WIDE_OR_INT(iResult, valuePtr, i, w);
+		    } else {
+			(void) Tcl_GetDoubleFromObj((Tcl_Interp *) NULL, 
+				valuePtr, &d1);
+		    }
+		    t1Ptr = valuePtr->typePtr;
+		}
+	    }
+
+		
+	    switch (*pc) {
+		case INST_EQ:
+		case INST_LE:
+		case INST_GE:
+		    iResult = !((t1Ptr == &tclDoubleType)
+			    && IS_NAN(valuePtr->internalRep.doubleValue));
+		    break;
+		case INST_LT:
+		case INST_GT:
+		    iResult = 0;
+		    break;
+		case INST_NEQ:
+		    iResult = ((t1Ptr == &tclDoubleType)
+			    && IS_NAN(valuePtr->internalRep.doubleValue));
+		    break;
+	    }		    	    
+	    goto foundResult;
+	}
+	
 	t1Ptr = valuePtr->typePtr;
 	t2Ptr = value2Ptr->typePtr;
 
@@ -3420,6 +3472,7 @@
 	 * from here.
 	 */
 
+	foundResult:
 	pc++;
 #ifndef TCL_COMPILE_DEBUG
 	switch (*pc) {