| Index: runtime/lib/integers.cc
|
| ===================================================================
|
| --- runtime/lib/integers.cc (revision 40060)
|
| +++ 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;
|
| }
|
|
|
| @@ -53,9 +52,9 @@
|
| OS::Print("Integer_bitAndFromInteger %s & %s\n",
|
| right.ToCString(), left.ToCString());
|
| }
|
| - const Integer& result =
|
| - Integer::Handle(left.BitOp(Token::kBIT_AND, right));
|
| - return result.AsValidInteger();
|
| + const Integer& result = Integer::Handle(left.BitOp(Token::kBIT_AND, right));
|
| + // A null result indicates that a bigint operation is required.
|
| + return result.IsNull() ? result.raw() : result.AsValidInteger();
|
| }
|
|
|
|
|
| @@ -68,9 +67,9 @@
|
| OS::Print("Integer_bitOrFromInteger %s | %s\n",
|
| left.ToCString(), right.ToCString());
|
| }
|
| - const Integer& result =
|
| - Integer::Handle(left.BitOp(Token::kBIT_OR, right));
|
| - return result.AsValidInteger();
|
| + const Integer& result = Integer::Handle(left.BitOp(Token::kBIT_OR, right));
|
| + // A null result indicates that a bigint operation is required.
|
| + return result.IsNull() ? result.raw() : result.AsValidInteger();
|
| }
|
|
|
|
|
| @@ -83,9 +82,9 @@
|
| OS::Print("Integer_bitXorFromInteger %s ^ %s\n",
|
| left.ToCString(), right.ToCString());
|
| }
|
| - const Integer& result =
|
| - Integer::Handle(left.BitOp(Token::kBIT_XOR, right));
|
| - return result.AsValidInteger();
|
| + const Integer& result = Integer::Handle(left.BitOp(Token::kBIT_XOR, right));
|
| + // A null result indicates that a bigint operation is required.
|
| + return result.IsNull() ? result.raw() : result.AsValidInteger();
|
| }
|
|
|
|
|
| @@ -100,7 +99,8 @@
|
| }
|
| const Integer& result =
|
| Integer::Handle(left_int.ArithmeticOp(Token::kADD, right_int));
|
| - return result.AsValidInteger();
|
| + // A null result indicates that a bigint operation is required.
|
| + return result.IsNull() ? result.raw() : result.AsValidInteger();
|
| }
|
|
|
|
|
| @@ -115,7 +115,8 @@
|
| }
|
| const Integer& result =
|
| Integer::Handle(left_int.ArithmeticOp(Token::kSUB, right_int));
|
| - return result.AsValidInteger();
|
| + // A null result indicates that a bigint operation is required.
|
| + return result.IsNull() ? result.raw() : result.AsValidInteger();
|
| }
|
|
|
|
|
| @@ -130,7 +131,8 @@
|
| }
|
| const Integer& result =
|
| Integer::Handle(left_int.ArithmeticOp(Token::kMUL, right_int));
|
| - return result.AsValidInteger();
|
| + // A null result indicates that a bigint operation is required.
|
| + return result.IsNull() ? result.raw() : result.AsValidInteger();
|
| }
|
|
|
|
|
| @@ -142,7 +144,8 @@
|
| ASSERT(!right_int.IsZero());
|
| const Integer& result =
|
| Integer::Handle(left_int.ArithmeticOp(Token::kTRUNCDIV, right_int));
|
| - return result.AsValidInteger();
|
| + // A null result indicates that a bigint operation is required.
|
| + return result.IsNull() ? result.raw() : result.AsValidInteger();
|
| }
|
|
|
|
|
| @@ -161,7 +164,8 @@
|
| }
|
| const Integer& result =
|
| Integer::Handle(left_int.ArithmeticOp(Token::kMOD, right_int));
|
| - return result.AsValidInteger();
|
| + // A null result indicates that a bigint operation is required.
|
| + return result.IsNull() ? result.raw() : result.AsValidInteger();
|
| }
|
|
|
|
|
| @@ -266,7 +270,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);
|
| @@ -285,20 +288,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();
|
| }
|
|
|
| @@ -332,7 +326,8 @@
|
| ASSERT(CheckInteger(value));
|
| const Integer& result = Integer::Handle(
|
| ShiftOperationHelper(Token::kSHR, value, amount));
|
| - return result.AsValidInteger();
|
| + // A null result indicates that a bigint operation is required.
|
| + return result.IsNull() ? result.raw() : result.AsValidInteger();
|
| }
|
|
|
|
|
| @@ -348,7 +343,8 @@
|
| }
|
| const Integer& result = Integer::Handle(
|
| ShiftOperationHelper(Token::kSHL, value, amount));
|
| - return result.AsValidInteger();
|
| + // A null result indicates that a bigint operation is required.
|
| + return result.IsNull() ? result.raw() : result.AsValidInteger();
|
| }
|
|
|
|
|
| @@ -414,29 +410,51 @@
|
|
|
| // 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) {
|
| + // Argument is null type arguments, since class Bigint is not parameterized.
|
| + return Bigint::New();
|
| +}
|
| +
|
| } // namespace dart
|
|
|