| 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) {
|
| // 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.
|
|
|