Version 1.11.0-dev.5.6
Cherry-pick a192ef4acb95fad1aad1887f59eed071eb5e8201 into dev
Cherry-pick d9da805f07feb8b613832a5820c875f5b8703141 into dev
Cherry-pick d0d5185550d5b41af75ec6e514c484da4abbf2b5 into dev
Cherry-pick e91b99b66d7cce90ec0784e01128834d861b9d82 into dev
diff --git a/runtime/lib/bigint.dart b/runtime/lib/bigint.dart
index 04b85b7..adfb0db 100644
--- a/runtime/lib/bigint.dart
+++ b/runtime/lib/bigint.dart
@@ -47,6 +47,7 @@
class _Bigint extends _IntegerImplementation implements int {
// Bits per digit.
static const int _DIGIT_BITS = 32;
+ static const int _LOG2_DIGIT_BITS = 5;
static const int _DIGIT_BASE = 1 << _DIGIT_BITS;
static const int _DIGIT_MASK = (1 << _DIGIT_BITS) - 1;
@@ -1538,27 +1539,52 @@
return z._revert(r_digits, r_used)._toValidInt();
}
- // Returns 1/this % m, with m > 0.
- int modInverse(int m) {
- if (m is! int) throw new ArgumentError(m);
- if (m <= 0) throw new RangeError(m);
- if (m == 1) return 0;
- m = m._toBigint();
- var t = this;
- if (t._neg || (t._absCompare(m) >= 0)) {
- t %= m;
- t = t._toBigint();
+ // If inv is false, returns gcd(x, y).
+ // If inv is true and gcd(x, y) = 1, returns d, so that c*x + d*y = 1.
+ // If inv is true and gcd(x, y) != 1, throws RangeError("Not coprime").
+ static int _binaryGcd(_Bigint x, _Bigint y, bool inv) {
+ var x_digits = x._digits;
+ var y_digits = y._digits;
+ var x_used = x._used;
+ var y_used = y._used;
+ var m_used = x_used > y_used ? x_used : y_used;
+ final m_len = m_used + (m_used & 1);
+ x_digits = _cloneDigits(x_digits, 0, x_used, m_len);
+ y_digits = _cloneDigits(y_digits, 0, y_used, m_len);
+ int s = 0;
+ if (inv) {
+ if ((y_used == 1) && (y_digits[0] == 1)) return 1;
+ if ((y_used == 0) || (y_digits[0].isEven && x_digits[0].isEven)) {
+ throw new RangeError("Not coprime");
+ }
+ } else {
+ if ((x_used == 0) || (y_used == 0)) throw new RangeError(0);
+ if (((x_used == 1) && (x_digits[0] == 1)) ||
+ ((y_used == 1) && (y_digits[0] == 1))) return 1;
+ bool xy_cloned = false;
+ while (x.isEven && y.isEven) {
+ _rsh(x_digits, x_used, 1, x_digits);
+ _rsh(y_digits, y_used, 1, y_digits);
+ s++;
+ }
+ if (s >= _DIGIT_BITS) {
+ var sd = s >> _LOG2_DIGIT_BITS;
+ x_used -= sd;
+ y_used -= sd;
+ m_used -= sd;
+ }
+ if ((y_digits[0] & 1) == 1) {
+ var t_digits = x_digits;
+ var t_used = x_used;
+ x_digits = y_digits;
+ x_used = y_used;
+ y_digits = t_digits;
+ y_used = t_used;
+ }
}
- final bool ac = m.isEven;
- final t_used = t._used;
- if ((t_used == 1) && (t._digits[0] == 1)) return 1;
- if ((t_used == 0) || (ac && t.isEven)) throw new RangeError("Not coprime");
- final m_digits = m._digits;
- final m_used = m._used;
- final tuv_len = m_used + (m_used & 1);
- final t_digits = _cloneDigits(t._digits, 0, t_used, tuv_len);
- var u_digits = _cloneDigits(m_digits, 0, m_used, tuv_len);
- var v_digits = _cloneDigits(t_digits, 0, t_used, tuv_len);
+ var u_digits = _cloneDigits(x_digits, 0, x_used, m_len);
+ var v_digits = _cloneDigits(y_digits, 0, y_used, m_len);
+ final bool ac = (x_digits[0] & 1) == 0;
// Variables a, b, c, and d require one more digit.
final abcd_used = m_used + 1;
@@ -1585,34 +1611,34 @@
if (((a_digits[0] & 1) == 1) || ((b_digits[0] & 1) == 1)) {
if (a_neg) {
if ((a_digits[m_used] != 0) ||
- (_compareDigits(a_digits, m_used, t_digits, m_used)) > 0) {
- _absSub(a_digits, abcd_used, t_digits, m_used, a_digits);
+ (_compareDigits(a_digits, m_used, y_digits, m_used)) > 0) {
+ _absSub(a_digits, abcd_used, y_digits, m_used, a_digits);
} else {
- _absSub(t_digits, m_used, a_digits, m_used, a_digits);
+ _absSub(y_digits, m_used, a_digits, m_used, a_digits);
a_neg = false;
}
} else {
- _absAdd(a_digits, abcd_used, t_digits, m_used, a_digits);
+ _absAdd(a_digits, abcd_used, y_digits, m_used, a_digits);
}
if (b_neg) {
- _absAdd(b_digits, abcd_used, m_digits, m_used, b_digits);
+ _absAdd(b_digits, abcd_used, x_digits, m_used, b_digits);
} else if ((b_digits[m_used] != 0) ||
- (_compareDigits(b_digits, m_used, m_digits, m_used) > 0)) {
- _absSub(b_digits, abcd_used, m_digits, m_used, b_digits);
+ (_compareDigits(b_digits, m_used, x_digits, m_used) > 0)) {
+ _absSub(b_digits, abcd_used, x_digits, m_used, b_digits);
} else {
- _absSub(m_digits, m_used, b_digits, m_used, b_digits);
+ _absSub(x_digits, m_used, b_digits, m_used, b_digits);
b_neg = true;
}
}
_rsh(a_digits, abcd_used, 1, a_digits);
} else if ((b_digits[0] & 1) == 1) {
if (b_neg) {
- _absAdd(b_digits, abcd_used, m_digits, m_used, b_digits);
+ _absAdd(b_digits, abcd_used, x_digits, m_used, b_digits);
} else if ((b_digits[m_used] != 0) ||
- (_compareDigits(b_digits, m_used, m_digits, m_used) > 0)) {
- _absSub(b_digits, abcd_used, m_digits, m_used, b_digits);
+ (_compareDigits(b_digits, m_used, x_digits, m_used) > 0)) {
+ _absSub(b_digits, abcd_used, x_digits, m_used, b_digits);
} else {
- _absSub(m_digits, m_used, b_digits, m_used, b_digits);
+ _absSub(x_digits, m_used, b_digits, m_used, b_digits);
b_neg = true;
}
}
@@ -1624,34 +1650,34 @@
if (((c_digits[0] & 1) == 1) || ((d_digits[0] & 1) == 1)) {
if (c_neg) {
if ((c_digits[m_used] != 0) ||
- (_compareDigits(c_digits, m_used, t_digits, m_used) > 0)) {
- _absSub(c_digits, abcd_used, t_digits, m_used, c_digits);
+ (_compareDigits(c_digits, m_used, y_digits, m_used) > 0)) {
+ _absSub(c_digits, abcd_used, y_digits, m_used, c_digits);
} else {
- _absSub(t_digits, m_used, c_digits, m_used, c_digits);
+ _absSub(y_digits, m_used, c_digits, m_used, c_digits);
c_neg = false;
}
} else {
- _absAdd(c_digits, abcd_used, t_digits, m_used, c_digits);
+ _absAdd(c_digits, abcd_used, y_digits, m_used, c_digits);
}
if (d_neg) {
- _absAdd(d_digits, abcd_used, m_digits, m_used, d_digits);
+ _absAdd(d_digits, abcd_used, x_digits, m_used, d_digits);
} else if ((d_digits[m_used] != 0) ||
- (_compareDigits(d_digits, m_used, m_digits, m_used) > 0)) {
- _absSub(d_digits, abcd_used, m_digits, m_used, d_digits);
+ (_compareDigits(d_digits, m_used, x_digits, m_used) > 0)) {
+ _absSub(d_digits, abcd_used, x_digits, m_used, d_digits);
} else {
- _absSub(m_digits, m_used, d_digits, m_used, d_digits);
+ _absSub(x_digits, m_used, d_digits, m_used, d_digits);
d_neg = true;
}
}
_rsh(c_digits, abcd_used, 1, c_digits);
} else if ((d_digits[0] & 1) == 1) {
if (d_neg) {
- _absAdd(d_digits, abcd_used, m_digits, m_used, d_digits);
+ _absAdd(d_digits, abcd_used, x_digits, m_used, d_digits);
} else if ((d_digits[m_used] != 0) ||
- (_compareDigits(d_digits, m_used, m_digits, m_used) > 0)) {
- _absSub(d_digits, abcd_used, m_digits, m_used, d_digits);
+ (_compareDigits(d_digits, m_used, x_digits, m_used) > 0)) {
+ _absSub(d_digits, abcd_used, x_digits, m_used, d_digits);
} else {
- _absSub(m_digits, m_used, d_digits, m_used, d_digits);
+ _absSub(x_digits, m_used, d_digits, m_used, d_digits);
d_neg = true;
}
}
@@ -1719,6 +1745,12 @@
while ((i > 0) && (u_digits[i - 1] == 0)) --i;
if (i == 0) break;
}
+ if (!inv) {
+ if (s > 0) {
+ _lsh(v_digits, m_used, s, v_digits);
+ }
+ return new _Bigint(false, m_used, v_digits)._toValidInt();
+ }
// No inverse if v != 1.
var i = m_used - 1;
while ((i > 0) && (v_digits[i] == 0)) --i;
@@ -1726,29 +1758,49 @@
if (d_neg) {
if ((d_digits[m_used] != 0) ||
- (_compareDigits(d_digits, m_used, m_digits, m_used) > 0)) {
- _absSub(d_digits, abcd_used, m_digits, m_used, d_digits);
+ (_compareDigits(d_digits, m_used, x_digits, m_used) > 0)) {
+ _absSub(d_digits, abcd_used, x_digits, m_used, d_digits);
if ((d_digits[m_used] != 0) ||
- (_compareDigits(d_digits, m_used, m_digits, m_used) > 0)) {
- _absSub(d_digits, abcd_used, m_digits, m_used, d_digits);
+ (_compareDigits(d_digits, m_used, x_digits, m_used) > 0)) {
+ _absSub(d_digits, abcd_used, x_digits, m_used, d_digits);
} else {
- _absSub(m_digits, m_used, d_digits, m_used, d_digits);
+ _absSub(x_digits, m_used, d_digits, m_used, d_digits);
d_neg = false;
}
} else {
- _absSub(m_digits, m_used, d_digits, m_used, d_digits);
+ _absSub(x_digits, m_used, d_digits, m_used, d_digits);
d_neg = false;
}
} else if ((d_digits[m_used] != 0) ||
- (_compareDigits(d_digits, m_used, m_digits, m_used) > 0)) {
- _absSub(d_digits, abcd_used, m_digits, m_used, d_digits);
+ (_compareDigits(d_digits, m_used, x_digits, m_used) > 0)) {
+ _absSub(d_digits, abcd_used, x_digits, m_used, d_digits);
if ((d_digits[m_used] != 0) ||
- (_compareDigits(d_digits, m_used, m_digits, m_used) > 0)) {
- _absSub(d_digits, abcd_used, m_digits, m_used, d_digits);
+ (_compareDigits(d_digits, m_used, x_digits, m_used) > 0)) {
+ _absSub(d_digits, abcd_used, x_digits, m_used, d_digits);
}
}
return new _Bigint(false, m_used, d_digits)._toValidInt();
}
+
+ // Returns 1/this % m, with m > 0.
+ int modInverse(int m) {
+ if (m is! int) throw new ArgumentError(m);
+ if (m <= 0) throw new RangeError(m);
+ if (m == 1) return 0;
+ m = m._toBigint();
+ var t = this;
+ if (t._neg || (t._absCompare(m) >= 0)) {
+ t %= m;
+ t = t._toBigint();
+ }
+ return _binaryGcd(m, t, true);
+ }
+
+ // Returns gcd of abs(this) and abs(other), with this != 0 and other !=0.
+ int gcd(int other) {
+ if (other is! int) throw new ArgumentError(other);
+ return _binaryGcd(this, other._toBigint(), false);
+ }
}
// Interface for modular reduction.
diff --git a/runtime/lib/integers.dart b/runtime/lib/integers.dart
index 1267d15..be0cb8f 100644
--- a/runtime/lib/integers.dart
+++ b/runtime/lib/integers.dart
@@ -290,21 +290,26 @@
return r;
}
- // Returns 1/this % m, with m > 0.
- int modInverse(int m) {
- if (m is! int) throw new ArgumentError(m);
- if (m <= 0) throw new RangeError(m);
- if (m == 1) return 0;
- if (m is _Bigint) {
- return _toBigint().modInverse(m);
+ // If inv is false, returns gcd(x, y).
+ // If inv is true and gcd(x, y) = 1, returns d, so that c*x + d*y = 1.
+ // If inv is true and gcd(x, y) != 1, throws RangeError("Not coprime").
+ static int _binaryGcd(int x, int y, bool inv) {
+ int s = 0;
+ if (!inv) {
+ while (x.isEven && y.isEven) {
+ x >>= 1;
+ y >>= 1;
+ s++;
+ }
+ if (y.isOdd) {
+ var t = x;
+ x = y;
+ y = t;
+ }
}
- int t = this;
- if ((t < 0) || (t >= m)) t %= m;
- if (t == 1) return 1;
- final bool ac = m.isEven;
- if ((t == 0) || (ac && t.isEven)) throw new RangeError("Not coprime");
- int u = m;
- int v = t;
+ final bool ac = x.isEven;
+ int u = x;
+ int v = y;
int a = 1,
b = 0,
c = 0,
@@ -314,12 +319,12 @@
u >>= 1;
if (ac) {
if (!a.isEven || !b.isEven) {
- a += t;
- b -= m;
+ a += y;
+ b -= x;
}
a >>= 1;
} else if (!b.isEven) {
- b -= m;
+ b -= x;
}
b >>= 1;
}
@@ -327,12 +332,12 @@
v >>= 1;
if (ac) {
if (!c.isEven || !d.isEven) {
- c += t;
- d -= m;
+ c += y;
+ d -= x;
}
c >>= 1;
} else if (!d.isEven) {
- d -= m;
+ d -= x;
}
d >>= 1;
}
@@ -346,16 +351,45 @@
d -= b;
}
} while (u != 0);
+ if (!inv) return v << s;
if (v != 1) throw new RangeError("Not coprime");
if (d < 0) {
- d += m;
- if (d < 0) d += m;
- } else if (d > m) {
- d -= m;
- if (d > m) d -= m;
+ d += x;
+ if (d < 0) d += x;
+ } else if (d > x) {
+ d -= x;
+ if (d > x) d -= x;
}
return d;
}
+
+ // Returns 1/this % m, with m > 0.
+ int modInverse(int m) {
+ if (m is! int) throw new ArgumentError(m);
+ if (m <= 0) throw new RangeError(m);
+ if (m == 1) return 0;
+ if (m is _Bigint) {
+ return _toBigint().modInverse(m);
+ }
+ int t = this;
+ if ((t < 0) || (t >= m)) t %= m;
+ if (t == 1) return 1;
+ if ((t == 0) || (t.isEven && m.isEven)) throw new RangeError("Not coprime");
+ return _binaryGcd(m, t, true);
+ }
+
+ // Returns gcd of abs(this) and abs(other), with this != 0 and other !=0.
+ int gcd(int other) {
+ if (other is! int) throw new ArgumentError(other);
+ if ((this == 0) || (other == 0)) throw new RangeError(0);
+ int x = this.abs();
+ int y = other.abs();
+ if ((x == 1) || (y == 1)) return 1;
+ if (other is _Bigint) {
+ return _toBigint().gcd(other);
+ }
+ return _binaryGcd(x, y, false);
+ }
}
class _Smi extends _IntegerImplementation implements int {
diff --git a/runtime/vm/constant_propagator.cc b/runtime/vm/constant_propagator.cc
index a1abaad..35bab84 100644
--- a/runtime/vm/constant_propagator.cc
+++ b/runtime/vm/constant_propagator.cc
@@ -508,13 +508,17 @@
}
+// Comparison instruction that is equivalent to the (left & right) == 0
+// comparison pattern.
void ConstantPropagator::VisitTestSmi(TestSmiInstr* instr) {
const Object& left = instr->left()->definition()->constant_value();
const Object& right = instr->right()->definition()->constant_value();
if (IsNonConstant(left) || IsNonConstant(right)) {
SetValue(instr, non_constant_);
} else if (IsConstant(left) && IsConstant(right)) {
- if (left.IsInteger() && right.IsInteger()) {
+ // BitOp does not work on Bigints.
+ if (left.IsInteger() && right.IsInteger() &&
+ !left.IsBigint() && !right.IsBigint()) {
const bool result = CompareIntegers(
instr->kind(),
Integer::Handle(I, Integer::Cast(left).BitOp(Token::kBIT_AND,
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index f78c295..1bdd070 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -1656,7 +1656,7 @@
case Token::kTRUNCDIV:
case Token::kMOD:
// Check right value for zero.
- if (right.AsInt64Value() == 0) {
+ if (right.IsSmi() && right.AsInt64Value() == 0) {
break; // Will throw.
}
// Fall through.
diff --git a/sdk/lib/_internal/compiler/js_lib/js_number.dart b/sdk/lib/_internal/compiler/js_lib/js_number.dart
index 8822911..64df825 100644
--- a/sdk/lib/_internal/compiler/js_lib/js_number.dart
+++ b/sdk/lib/_internal/compiler/js_lib/js_number.dart
@@ -411,18 +411,26 @@
return r;
}
- // Returns 1/this % m, with m > 0.
- int modInverse(int m) {
- if (m is! int) throw new ArgumentError(m);
- if (m <= 0) throw new RangeError(m);
- if (m == 1) return 0;
- int t = this;
- if ((t < 0) || (t >= m)) t %= m;
- if (t == 1) return 1;
- final bool ac = m.isEven;
- if ((t == 0) || (ac && t.isEven)) throw new RangeError("Not coprime");
- int u = m;
- int v = t;
+ // If inv is false, returns gcd(x, y).
+ // If inv is true and gcd(x, y) = 1, returns d, so that c*x + d*y = 1.
+ // If inv is true and gcd(x, y) != 1, throws RangeError("Not coprime").
+ static int _binaryGcd(int x, int y, bool inv) {
+ int s = 1;
+ if (!inv) {
+ while (x.isEven && y.isEven) {
+ x ~/= 2;
+ y ~/= 2;
+ s *= 2;
+ }
+ if (y.isOdd) {
+ var t = x;
+ x = y;
+ y = t;
+ }
+ }
+ final bool ac = x.isEven;
+ int u = x;
+ int v = y;
int a = 1,
b = 0,
c = 0,
@@ -432,12 +440,12 @@
u ~/= 2;
if (ac) {
if (!a.isEven || !b.isEven) {
- a += t;
- b -= m;
+ a += y;
+ b -= x;
}
a ~/= 2;
} else if (!b.isEven) {
- b -= m;
+ b -= x;
}
b ~/= 2;
}
@@ -445,12 +453,12 @@
v ~/= 2;
if (ac) {
if (!c.isEven || !d.isEven) {
- c += t;
- d -= m;
+ c += y;
+ d -= x;
}
c ~/= 2;
} else if (!d.isEven) {
- d -= m;
+ d -= x;
}
d ~/= 2;
}
@@ -464,17 +472,40 @@
d -= b;
}
} while (u != 0);
+ if (!inv) return s*v;
if (v != 1) throw new RangeError("Not coprime");
if (d < 0) {
- d += m;
- if (d < 0) d += m;
- } else if (d > m) {
- d -= m;
- if (d > m) d -= m;
+ d += x;
+ if (d < 0) d += x;
+ } else if (d > x) {
+ d -= x;
+ if (d > x) d -= x;
}
return d;
}
+ // Returns 1/this % m, with m > 0.
+ int modInverse(int m) {
+ if (m is! int) throw new ArgumentError(m);
+ if (m <= 0) throw new RangeError(m);
+ if (m == 1) return 0;
+ int t = this;
+ if ((t < 0) || (t >= m)) t %= m;
+ if (t == 1) return 1;
+ if ((t == 0) || (t.isEven && m.isEven)) throw new RangeError("Not coprime");
+ return _binaryGcd(m, t, true);
+ }
+
+ // Returns gcd of abs(this) and abs(other), with this != 0 and other !=0.
+ int gcd(int other) {
+ if (other is! int) throw new ArgumentError(other);
+ if ((this == 0) || (other == 0)) throw new RangeError(0);
+ int x = this.abs();
+ int y = other.abs();
+ if ((x == 1) || (y == 1)) return 1;
+ return _binaryGcd(x, y, false);
+ }
+
// Assumes i is <= 32-bit and unsigned.
static int _bitCount(int i) {
// See "Hacker's Delight", section 5-1, "Counting 1-Bits".
diff --git a/sdk/lib/core/int.dart b/sdk/lib/core/int.dart
index 5aee609..58d80b8 100644
--- a/sdk/lib/core/int.dart
+++ b/sdk/lib/core/int.dart
@@ -120,6 +120,14 @@
*/
int modInverse(int modulus);
+ /**
+ * Returns the greatest common divisor of the absolute value of
+ * this integer and the absolute value of [other].
+ *
+ * Both this and [other] must be non-zero.
+ */
+ int gcd(int other);
+
/** Returns true if and only if this integer is even. */
bool get isEven;
diff --git a/tests/corelib/big_integer_arith_vm_test.dart b/tests/corelib/big_integer_arith_vm_test.dart
index 3353756..8b76ba0 100644
--- a/tests/corelib/big_integer_arith_vm_test.dart
+++ b/tests/corelib/big_integer_arith_vm_test.dart
@@ -5,6 +5,7 @@
// Testing Bigints with and without intrinsics.
// VMOptions=
// VMOptions=--no_intrinsify
+// VMOptions=--optimization_counter_threshold=10
library big_integer_test;
import "package:expect/expect.dart";
@@ -293,6 +294,88 @@
Expect.equals(46296295879629629587962962962, x.modInverse(m));
}
+testBigintGcd() {
+ var x, m;
+ x = 1;
+ m = 1;
+ Expect.equals(1, x.gcd(m));
+ x = 693;
+ m = 609;
+ Expect.equals(21, x.gcd(m));
+ x = 693 << 40;
+ m = 609 << 40;
+ Expect.equals(21 << 40, x.gcd(m));
+ x = 609 << 40;;
+ m = 693 << 40;;
+ Expect.equals(21 <<40, x.gcd(m));
+ x = 0;
+ m = 1000000001;
+ Expect.throws(() => x.gcd(m), (e) => e is RangeError);
+ x = 1000000001;
+ m = 0;
+ Expect.throws(() => x.gcd(m), (e) => e is RangeError);
+ x = 1234567890;
+ m = 19;
+ Expect.equals(1, x.gcd(m));
+ x = 1234567890;
+ m = 1000000001;
+ Expect.equals(1, x.gcd(m));
+ x = 19;
+ m = 1000000001;
+ Expect.equals(19, x.gcd(m));
+ x = 19;
+ m = 1234567890;
+ Expect.equals(1, x.gcd(m));
+ x = 1000000001;
+ m = 1234567890;
+ Expect.equals(1, x.gcd(m));
+ x = 1000000001;
+ m = 19;
+ Expect.equals(19, x.gcd(m));
+ x = 12345678901234567890;
+ m = 19;
+ Expect.equals(1, x.gcd(m));
+ x = 12345678901234567890;
+ m = 10000000000000000001;
+ Expect.equals(1, x.gcd(m));
+ x = 19;
+ m = 10000000000000000001;
+ Expect.equals(1, x.gcd(m));
+ x = 19;
+ m = 12345678901234567890;
+ Expect.equals(1, x.gcd(m));
+ x = 10000000000000000001;
+ m = 12345678901234567890;
+ Expect.equals(1, x.gcd(m));
+ x = 10000000000000000001;
+ m = 19;
+ Expect.equals(1, x.gcd(m));
+ x = 12345678901234567890;
+ m = 10000000000000000001;
+ Expect.equals(1, x.gcd(m));
+ x = 12345678901234567890;
+ m = 19;
+ Expect.equals(1, x.gcd(m));
+ x = 123456789012345678901234567890;
+ m = 123456789012345678901234567899;
+ Expect.equals(9, x.gcd(m));
+ x = 123456789012345678901234567890;
+ m = 123456789012345678901234567891;
+ Expect.equals(1, x.gcd(m));
+ x = 123456789012345678901234567899;
+ m = 123456789012345678901234567891;
+ Expect.equals(1, x.gcd(m));
+ x = 123456789012345678901234567899;
+ m = 123456789012345678901234567890;
+ Expect.equals(9, x.gcd(m));
+ x = 123456789012345678901234567891;
+ m = 123456789012345678901234567890;
+ Expect.equals(1, x.gcd(m));
+ x = 123456789012345678901234567891;
+ m = 123456789012345678901234567899;
+ Expect.equals(1, x.gcd(m));
+}
+
testBigintNegate() {
var a = 0xF000000000000000F;
var b = ~a; // negate.
@@ -314,23 +397,26 @@
}
main() {
- Expect.equals(1234567890123456789, foo());
- Expect.equals(12345678901234567890, bar());
- testSmiOverflow();
- testBigintAdd();
- testBigintSub();
- testBigintMul();
- testBigintTruncDiv();
- testBigintDiv();
- testBigintModulo();
- testBigintModPow();
- testBigintModInverse();
- testBigintNegate();
- testShiftAmount();
- Expect.equals(12345678901234567890, (12345678901234567890).abs());
- Expect.equals(12345678901234567890, (-12345678901234567890).abs());
- var a = 10000000000000000000;
- var b = 10000000000000000001;
- Expect.equals(false, a.hashCode == b.hashCode);
- Expect.equals(true, a.hashCode == (b - 1).hashCode);
+ for (int i = 0; i < 10; i++) {
+ Expect.equals(1234567890123456789, foo());
+ Expect.equals(12345678901234567890, bar());
+ testSmiOverflow(); /// overflow: ok
+ testBigintAdd(); /// add: ok
+ testBigintSub(); /// sub: ok
+ testBigintMul(); /// mul: ok
+ testBigintTruncDiv(); /// trunDiv: ok
+ testBigintDiv(); /// div: ok
+ testBigintModulo(); /// mod: ok
+ testBigintModPow(); /// modPow: ok
+ testBigintModInverse(); /// modInv: ok
+ testBigintGcd(); /// gcd: ok
+ testBigintNegate(); /// negate: ok
+ testShiftAmount(); /// shift: ok
+ Expect.equals(12345678901234567890, (12345678901234567890).abs());
+ Expect.equals(12345678901234567890, (-12345678901234567890).abs());
+ var a = 10000000000000000000;
+ var b = 10000000000000000001;
+ Expect.equals(false, a.hashCode == b.hashCode);
+ Expect.equals(true, a.hashCode == (b - 1).hashCode);
+ }
}
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 97080cb..f107d2c 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -205,6 +205,10 @@
[ $mode == debug ]
regexp/pcre_test: Pass, Slow # Timeout. Issue 22008
+[ $mode == debug && $runtime == vm]
+big_integer_arith_vm_test/gcd: Pass, Crash # Issue 23693
+big_integer_arith_vm_test/modInv: Pass, Crash # Issue 23693
+
[ $runtime == vm && $arch == simarmv5te ]
int_parse_radix_test/*: Pass, Slow
big_integer_parsed_mul_div_vm_test: Pass, Slow
diff --git a/tools/VERSION b/tools/VERSION
index 1782662..7f622f5 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -28,4 +28,4 @@
MINOR 11
PATCH 0
PRERELEASE 5
-PRERELEASE_PATCH 5
+PRERELEASE_PATCH 6