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) {