Chromium Code Reviews| Index: runtime/lib/integers.cc |
| =================================================================== |
| --- runtime/lib/integers.cc (revision 39937) |
| +++ runtime/lib/integers.cc (working copy) |
| @@ -5,7 +5,6 @@ |
| #include "vm/bootstrap_natives.h" |
| #include "include/dart_api.h" |
| -#include "vm/bigint_operations.h" |
| #include "vm/dart_entry.h" |
| #include "vm/dart_api_impl.h" |
| #include "vm/exceptions.h" |
| @@ -27,8 +26,7 @@ |
| static bool CheckInteger(const Integer& i) { |
| if (i.IsBigint()) { |
| const Bigint& bigint = Bigint::Cast(i); |
| - return !BigintOperations::FitsIntoSmi(bigint) && |
| - !BigintOperations::FitsIntoInt64(bigint); |
| + return !bigint.FitsIntoSmi() && !bigint.FitsIntoInt64(); |
| } |
| if (i.IsMint()) { |
| const Mint& mint = Mint::Cast(i); |
| @@ -40,6 +38,7 @@ |
| static int BitLengthInt64(int64_t value) { |
| value ^= value >> (8 * sizeof(value) - 1); // flip bits if negative. |
| + // TODO(regis): Utils::HighestBit handles negative values. Why the above? |
| return value == 0 ? 0 : Utils::HighestBit(value) + 1; |
| } |
| @@ -55,6 +54,9 @@ |
| } |
| const Integer& result = |
| Integer::Handle(left.BitOp(Token::kBIT_AND, right)); |
| + if (result.IsNull()) { |
| + return result.raw(); // A bigint operation is required. |
| + } |
| return result.AsValidInteger(); |
|
srdjan
2014/09/08 19:19:49
maybe: result.IsNull() ? result.raw() : result.AsV
regis
2014/09/09 19:18:14
Done.
|
| } |
| @@ -70,6 +72,9 @@ |
| } |
| const Integer& result = |
| Integer::Handle(left.BitOp(Token::kBIT_OR, right)); |
| + if (result.IsNull()) { |
| + return result.raw(); // A bigint operation is required. |
| + } |
| return result.AsValidInteger(); |
| } |
| @@ -85,6 +90,9 @@ |
| } |
| const Integer& result = |
| Integer::Handle(left.BitOp(Token::kBIT_XOR, right)); |
| + if (result.IsNull()) { |
| + return result.raw(); // A bigint operation is required. |
| + } |
| return result.AsValidInteger(); |
| } |
| @@ -100,6 +108,9 @@ |
| } |
| const Integer& result = |
| Integer::Handle(left_int.ArithmeticOp(Token::kADD, right_int)); |
| + if (result.IsNull()) { |
| + return result.raw(); // A bigint operation is required. |
| + } |
| return result.AsValidInteger(); |
| } |
| @@ -115,6 +126,9 @@ |
| } |
| const Integer& result = |
| Integer::Handle(left_int.ArithmeticOp(Token::kSUB, right_int)); |
| + if (result.IsNull()) { |
| + return result.raw(); // A bigint operation is required. |
| + } |
| return result.AsValidInteger(); |
| } |
| @@ -130,6 +144,9 @@ |
| } |
| const Integer& result = |
| Integer::Handle(left_int.ArithmeticOp(Token::kMUL, right_int)); |
| + if (result.IsNull()) { |
| + return result.raw(); // A bigint operation is required. |
| + } |
| return result.AsValidInteger(); |
| } |
| @@ -142,6 +159,9 @@ |
| ASSERT(!right_int.IsZero()); |
| const Integer& result = |
| Integer::Handle(left_int.ArithmeticOp(Token::kTRUNCDIV, right_int)); |
| + if (result.IsNull()) { |
| + return result.raw(); // A bigint operation is required. |
| + } |
| return result.AsValidInteger(); |
| } |
| @@ -161,6 +181,9 @@ |
| } |
| const Integer& result = |
| Integer::Handle(left_int.ArithmeticOp(Token::kMOD, right_int)); |
| + if (result.IsNull()) { |
| + return result.raw(); // A bigint operation is required. |
| + } |
| return result.AsValidInteger(); |
| } |
| @@ -278,7 +301,6 @@ |
| const Smi& smi_value = Smi::Cast(value); |
| return smi_value.ShiftOp(kind, amount, silent); |
| } |
| - Bigint& big_value = Bigint::Handle(); |
| if (value.IsMint()) { |
| const int64_t mint_value = value.AsInt64Value(); |
| const int count = Utils::HighestBit(mint_value); |
| @@ -297,20 +319,11 @@ |
| } |
| } else { |
| // Overflow in shift, use Bigints |
| - big_value = BigintOperations::NewFromInt64(mint_value); |
| + return Integer::null(); |
| } |
| } else { |
| ASSERT(value.IsBigint()); |
| - big_value = Bigint::Cast(value).raw(); |
| } |
| - switch (kind) { |
| - case Token::kSHL: |
| - return BigintOperations::ShiftLeft(big_value, amount.Value()); |
| - case Token::kSHR: |
| - return BigintOperations::ShiftRight(big_value, amount.Value()); |
| - default: |
| - UNIMPLEMENTED(); |
| - } |
| return Integer::null(); |
| } |
| @@ -344,6 +357,9 @@ |
| ASSERT(CheckInteger(value)); |
| const Integer& result = Integer::Handle( |
| ShiftOperationHelper(Token::kSHR, value, amount)); |
| + if (result.IsNull()) { |
| + return result.raw(); // A bigint operation is required. |
| + } |
| return result.AsValidInteger(); |
| } |
| @@ -360,6 +376,9 @@ |
| } |
| const Integer& result = Integer::Handle( |
| ShiftOperationHelper(Token::kSHL, value, amount)); |
| + if (result.IsNull()) { |
| + return result.raw(); // A bigint operation is required. |
| + } |
| return result.AsValidInteger(); |
| } |
| @@ -423,32 +442,52 @@ |
| return 0; |
| } |
| - |
| // Bigint natives. |
| -DEFINE_NATIVE_ENTRY(Bigint_bitNegate, 1) { |
| - const Bigint& value = Bigint::CheckedHandle(arguments->NativeArgAt(0)); |
| - const Bigint& result = Bigint::Handle(BigintOperations::BitNot(value)); |
| - ASSERT(CheckInteger(value)); |
| - ASSERT(CheckInteger(result)); |
| - return result.AsValidInteger(); |
| +DEFINE_NATIVE_ENTRY(Bigint_getNeg, 1) { |
| + const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0)); |
| + return bigint.neg(); |
| } |
| -DEFINE_NATIVE_ENTRY(Bigint_bitLength, 1) { |
| - const Bigint& value = Bigint::CheckedHandle(arguments->NativeArgAt(0)); |
| - return Integer::New(BigintOperations::BitLength(value)); |
| +DEFINE_NATIVE_ENTRY(Bigint_setNeg, 2) { |
| + const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0)); |
| + const Bool& neg = Bool::CheckedHandle(arguments->NativeArgAt(1)); |
| + bigint.set_neg(neg); |
| + return Object::null(); |
| } |
| -DEFINE_NATIVE_ENTRY(Bigint_shlFromInt, 2) { |
| - // Use the preallocated out of memory exception to avoid calling |
| - // into dart code or allocating any code. |
| - const Instance& exception = |
| - Instance::Handle(isolate->object_store()->out_of_memory()); |
| - Exceptions::Throw(isolate, exception); |
| - UNREACHABLE(); |
| - return 0; |
| +DEFINE_NATIVE_ENTRY(Bigint_getUsed, 1) { |
| + const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0)); |
| + return bigint.used(); |
| } |
| + |
| +DEFINE_NATIVE_ENTRY(Bigint_setUsed, 2) { |
| + const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0)); |
| + const Smi& used = Smi::CheckedHandle(arguments->NativeArgAt(1)); |
| + bigint.set_used(used); |
| + return Object::null(); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(Bigint_getDigits, 1) { |
| + const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0)); |
| + return bigint.digits(); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(Bigint_setDigits, 2) { |
| + const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0)); |
| + const TypedData& digits = TypedData::CheckedHandle(arguments->NativeArgAt(1)); |
| + bigint.set_digits(digits); |
| + return Object::null(); |
| +} |
| + |
| + |
| +DEFINE_NATIVE_ENTRY(Bigint_allocate, 1) { |
|
srdjan
2014/09/08 19:19:49
Why one argument? type?
regis
2014/09/09 19:18:14
This is the null type arguments, since class Bigin
|
| + return Bigint::New(); |
| +} |
| + |
| } // namespace dart |