v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
bigint.h
Go to the documentation of this file.
1// Copyright 2017 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_OBJECTS_BIGINT_H_
6#define V8_OBJECTS_BIGINT_H_
7
8#include <atomic>
9
10#include "src/common/globals.h"
11#include "src/objects/objects.h"
13#include "src/utils/utils.h"
14
15// Has to be the last include (doesn't have include guards):
17
18namespace v8 {
19
20namespace bigint {
21class Digits;
22class FromStringAccumulator;
23} // namespace bigint
24
25namespace internal {
26
28 Address x_addr, Address y_addr);
31 Address x_addr, Address y_addr);
33 Address x_addr,
34 Address y_addr);
36 Address x_addr,
37 Address y_addr);
39 Address x_addr,
40 Address y_addr);
42 Address x_addr,
43 Address y_addr);
45 Address x_addr,
46 Address y_addr);
48 Address x_addr,
49 Address y_addr);
51 Address x_addr,
52 Address y_addr);
54 Address x_addr,
55 Address y_addr);
57 Address x_addr,
58 Address y_addr);
60 Address x_addr,
61 Address y_addr);
63 Address x_addr,
64 Address y_addr);
66 Address x_addr,
67 Address y_addr);
69 intptr_t shift);
70uint32_t RightShiftResultLength(Address x_addr, uint32_t x_sign,
71 intptr_t shift);
73 Address x_addr, intptr_t shift,
74 uint32_t must_round_down);
75
76class BigInt;
77class ValueDeserializer;
78class ValueSerializer;
79
80#if V8_HOST_ARCH_64_BIT && !V8_COMPRESS_POINTERS
81// On non-pointer-compressed 64-bit builts, we want the digits to be 8-byte
82// aligned, which requires padding.
83#define BIGINT_NEEDS_PADDING 1
84#endif
85
86// BigIntBase is just the raw data object underlying a BigInt. Use with care!
87// Most code should be using BigInts instead.
89 public:
90 inline uint32_t length() const {
91 return LengthBits::decode(bitfield_.load(std::memory_order_relaxed));
92 }
93
94 // For use by the GC.
95 inline uint32_t length(AcquireLoadTag) const {
96 return LengthBits::decode(bitfield_.load(std::memory_order_acquire));
97 }
98
99 bigint::Digits digits() const;
100
101 // The maximum kMaxLengthBits that the current implementation supports
102 // would be kMaxInt - kSystemPointerSize * kBitsPerByte - 1.
103 // Since we want a platform independent limit, choose a nice round number
104 // somewhere below that maximum.
105 static const uint32_t kMaxLengthBits = 1 << 30; // ~1 billion.
106 static const uint32_t kMaxLength =
108
109 // Sign and length are stored in the same bitfield. Since the GC needs to be
110 // able to read the length concurrently, the getters and setters are atomic.
111 static const uint32_t kLengthFieldBits = 30;
112 static_assert(kMaxLength <= ((1 << kLengthFieldBits) - 1));
115 static_assert(LengthBits::kLastUsedBit < 32);
116
119
120 private:
121 friend class ::v8::internal::BigInt; // MSVC wants full namespace.
122 friend class MutableBigInt;
124
125 friend struct OffsetsForDebug;
126 friend class CodeStubAssembler;
129
130 using digit_t = uintptr_t;
131
132 static const uint32_t kDigitSize = sizeof(digit_t);
133 // kMaxLength definition assumes this:
134 static_assert(kDigitSize == kSystemPointerSize);
135
136 static const uint32_t kDigitBits = kDigitSize * kBitsPerByte;
137 static const uint32_t kHalfDigitBits = kDigitBits / 2;
138 static const digit_t kHalfDigitMask = (1ull << kHalfDigitBits) - 1;
139
140 // sign() == true means negative.
141 inline bool sign() const {
142 return SignBits::decode(bitfield_.load(std::memory_order_relaxed));
143 }
144
145 inline digit_t digit(uint32_t n) const {
146 SLOW_DCHECK(n < length());
147 return raw_digits()[n].value();
148 }
149
150 bool is_zero() const { return length() == 0; }
151
152 std::atomic_uint32_t bitfield_;
153#ifdef BIGINT_NEEDS_PADDING
154 char padding_[4];
155#endif
158
160 // This class is essentially the publicly accessible abstract version of
161 // MutableBigInt (which is a hidden implementation detail). It serves as
162 // the return type of Factory::NewBigInt, and makes it possible to enforce
163 // casting restrictions:
164 // - FreshlyAllocatedBigInt can be cast explicitly to MutableBigInt
165 // (with MutableBigInt::Cast) for initialization.
166 // - MutableBigInt can be cast/converted explicitly to BigInt
167 // (with MutableBigInt::MakeImmutable); is afterwards treated as readonly.
168 // - No accidental implicit casting is possible from BigInt to MutableBigInt
169 // (and no explicit operator is provided either).
170
171 public:
172 // Clear uninitialized padding space.
173 inline void clear_padding() {
174#ifdef BIGINT_NEEDS_PADDING
175 memset(padding_, 0, arraysize(padding_));
176#endif
177 }
179
180// Arbitrary precision integers in JavaScript.
182 public:
183 // Implementation of the Spec methods, see:
184 // https://tc39.github.io/proposal-bigint/#sec-numeric-types
185 // Sections 1.1.1 through 1.1.19.
191 DirectHandle<BigInt> exponent);
202 // More convenient version of "bool LessThan(x, y)".
206
207 // Other parts of the public interface.
208 static MaybeHandle<BigInt> Increment(Isolate* isolate,
210 static MaybeHandle<BigInt> Decrement(Isolate* isolate,
212
213 bool ToBoolean() { return !is_zero(); }
214 uint32_t Hash() {
215 return ComputeUnseededHash(length() | (sign() ? (1 << 30) : 0)) ^
216 ComputeLongHash(static_cast<uint64_t>(is_zero() ? 0 : digit(0)));
217 }
218
219 bool IsNegative() const { return sign(); }
220
229 // Exposed for tests, do not call directly. Use CompareToNumber() instead.
231 DirectHandle<BigInt> x, double y);
232
233 static DirectHandle<BigInt> AsIntN(Isolate* isolate, uint64_t n,
235 static MaybeDirectHandle<BigInt> AsUintN(Isolate* isolate, uint64_t n,
237
239 int64_t n);
241 uint64_t n);
242 static MaybeDirectHandle<BigInt> FromWords64(Isolate* isolate, int sign_bit,
243 uint32_t words64_count,
244 const uint64_t* words);
245 V8_EXPORT_PRIVATE int64_t AsInt64(bool* lossless = nullptr);
246 uint64_t AsUint64(bool* lossless = nullptr);
247 uint32_t Words64Count();
248 void ToWordsArray64(int* sign_bit, uint32_t* words64_count, uint64_t* words);
249
250 void BigIntShortPrint(std::ostream& os);
251
252 inline static uint32_t SizeFor(uint32_t length) {
253 return sizeof(BigInt) + length * kDigitSize;
254 }
255
256 static MaybeHandle<String> ToString(Isolate* isolate,
258 int radix = 10,
259 ShouldThrow should_throw = kThrowOnError);
260 // Like the above, but adapted for the needs of producing error messages:
261 // doesn't care about termination requests, and returns a default string
262 // for inputs beyond a relatively low upper bound.
264 Isolate* isolate, DirectHandle<BigInt> bigint);
265
266 // "The Number value for x", see:
267 // https://tc39.github.io/ecma262/#sec-ecmascript-language-types-number-type
268 // Returns a Smi or HeapNumber.
269 static DirectHandle<Number> ToNumber(Isolate* isolate,
271
272 // ECMAScript's NumberToBigInt
274 Isolate* isolate, DirectHandle<Object> number);
275
276 // ECMAScript's ToBigInt (throws for Number input)
277 template <template <typename> typename HandleType>
278 requires(std::is_convertible_v<HandleType<Object>, DirectHandle<Object>>)
280 typename HandleType<BigInt>::MaybeType
281 FromObject(Isolate* isolate, HandleType<Object> obj);
282
283 class BodyDescriptor;
284
285 private:
286 template <typename IsolateT>
288 friend class ValueDeserializer;
289 friend class ValueSerializer;
290
291 // Special functions for StringToBigIntHelper:
292 template <typename IsolateT>
293 static Handle<BigInt> Zero(
294 IsolateT* isolate, AllocationType allocation = AllocationType::kYoung);
295 template <typename IsolateT>
297 IsolateT* isolate, bigint::FromStringAccumulator* accumulator,
298 bool negative, AllocationType allocation);
299
300 // Special functions for ValueSerializer/ValueDeserializer:
301 uint32_t GetBitfieldForSerialization() const;
302 static size_t DigitsByteLengthForBitfield(uint32_t bitfield);
303 // Serialize the raw digits. {storage_length} is expected to be
304 // {DigitsByteLengthForBitfield(GetBitfieldForSerialization())}.
305 void SerializeDigits(uint8_t* storage, size_t storage_length);
307 Isolate* isolate, uint32_t bitfield,
308 base::Vector<const uint8_t> digits_storage);
310
311} // namespace internal
312} // namespace v8
313
315
316#endif // V8_OBJECTS_BIGINT_H_
#define SLOW_DCHECK(condition)
Definition checks.h:21
static constexpr int kLastUsedBit
Definition bit-field.h:42
static constexpr T decode(U value)
Definition bit-field.h:66
bigint::Digits digits() const
Definition bigint.cc:146
friend struct OffsetsForDebug
Definition bigint.h:125
static const uint32_t kDigitBits
Definition bigint.h:136
static const uint32_t kHalfDigitBits
Definition bigint.h:137
bool is_zero() const
Definition bigint.h:150
bool sign() const
Definition bigint.h:141
static const uint32_t kDigitSize
Definition bigint.h:132
static const uint32_t kLengthFieldBits
Definition bigint.h:111
uint32_t length(AcquireLoadTag) const
Definition bigint.h:95
digit_t digit(uint32_t n) const
Definition bigint.h:145
std::atomic_uint32_t bitfield_
Definition bigint.h:152
uint32_t length() const
Definition bigint.h:90
static const uint32_t kMaxLength
Definition bigint.h:106
FLEXIBLE_ARRAY_MEMBER(UnalignedValueMember< digit_t >, raw_digits)
static const uint32_t kMaxLengthBits
Definition bigint.h:105
static const digit_t kHalfDigitMask
Definition bigint.h:138
friend class ::v8::internal::BigInt
Definition bigint.h:121
V8_EXPORT_PRIVATE int64_t AsInt64(bool *lossless=nullptr)
Definition bigint.cc:1442
uint32_t GetBitfieldForSerialization() const
Definition bigint.cc:1217
static Maybe< ComparisonResult > CompareToString(Isolate *isolate, DirectHandle< BigInt > x, DirectHandle< String > y)
Definition bigint.cc:625
static MaybeHandle< BigInt > Remainder(Isolate *isolate, DirectHandle< BigInt > x, DirectHandle< BigInt > y)
Definition bigint.cc:488
static Maybe< bool > EqualToString(Isolate *isolate, DirectHandle< BigInt > x, DirectHandle< String > y)
Definition bigint.cc:643
static ComparisonResult CompareToBigInt(DirectHandle< BigInt > x, DirectHandle< BigInt > y)
Definition bigint.cc:579
static MaybeHandle< BigInt > Multiply(Isolate *isolate, DirectHandle< BigInt > x, DirectHandle< BigInt > y)
Definition bigint.cc:432
static uint32_t SizeFor(uint32_t length)
Definition bigint.h:252
uint32_t Words64Count()
Definition bigint.cc:1398
static DirectHandle< Number > ToNumber(Isolate *isolate, DirectHandle< BigInt > x)
Definition bigint.cc:1023
void ToWordsArray64(int *sign_bit, uint32_t *words64_count, uint64_t *words)
Definition bigint.cc:1404
static MaybeDirectHandle< BigInt > Exponentiate(Isolate *isolate, DirectHandle< BigInt > base, DirectHandle< BigInt > exponent)
Definition bigint.cc:362
uint32_t Hash()
Definition bigint.h:214
void SerializeDigits(uint8_t *storage, size_t storage_length)
Definition bigint.cc:1232
static MaybeDirectHandle< BigInt > AsUintN(Isolate *isolate, uint64_t n, DirectHandle< BigInt > x)
Definition bigint.cc:1309
static MaybeHandle< BigInt > Divide(Isolate *isolate, DirectHandle< BigInt > x, DirectHandle< BigInt > y)
Definition bigint.cc:454
static MaybeHandle< String > ToString(Isolate *isolate, DirectHandle< BigInt > bigint, int radix=10, ShouldThrow should_throw=kThrowOnError)
Definition bigint.cc:835
static MaybeHandle< BigInt > Increment(Isolate *isolate, DirectHandle< BigInt > x)
Definition bigint.cc:599
static bool EqualToBigInt(Tagged< BigInt > x, Tagged< BigInt > y)
Definition bigint.cc:590
static Handle< BigInt > Zero(IsolateT *isolate, AllocationType allocation=AllocationType::kYoung)
Definition bigint.cc:333
static bool EqualToNumber(DirectHandle< BigInt > x, DirectHandle< Object > y)
Definition bigint.cc:660
static V8_EXPORT_PRIVATE Handle< BigInt > FromUint64(Isolate *isolate, uint64_t n)
Definition bigint.cc:1355
static MaybeDirectHandle< BigInt > FromWords64(Isolate *isolate, int sign_bit, uint32_t words64_count, const uint64_t *words)
Definition bigint.cc:1366
static MaybeHandle< BigInt > Decrement(Isolate *isolate, DirectHandle< BigInt > x)
Definition bigint.cc:611
static MaybeHandle< BigInt > Allocate(IsolateT *isolate, bigint::FromStringAccumulator *accumulator, bool negative, AllocationType allocation)
Definition bigint.cc:1192
static Handle< BigInt > UnaryMinus(Isolate *isolate, DirectHandle< BigInt > x)
Definition bigint.cc:341
static DirectHandle< String > NoSideEffectsToString(Isolate *isolate, DirectHandle< BigInt > bigint)
Definition bigint.cc:922
static V8_EXPORT_PRIVATE ComparisonResult CompareToDouble(DirectHandle< BigInt > x, double y)
Definition bigint.cc:708
static V8_EXPORT_PRIVATE Handle< BigInt > FromInt64(Isolate *isolate, int64_t n)
Definition bigint.cc:1333
void BigIntShortPrint(std::ostream &os)
Definition bigint.cc:1124
static MaybeDirectHandle< BigInt > BitwiseNot(Isolate *isolate, DirectHandle< BigInt > x)
Definition bigint.cc:349
static MaybeHandle< BigInt > Add(Isolate *isolate, DirectHandle< BigInt > x, DirectHandle< BigInt > y)
Definition bigint.cc:516
static ComparisonResult CompareToNumber(DirectHandle< BigInt > x, DirectHandle< Object > y)
Definition bigint.cc:679
bool IsNegative() const
Definition bigint.h:219
static DirectHandle< BigInt > AsIntN(Isolate *isolate, uint64_t n, DirectHandle< BigInt > x)
Definition bigint.cc:1294
static size_t DigitsByteLengthForBitfield(uint32_t bitfield)
Definition bigint.cc:1226
uint64_t AsUint64(bool *lossless=nullptr)
Definition bigint.cc:1449
static MaybeHandle< BigInt > Subtract(Isolate *isolate, DirectHandle< BigInt > x, DirectHandle< BigInt > y)
Definition bigint.cc:536
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< BigInt > FromSerializedDigits(Isolate *isolate, uint32_t bitfield, base::Vector< const uint8_t > digits_storage)
Definition bigint.cc:1251
static V8_EXPORT_PRIVATE MaybeHandle< BigInt > FromNumber(Isolate *isolate, DirectHandle< Object > number)
Definition bigint.cc:954
#define EXPORT_TEMPLATE_DECLARE(export)
int x
int n
Definition mul-fft.cc:296
int int32_t
Definition unicode.cc:40
uint32_t RightShiftResultLength(Address x_addr, uint32_t x_sign, intptr_t shift)
Definition bigint.cc:1705
void MutableBigInt_BitwiseAndNegNegAndCanonicalize(Address result_addr, Address x_addr, Address y_addr)
Definition bigint.cc:1599
constexpr int kBitsPerByte
Definition globals.h:682
uint32_t ComputeLongHash(uint64_t key)
Definition utils.h:282
void MutableBigInt_BitwiseXorNegNegAndCanonicalize(Address result_addr, Address x_addr, Address y_addr)
Definition bigint.cc:1671
void MutableBigInt_RightShiftAndCanonicalize(Address result_addr, Address x_addr, intptr_t shift, uint32_t must_round_down)
Definition bigint.cc:1718
uint32_t ComputeUnseededHash(uint32_t key)
Definition utils.h:271
void MutableBigInt_BitwiseOrNegNegAndCanonicalize(Address result_addr, Address x_addr, Address y_addr)
Definition bigint.cc:1635
int32_t MutableBigInt_AbsoluteMulAndCanonicalize(Address result_addr, Address x_addr, Address y_addr)
Definition bigint.cc:1513
void MutableBigInt_BitwiseOrPosPosAndCanonicalize(Address result_addr, Address x_addr, Address y_addr)
Definition bigint.cc:1623
v8::internal::LoadHandler V8_OBJECT_END
constexpr int kSystemPointerSize
Definition globals.h:410
int32_t MutableBigInt_AbsoluteCompare(Address x_addr, Address y_addr)
Definition bigint.cc:1493
void MutableBigInt_BitwiseXorPosNegAndCanonicalize(Address result_addr, Address x_addr, Address y_addr)
Definition bigint.cc:1683
void MutableBigInt_BitwiseAndPosNegAndCanonicalize(Address result_addr, Address x_addr, Address y_addr)
Definition bigint.cc:1611
void MutableBigInt_BitwiseOrPosNegAndCanonicalize(Address result_addr, Address x_addr, Address y_addr)
Definition bigint.cc:1647
void MutableBigInt_BitwiseAndPosPosAndCanonicalize(Address result_addr, Address x_addr, Address y_addr)
Definition bigint.cc:1587
void MutableBigInt_AbsoluteSubAndCanonicalize(Address result_addr, Address x_addr, Address y_addr)
Definition bigint.cc:1500
void MutableBigInt_AbsoluteAddAndCanonicalize(Address result_addr, Address x_addr, Address y_addr)
Definition bigint.cc:1482
void MutableBigInt_LeftShiftAndCanonicalize(Address result_addr, Address x_addr, intptr_t shift)
Definition bigint.cc:1695
int32_t MutableBigInt_AbsoluteModAndCanonicalize(Address result_addr, Address x_addr, Address y_addr)
Definition bigint.cc:1563
int32_t MutableBigInt_AbsoluteDivAndCanonicalize(Address result_addr, Address x_addr, Address y_addr)
Definition bigint.cc:1537
void MutableBigInt_BitwiseXorPosPosAndCanonicalize(Address result_addr, Address x_addr, Address y_addr)
Definition bigint.cc:1659
#define DECL_VERIFIER(Name)
#define V8_OBJECT
#define DECL_PRINTER(Name)
#define V8_EXPORT_PRIVATE
Definition macros.h:460
#define arraysize(array)
Definition macros.h:67
#define V8_WARN_UNUSED_RESULT
Definition v8config.h:671