Chromium Code Reviews| Index: runtime/lib/integers.cc |
| diff --git a/runtime/lib/integers.cc b/runtime/lib/integers.cc |
| index a3fdc274f2b0f6eeb6a88bd0f180dc3f90ac81ea..70707d389c5e1f9e3ed0611fe43e8830dcb9d060 100644 |
| --- a/runtime/lib/integers.cc |
| +++ b/runtime/lib/integers.cc |
| @@ -27,6 +27,7 @@ DEFINE_FLAG(bool, |
| // when it could have been a Smi. |
| static bool CheckInteger(const Integer& i) { |
| if (i.IsBigint()) { |
| + ASSERT(!FLAG_truncate_ints_to_64_bits); |
| const Bigint& bigint = Bigint::Cast(i); |
| return !bigint.FitsIntoSmi() && !bigint.FitsIntoInt64(); |
| } |
| @@ -260,29 +261,32 @@ static RawInteger* ShiftOperationHelper(Token::Kind kind, |
| } |
| if (value.IsMint()) { |
| const int64_t mint_value = value.AsInt64Value(); |
| - const int count = Utils::HighestBit(mint_value); |
| intptr_t shift_count = amount.Value(); |
| - if (kind == Token::kSHR) { |
| - shift_count = -shift_count; |
| - } |
| - if ((count + shift_count) < Mint::kBits) { |
| - switch (kind) { |
| - case Token::kSHL: |
| - return Integer::New(mint_value << shift_count, Heap::kNew); |
| - case Token::kSHR: |
| - shift_count = |
| - (-shift_count > Mint::kBits) ? Mint::kBits : -shift_count; |
| - return Integer::New(mint_value >> shift_count, Heap::kNew); |
| - default: |
| - UNIMPLEMENTED(); |
| - } |
| - } else { |
| - // Overflow in shift, use Bigints |
| - return Integer::null(); |
| + switch (kind) { |
| + case Token::kSHL: |
| + if (FLAG_truncate_ints_to_64_bits) { |
| + return Integer::New( |
| + Utils::ShiftLeftWithTruncation(mint_value, shift_count), |
| + Heap::kNew); |
| + } else { |
| + const int count = Utils::HighestBit(mint_value); |
| + if (shift_count < (Mint::kBits - count)) { |
| + return Integer::New(mint_value << shift_count, Heap::kNew); |
| + } else { |
| + // Overflow in shift, use Bigints |
| + return Integer::null(); |
| + } |
| + } |
| + case Token::kSHR: |
| + shift_count = Utils::Minimum(shift_count, Mint::kBits); |
| + return Integer::New(mint_value >> shift_count, Heap::kNew); |
| + default: |
| + UNIMPLEMENTED(); |
| } |
| } else { |
| ASSERT(value.IsBigint()); |
| } |
| + ASSERT(!FLAG_truncate_ints_to_64_bits); |
| return Integer::null(); |
| } |
| @@ -409,6 +413,7 @@ DEFINE_NATIVE_ENTRY(Bigint_getDigits, 1) { |
| DEFINE_NATIVE_ENTRY(Bigint_allocate, 4) { |
| + // TODO(alexmarkov): Consider throwing error if --truncate-ints-to-64-bits. |
| if (FLAG_limit_ints_to_64_bits) { |
|
siva
2017/07/07 23:11:20
Not sure I understand why we should have two flags
alexmarkov
2017/07/10 16:58:12
Done.
|
| // The allocated Bigint value is not necessarily out of range, but it may |
| // be used as an operand in an operation resulting in a Bigint. |