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("~", () {