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