Update dart2js/ddc int.bitLength

1. Make bitLength work on very large values. This fixes problems with
BigInt.from on large values.

2. Restructure to allow Math.clz32 to be used once dart2js no longer
supporst IE11.

Change-Id: I255f030ff3b3630cdee63502d11a8b6630a4f008
Reviewed-on: https://dart-review.googlesource.com/41960
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Reviewed-by: Vijay Menon <vsm@google.com>
This commit is contained in:
Stephen Adams 2018-02-16 22:26:35 +00:00
parent 188697d6e1
commit e1cfc35572
2 changed files with 22 additions and 9 deletions

View file

@ -384,11 +384,18 @@ class JSNumber extends Interceptor implements int, double {
@notNull
int get bitLength {
int nonneg = this < 0 ? -this - 1 : this;
if (nonneg >= 0x100000000) {
int wordBits = 32;
while (nonneg >= 0x100000000) {
nonneg = nonneg ~/ 0x100000000;
return _bitCount(_spread(nonneg)) + 32;
wordBits += 32;
}
return _bitCount(_spread(nonneg));
return wordBits - _clz32(nonneg);
}
@notNull
static int _clz32(@notNull int uint32) {
// TODO(sra): Use `Math.clz32(uint32)` (not available on IE11).
return 32 - _bitCount(_spread(uint32));
}
// Returns pow(this, e) % m.

View file

@ -433,11 +433,17 @@ class JSInt extends JSNumber implements int, double {
int get bitLength {
int nonneg = this < 0 ? -this - 1 : this;
if (nonneg >= 0x100000000) {
int wordBits = 32;
while (nonneg >= 0x100000000) {
nonneg = nonneg ~/ 0x100000000;
return _bitCount(_spread(nonneg)) + 32;
wordBits += 32;
}
return _bitCount(_spread(nonneg));
return wordBits - _clz32(nonneg);
}
static int _clz32(int uint32) {
// TODO(sra): Use `Math.clz32(uint32)` (not available on IE11).
return 32 - _bitCount(_spread(uint32));
}
// Returns pow(this, e) % m.
@ -592,9 +598,9 @@ class JSInt extends JSNumber implements int, double {
return (i & 0x0000003F);
}
static _shru(int value, int shift) => JS('int', '# >>> #', value, shift);
static _shrs(int value, int shift) => JS('int', '# >> #', value, shift);
static _ors(int a, int b) => JS('int', '# | #', a, b);
static int _shru(int value, int shift) => JS('int', '# >>> #', value, shift);
static int _shrs(int value, int shift) => JS('int', '# >> #', value, shift);
static int _ors(int a, int b) => JS('int', '# | #', a, b);
// Assumes i is <= 32-bit
static int _spread(int i) {