Commit 0c370623 authored by Georg Neis's avatar Georg Neis Committed by Commit Bot

[bigint] Add NewBigIntFromInt factory function.

R=jkummerow@chromium.org

Bug: v8:6791
Change-Id: I9bbb4c6b9b387fa0cd29fa24058ae807157f40de
Reviewed-on: https://chromium-review.googlesource.com/707004
Commit-Queue: Georg Neis <neis@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48417}
parent 0c930218
......@@ -20,10 +20,7 @@ BUILTIN(BigIntConstructor) {
// Dummy implementation only takes Smi args.
if (!value->IsSmi()) return isolate->heap()->undefined_value();
int num = Smi::ToInt(*value);
if (num == 0) return *isolate->factory()->NewBigInt(0);
Handle<BigInt> result = isolate->factory()->NewBigIntRaw(1);
result->set_value(num);
return *result;
return *isolate->factory()->NewBigIntFromInt(num);
}
BUILTIN(BigIntConstructor_ConstructStub) {
......@@ -51,11 +48,8 @@ BUILTIN(BigIntParseInt) {
// Convert {string} to a String and flatten it.
// Fast path: avoid back-and-forth conversion for Smi inputs.
if (string->IsSmi() && radix->IsUndefined(isolate)) {
int number = Smi::ToInt(*string);
if (number == 0) return *isolate->factory()->NewBigInt(0);
Handle<BigInt> result = isolate->factory()->NewBigIntRaw(1);
result->set_value(number);
return *result;
int num = Smi::ToInt(*string);
return *isolate->factory()->NewBigIntFromInt(num);
}
Handle<String> subject;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, subject,
......
......@@ -813,7 +813,7 @@ class BigIntParseIntHelper : public StringToIntHelper {
NewSyntaxError(MessageTemplate::kBigIntInvalidString),
BigInt);
case kZero:
return isolate()->factory()->NewBigInt(0);
return isolate()->factory()->NewBigIntFromInt(0);
case kError:
return MaybeHandle<BigInt>();
case kDone:
......
......@@ -1423,6 +1423,22 @@ Handle<BigInt> Factory::NewBigIntRaw(int length, PretenureFlag pretenure) {
BigInt);
}
Handle<BigInt> Factory::NewBigIntFromInt(int value, PretenureFlag pretenure) {
if (value == 0) return NewBigInt(0);
Handle<BigInt> result = NewBigIntRaw(1);
if (value > 0) {
result->set_digit(0, value);
} else if (value == kMinInt) {
STATIC_ASSERT(kMinInt == -kMaxInt - 1);
result->set_digit(0, static_cast<BigInt::digit_t>(kMaxInt) + 1);
result->set_sign(true);
} else {
result->set_digit(0, -value);
result->set_sign(true);
}
return result;
}
Handle<Object> Factory::NewError(Handle<JSFunction> constructor,
MessageTemplate::Template template_index,
Handle<Object> arg0, Handle<Object> arg1,
......
......@@ -486,6 +486,8 @@ class V8_EXPORT_PRIVATE Factory final {
// Initializes length and sign fields, but leaves digits uninitialized.
Handle<BigInt> NewBigIntRaw(int length,
PretenureFlag pretenure = NOT_TENURED);
Handle<BigInt> NewBigIntFromInt(int value,
PretenureFlag pretenure = NOT_TENURED);
Handle<JSWeakMap> NewJSWeakMap();
......
......@@ -67,7 +67,7 @@ MaybeHandle<BigInt> BigInt::Divide(Handle<BigInt> x, Handle<BigInt> y) {
// integral value.
if (AbsoluteCompare(x, y) < 0) {
// TODO(jkummerow): Consider caching a canonical zero-BigInt.
return x->GetIsolate()->factory()->NewBigInt(0);
return x->GetIsolate()->factory()->NewBigIntFromInt(0);
}
Handle<BigInt> quotient;
if (y->length() == 1) {
......@@ -95,7 +95,7 @@ MaybeHandle<BigInt> BigInt::Remainder(Handle<BigInt> x, Handle<BigInt> y) {
digit_t remainder_digit;
AbsoluteDivSmall(x, y->digit(0), nullptr, &remainder_digit);
if (remainder_digit == 0) {
return x->GetIsolate()->factory()->NewBigInt(0);
return x->GetIsolate()->factory()->NewBigIntFromInt(0);
}
remainder = x->GetIsolate()->factory()->NewBigIntRaw(1);
remainder->set_digit(0, remainder_digit);
......@@ -897,15 +897,11 @@ Handle<BigInt> BigInt::RightShiftByAbsolute(Handle<BigInt> x,
Handle<BigInt> BigInt::RightShiftByMaximum(Isolate* isolate, bool sign) {
if (sign) {
// Return -1n.
// TODO(jkummerow): Consider caching a canonical -1n BigInt.
Handle<BigInt> result = isolate->factory()->NewBigInt(1);
result->set_digit(0, 1);
result->set_sign(true);
return result;
return isolate->factory()->NewBigIntFromInt(-1);
} else {
// TODO(jkummerow): Consider caching a canonical zero BigInt.
return isolate->factory()->NewBigInt(0);
return isolate->factory()->NewBigIntFromInt(0);
}
}
......
......@@ -64,17 +64,6 @@ class BigInt : public HeapObject {
static MaybeHandle<String> ToString(Handle<BigInt> bigint, int radix = 10);
// Temporarily exposed helper, pending proper initialization.
void set_value(int value) {
DCHECK(length() == 1);
if (value > 0) {
set_digit(0, value);
} else {
set_digit(0, -value); // This can overflow. We don't care.
set_sign(true);
}
}
// The maximum length that the current implementation supports would be
// kMaxInt / kDigitBits. However, we use a lower limit for now, because
// raising it later is easier than lowering it.
......@@ -84,6 +73,7 @@ class BigInt : public HeapObject {
class BodyDescriptor;
private:
friend class Factory;
friend class BigIntParseIntHelper;
typedef uintptr_t digit_t;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment