Don't throw exception for non-integer args to fixnum int32,int64 op ==

Original bug
https://code.google.com/p/dart/issues/detail?id=12073

BUG=
R=justinfagnani@google.com

Review URL: https://codereview.chromium.org//20803006

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@25577 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkg/fixnum/lib/src/int32.dart b/pkg/fixnum/lib/src/int32.dart
index 6c8a6f4..84d9bfc 100644
--- a/pkg/fixnum/lib/src/int32.dart
+++ b/pkg/fixnum/lib/src/int32.dart
@@ -138,18 +138,15 @@
    */
   int32.fromInt(int i) : _i = (i & 0x7fffffff) - (i & 0x80000000);
 
-  // Convert an [int] or [intx] to an [int32].  Note that an [int64]
-  // will be truncated.
-  int _convert(other) {
-    if (other == null) {
-      throw new ArgumentError(null);
-    } else if (other is intx) {
-      return other.toInt32()._i;
-    } else if (other is int) {
-      return other;
-    } else {
-      throw new Exception("Can't retrieve 32-bit int from $other");
+  // Returns the [int] representation of the specified value. Throws
+  // [ArgumentError] for non-integer arguments.
+  int _toInt(val) {
+    if (val is int32) {
+      return val._i;
+    } else if (val is int) {
+      return val;
     }
+    throw new ArgumentError(val);
   }
 
   // The +, -, * , &, |, and ^ operaters deal with types as follows:
@@ -170,14 +167,14 @@
     if (other is int64) {
       return this.toInt64() + other;
     }
-    return new int32.fromInt(_i + _convert(other));
+    return new int32.fromInt(_i + _toInt(other));
   }
 
   intx operator -(other) {
     if (other is int64) {
       return this.toInt64() - other;
     }
-    return new int32.fromInt(_i - _convert(other));
+    return new int32.fromInt(_i - _toInt(other));
   }
 
   int32 operator -() => new int32.fromInt(-_i);
@@ -195,20 +192,18 @@
       // Result will be int32
       return (this.toInt64() % other).toInt32();
     }
-    return new int32.fromInt(_i % _convert(other));
+    return new int32.fromInt(_i % _toInt(other));
   }
 
   int32 operator ~/(other) {
     if (other is int64) {
-      // Result will be int32
       return (this.toInt64() ~/ other).toInt32();
     }
-    return new int32.fromInt(_i ~/ _convert(other));
+    return new int32.fromInt(_i ~/ _toInt(other));
   }
 
   int32 remainder(other) {
     if (other is int64) {
-      // Result will be int32
       int64 t = this.toInt64();
       return (t - (t ~/ other) * other).toInt32();
     }
@@ -219,21 +214,21 @@
     if (other is int64) {
       return (this.toInt64() & other).toInt32();
     }
-    return new int32.fromInt(_i & _convert(other));
+    return new int32.fromInt(_i & _toInt(other));
   }
 
   int32 operator |(other) {
     if (other is int64) {
       return (this.toInt64() | other).toInt32();
     }
-    return new int32.fromInt(_i | _convert(other));
+    return new int32.fromInt(_i | _toInt(other));
   }
 
   int32 operator ^(other) {
     if (other is int64) {
       return (this.toInt64() ^ other).toInt32();
     }
-    return new int32.fromInt(_i ^ _convert(other));
+    return new int32.fromInt(_i ^ _toInt(other));
   }
 
   int32 operator ~() => new int32.fromInt(~_i);
@@ -279,48 +274,49 @@
    * given object.  The argument may be an [int] or an [intx].
    */
   bool operator ==(other) {
-    if (other == null) {
-      return false;
-    }
-    if (other is int64) {
+    if (other is int32) {
+      return _i == other._i;
+    } else if (other is int64) {
       return this.toInt64() == other;
+    } else if (other is int) {
+      return _i == other;
     }
-    return _i == _convert(other);
+    return false;
   }
 
   int compareTo(Comparable other) {
     if (other is int64) {
       return this.toInt64().compareTo(other);
     }
-    return _i.compareTo(_convert(other));
+    return _i.compareTo(_toInt(other));
   }
 
   bool operator <(other) {
     if (other is int64) {
       return this.toInt64() < other;
     }
-    return _i < _convert(other);
+    return _i < _toInt(other);
   }
 
   bool operator <=(other) {
     if (other is int64) {
-      return this.toInt64() < other;
+      return this.toInt64() <= other;
     }
-    return _i <= _convert(other);
+    return _i <= _toInt(other);
   }
 
   bool operator >(other) {
     if (other is int64) {
-      return this.toInt64() < other;
+      return this.toInt64() > other;
     }
-    return _i > _convert(other);
+    return _i > _toInt(other);
   }
 
   bool operator >=(other) {
     if (other is int64) {
-      return this.toInt64() < other;
+      return this.toInt64() >= other;
     }
-    return _i >= _convert(other);
+    return _i >= _toInt(other);
   }
 
   bool get isEven => (_i & 0x1) == 0;
diff --git a/pkg/fixnum/lib/src/int64.dart b/pkg/fixnum/lib/src/int64.dart
index 81607de..a179105 100644
--- a/pkg/fixnum/lib/src/int64.dart
+++ b/pkg/fixnum/lib/src/int64.dart
@@ -240,18 +240,17 @@
     _h = (top >> 12) & _MASK_2;
   }
 
