Commit 98bb0673 authored by Jakob Kummerow's avatar Jakob Kummerow Committed by Commit Bot

[bigint] Proper variable-length object layout

Bug: v8:6791
Change-Id: I2da258f7db6c74d764c674eb8d550418a566c5ea
Reviewed-on: https://chromium-review.googlesource.com/662138
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48002}
parent 7b5a4022
...@@ -1396,11 +1396,18 @@ Handle<HeapNumber> Factory::NewHeapNumber(MutableMode mode, ...@@ -1396,11 +1396,18 @@ Handle<HeapNumber> Factory::NewHeapNumber(MutableMode mode,
HeapNumber); HeapNumber);
} }
Handle<BigInt> Factory::NewBigInt(PretenureFlag pretenure) { Handle<BigInt> Factory::NewBigInt(int length, PretenureFlag pretenure) {
CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->AllocateBigInt(pretenure), CALL_HEAP_FUNCTION(isolate(),
isolate()->heap()->AllocateBigInt(length, true, pretenure),
BigInt); BigInt);
} }
Handle<BigInt> Factory::NewBigIntRaw(int length, PretenureFlag pretenure) {
CALL_HEAP_FUNCTION(
isolate(), isolate()->heap()->AllocateBigInt(length, false, pretenure),
BigInt);
}
Handle<Object> Factory::NewError(Handle<JSFunction> constructor, Handle<Object> Factory::NewError(Handle<JSFunction> constructor,
MessageTemplate::Template template_index, MessageTemplate::Template template_index,
Handle<Object> arg0, Handle<Object> arg1, Handle<Object> arg0, Handle<Object> arg1,
......
...@@ -474,7 +474,11 @@ class V8_EXPORT_PRIVATE Factory final { ...@@ -474,7 +474,11 @@ class V8_EXPORT_PRIVATE Factory final {
Handle<HeapNumber> NewHeapNumber(MutableMode mode, Handle<HeapNumber> NewHeapNumber(MutableMode mode,
PretenureFlag pretenure = NOT_TENURED); PretenureFlag pretenure = NOT_TENURED);
Handle<BigInt> NewBigInt(PretenureFlag pretenure = NOT_TENURED); // Allocates a new BigInt with {length} digits and zero-initializes them.
Handle<BigInt> NewBigInt(int length, PretenureFlag pretenure = NOT_TENURED);
// Initializes length and sign fields, but leaves digits uninitialized.
Handle<BigInt> NewBigIntRaw(int length,
PretenureFlag pretenure = NOT_TENURED);
Handle<JSWeakMap> NewJSWeakMap(); Handle<JSWeakMap> NewJSWeakMap();
......
...@@ -2468,16 +2468,20 @@ AllocationResult Heap::AllocateHeapNumber(MutableMode mode, ...@@ -2468,16 +2468,20 @@ AllocationResult Heap::AllocateHeapNumber(MutableMode mode,
return result; return result;
} }
AllocationResult Heap::AllocateBigInt(PretenureFlag pretenure) { AllocationResult Heap::AllocateBigInt(int length, bool zero_initialize,
STATIC_ASSERT(BigInt::kSize <= kMaxRegularHeapObjectSize); PretenureFlag pretenure) {
if (length < 0 || length > BigInt::kMaxLength) {
v8::internal::Heap::FatalProcessOutOfMemory("invalid BigInt length", true);
}
int size = BigInt::SizeFor(length);
AllocationSpace space = SelectSpace(pretenure);
HeapObject* result = nullptr; HeapObject* result = nullptr;
{ {
AllocationSpace space = SelectSpace(pretenure); AllocationResult allocation = AllocateRaw(size, space);
AllocationResult allocation = AllocateRaw(BigInt::kSize, space);
if (!allocation.To(&result)) return allocation; if (!allocation.To(&result)) return allocation;
} }
result->set_map_after_allocation(bigint_map(), SKIP_WRITE_BARRIER); result->set_map_after_allocation(bigint_map(), SKIP_WRITE_BARRIER);
BigInt::cast(result)->Initialize(length, zero_initialize);
return result; return result;
} }
......
...@@ -1982,7 +1982,9 @@ class Heap { ...@@ -1982,7 +1982,9 @@ class Heap {
MUST_USE_RESULT AllocationResult AllocateHeapNumber( MUST_USE_RESULT AllocationResult AllocateHeapNumber(
MutableMode mode = IMMUTABLE, PretenureFlag pretenure = NOT_TENURED); MutableMode mode = IMMUTABLE, PretenureFlag pretenure = NOT_TENURED);
MUST_USE_RESULT AllocationResult AllocateBigInt(PretenureFlag pretenure); MUST_USE_RESULT AllocationResult AllocateBigInt(int length,
bool zero_initialize,
PretenureFlag pretenure);
// Allocates a byte array of the specified length // Allocates a byte array of the specified length
MUST_USE_RESULT AllocationResult MUST_USE_RESULT AllocationResult
......
...@@ -15,8 +15,11 @@ ...@@ -15,8 +15,11 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
class BigInt;
#define TYPED_VISITOR_ID_LIST(V) \ #define TYPED_VISITOR_ID_LIST(V) \
V(AllocationSite) \ V(AllocationSite) \
V(BigInt) \
V(ByteArray) \ V(ByteArray) \
V(BytecodeArray) \ V(BytecodeArray) \
V(Cell) \ V(Cell) \
......
...@@ -229,7 +229,7 @@ bool Heap::CreateInitialMaps() { ...@@ -229,7 +229,7 @@ bool Heap::CreateInitialMaps() {
ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, termination_exception); ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, termination_exception);
ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, optimized_out); ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, optimized_out);
ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, stale_register); ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, stale_register);
ALLOCATE_MAP(BIGINT_TYPE, BigInt::kSize, bigint); ALLOCATE_VARSIZE_MAP(BIGINT_TYPE, bigint);
for (unsigned i = 0; i < arraysize(string_type_table); i++) { for (unsigned i = 0; i < arraysize(string_type_table); i++) {
const StringTypeTable& entry = string_type_table[i]; const StringTypeTable& entry = string_type_table[i];
......
...@@ -214,6 +214,19 @@ class BytecodeArray::BodyDescriptor final : public BodyDescriptorBase { ...@@ -214,6 +214,19 @@ class BytecodeArray::BodyDescriptor final : public BodyDescriptorBase {
} }
}; };
class BigInt::BodyDescriptor final : public BodyDescriptorBase {
public:
static bool IsValidSlot(HeapObject* obj, int offset) { return false; }
template <typename ObjectVisitor>
static inline void IterateBody(HeapObject* obj, int object_size,
ObjectVisitor* v) {}
static inline int SizeOf(Map* map, HeapObject* obj) {
return BigInt::SizeFor(BigInt::cast(obj)->length());
}
};
class FixedDoubleArray::BodyDescriptor final : public BodyDescriptorBase { class FixedDoubleArray::BodyDescriptor final : public BodyDescriptorBase {
public: public:
static bool IsValidSlot(HeapObject* obj, int offset) { return false; } static bool IsValidSlot(HeapObject* obj, int offset) { return false; }
......
...@@ -3264,6 +3264,9 @@ int HeapObject::SizeFromMap(Map* map) const { ...@@ -3264,6 +3264,9 @@ int HeapObject::SizeFromMap(Map* map) const {
return FeedbackVector::SizeFor( return FeedbackVector::SizeFor(
reinterpret_cast<const FeedbackVector*>(this)->length()); reinterpret_cast<const FeedbackVector*>(this)->length());
} }
if (instance_type == BIGINT_TYPE) {
return BigInt::SizeFor(reinterpret_cast<const BigInt*>(this)->length());
}
DCHECK(instance_type == CODE_TYPE); DCHECK(instance_type == CODE_TYPE);
return reinterpret_cast<const Code*>(this)->CodeSize(); return reinterpret_cast<const Code*>(this)->CodeSize();
} }
......
...@@ -256,7 +256,7 @@ MaybeHandle<String> Object::ConvertToString(Isolate* isolate, ...@@ -256,7 +256,7 @@ MaybeHandle<String> Object::ConvertToString(Isolate* isolate,
String); String);
} }
if (input->IsBigInt()) { if (input->IsBigInt()) {
return BigInt::ToString(Handle<BigInt>::cast(input)); return BigInt::ToString(Handle<BigInt>::cast(input), 10);
} }
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(
isolate, input, JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(input), isolate, input, JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(input),
...@@ -2358,7 +2358,7 @@ Object* GetSimpleHash(Object* object) { ...@@ -2358,7 +2358,7 @@ Object* GetSimpleHash(Object* object) {
return Smi::FromInt(hash); return Smi::FromInt(hash);
} }
if (object->IsBigInt()) { if (object->IsBigInt()) {
uint32_t hash = ComputeIntegerHash(BigInt::cast(object)->value()); uint32_t hash = BigInt::cast(object)->Hash();
return Smi::FromInt(hash & Smi::kMaxValue); return Smi::FromInt(hash & Smi::kMaxValue);
} }
DCHECK(object->IsJSReceiver()); DCHECK(object->IsJSReceiver());
...@@ -2413,7 +2413,7 @@ bool Object::SameValue(Object* other) { ...@@ -2413,7 +2413,7 @@ bool Object::SameValue(Object* other) {
return String::cast(this)->Equals(String::cast(other)); return String::cast(this)->Equals(String::cast(other));
} }
if (IsBigInt() && other->IsBigInt()) { if (IsBigInt() && other->IsBigInt()) {
return BigInt::cast(this)->Equals(BigInt::cast(other)); return BigInt::Equal(BigInt::cast(this), BigInt::cast(other));
} }
return false; return false;
} }
...@@ -3168,9 +3168,11 @@ VisitorId Map::GetVisitorId(Map* map) { ...@@ -3168,9 +3168,11 @@ VisitorId Map::GetVisitorId(Map* map) {
case FOREIGN_TYPE: case FOREIGN_TYPE:
case HEAP_NUMBER_TYPE: case HEAP_NUMBER_TYPE:
case MUTABLE_HEAP_NUMBER_TYPE: case MUTABLE_HEAP_NUMBER_TYPE:
case BIGINT_TYPE:
return kVisitDataObject; return kVisitDataObject;
case BIGINT_TYPE:
return kVisitBigInt;
case FIXED_UINT8_ARRAY_TYPE: case FIXED_UINT8_ARRAY_TYPE:
case FIXED_INT8_ARRAY_TYPE: case FIXED_INT8_ARRAY_TYPE:
case FIXED_UINT16_ARRAY_TYPE: case FIXED_UINT16_ARRAY_TYPE:
......
...@@ -15,7 +15,35 @@ ...@@ -15,7 +15,35 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
SMI_ACCESSORS(BigInt, value, kValueOffset) int BigInt::length() const {
intptr_t bitfield = READ_INTPTR_FIELD(this, kBitfieldOffset);
return LengthBits::decode(static_cast<uint32_t>(bitfield));
}
void BigInt::set_length(int new_length) {
intptr_t bitfield = READ_INTPTR_FIELD(this, kBitfieldOffset);
bitfield = LengthBits::update(static_cast<uint32_t>(bitfield), new_length);
WRITE_INTPTR_FIELD(this, kBitfieldOffset, bitfield);
}
bool BigInt::sign() const {
intptr_t bitfield = READ_INTPTR_FIELD(this, kBitfieldOffset);
return SignBits::decode(static_cast<uint32_t>(bitfield));
}
void BigInt::set_sign(bool new_sign) {
intptr_t bitfield = READ_INTPTR_FIELD(this, kBitfieldOffset);
bitfield = SignBits::update(static_cast<uint32_t>(bitfield), new_sign);
WRITE_INTPTR_FIELD(this, kBitfieldOffset, bitfield);
}
BigInt::digit_t BigInt::digit(int n) const {
const byte* address = FIELD_ADDR_CONST(this, kDigitsOffset + n * kDigitSize);
return *reinterpret_cast<digit_t*>(reinterpret_cast<intptr_t>(address));
}
void BigInt::set_digit(int n, digit_t value) {
byte* address = FIELD_ADDR(this, kDigitsOffset + n * kDigitSize);
(*reinterpret_cast<digit_t*>(reinterpret_cast<intptr_t>(address))) = value;
}
TYPE_CHECKER(BigInt, BIGINT_TYPE) TYPE_CHECKER(BigInt, BIGINT_TYPE)
} // namespace internal } // namespace internal
......
...@@ -9,25 +9,120 @@ ...@@ -9,25 +9,120 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
Handle<BigInt> BigInt::UnaryMinus(Handle<BigInt> x) {
UNIMPLEMENTED(); // TODO(jkummerow): Implement.
}
Handle<BigInt> BigInt::BitwiseNot(Handle<BigInt> x) {
UNIMPLEMENTED(); // TODO(jkummerow): Implement.
}
MaybeHandle<BigInt> BigInt::Exponentiate(Handle<BigInt> base,
Handle<BigInt> exponent) {
UNIMPLEMENTED(); // TODO(jkummerow): Implement.
}
Handle<BigInt> BigInt::Multiply(Handle<BigInt> x, Handle<BigInt> y) {
UNIMPLEMENTED(); // TODO(jkummerow): Implement.
}
MaybeHandle<BigInt> BigInt::Divide(Handle<BigInt> x, Handle<BigInt> y) {
UNIMPLEMENTED(); // TODO(jkummerow): Implement.
}
MaybeHandle<BigInt> BigInt::Remainder(Handle<BigInt> x, Handle<BigInt> y) {
UNIMPLEMENTED(); // TODO(jkummerow): Implement.
}
Handle<BigInt> BigInt::Add(Handle<BigInt> x, Handle<BigInt> y) {
UNIMPLEMENTED(); // TODO(jkummerow): Implement.
}
Handle<BigInt> BigInt::Subtract(Handle<BigInt> x, Handle<BigInt> y) {
UNIMPLEMENTED(); // TODO(jkummerow): Implement.
}
Handle<BigInt> BigInt::LeftShift(Handle<BigInt> x, Handle<BigInt> y) {
UNIMPLEMENTED(); // TODO(jkummerow): Implement.
}
Handle<BigInt> BigInt::SignedRightShift(Handle<BigInt> x, Handle<BigInt> y) {
UNIMPLEMENTED(); // TODO(jkummerow): Implement.
}
MaybeHandle<BigInt> BigInt::UnsignedRightShift(Handle<BigInt> x,
Handle<BigInt> y) {
UNIMPLEMENTED(); // TODO(jkummerow): Implement.
}
bool BigInt::LessThan(Handle<BigInt> x, Handle<BigInt> y) {
UNIMPLEMENTED(); // TODO(jkummerow): Implement.
}
bool BigInt::Equal(BigInt* x, BigInt* y) {
if (x->sign() != y->sign()) return false;
if (x->length() != y->length()) return false;
for (int i = 0; i < x->length(); i++) {
if (x->digit(i) != y->digit(i)) return false;
}
return true;
}
Handle<BigInt> BigInt::BitwiseAnd(Handle<BigInt> x, Handle<BigInt> y) {
UNIMPLEMENTED(); // TODO(jkummerow): Implement.
}
Handle<BigInt> BigInt::BitwiseXor(Handle<BigInt> x, Handle<BigInt> y) {
UNIMPLEMENTED(); // TODO(jkummerow): Implement.
}
Handle<BigInt> BigInt::BitwiseOr(Handle<BigInt> x, Handle<BigInt> y) {
UNIMPLEMENTED(); // TODO(jkummerow): Implement.
}
Handle<String> BigInt::ToString(Handle<BigInt> bigint, int radix) {
// TODO(jkummerow): Implement this properly.
Factory* factory = bigint->GetIsolate()->factory();
if (bigint->is_zero()) return factory->NewStringFromStaticChars("0");
DCHECK(bigint->length() == 1);
int value = static_cast<uint32_t>(bigint->digit(0));
if (bigint->sign()) value = -value; // This can overflow. We don't care.
Handle<Object> number = factory->NewNumberFromInt(value);
return factory->NumberToString(number);
}
void BigInt::Initialize(int length, bool zero_initialize) {
set_length(length);
set_sign(false);
if (zero_initialize) {
memset(reinterpret_cast<void*>(reinterpret_cast<Address>(this) +
kDigitsOffset - kHeapObjectTag),
0, length * kDigitSize);
#if DEBUG
} else {
memset(reinterpret_cast<void*>(reinterpret_cast<Address>(this) +
kDigitsOffset - kHeapObjectTag),
0xbf, length * kDigitSize);
#endif
}
}
#ifdef OBJECT_PRINT #ifdef OBJECT_PRINT
void BigInt::BigIntPrint(std::ostream& os) { void BigInt::BigIntPrint(std::ostream& os) {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
HeapObject::PrintHeader(os, "BigInt"); HeapObject::PrintHeader(os, "BigInt");
os << "- value: " << value(); int len = length();
os << "\n"; os << "- length: " << len << "\n";
os << "- sign: " << sign() << "\n";
if (len > 0) {
os << "- digits:";
for (int i = 0; i < len; i++) {
os << "\n 0x" << std::hex << digit(i);
}
os << std::dec << "\n";
}
} }
#endif // OBJECT_PRINT #endif // OBJECT_PRINT
bool BigInt::Equals(BigInt* other) const {
DisallowHeapAllocation no_gc;
return value() == other->value();
}
Handle<String> BigInt::ToString(Handle<BigInt> bigint) {
Isolate* isolate = bigint->GetIsolate();
Handle<Object> number = isolate->factory()->NewNumberFromInt(bigint->value());
return isolate->factory()->NumberToString(number);
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -19,19 +19,91 @@ namespace internal { ...@@ -19,19 +19,91 @@ namespace internal {
// Arbitrary precision integers in JavaScript. // Arbitrary precision integers in JavaScript.
class BigInt : public HeapObject { class BigInt : public HeapObject {
public: public:
// Implementation of the Spec methods, see:
// https://tc39.github.io/proposal-bigint/#sec-numeric-types
// Sections 1.1.1 through 1.1.19.
static Handle<BigInt> UnaryMinus(Handle<BigInt> x);
static Handle<BigInt> BitwiseNot(Handle<BigInt> x);
static MaybeHandle<BigInt> Exponentiate(Handle<BigInt> base,
Handle<BigInt> exponent);
static Handle<BigInt> Multiply(Handle<BigInt> x, Handle<BigInt> y);
static MaybeHandle<BigInt> Divide(Handle<BigInt> x, Handle<BigInt> y);
static MaybeHandle<BigInt> Remainder(Handle<BigInt> x, Handle<BigInt> y);
static Handle<BigInt> Add(Handle<BigInt> x, Handle<BigInt> y);
static Handle<BigInt> Subtract(Handle<BigInt> x, Handle<BigInt> y);
static Handle<BigInt> LeftShift(Handle<BigInt> x, Handle<BigInt> y);
static Handle<BigInt> SignedRightShift(Handle<BigInt> x, Handle<BigInt> y);
static MaybeHandle<BigInt> UnsignedRightShift(Handle<BigInt> x,
Handle<BigInt> y);
static bool LessThan(Handle<BigInt> x, Handle<BigInt> y);
static bool Equal(BigInt* x, BigInt* y);
static Handle<BigInt> BitwiseAnd(Handle<BigInt> x, Handle<BigInt> y);
static Handle<BigInt> BitwiseXor(Handle<BigInt> x, Handle<BigInt> y);
static Handle<BigInt> BitwiseOr(Handle<BigInt> x, Handle<BigInt> y);
// Other parts of the public interface.
bool ToBoolean() { return !is_zero(); }
uint32_t Hash() {
// TODO(jkummerow): Improve this. At least use length and sign.
return is_zero() ? 0 : ComputeIntegerHash(static_cast<uint32_t>(digit(0)));
}
DECL_CAST(BigInt) DECL_CAST(BigInt)
DECL_VERIFIER(BigInt) DECL_VERIFIER(BigInt)
DECL_PRINTER(BigInt) DECL_PRINTER(BigInt)
DECL_INT_ACCESSORS(value) // TODO(jkummerow): Do we need {synchronized_length} for GC purposes?
DECL_INT_ACCESSORS(length)
inline static int SizeFor(int length) {
return kHeaderSize + length * kDigitSize;
}
void Initialize(int length, bool zero_initialize);
static Handle<String> ToString(Handle<BigInt> bigint, int radix);
static const int kValueOffset = HeapObject::kHeaderSize; // Temporarily exposed helper, pending proper initialization.
static const int kSize = kValueOffset + kPointerSize; 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);
}
}
bool Equals(BigInt* other) const; // The maximum length that the current implementation supports would be
static Handle<String> ToString(Handle<BigInt> bigint); // kMaxInt / kDigitBits. However, we use a lower limit for now, because
// raising it later is easier than lowering it.
static const int kMaxLengthBits = 20;
static const int kMaxLength = (1 << kMaxLengthBits) - 1;
class BodyDescriptor;
private: private:
typedef uintptr_t digit_t;
static const int kDigitSize = sizeof(digit_t);
static const int kDigitBits = kDigitSize * kBitsPerByte;
static const int kHalfDigitBits = kDigitBits / 2;
static const digit_t kHalfDigitMask = (1ull << kHalfDigitBits) - 1;
class LengthBits : public BitField<int, 0, kMaxLengthBits> {};
class SignBits : public BitField<bool, LengthBits::kNext, 1> {};
// Low-level accessors.
// sign() == true means negative.
DECL_BOOLEAN_ACCESSORS(sign)
inline digit_t digit(int n) const;
inline void set_digit(int n, digit_t value);
bool is_zero() {
DCHECK(length() > 0 || !sign()); // There is no -0n.
return length() == 0;
}
static const int kBitfieldOffset = HeapObject::kHeaderSize;
static const int kDigitsOffset = kBitfieldOffset + kPointerSize;
static const int kHeaderSize = kDigitsOffset;
DISALLOW_IMPLICIT_CONSTRUCTORS(BigInt); DISALLOW_IMPLICIT_CONSTRUCTORS(BigInt);
}; };
......
...@@ -17,6 +17,7 @@ namespace internal { ...@@ -17,6 +17,7 @@ namespace internal {
#define VISITOR_ID_LIST(V) \ #define VISITOR_ID_LIST(V) \
V(AllocationSite) \ V(AllocationSite) \
V(BigInt) \
V(ByteArray) \ V(ByteArray) \
V(BytecodeArray) \ V(BytecodeArray) \
V(Cell) \ V(Cell) \
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "src/arguments.h" #include "src/arguments.h"
#include "src/counters.h" #include "src/counters.h"
#include "src/objects-inl.h" #include "src/objects-inl.h"
#include "src/objects/bigint.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -26,7 +27,9 @@ RUNTIME_FUNCTION(Runtime_BigInt) { ...@@ -26,7 +27,9 @@ RUNTIME_FUNCTION(Runtime_BigInt) {
NewTypeError(MessageTemplate::kUnsupported)); NewTypeError(MessageTemplate::kUnsupported));
} }
Handle<BigInt> result = isolate->factory()->NewBigInt(); if (value == 0) return *isolate->factory()->NewBigInt(0);
Handle<BigInt> result = isolate->factory()->NewBigInt(1);
result->set_value(value); result->set_value(value);
return *result; return *result;
} }
...@@ -37,7 +40,7 @@ RUNTIME_FUNCTION(Runtime_BigIntEqual) { ...@@ -37,7 +40,7 @@ RUNTIME_FUNCTION(Runtime_BigIntEqual) {
CONVERT_ARG_HANDLE_CHECKED(Object, lhs, 0); CONVERT_ARG_HANDLE_CHECKED(Object, lhs, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1); CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1);
bool result = lhs->IsBigInt() && rhs->IsBigInt() && bool result = lhs->IsBigInt() && rhs->IsBigInt() &&
BigInt::cast(*lhs)->Equals(BigInt::cast(*rhs)); BigInt::Equal(BigInt::cast(*lhs), BigInt::cast(*rhs));
return *isolate->factory()->ToBoolean(result); return *isolate->factory()->ToBoolean(result);
} }
...@@ -45,7 +48,7 @@ RUNTIME_FUNCTION(Runtime_BigIntToBoolean) { ...@@ -45,7 +48,7 @@ RUNTIME_FUNCTION(Runtime_BigIntToBoolean) {
SealHandleScope shs(isolate); SealHandleScope shs(isolate);
DCHECK_EQ(1, args.length()); DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(BigInt, bigint, 0); CONVERT_ARG_HANDLE_CHECKED(BigInt, bigint, 0);
return *isolate->factory()->ToBoolean(bigint->value()); return *isolate->factory()->ToBoolean(bigint->ToBoolean());
} }
} // namespace internal } // namespace internal
......
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