[VM] Clean up typing violations in the numerics implementation.

Bug: https://github.com/dart-lang/sdk/issues/31052
Change-Id: I93d7bca2ff627431f1a316bb01a5dada1b5f2354
Reviewed-on: https://dart-review.googlesource.com/14522
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
Reviewed-by: Kevin Millikin <kmillikin@google.com>
This commit is contained in:
Vyacheslav Egorov 2017-10-17 21:00:24 +00:00 committed by commit-bot@chromium.org
parent 5bdffcd32e
commit 826b48ee8a
7 changed files with 89 additions and 53 deletions

View file

@ -46,7 +46,7 @@
// meaningful, so that pairs of digits can be processed as 64-bit unsigned
// numbers on a 64-bit platform. This requires the initialization of a leading
// zero if the number of used digits is odd.
class _Bigint extends _IntegerImplementation implements int {
class _Bigint extends _IntegerImplementation {
// Bits per digit.
static const int _DIGIT_BITS = 32;
static const int _LOG2_DIGIT_BITS = 5;
@ -1293,7 +1293,7 @@ class _Bigint extends _IntegerImplementation implements int {
return other._toBigintOrDouble()._mulFromInteger(this);
}
num operator ~/(num other) {
int operator ~/(num other) {
return other._toBigintOrDouble()._truncDivFromInteger(this);
}
@ -1302,23 +1302,23 @@ class _Bigint extends _IntegerImplementation implements int {
}
int operator &(int other) {
return other._toBigintOrDouble()._bitAndFromInteger(this);
return other._toBigint()._bitAndFromInteger(this);
}
int operator |(int other) {
return other._toBigintOrDouble()._bitOrFromInteger(this);
return other._toBigint()._bitOrFromInteger(this);
}
int operator ^(int other) {
return other._toBigintOrDouble()._bitXorFromInteger(this);
return other._toBigint()._bitXorFromInteger(this);
}
int operator >>(int other) {
return other._toBigintOrDouble()._shrFromInt(this);
return other._toBigint()._shrFromInt(this);
}
int operator <<(int other) {
return other._toBigintOrDouble()._shlFromInt(this);
return other._toBigint()._shlFromInt(this);
}
// End of operator shortcuts.
@ -1368,7 +1368,7 @@ class _Bigint extends _IntegerImplementation implements int {
return str;
}
int _bitAndFromSmi(int other) => _bitAndFromInteger(other);
int _bitAndFromSmi(_Smi other) => _bitAndFromInteger(other);
int _bitAndFromInteger(int other) {
return other._toBigint()._and(this)._toValidInt();
@ -1442,16 +1442,16 @@ class _Bigint extends _IntegerImplementation implements int {
if (e < 0) throw new RangeError.range(e, 0, null, "exponent");
if (m <= 0) throw new RangeError.range(m, 1, null, "modulus");
if (e == 0) return 1;
m = m._toBigint();
final m_used = m._used;
final mAsBigint = m._toBigint();
final m_used = mAsBigint._used;
final m_used2p4 = 2 * m_used + 4;
final e_bitlen = e.bitLength;
if (e_bitlen <= 0) return 1;
final bool cannotUseMontgomery = m.isEven || _abs() >= m;
final bool cannotUseMontgomery = mAsBigint.isEven || _abs() >= mAsBigint;
if (cannotUseMontgomery || e_bitlen < 64) {
_Reduction z = (cannotUseMontgomery || e_bitlen < 8)
? new _Classic(m)
: new _Montgomery(m);
? new _Classic(mAsBigint)
: new _Montgomery(mAsBigint);
// TODO(regis): Should we use Barrett reduction for an even modulus and a
// large exponent?
var r_digits = new Uint32List(m_used2p4);
@ -1481,7 +1481,7 @@ class _Bigint extends _IntegerImplementation implements int {
}
return z._revert(r_digits, r_used)._toValidInt();
}
e = e._toBigint();
final eAsBigint = e._toBigint();
var k;
if (e_bitlen < 18)
k = 1;
@ -1493,7 +1493,7 @@ class _Bigint extends _IntegerImplementation implements int {
k = 5;
else
k = 6;
_Reduction z = new _Montgomery(m);
_Reduction z = new _Montgomery(mAsBigint);
var n = 3;
final k1 = k - 1;
final km = (1 << k) - 1;
@ -1517,8 +1517,8 @@ class _Bigint extends _IntegerImplementation implements int {
var r_used = _ONE._used;
var r2_digits = new Uint32List(m_used2p4);
var r2_used;
var e_digits = e._digits;
var j = e._used - 1;
var e_digits = eAsBigint._digits;
var j = eAsBigint._used - 1;
var i = _nbits(e_digits[j]) - 1;
while (j >= 0) {
if (i >= k1) {
@ -1841,13 +1841,13 @@ class _Bigint extends _IntegerImplementation implements int {
}
if (m <= 0) throw new RangeError.range(m, 1, null, "modulus");
if (m == 1) return 0;
m = m._toBigint();
final mAsBigint = m._toBigint();
var t = this;
if (t._neg || (t._absCompare(m) >= 0)) {
t %= m;
if (t._neg || (t._absCompare(mAsBigint) >= 0)) {
t %= mAsBigint;
t = t._toBigint();
}
return _binaryGcd(m, t, true);
return _binaryGcd(mAsBigint, t, true);
}
// Returns gcd of abs(this) and abs(other).
@ -1876,7 +1876,7 @@ class _Reduction {
// Montgomery reduction on _Bigint.
class _Montgomery implements _Reduction {
_Bigint _m; // Modulus.
final _Bigint _m; // Modulus.
int _mused2p2;
Uint32List _args;
int _digits_per_step; // Number of digits processed in one step. 1 or 2.
@ -1887,8 +1887,7 @@ class _Montgomery implements _Reduction {
static const int _MU = 4; // Index of mu.
static const int _MU_HI = 5; // Index of high 32-bits of mu (64-bit only).
_Montgomery(m) {
_m = m._toBigint();
_Montgomery(this._m) {
_mused2p2 = 2 * _m._used + 2;
_args = new Uint32List(6);
// Determine if we can process digit pairs by calling an intrinsic.
@ -2044,7 +2043,7 @@ class _Montgomery implements _Reduction {
// Modular reduction using "classic" algorithm.
class _Classic implements _Reduction {
_Bigint _m; // Modulus.
final _Bigint _m; // Modulus.
_Bigint _norm_m; // Normalized _m.
Uint32List _neg_norm_m_digits; // Negated _norm_m digits.
int _m_nsh; // Normalization shift amount.
@ -2052,8 +2051,7 @@ class _Classic implements _Reduction {
// estimated quotient digit(s).
Uint32List _t_digits; // Temporary digits used during reduction.
_Classic(int m) {
_m = m._toBigint();
_Classic(this._m) {
// Preprocess arguments to _remDigits.
var nsh = _Bigint._DIGIT_BITS - _Bigint._nbits(_m._digits[_m._used - 1]);
// For 64-bit processing, make sure _norm_m_digits has an even number of

View file

@ -78,6 +78,19 @@ import "dart:typed_data" show Uint8List, Int64List, Uint16List, Uint32List;
// part "uri_patch.dart";
// part "weak_property.dart";
@patch
class num {
num _addFromInteger(int other);
num _subFromInteger(int other);
num _mulFromInteger(int other);
int _truncDivFromInteger(int other);
num _moduloFromInteger(int other);
num _remainderFromInteger(int other);
bool _greaterThanFromInteger(int other);
bool _equalToInteger(int other);
num _toBigintOrDouble();
}
// The members of this class are cloned and added to each class that
// represents an enum type.
class _EnumHelper {

View file

@ -8,38 +8,39 @@
// propagation and range analysis. It is implemented by _Smi and _Mint.
abstract class _int64 implements int {}
abstract class _IntegerImplementation {
// The Dart class _Bigint extending _IntegerImplementation requires a
// default constructor.
abstract class _IntegerImplementation implements int {
num operator +(num other) {
var result = other._addFromInteger(this);
if (result != null) return result;
return other._toBigint()._addFromInteger(this);
final _IntegerImplementation otherAsIntImpl = other;
return otherAsIntImpl._toBigint()._addFromInteger(this);
}
num operator -(num other) {
var result = other._subFromInteger(this);
if (result != null) return result;
return other._toBigint()._subFromInteger(this);
final _IntegerImplementation otherAsIntImpl = other;
return otherAsIntImpl._toBigint()._subFromInteger(this);
}
num operator *(num other) {
var result = other._mulFromInteger(this);
if (result != null) return result;
return other._toBigint()._mulFromInteger(this);
final _IntegerImplementation otherAsIntImpl = other;
return otherAsIntImpl._toBigint()._mulFromInteger(this);
}
num operator ~/(num other) {
int operator ~/(num other) {
if ((other is int) && (other == 0)) {
throw const IntegerDivisionByZeroException();
}
var result = other._truncDivFromInteger(this);
if (result != null) return result;
return other._toBigint()._truncDivFromInteger(this);
final _IntegerImplementation otherAsIntImpl = other;
return otherAsIntImpl._toBigint()._truncDivFromInteger(this);
}
num operator /(num other) {
double operator /(num other) {
return this.toDouble() / other.toDouble();
}
@ -49,7 +50,8 @@ abstract class _IntegerImplementation {
}
var result = other._moduloFromInteger(this);
if (result != null) return result;
return other._toBigint()._moduloFromInteger(this);
final _IntegerImplementation otherAsIntImpl = other;
return otherAsIntImpl._toBigint()._moduloFromInteger(this);
}
int operator -() {
@ -78,7 +80,7 @@ abstract class _IntegerImplementation {
return other._remainderFromInteger(this);
}
int _bitAndFromSmi(int other) native "Integer_bitAndFromInteger";
int _bitAndFromSmi(_Smi other) native "Integer_bitAndFromInteger";
int _bitAndFromInteger(int other) native "Integer_bitAndFromInteger";
int _bitOrFromInteger(int other) native "Integer_bitOrFromInteger";
int _bitXorFromInteger(int other) native "Integer_bitXorFromInteger";
@ -121,6 +123,7 @@ abstract class _IntegerImplementation {
bool _greaterThanFromInteger(int other)
native "Integer_greaterThanFromInteger";
bool operator ==(other) {
if (other is num) {
return other._equalToInteger(this);
@ -460,7 +463,7 @@ abstract class _IntegerImplementation {
}
}
class _Smi extends _IntegerImplementation implements int, _int64 {
class _Smi extends _IntegerImplementation implements _int64 {
factory _Smi._uninstantiable() {
throw new UnsupportedError("_Smi can only be allocated by the VM");
}
@ -471,7 +474,7 @@ class _Smi extends _IntegerImplementation implements int, _int64 {
int operator &(int other) => other._bitAndFromSmi(this);
int _bitAndFromSmi(int other) native "Smi_bitAndFromSmi";
int _bitAndFromSmi(_Smi other) native "Smi_bitAndFromSmi";
int _shrFromInt(int other) native "Smi_shrFromInt";
int _shlFromInt(int other) native "Smi_shlFromInt";
@ -660,7 +663,7 @@ class _Smi extends _IntegerImplementation implements int, _int64 {
}
// Represents integers that cannot be represented by Smi but fit into 64bits.
class _Mint extends _IntegerImplementation implements int, _int64 {
class _Mint extends _IntegerImplementation implements _int64 {
factory _Mint._uninstantiable() {
throw new UnsupportedError("_Mint can only be allocated by the VM");
}
@ -669,7 +672,7 @@ class _Mint extends _IntegerImplementation implements int, _int64 {
int operator ~() native "Mint_bitNegate";
int get bitLength native "Mint_bitLength";
int _bitAndFromSmi(int other) => _bitAndFromInteger(other);
int _bitAndFromSmi(_Smi other) => _bitAndFromInteger(other);
// Shift by mint exceeds range that can be handled by the VM.
int _shrFromInt(int other) {

View file

@ -11,6 +11,14 @@ class int {
const factory int.fromEnvironment(String name, {int defaultValue})
native "Integer_fromEnvironment";
_Bigint _toBigint();
int _shrFromInt(int other);
int _shlFromInt(int other);
int _bitAndFromSmi(_Smi other);
int _bitAndFromInteger(int other);
int _bitOrFromInteger(int other);
int _bitXorFromInteger(int other);
static int _tryParseSmi(String str, int first, int last) {
assert(first <= last);
var ix = first;
@ -54,7 +62,7 @@ class int {
return _parse(source, radix, onError);
}
static int _parse(String source, int radix, onError) {
static int _parse(_StringBase source, int radix, onError) {
int end = source._lastNonWhitespace() + 1;
if (end == 0) {
return _throwFormatException(onError, source, source.length, radix);

View file

@ -143,7 +143,7 @@ namespace dart {
#define CORE_LIB_INTRINSIC_LIST(V) \
V(_Smi, ~, Smi_bitNegate, Smi, 0x6574c6b0) \
V(_Smi, get:bitLength, Smi_bitLength, Smi, 0x25b356ab) \
V(_Smi, _bitAndFromSmi, Smi_bitAndFromSmi, Smi, 0x490a4da1) \
V(_Smi, _bitAndFromSmi, Smi_bitAndFromSmi, Smi, 0x562d5047) \
V(_Bigint, _lsh, Bigint_lsh, Dynamic, 0x40d9f1cc) \
V(_Bigint, _rsh, Bigint_rsh, Dynamic, 0x703f1a40) \
V(_Bigint, _absAdd, Bigint_absAdd, Dynamic, 0x50fb1e47) \
@ -197,16 +197,16 @@ namespace dart {
#define CORE_INTEGER_LIB_INTRINSIC_LIST(V) \
V(_IntegerImplementation, _addFromInteger, Integer_addFromInteger, \
Dynamic, 0x6a10c54a) \
V(_IntegerImplementation, +, Integer_add, Dynamic, 0x5125faaa) \
V(_IntegerImplementation, +, Integer_add, Dynamic, 0x1bb7f19d) \
V(_IntegerImplementation, _subFromInteger, Integer_subFromInteger, Dynamic, \
0x3fa4b1ed) \
V(_IntegerImplementation, -, Integer_sub, Dynamic, 0x0c94540b) \
V(_IntegerImplementation, -, Integer_sub, Dynamic, 0x649b007e) \
V(_IntegerImplementation, _mulFromInteger, Integer_mulFromInteger, \
Dynamic, 0x3216e299) \
V(_IntegerImplementation, *, Integer_mul, Dynamic, 0x4535624c) \
V(_IntegerImplementation, *, Integer_mul, Dynamic, 0x0c74b07f) \
V(_IntegerImplementation, _moduloFromInteger, Integer_moduloFromInteger, \
Dynamic, 0x6348b974) \
V(_IntegerImplementation, ~/, Integer_truncDivide, Dynamic, 0x1f48f4c9) \
V(_IntegerImplementation, ~/, Integer_truncDivide, Dynamic, 0x305174bc) \
V(_IntegerImplementation, unary-, Integer_negate, Dynamic, 0x4e346e3b) \
V(_IntegerImplementation, _bitAndFromInteger, Integer_bitAndFromInteger, \
Dynamic, 0x395b1678) \
@ -471,10 +471,10 @@ namespace dart {
V(_Double, -, Double_sub, 0x76768546) \
V(_Double, *, Double_mul, 0x66c66e3d) \
V(_Double, /, Double_div, 0x034b9f08) \
V(_IntegerImplementation, +, Integer_add, 0x5125faaa) \
V(_IntegerImplementation, -, Integer_sub, 0x0c94540b) \
V(_IntegerImplementation, *, Integer_mul, 0x4535624c) \
V(_IntegerImplementation, ~/, Integer_truncDivide, 0x1f48f4c9) \
V(_IntegerImplementation, +, Integer_add, 0x1bb7f19d) \
V(_IntegerImplementation, -, Integer_sub, 0x649b007e) \
V(_IntegerImplementation, *, Integer_mul, 0x0c74b07f) \
V(_IntegerImplementation, ~/, Integer_truncDivide, 0x305174bc) \
V(_IntegerImplementation, unary-, Integer_negate, 0x4e346e3b) \
V(_IntegerImplementation, &, Integer_bitAnd, 0x01b79186) \
V(_IntegerImplementation, |, Integer_bitOr, 0x71c6af64) \

View file

@ -27,6 +27,13 @@ checkImplements(object, String name) {
cls = cls.superclass;
}
// The VM implements int through an intermediate abstract
// class.
if (object is int &&
stringify(cls.superclass.simpleName) == 's(_IntegerImplementation)') {
cls = cls.superclass;
}
List<ClassMirror> superinterfaces = cls.superinterfaces;
String symName = 's($name)';
for (ClassMirror superinterface in superinterfaces) {

View file

@ -27,6 +27,13 @@ checkImplements(object, String name) {
cls = cls.superclass;
}
// The VM implements int through an intermediate abstract
// class.
if (object is int &&
stringify(cls.superclass.simpleName) == 's(_IntegerImplementation)') {
cls = cls.superclass;
}
List<ClassMirror> superinterfaces = cls.superinterfaces;
String symName = 's($name)';
for (ClassMirror superinterface in superinterfaces) {