Merge in changes from SDK branch

Includes performance fixes and error tests.

R=kevmoo@google.com

Review URL: https://codereview.chromium.org//1834783004 .
diff --git a/README.md b/README.md
index bb39a08..3e6af18 100644
--- a/README.md
+++ b/README.md
@@ -12,14 +12,6 @@
 The integer implementations in this library are designed to work identically
 whether executed on the Dart VM or compiled to JavaScript.
 
-## Installation
-
-Use [pub](http://pub.dartlang.org) to install this package. Add the following
-to your `pubspec.yaml` file:
-
-    dependencies:
-      fixnum: '>=0.9.1 <0.10.0'
-
 For more information, see the
 [fixnum package](http://pub.dartlang.org/packages/fixnum) on
 [pub.dartlang.org](http://pub.dartlang.org).
diff --git a/lib/src/int32.dart b/lib/src/int32.dart
index 32f3620..c5996f8 100644
--- a/lib/src/int32.dart
+++ b/lib/src/int32.dart
@@ -57,15 +57,18 @@
     }
   }
 
+  static int _validateRadix(int radix) {
+    if (2 <= radix && radix <= 36) return radix;
+    throw new RangeError.range(radix, 2, 36, 'radix');
+  }
+
   /**
    * Parses a [String] in a given [radix] between 2 and 16 and returns an
    * [Int32].
    */
   // TODO(rice) - Make this faster by converting several digits at once.
   static Int32 parseRadix(String s, int radix) {
-    if ((radix <= 1) || (radix > 16)) {
-      throw new ArgumentError("Bad radix: $radix");
-    }
+    _validateRadix(radix);
     Int32 x = ZERO;
     for (int i = 0; i < s.length; i++) {
       int c = s.codeUnitAt(i);
@@ -348,12 +351,12 @@
   int numberOfTrailingZeros() => _numberOfTrailingZeros(_i);
 
   Int32 toSigned(int width) {
-    if (width < 1 || width > 32) throw new ArgumentError(width);
+    if (width < 1 || width > 32) throw new RangeError.range(width, 1, 32);
     return new Int32(_i.toSigned(width));
   }
 
   Int32 toUnsigned(int width) {
-    if (width < 0 || width > 32) throw new ArgumentError(width);
+    if (width < 0 || width > 32) throw new RangeError.range(width, 0, 32);
     return new Int32(_i.toUnsigned(width));
   }
 
diff --git a/lib/src/int64.dart b/lib/src/int64.dart
index 641bf71..2ff4822 100644
--- a/lib/src/int64.dart
+++ b/lib/src/int64.dart
@@ -30,7 +30,7 @@
   static const int _MASK = 4194303; // (1 << _BITS) - 1
   static const int _MASK2 = 1048575; // (1 << _BITS2) - 1
   static const int _SIGN_BIT = 19; // _BITS2 - 1
-  static const int _SIGN_BIT_MASK = 524288; // 1 << _SIGN_BIT
+  static const int _SIGN_BIT_MASK = 1 << _SIGN_BIT;
 
   /**
    * The maximum positive value attainable by an [Int64], namely
@@ -70,10 +70,7 @@
    * [Int64].
    */
   static Int64 parseRadix(String s, int radix) {
-    if ((radix <= 1) || (radix > 36)) {
-      throw new ArgumentError("Bad radix: $radix");
-    }
-    return _parseRadix(s, radix);
+    return _parseRadix(s, Int32._validateRadix(radix));
   }
 
   static Int64 _parseRadix(String s, int radix) {
@@ -83,9 +80,7 @@
       negative = true;
       i++;
     }
-    int d0 = 0,
-        d1 = 0,
-        d2 = 0; //  low, middle, high components.
+    int d0 = 0, d1 = 0, d2 = 0;  //  low, middle, high components.
     for (; i < s.length; i++) {
       int c = s.codeUnitAt(i);
       int digit = Int32._decodeDigit(c);
@@ -109,7 +104,7 @@
 
     if (negative) return _negate(d0, d1, d2);
 
-    return new Int64._bits(d0, d1, d2);
+    return Int64._masked(d0, d1, d2);
   }
 
   /**
@@ -129,27 +124,20 @@
   /**
    * Constructs an [Int64] with a given [int] value; zero by default.
    */
-  factory Int64([int value = 0]) {
-    int v0 = 0,
-        v1 = 0,
-        v2 = 0;
+  factory Int64([int value=0]) {
+    int v0 = 0, v1 = 0, v2 = 0;
     bool negative = false;
     if (value < 0) {
       negative = true;
       value = -value - 1;
     }
-    if (_haveBigInts) {
-      v0 = _MASK & value;
-      v1 = _MASK & (value >> _BITS);
-      v2 = _MASK2 & (value >> _BITS01);
-    } else {
-      // Avoid using bitwise operations that coerce their input to 32 bits.
-      v2 = value ~/ 17592186044416; // 2^44
-      value -= v2 * 17592186044416;
-      v1 = value ~/ 4194304; // 2^22
-      value -= v1 * 4194304;
-      v0 = value;
-    }
+    // Avoid using bitwise operations that in JavaScript coerce their input to
+    // 32 bits.
+    v2 = value ~/ 17592186044416; // 2^44
+    value -= v2 * 17592186044416;
+    v1 = value ~/ 4194304; // 2^22
+    value -= v1 * 4194304;
+    v0 = value;
 
     if (negative) {
       v0 = ~v0;
@@ -197,7 +185,7 @@
     bottom |= bytes[7] & 0xff;
 
     return new Int64.fromInts(top, bottom);
-  }
+ }
 
   /**
    * Constructs an [Int64] from a pair of 32-bit integers having the value
@@ -206,23 +194,23 @@
   factory Int64.fromInts(int top, int bottom) {
     top &= 0xffffffff;
     bottom &= 0xffffffff;
-    int d0 = bottom & _MASK;
-    int d1 = ((top & 0xfff) << 10) | ((bottom >> _BITS) & 0x3ff);
-    int d2 = (top >> 12) & _MASK2;
-    return new Int64._bits(d0, d1, d2);
+    int d0 = _MASK & bottom;
+    int d1 = ((0xfff & top) << 10) | (0x3ff & (bottom >> _BITS));
+    int d2 = _MASK2 & (top >> 12);
+    return  Int64._masked(d0, d1, d2);
   }
 
   // Returns the [Int64] representation of the specified value. Throws
   // [ArgumentError] for non-integer arguments.
-  static Int64 _promote(val) {
-    if (val is Int64) {
-      return val;
-    } else if (val is int) {
-      return new Int64(val);
-    } else if (val is Int32) {
-      return val.toInt64();
+  static Int64 _promote(value) {
+    if (value is Int64) {
+      return value;
+    } else if (value is int) {
+      return new Int64(value);
+    } else if (value is Int32) {
+      return value.toInt64();
     }
-    throw new ArgumentError(val);
+    throw new ArgumentError.value(value);
   }
 
   Int64 operator +(other) {
@@ -316,12 +304,9 @@
 
     // Propagate high bits from c0 -> c1, c1 -> c2.
     c1 += c0 >> _BITS;
-    c0 &= _MASK;
     c2 += c1 >> _BITS;
-    c1 &= _MASK;
-    c2 &= _MASK2;
 
-    return new Int64._bits(c0, c1, c2);
+    return Int64._masked(c0, c1, c2);
   }
 
   Int64 operator %(other) => _divide(this, other, _RETURN_MOD);
@@ -335,7 +320,7 @@
     int a0 = _l & o._l;
     int a1 = _m & o._m;
     int a2 = _h & o._h;
-    return new Int64._bits(a0, a1, a2);
+    return Int64._masked(a0, a1, a2);
   }
 
   Int64 operator |(other) {
@@ -343,7 +328,7 @@
     int a0 = _l | o._l;
     int a1 = _m | o._m;
     int a2 = _h | o._h;
-    return new Int64._bits(a0, a1, a2);
+    return Int64._masked(a0, a1, a2);
   }
 
   Int64 operator ^(other) {
@@ -351,7 +336,7 @@
     int a0 = _l ^ o._l;
     int a1 = _m ^ o._m;
     int a2 = _h ^ o._h;
-    return new Int64._bits(a0, a1, a2);
+    return Int64._masked(a0, a1, a2);
   }
 
   Int64 operator ~() {
@@ -360,7 +345,7 @@
 
   Int64 operator <<(int n) {
     if (n < 0) {
-      throw new ArgumentError(n);
+      throw new ArgumentError.value(n);
     }
     n &= 63;
 
@@ -384,7 +369,7 @@
 
   Int64 operator >>(int n) {
     if (n < 0) {
-      throw new ArgumentError(n);
+      throw new ArgumentError.value(n);
     }
     n &= 63;
 
@@ -427,7 +412,7 @@
 
   Int64 shiftRightUnsigned(int n) {
     if (n < 0) {
-      throw new ArgumentError(n);
+      throw new ArgumentError.value(n);
     }
     n &= 63;
 
@@ -473,7 +458,9 @@
     return false;
   }
 
-  int compareTo(Comparable other) {
+  int compareTo(Comparable other) =>_compareTo(other);
+
+  int _compareTo(other) {
     Int64 o = _promote(other);
     int signa = _h >> (_BITS2 - 1);
     int signb = o._h >> (_BITS2 - 1);
@@ -498,21 +485,10 @@
     return 0;
   }
 
-  bool operator <(other) {
-    return this.compareTo(other) < 0;
-  }
-
-  bool operator <=(other) {
-    return this.compareTo(other) <= 0;
-  }
-
-  bool operator >(other) {
-    return this.compareTo(other) > 0;
-  }
-
-  bool operator >=(other) {
-    return this.compareTo(other) >= 0;
-  }
+  bool operator <(other) => _compareTo(other) < 0;
+  bool operator <=(other) => _compareTo(other) <= 0;
+  bool operator >(other) => this._compareTo(other) > 0;
+  bool operator >=(other) => _compareTo(other) >= 0;
 
   bool get isEven => (_l & 0x1) == 0;
   bool get isMaxValue => (_h == _MASK2 >> 1) && _m == _MASK && _l == _MASK;
@@ -523,9 +499,7 @@
 
   int get bitLength {
     if (isZero) return 0;
-    int a0 = _l,
-        a1 = _m,
-        a2 = _h;
+    int a0 = _l, a1 = _m, a2 = _h;
     if (isNegative) {
       a0 = _MASK & ~a0;
       a1 = _MASK & ~a1;
@@ -601,24 +575,24 @@
   }
 
   Int64 toSigned(int width) {
-    if (width < 1 || width > 64) throw new ArgumentError(width);
+    if (width < 1 || width > 64) throw new RangeError.range(width, 1, 64);
     if (width > _BITS01) {
       return Int64._masked(_l, _m, _h.toSigned(width - _BITS01));
     } else if (width > _BITS) {
       int m = _m.toSigned(width - _BITS);
       return m.isNegative
           ? Int64._masked(_l, m, _MASK2)
-          : Int64._masked(_l, m, 0); // Masking for type inferrer.
+          : Int64._masked(_l, m, 0);  // Masking for type inferrer.
     } else {
       int l = _l.toSigned(width);
       return l.isNegative
           ? Int64._masked(l, _MASK, _MASK2)
-          : Int64._masked(l, 0, 0); // Masking for type inferrer.
+          : Int64._masked(l, 0, 0);  // Masking for type inferrer.
     }
   }
 
   Int64 toUnsigned(int width) {
-    if (width < 0 || width > 64) throw new ArgumentError(width);
+    if (width < 0 || width > 64) throw new RangeError.range(width, 0, 64);
     if (width > _BITS01) {
       int h = _h.toUnsigned(width - _BITS01);
       return Int64._masked(_l, _m, h);
@@ -650,23 +624,15 @@
     int l = _l;
     int m = _m;
     int h = _h;
-    bool negative = false;
+    // In the sum we add least significant to most significant so that in
+    // JavaScript double arithmetic rounding occurs on only the last addition.
     if ((_h & _SIGN_BIT_MASK) != 0) {
       l = _MASK & ~_l;
       m = _MASK & ~_m;
       h = _MASK2 & ~_h;
-      negative = true;
-    }
-
-    if (_haveBigInts) {
-      int result = (h << _BITS01) | (m << _BITS) | l;
-      return negative ? -result - 1 : result;
+      return -((1 + l) + (4194304 * m) + (17592186044416 * h));
     } else {
-      if (negative) {
-        return -((l + 1) + (m * 4194304) + (h * 17592186044416));
-      } else {
-        return (l + (m * 4194304)) + (h * 17592186044416);
-      }
+      return l + (4194304 * m) + (17592186044416 * h);
     }
   }
 
@@ -692,7 +658,6 @@
     if (isZero) return "0";
     Int64 x = this;
     String hexStr = "";
-    Int64 digit_f = new Int64(0xf);
     while (!x.isZero) {
       int digit = x._l & 0xf;
       hexStr = "${_hexDigit(digit)}$hexStr";
@@ -702,10 +667,7 @@
   }
 
   String toRadixString(int radix) {
-    if ((radix <= 1) || (radix > 36)) {
-      throw new ArgumentError("Bad radix: $radix");
-    }
-    return _toRadixString(radix);
+    return _toRadixString(Int32._validateRadix(radix));
   }
 
   String _toRadixString(int radix) {
@@ -764,9 +726,7 @@
     // need only two chunks, but radix values 17-19 and 33-36 generate only 15
     // or 16 bits per iteration, so sometimes the third chunk is needed.
 
-    String chunk1 = "",
-        chunk2 = "",
-        chunk3 = "";
+    String chunk1 = "", chunk2 = "", chunk3 = "";
 
     while (!(d4 == 0 && d3 == 0)) {
       int q = d4 ~/ fatRadix;
@@ -867,24 +827,6 @@
     return _sub(0, 0, 0, b0, b1, b2);
   }
 
-  // Determine whether the platform supports ints greater than 2^53
-  // without loss of precision.
-  static bool _haveBigIntsCached = null;
-
-  static bool get _haveBigInts {
-    if (_haveBigIntsCached == null) {
-      var x = 9007199254740992;
-      // Defeat compile-time constant folding.
-      if (2 + 2 != 4) {
-        x = 0;
-      }
-      var y = x + 1;
-      var same = y == x;
-      _haveBigIntsCached = !same;
-    }
-    return _haveBigIntsCached;
-  }
-
   String _hexDigit(int digit) => "0123456789ABCDEF"[digit];
 
   // Work around dart2js bugs with negative arguments to '>>' operator.
@@ -930,15 +872,11 @@
 
   static _divideHelper(
       // up to 64 bits unsigned in a2/a1/a0 and b2/b1/b0
-      int a0, int a1, int a2, bool aNeg, // input A.
-      int b0, int b1, int b2, bool bNeg, // input B.
+      int a0, int a1, int a2, bool aNeg,  // input A.
+      int b0, int b1, int b2, bool bNeg,  // input B.
       int what) {
-    int q0 = 0,
-        q1 = 0,
-        q2 = 0; // result Q.
-    int r0 = 0,
-        r1 = 0,
-        r2 = 0; // result R.
+    int q0 = 0, q1 = 0, q2 = 0;  // result Q.
+    int r0 = 0, r1 = 0, r2 = 0;  // result R.
 
     if (b2 == 0 && b1 == 0 && b0 < (1 << (30 - _BITS))) {
       // Small divisor can be handled by single-digit division within Smi range.
@@ -986,7 +924,7 @@
       q0 = q0d.toInt();
 
       assert(q0 + K1 * q1 + K2 * q2 == (ad / bd).floorToDouble());
-      assert(q2 == 0 || b2 == 0); // Q and B can't both be big since Q*B <= A.
+      assert(q2 == 0 || b2 == 0);  // Q and B can't both be big since Q*B <= A.
 
       // P = Q * B, using doubles to hold intermediates.
       // We don't need all partial sums since Q*B <= A.
@@ -997,7 +935,7 @@
       double p1carry = (p1d / K1).floorToDouble();
       p1d = p1d - p1carry * K1;
       double p2d = q2d * b0 + q1d * b1 + q0d * b2 + p1carry;
-      assert(p2d <= _MASK2); // No partial sum overflow.
+      assert(p2d <= _MASK2);  // No partial sum overflow.
 
       // R = A - P
       int diff0 = a0 - p0d.toInt();
@@ -1009,7 +947,8 @@
 
       // while (R < 0 || R >= B)
       //  adjust R towards [0, B)
-      while (r2 >= _SIGN_BIT_MASK ||
+      while (
+          r2 >= _SIGN_BIT_MASK ||
           r2 > b2 ||
           (r2 == b2 && (r1 > b1 || (r1 == b1 && r0 >= b0)))) {
         // Direction multiplier for adjustment.
@@ -1034,17 +973,17 @@
 
     // 0 <= R < B
     assert(Int64.ZERO <= new Int64._bits(r0, r1, r2));
-    assert(r2 < b2 || // Handles case where B = -(MIN_VALUE)
+    assert(r2 < b2 ||  // Handles case where B = -(MIN_VALUE)
         new Int64._bits(r0, r1, r2) < new Int64._bits(b0, b1, b2));
 
     assert(what == _RETURN_DIV || what == _RETURN_MOD || what == _RETURN_REM);
     if (what == _RETURN_DIV) {
       if (aNeg != bNeg) return _negate(q0, q1, q2);
-      return Int64._masked(q0, q1, q2); // Masking for type inferrer.
+      return Int64._masked(q0, q1, q2);  // Masking for type inferrer.
     }
 
     if (!aNeg) {
-      return new Int64._bits(_MASK & r0, r1, r2); // Masking for type inferrer.
+      return Int64._masked(r0, r1, r2);  // Masking for type inferrer.
     }
 
     if (what == _RETURN_MOD) {
diff --git a/lib/src/intx.dart b/lib/src/intx.dart
index 859cb95..b47a35e 100644
--- a/lib/src/intx.dart
+++ b/lib/src/intx.dart
@@ -130,7 +130,7 @@
   IntX abs();
 
   /** Clamps this integer to be in the range [lowerLimit] - [upperLimit]. */
-  IntX clamp(IntX lowerLimit, IntX upperLimit);
+  IntX clamp(lowerLimit, upperLimit);
 
   /**
    * Returns the minimum number of bits required to store this integer.
diff --git a/pubspec.yaml b/pubspec.yaml
index 1a3f474..99f990e 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: fixnum
-version: 0.9.1+2
+version: 0.10.4
 author: Dart Team <misc@dartlang.org>
 description: Library for 32- and 64-bit signed fixed-width integers.
 homepage: https://github.com/dart-lang/fixnum
diff --git a/test/int32_test.dart b/test/int32_test.dart
index a5a5a00..df95894 100644
--- a/test/int32_test.dart
+++ b/test/int32_test.dart
@@ -57,8 +57,6 @@
     Int32 n2 = new Int32(9876);
     Int32 n3 = new Int32(-1234);
     Int32 n4 = new Int32(-9876);
-    Int32 n5 = new Int32(0x12345678);
-    Int32 n6 = new Int32(0x22222222);
 
     test("+", () {
       expect(n1 + n2, new Int32(11110));
@@ -317,8 +315,8 @@
       expect(Int32.MIN_VALUE.toSigned(32), Int32.MIN_VALUE);
       expect(Int32.MAX_VALUE.toSigned(31), -Int32.ONE);
       expect(Int32.MIN_VALUE.toSigned(31), Int32.ZERO);
-      expect(() => Int32.ONE.toSigned(0), throws);
-      expect(() => Int32.ONE.toSigned(33), throws);
+      expect(() => Int32.ONE.toSigned(0), throwsRangeError);
+      expect(() => Int32.ONE.toSigned(33), throwsRangeError);
     });
     test("toUnsigned", () {
       expect(Int32.ONE.toUnsigned(1), Int32.ONE);
@@ -327,8 +325,8 @@
       expect(Int32.MIN_VALUE.toUnsigned(32), Int32.MIN_VALUE);
       expect(Int32.MAX_VALUE.toUnsigned(31), Int32.MAX_VALUE);
       expect(Int32.MIN_VALUE.toUnsigned(31), Int32.ZERO);
-      expect(() => Int32.ONE.toUnsigned(-1), throws);
-      expect(() => Int32.ONE.toUnsigned(33), throws);
+      expect(() => Int32.ONE.toUnsigned(-1), throwsRangeError);
+      expect(() => Int32.ONE.toUnsigned(33), throwsRangeError);
     });
     test("toDouble", () {
       expect(new Int32(17).toDouble(), same(17.0));
diff --git a/test/int64_test.dart b/test/int64_test.dart
index e7caa8f..c449822 100644
--- a/test/int64_test.dart
+++ b/test/int64_test.dart
@@ -35,6 +35,14 @@
     });
   });
 
+  argumentErrorTest(name, op, [receiver = Int64.ONE]) {
+    throwsArgumentErrorMentioning(substring) =>
+        throwsA((e) => e is ArgumentError && '$e'.contains(substring));
+
+    expect(() => op(receiver, null), throwsArgumentErrorMentioning('null'));
+    expect(() => op(receiver, 'foo'), throwsArgumentErrorMentioning(r'"foo"'));
+  }
+
   group("is-tests", () {
     test("isEven", () {
       expect((-Int64.ONE).isEven, false);
@@ -96,6 +104,7 @@
       expect(n3 + n4, new Int64(-11110));
       expect(n5 + n6, new Int64.fromInts(0x89ab89ab, 0xcdeff011));
       expect(Int64.MAX_VALUE + 1, Int64.MIN_VALUE);
+      argumentErrorTest("+", (a, b) => a + b);
     });
 
     test("-", () {
@@ -104,6 +113,7 @@
       expect(n3 - n4, new Int64(8642));
       expect(n5 - n6, new Int64.fromInts(0x9abd2345, 0x89ab6789));
       expect(Int64.MIN_VALUE - 1, Int64.MAX_VALUE);
+      argumentErrorTest("-", (a, b) => a - b);
     });
 
     test("unary -", () {
@@ -141,6 +151,7 @@
       expect(Int64.MIN_VALUE * new Int64(2), Int64.ZERO);
       expect(Int64.MIN_VALUE * new Int64(1), Int64.MIN_VALUE);
       expect(Int64.MIN_VALUE * new Int64(-1), Int64.MIN_VALUE);
+      argumentErrorTest("*", (a, b) => a * b);
     });
 
     test("~/", () {
@@ -213,7 +224,7 @@
       expect(Int64.MIN_VALUE ~/ new Int64(1), Int64.MIN_VALUE);
       expect(Int64.MIN_VALUE ~/ new Int64(-1), Int64.MIN_VALUE);
       expect(() => new Int64(17) ~/ Int64.ZERO, throws);
-      expect(() => new Int64(17) ~/ null, throwsArgumentError);
+      argumentErrorTest("~/", (a, b) => a ~/ b);
     });
 
     test("%", () {
@@ -253,6 +264,7 @@
           new Int64(-0x12345678.remainder(0x22)));
       expect(new Int32(0x12345678).remainder(new Int64(0x22)),
           new Int64(0x12345678.remainder(0x22)));
+      argumentErrorTest("%", (a, b) => a % b);
     });
 
     test("clamp", () {
@@ -327,7 +339,7 @@
       expect(largePosPlusOne < largePos, false);
       expect(Int64.MIN_VALUE < Int64.MAX_VALUE, true);
       expect(Int64.MAX_VALUE < Int64.MIN_VALUE, false);
-      expect(() => new Int64(17) < null, throwsArgumentError);
+      argumentErrorTest("<", (a, b) => a < b);
     });
 
     test("<=", () {
@@ -346,7 +358,7 @@
       expect(largePosPlusOne <= largePos, false);
       expect(Int64.MIN_VALUE <= Int64.MAX_VALUE, true);
       expect(Int64.MAX_VALUE <= Int64.MIN_VALUE, false);
-      expect(() => new Int64(17) <= null, throwsArgumentError);
+      argumentErrorTest("<=", (a, b) => a <= b);
     });
 
     test("==", () {
@@ -393,7 +405,7 @@
       expect(largePosPlusOne >= largePos, true);
       expect(Int64.MIN_VALUE >= Int64.MAX_VALUE, false);
       expect(Int64.MAX_VALUE >= Int64.MIN_VALUE, true);
-      expect(() => new Int64(17) >= null, throwsArgumentError);
+      argumentErrorTest(">=", (a, b) => a >= b);
     });
 
     test(">", () {
@@ -414,7 +426,7 @@
       expect(Int64.ZERO > Int64.MIN_VALUE, true);
       expect(Int64.MIN_VALUE > Int64.MAX_VALUE, false);
       expect(Int64.MAX_VALUE > Int64.MIN_VALUE, true);
-      expect(() => new Int64(17) > null, throwsArgumentError);
+      argumentErrorTest(">", (a, b) => a > b);
     });
   });
 
@@ -430,6 +442,7 @@
       expect(n3 & n2, new Int64(8708));
       expect(n4 & n5, new Int64(0x1034) << 32);
       expect(() => n1 & null, throwsArgumentError);
+      argumentErrorTest("&", (a, b) => a & b);
     });
 
     test("|", () {
@@ -437,6 +450,7 @@
       expect(n3 | n2, new Int64(-66));
       expect(n4 | n5, new Int64(0x9a76) << 32);
       expect(() => n1 | null, throwsArgumentError);
+      argumentErrorTest("|", (a, b) => a | b);
     });
 
     test("^", () {
@@ -444,6 +458,7 @@
       expect(n3 ^ n2, new Int64(-8774));
       expect(n4 ^ n5, new Int64(0x8a42) << 32);
       expect(() => n1 ^ null, throwsArgumentError);
+      argumentErrorTest("^", (a, b) => a ^ b);
     });
 
     test("~", () {
@@ -592,8 +607,8 @@
       expect(Int64.MIN_VALUE.toSigned(64), Int64.MIN_VALUE);
       expect(Int64.MAX_VALUE.toSigned(63), -Int64.ONE);
       expect(Int64.MIN_VALUE.toSigned(63), Int64.ZERO);
-      expect(() => Int64.ONE.toSigned(0), throws);
-      expect(() => Int64.ONE.toSigned(65), throws);
+      expect(() => Int64.ONE.toSigned(0), throwsRangeError);
+      expect(() => Int64.ONE.toSigned(65), throwsRangeError);
     });
     test("toUnsigned", () {
       expect((Int64.ONE << 44).toUnsigned(45), Int64.ONE << 44);
@@ -606,8 +621,8 @@
       expect(Int64.MIN_VALUE.toUnsigned(64), Int64.MIN_VALUE);
       expect(Int64.MAX_VALUE.toUnsigned(63), Int64.MAX_VALUE);
       expect(Int64.MIN_VALUE.toUnsigned(63), Int64.ZERO);
-      expect(() => Int64.ONE.toUnsigned(-1), throws);
-      expect(() => Int64.ONE.toUnsigned(65), throws);
+      expect(() => Int64.ONE.toUnsigned(-1), throwsRangeError);
+      expect(() => Int64.ONE.toUnsigned(65), throwsRangeError);
     });
     test("toDouble", () {
       expect(new Int64(0).toDouble(), same(0.0));
@@ -619,14 +634,12 @@
       expect(new Int64(-2147483648).toDouble(), same(-2147483648.0));
       expect(new Int64(4503599627370495).toDouble(), same(4503599627370495.0));
       expect(new Int64(4503599627370496).toDouble(), same(4503599627370496.0));
-      expect(
-          new Int64(-4503599627370495).toDouble(), same(-4503599627370495.0));
-      expect(
-          new Int64(-4503599627370496).toDouble(), same(-4503599627370496.0));
-      expect(Int64
-          .parseInt("-10000000000000000")
-          .toDouble()
-          .toStringAsFixed(1), "-10000000000000000.0");
+      expect(new Int64(-4503599627370495).toDouble(),
+          same(-4503599627370495.0));
+      expect(new Int64(-4503599627370496).toDouble(),
+          same(-4503599627370496.0));
+      expect(Int64.parseInt("-10000000000000000").toDouble().toStringAsFixed(1),
+          "-10000000000000000.0");
       expect(Int64.parseInt("-10000000000000001").toDouble().toStringAsFixed(1),
           "-10000000000000000.0");
       expect(Int64.parseInt("-10000000000000002").toDouble().toStringAsFixed(1),
@@ -657,9 +670,8 @@
       expect(new Int64(4503599627370496).toInt(), 4503599627370496);
       expect(new Int64(-4503599627370495).toInt(), -4503599627370495);
       expect(new Int64(-4503599627370496).toInt(), -4503599627370496);
-      expect(Int64
-          .parseInt("-10000000000000000")
-          .toInt(), same(-10000000000000000));
+      expect(Int64.parseInt("-10000000000000000").toInt(),
+          same(-10000000000000000));
       expect(Int64.parseInt("-10000000000000001").toInt(),
           same(-10000000000000001));
       expect(Int64.parseInt("-10000000000000002").toInt(),
@@ -775,13 +787,18 @@
       check("9223372036854775807", 10, "9223372036854775807");
       // Overflow during parsing.
       check("9223372036854775808", 10, "-9223372036854775808");
+
+      expect(() => Int64.parseRadix('0', 1), throwsRangeError);
+      expect(() => Int64.parseRadix('0', 37), throwsRangeError);
+      expect(() => Int64.parseRadix('xyzzy', -1), throwsRangeError);
+      expect(() => Int64.parseRadix('xyzzy', 10), throwsFormatException);
     });
 
     test("parseRadixN", () {
       check(String s, int r) {
         expect(Int64.parseRadix(s, r).toRadixString(r), s);
       }
-      check("2ppp111222333", 33); // This value & radix requires three chunks.
+      check("2ppp111222333", 33);  // This value & radix requires three chunks.
     });
   });
 
@@ -836,8 +853,8 @@
           "111111111111111111111111111111111111111111111111111111111111111");
       expect(Int64.MAX_VALUE.toRadixString(3),
           "2021110011022210012102010021220101220221");
-      expect(
-          Int64.MAX_VALUE.toRadixString(4), "13333333333333333333333333333333");
+      expect(Int64.MAX_VALUE.toRadixString(4),
+          "13333333333333333333333333333333");
       expect(Int64.MAX_VALUE.toRadixString(5), "1104332401304422434310311212");
       expect(Int64.MAX_VALUE.toRadixString(6), "1540241003031030222122211");
       expect(Int64.MAX_VALUE.toRadixString(7), "22341010611245052052300");