-  int64 _promote(other) {
-    if (other == null) {
-      throw new ArgumentError(null);
-    } else if (other is intx) {
-      other = other.toInt64();
-    } else if (other is int) {
-      other = new int64.fromInt(other);
+  // Returns the [int64] representation of the specified value. Throws
+  // [ArgumentError] for non-integer arguments.
+  int64 _promote(val) {
+    if (val is int64) {
+      return val;
+    } else if (val is int) {
+      return new int64.fromInt(val);
+    } else if (val is int32) {
+      return val.toInt64();
     }
-    if (other is !int64) {
-      throw new Exception("Can't promote $other to int64");
-    }
-    return other;
+    throw new ArgumentError(val);
   }
 
   int64 operator +(other) {
@@ -266,7 +265,6 @@
 
   int64 operator -(other) {
     int64 o = _promote(other);
-
     int sum0 = _l - o._l;
     int sum1 = _m - o._m + _shiftRight(sum0, _BITS);
     int sum2 = _h - o._h + _shiftRight(sum1, _BITS);
@@ -286,6 +284,7 @@
 
   int64 operator *(other) {
     int64 o = _promote(other);
+
     // Grab 13-bit chunks.
     int a0 = _l & 0x1fff;
     int a1 = (_l >> 13) | ((_m & 0xf) << 9);
@@ -515,11 +514,18 @@
    * given object.  The argument may be an [int] or an [intx].
    */
   bool operator ==(other) {
-    if (other == null) {
-      return false;
+    int64 o;
+    if (other is int64) {
+      o = other;
+    } else if (other is int) {
+      o = new int64.fromInt(other);
+    } else if (other is int32) {
+      o = other.toInt64();
     }
-    int64 o = _promote(other);
-    return _l == o._l && _m == o._m && _h == o._h;
+    if (o != null) {
+      return _l == o._l && _m == o._m && _h == o._h;
+    }
+    return false;
   }
 
   int compareTo(Comparable other) {
@@ -944,7 +950,7 @@
     _h = b2;
   }
 
-  int64 _divModByShift(int64 a, int bpower, bool negative, bool aIsCopy,
+  static int64 _divModByShift(int64 a, int bpower, bool negative, bool aIsCopy,
       bool aIsNegative, bool computeRemainder) {
     int64 c = a >> bpower;
     if (negative) {
@@ -997,7 +1003,7 @@
     return -1;
   }
 
-  int64 _divMod(int64 a, int64 b, bool computeRemainder) {
+  static int64 _divMod(int64 a, int64 b, bool computeRemainder) {
     if (b.isZero) {
       throw new IntegerDivisionByZeroException();
     }
diff --git a/pkg/fixnum/test/int_32_test.dart b/pkg/fixnum/test/int_32_test.dart
index 77a6b27..7e27d41 100644
--- a/pkg/fixnum/test/int_32_test.dart
+++ b/pkg/fixnum/test/int_32_test.dart
@@ -94,6 +94,9 @@
       expect(new int32.fromInt(17) < new int32.fromInt(18), true);
       expect(new int32.fromInt(17) < new int32.fromInt(17), false);
       expect(new int32.fromInt(17) < new int32.fromInt(16), false);
+      expect(new int32.fromInt(17) < new int64.fromInt(18), true);
+      expect(new int32.fromInt(17) < new int64.fromInt(17), false);
+      expect(new int32.fromInt(17) < new int64.fromInt(16), false);
       expect(int32.MIN_VALUE < int32.MAX_VALUE, true);
       expect(int32.MAX_VALUE < int32.MIN_VALUE, false);
       expect(() => new int32.fromInt(17) < null, throws);
@@ -103,6 +106,9 @@
       expect(new int32.fromInt(17) <= new int32.fromInt(18), true);
       expect(new int32.fromInt(17) <= new int32.fromInt(17), true);
       expect(new int32.fromInt(17) <= new int32.fromInt(16), false);
+      expect(new int32.fromInt(17) <= new int64.fromInt(18), true);
+      expect(new int32.fromInt(17) <= new int64.fromInt(17), true);
+      expect(new int32.fromInt(17) <= new int64.fromInt(16), false);
       expect(int32.MIN_VALUE <= int32.MAX_VALUE, true);
       expect(int32.MAX_VALUE <= int32.MIN_VALUE, false);
       expect(() => new int32.fromInt(17) <= null, throws);
@@ -112,7 +118,11 @@
       expect(new int32.fromInt(17) == new int32.fromInt(18), false);
       expect(new int32.fromInt(17) == new int32.fromInt(17), true);
       expect(new int32.fromInt(17) == new int32.fromInt(16), false);
+      expect(new int32.fromInt(17) == new int64.fromInt(18), false);
+      expect(new int32.fromInt(17) == new int64.fromInt(17), true);
+      expect(new int32.fromInt(17) == new int64.fromInt(16), false);
       expect(int32.MIN_VALUE == int32.MAX_VALUE, false);
+      expect(new int32.fromInt(17) == new Object(), false);
       expect(new int32.fromInt(17) == null, false);
     });
 
@@ -120,6 +130,9 @@
       expect(new int32.fromInt(17) >= new int32.fromInt(18), false);
       expect(new int32.fromInt(17) >= new int32.fromInt(17), true);
       expect(new int32.fromInt(17) >= new int32.fromInt(16), true);
+      expect(new int32.fromInt(17) >= new int64.fromInt(18), false);
+      expect(new int32.fromInt(17) >= new int64.fromInt(17), true);
+      expect(new int32.fromInt(17) >= new int64.fromInt(16), true);
       expect(int32.MIN_VALUE >= int32.MAX_VALUE, false);
       expect(int32.MAX_VALUE >= int32.MIN_VALUE, true);
       expect(() => new int32.fromInt(17) >= null, throws);
@@ -129,6 +142,9 @@
       expect(new int32.fromInt(17) > new int32.fromInt(18), false);
       expect(new int32.fromInt(17) > new int32.fromInt(17), false);
       expect(new int32.fromInt(17) > new int32.fromInt(16), true);
+      expect(new int32.fromInt(17) > new int64.fromInt(18), false);
+      expect(new int32.fromInt(17) > new int64.fromInt(17), false);
+      expect(new int32.fromInt(17) > new int64.fromInt(16), true);
       expect(int32.MIN_VALUE > int32.MAX_VALUE, false);
       expect(int32.MAX_VALUE > int32.MIN_VALUE, true);
       expect(() => new int32.fromInt(17) > null, throws);
diff --git a/pkg/fixnum/test/int_64_test.dart b/pkg/fixnum/test/int_64_test.dart
index fddb409..4ff8e1c 100644
--- a/pkg/fixnum/test/int_64_test.dart
+++ b/pkg/fixnum/test/int_64_test.dart
@@ -159,7 +159,7 @@
       expect(int64.MIN_VALUE ~/ new int64.fromInt(1), int64.MIN_VALUE);
       expect(int64.MIN_VALUE ~/ new int64.fromInt(-1), int64.MIN_VALUE);
       expect(() => new int64.fromInt(17) ~/ int64.ZERO, throws);
-      expect(() => new int64.fromInt(17) ~/ null, throws);
+      expect(() => new int64.fromInt(17) ~/ null, throwsArgumentError);
     });
 
     test("%", () {
@@ -218,7 +218,10 @@
     test("<", () {
       expect(new int64.fromInt(10) < new int64.fromInt(11), true);
       expect(new int64.fromInt(10) < new int64.fromInt(10), false);
-      expect(new int64.fromInt(12) < new int64.fromInt(11), false);
+      expect(new int64.fromInt(10) < new int64.fromInt(9), false);
+      expect(new int64.fromInt(10) < new int32.fromInt(11), true);
+      expect(new int64.fromInt(10) < new int32.fromInt(10), false);
+      expect(new int64.fromInt(10) < new int32.fromInt(9), false);
       expect(new int64.fromInt(-10) < new int64.fromInt(-11), false);
       expect(int64.MIN_VALUE < new int64.fromInt(0), true);
       expect(largeNeg < largePos, true);
@@ -233,7 +236,10 @@
     test("<=", () {
       expect(new int64.fromInt(10) <= new int64.fromInt(11), true);
       expect(new int64.fromInt(10) <= new int64.fromInt(10), true);
-      expect(new int64.fromInt(12) <= new int64.fromInt(11), false);
+      expect(new int64.fromInt(10) <= new int64.fromInt(9), false);
+      expect(new int64.fromInt(10) <= new int32.fromInt(11), true);
+      expect(new int64.fromInt(10) <= new int32.fromInt(10), true);
+      expect(new int64.fromInt(10) <= new int64.fromInt(9), false);
       expect(new int64.fromInt(-10) <= new int64.fromInt(-11), false);
       expect(new int64.fromInt(-10) <= new int64.fromInt(-10), true);
       expect(largeNeg <= largePos, true);
@@ -249,20 +255,27 @@
     test("==", () {
       expect(new int64.fromInt(10) == new int64.fromInt(11), false);
       expect(new int64.fromInt(10) == new int64.fromInt(10), true);
-      expect(new int64.fromInt(12) == new int64.fromInt(11), false);
+      expect(new int64.fromInt(10) == new int64.fromInt(9), false);
+      expect(new int64.fromInt(10) == new int32.fromInt(11), false);
+      expect(new int64.fromInt(10) == new int32.fromInt(10), true);
+      expect(new int64.fromInt(10) == new int32.fromInt(9), false);
       expect(new int64.fromInt(-10) == new int64.fromInt(-10), true);
       expect(new int64.fromInt(-10) != new int64.fromInt(-10), false);
       expect(largePos == largePos, true);
       expect(largePos == largePosPlusOne, false);
       expect(largePosPlusOne == largePos, false);
       expect(int64.MIN_VALUE == int64.MAX_VALUE, false);
+      expect(new int64.fromInt(17) == new Object(), false);
       expect(new int64.fromInt(17) == null, false);
     });
 
     test(">=", () {
       expect(new int64.fromInt(10) >= new int64.fromInt(11), false);
       expect(new int64.fromInt(10) >= new int64.fromInt(10), true);
-      expect(new int64.fromInt(12) >= new int64.fromInt(11), true);
+      expect(new int64.fromInt(10) >= new int64.fromInt(9), true);
+      expect(new int64.fromInt(10) >= new int32.fromInt(11), false);
+      expect(new int64.fromInt(10) >= new int32.fromInt(10), true);
+      expect(new int64.fromInt(10) >= new int32.fromInt(9), true);
       expect(new int64.fromInt(-10) >= new int64.fromInt(-11), true);
       expect(new int64.fromInt(-10) >= new int64.fromInt(-10), true);
       expect(largePos >= largeNeg, true);
@@ -278,7 +291,10 @@
     test(">", () {
       expect(new int64.fromInt(10) > new int64.fromInt(11), false);
       expect(new int64.fromInt(10) > new int64.fromInt(10), false);
-      expect(new int64.fromInt(12) > new int64.fromInt(11), true);
+      expect(new int64.fromInt(10) > new int64.fromInt(9), true);
+      expect(new int64.fromInt(10) > new int32.fromInt(11), false);
+      expect(new int64.fromInt(10) > new int32.fromInt(10), false);
+      expect(new int64.fromInt(10) > new int32.fromInt(9), true);
       expect(new int64.fromInt(-10) > new int64.fromInt(-11), true);
       expect(new int64.fromInt(10) > new int64.fromInt(-11), true);
       expect(new int64.fromInt(-10) > new int64.fromInt(11), false);
@@ -305,21 +321,21 @@
       expect(n1 & n2, new int64.fromInt(1168));
       expect(n3 & n2, new int64.fromInt(8708));
       expect(n4 & n5, new int64.fromInt(0x1034) << 32);
-      expect(() => n1 & null, throws);
+      expect(() => n1 & null, throwsArgumentError);
     });
 
     test("|", () {
       expect(n1 | n2, new int64.fromInt(9942));
       expect(n3 | n2, new int64.fromInt(-66));
       expect(n4 | n5, new int64.fromInt(0x9a76) << 32);
-      expect(() => n1 | null, throws);
+      expect(() => n1 | null, throwsArgumentError);
     });
 
     test("^", () {
       expect(n1 ^ n2, new int64.fromInt(8774));
       expect(n3 ^ n2, new int64.fromInt(-8774));
       expect(n4 ^ n5, new int64.fromInt(0x8a42) << 32);
-      expect(() => n1 ^ null, throws);
+      expect(() => n1 ^ null, throwsArgumentError);
     });
 
     test("~", () {