Tcl Source Code

Artifact [b5c85694b8]
Login

Artifact b5c85694b8f81e67e7b45e656c0dc4b37764f129:

Attachment "NaN.patch" to ticket [761471ffff] added by msofer 2004-11-01 23:38:58.
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 16:33:14 -0000
@@ -3237,23 +3237,22 @@
 	int length;
 	Tcl_WideInt w;
 	long i;
-		
+	int firstConverted = 0;
+	
 	value2Ptr = *tosPtr;
 	valuePtr  = *(tosPtr - 1);
 
 	/*
-	 * Can't optimize the equal-object case; 'NaN' isn't supposed
+	 * Can't optimize the equal-object case without converting the object
+	 * to numeric type,in order to check for NaN: 'NaN' isn't supposed
 	 * to be equal to even itself. [Bug 761471]
+	 *
+	 * Convert the first object.
 	 */
 
 	t1Ptr = valuePtr->typePtr;
 	t2Ptr = value2Ptr->typePtr;
 
-	/*
-	 * We only want to coerce numeric validation if neither type
-	 * is NULL.  A NULL type means the arg is essentially an empty
-	 * object ("", {} or [list]).
-	 */
 	if (!(     (!t1Ptr && !valuePtr->bytes)
 	        || (valuePtr->bytes && !valuePtr->length)
 		   || (!t2Ptr && !value2Ptr->bytes)
@@ -3268,6 +3267,42 @@
 		}
 		t1Ptr = valuePtr->typePtr;
 	    }
+	    firstConverted = 1;
+	}
+
+	/*
+	 * Allow equal-obj shortcut if the first object is not a double.
+	 */
+	
+	
+	if ((valuePtr == value2Ptr) && (t1Ptr != &tclDoubleType))  {
+	    /*
+	     * Optimize the equal object case for non-doubles.
+	     */
+	    switch (*pc) {
+	        case INST_EQ:
+	        case INST_LE:
+	        case INST_GE:
+		    iResult = 1;
+		    break;
+	        case INST_NEQ:
+	        case INST_LT:
+	        case INST_GT:
+		    iResult = 0;
+		    break;
+	    }
+	    goto foundResult;
+	} else if (valuePtr == value2Ptr) {
+	    /*
+	     * Equal object case for doubles; avoid converting again.
+	     */
+
+	    t2Ptr = t1Ptr;
+	} else if (firstConverted) {
+	    /*
+	     * Attempt conversion of the second object.
+	     */
+	    
 	    if (!IS_NUMERIC_TYPE(t2Ptr)) {
 		s2 = Tcl_GetStringFromObj(value2Ptr, &length);
 		if (TclLooksLikeInt(s2, length)) {
@@ -3278,7 +3313,9 @@
 		}
 		t2Ptr = value2Ptr->typePtr;
 	    }
+	    t2Ptr = value2Ptr->typePtr;
 	}
+
 	if (!IS_NUMERIC_TYPE(t1Ptr) || !IS_NUMERIC_TYPE(t2Ptr)) {
 	    /*
 	     * One operand is not numeric. Compare as strings.  NOTE:
@@ -3420,6 +3457,7 @@
 	 * from here.
 	 */
 
+	foundResult:
 	pc++;
 #ifndef TCL_COMPILE_DEBUG
 	switch (*pc) {