| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 3afffeb commit a9ec888
8 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -29,7 +29,7 @@ | |||
| 29 | 29 | ||
| 30 | 30 | # Reset this number to 0 on major V8 upgrades. | |
| 31 | 31 | # Increment by one for each non-official patch applied to deps/v8. | |
| 32 | - 'v8_embedder_string': '-node.6', | ||
| 32 | + 'v8_embedder_string': '-node.7', | ||
| 33 | 33 | ||
| 34 | 34 | # Enable disassembler for `--print-code` v8 options | |
| 35 | 35 | 'v8_enable_disassembler': 1, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3165,6 +3165,48 @@ class V8_EXPORT Uint32 : public Integer { | |||
| 3165 | 3165 | class V8_EXPORT BigInt : public Primitive { | |
| 3166 | 3166 | public: | |
| 3167 | 3167 | static Local<BigInt> New(Isolate* isolate, int64_t value); | |
| 3168 | + static Local<BigInt> NewFromUnsigned(Isolate* isolate, uint64_t value); | ||
| 3169 | + /** | ||
| 3170 | + * Creates a new BigInt object using a specified sign bit and a | ||
| 3171 | + * specified list of digits/words. | ||
| 3172 | + * The resulting number is calculated as: | ||
| 3173 | + * | ||
| 3174 | + * (-1)^sign_bit * (words[0] * (2^64)^0 + words[1] * (2^64)^1 + ...) | ||
| 3175 | + */ | ||
| 3176 | + static MaybeLocal<BigInt> NewFromWords(Local<Context> context, int sign_bit, | ||
| 3177 | + int word_count, const uint64_t* words); | ||
| 3178 | + | ||
| 3179 | + /** | ||
| 3180 | + * Returns the value of this BigInt as an unsigned 64-bit integer. | ||
| 3181 | + * If `lossless` is provided, it will reflect whether the return value was | ||
| 3182 | + * truncated or wrapped around. In particular, it is set to `false` if this | ||
| 3183 | + * BigInt is negative. | ||
| 3184 | + */ | ||
| 3185 | + uint64_t Uint64Value(bool* lossless = nullptr) const; | ||
| 3186 | + | ||
| 3187 | + /** | ||
| 3188 | + * Returns the value of this BigInt as a signed 64-bit integer. | ||
| 3189 | + * If `lossless` is provided, it will reflect whether this BigInt was | ||
| 3190 | + * truncated or not. | ||
| 3191 | + */ | ||
| 3192 | + int64_t Int64Value(bool* lossless = nullptr) const; | ||
| 3193 | + | ||
| 3194 | + /** | ||
| 3195 | + * Returns the number of 64-bit words needed to store the result of | ||
| 3196 | + * ToWordsArray(). | ||
| 3197 | + */ | ||
| 3198 | + int WordCount() const; | ||
| 3199 | + | ||
| 3200 | + /** | ||
| 3201 | + * Writes the contents of this BigInt to a specified memory location. | ||
| 3202 | + * `sign_bit` must be provided and will be set to 1 if this BigInt is | ||
| 3203 | + * negative. | ||
| 3204 | + * `*word_count` has to be initialized to the length of the `words` array. | ||
| 3205 | + * Upon return, it will be set to the actual number of words that would | ||
| 3206 | + * be needed to store this BigInt (i.e. the return value of `WordCount()`). | ||
| 3207 | + */ | ||
| 3208 | + void ToWordsArray(int* sign_bit, int* word_count, uint64_t* words) const; | ||
| 3209 | + | ||
| 3168 | 3210 | V8_INLINE static BigInt* Cast(v8::Value* obj); | |
| 3169 | 3211 | ||
| 3170 | 3212 | private: | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -8000,6 +8000,49 @@ Local<BigInt> v8::BigInt::New(Isolate* isolate, int64_t value) { | |||
| 8000 | 8000 | return Utils::ToLocal(result); | |
| 8001 | 8001 | } | |
| 8002 | 8002 | ||
| 8003 | + Local<BigInt> v8::BigInt::NewFromUnsigned(Isolate* isolate, uint64_t value) { | ||
| 8004 | + CHECK(i::FLAG_harmony_bigint); | ||
| 8005 | + i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); | ||
| 8006 | + ENTER_V8_NO_SCRIPT_NO_EXCEPTION(internal_isolate); | ||
| 8007 | + i::Handle<i::BigInt> result = i::BigInt::FromUint64(internal_isolate, value); | ||
| 8008 | + return Utils::ToLocal(result); | ||
| 8009 | + } | ||
| 8010 | + | ||
| 8011 | + MaybeLocal<BigInt> v8::BigInt::NewFromWords(Local<Context> context, | ||
| 8012 | + int sign_bit, int word_count, | ||
| 8013 | + const uint64_t* words) { | ||
| 8014 | + CHECK(i::FLAG_harmony_bigint); | ||
| 8015 | + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate()); | ||
| 8016 | + ENTER_V8_NO_SCRIPT(isolate, context, BigInt, NewFromWords, | ||
| 8017 | + MaybeLocal<BigInt>(), InternalEscapableScope); | ||
| 8018 | + i::MaybeHandle<i::BigInt> result = | ||
| 8019 | + i::BigInt::FromWords64(isolate, sign_bit, word_count, words); | ||
| 8020 | + has_pending_exception = result.is_null(); | ||
| 8021 | + RETURN_ON_FAILED_EXECUTION(BigInt); | ||
| 8022 | + RETURN_ESCAPED(Utils::ToLocal(result.ToHandleChecked())); | ||
| 8023 | + } | ||
| 8024 | + | ||
| 8025 | + uint64_t v8::BigInt::Uint64Value(bool* lossless) const { | ||
| 8026 | + i::Handle<i::BigInt> handle = Utils::OpenHandle(this); | ||
| 8027 | + return handle->AsUint64(lossless); | ||
| 8028 | + } | ||
| 8029 | + | ||
| 8030 | + int64_t v8::BigInt::Int64Value(bool* lossless) const { | ||
| 8031 | + i::Handle<i::BigInt> handle = Utils::OpenHandle(this); | ||
| 8032 | + return handle->AsInt64(lossless); | ||
| 8033 | + } | ||
| 8034 | + | ||
| 8035 | + int BigInt::WordCount() const { | ||
| 8036 | + i::Handle<i::BigInt> handle = Utils::OpenHandle(this); | ||
| 8037 | + return handle->Words64Count(); | ||
| 8038 | + } | ||
| 8039 | + | ||
| 8040 | + void BigInt::ToWordsArray(int* sign_bit, int* word_count, | ||
| 8041 | + uint64_t* words) const { | ||
| 8042 | + i::Handle<i::BigInt> handle = Utils::OpenHandle(this); | ||
| 8043 | + return handle->ToWordsArray64(sign_bit, word_count, words); | ||
| 8044 | + } | ||
| 8045 | + | ||
| 8003 | 8046 | void Isolate::ReportExternalAllocationLimitReached() { | |
| 8004 | 8047 | i::Heap* heap = reinterpret_cast<i::Isolate*>(this)->heap(); | |
| 8005 | 8048 | if (heap->gc_state() != i::Heap::NOT_IN_GC) return; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -127,6 +127,7 @@ class RegisteredExtension { | |||
| 127 | 127 | V(Promise, JSPromise) \ | |
| 128 | 128 | V(Primitive, Object) \ | |
| 129 | 129 | V(PrimitiveArray, FixedArray) \ | |
| 130 | + V(BigInt, BigInt) \ | ||
| 130 | 131 | V(ScriptOrModule, Script) | |
| 131 | 132 | ||
| 132 | 133 | class Utils { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -692,6 +692,7 @@ class RuntimeCallTimer final { | |||
| 692 | 692 | V(ArrayBuffer_New) \ | |
| 693 | 693 | V(Array_CloneElementAt) \ | |
| 694 | 694 | V(Array_New) \ | |
| 695 | + V(BigInt_NewFromWords) \ | ||
| 695 | 696 | V(BigInt64Array_New) \ | |
| 696 | 697 | V(BigUint64Array_New) \ | |
| 697 | 698 | V(BigIntObject_New) \ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2259,6 +2259,70 @@ Handle<BigInt> BigInt::FromUint64(Isolate* isolate, uint64_t n) { | |||
| 2259 | 2259 | return MutableBigInt::MakeImmutable(result); | |
| 2260 | 2260 | } | |
| 2261 | 2261 | ||
| 2262 | + MaybeHandle<BigInt> BigInt::FromWords64(Isolate* isolate, int sign_bit, | ||
| 2263 | + int words64_count, | ||
| 2264 | + const uint64_t* words) { | ||
| 2265 | + if (words64_count < 0 || words64_count > kMaxLength / (64 / kDigitBits)) { | ||
| 2266 | + THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kBigIntTooBig), | ||
| 2267 | + BigInt); | ||
| 2268 | + } | ||
| 2269 | + if (words64_count == 0) return MutableBigInt::Zero(isolate); | ||
| 2270 | + STATIC_ASSERT(kDigitBits == 64 || kDigitBits == 32); | ||
| 2271 | + int length = (64 / kDigitBits) * words64_count; | ||
| 2272 | + DCHECK_GT(length, 0); | ||
| 2273 | + if (kDigitBits == 32 && words[words64_count - 1] <= (1ULL << 32)) length--; | ||
| 2274 | + | ||
| 2275 | + Handle<MutableBigInt> result; | ||
| 2276 | + if (!MutableBigInt::New(isolate, length).ToHandle(&result)) { | ||
| 2277 | + return MaybeHandle<BigInt>(); | ||
| 2278 | + } | ||
| 2279 | + | ||
| 2280 | + result->set_sign(sign_bit); | ||
| 2281 | + if (kDigitBits == 64) { | ||
| 2282 | + for (int i = 0; i < length; ++i) { | ||
| 2283 | + result->set_digit(i, static_cast<digit_t>(words[i])); | ||
| 2284 | + } | ||
| 2285 | + } else { | ||
| 2286 | + for (int i = 0; i < length; i += 2) { | ||
| 2287 | + digit_t lo = static_cast<digit_t>(words[i / 2]); | ||
| 2288 | + digit_t hi = static_cast<digit_t>(words[i / 2] >> 32); | ||
| 2289 | + result->set_digit(i, lo); | ||
| 2290 | + if (i + 1 < length) result->set_digit(i + 1, hi); | ||
| 2291 | + } | ||
| 2292 | + } | ||
| 2293 | + | ||
| 2294 | + return MutableBigInt::MakeImmutable(result); | ||
| 2295 | + } | ||
| 2296 | + | ||
| 2297 | + int BigInt::Words64Count() { | ||
| 2298 | + STATIC_ASSERT(kDigitBits == 64 || kDigitBits == 32); | ||
| 2299 | + return length() / (64 / kDigitBits) + | ||
| 2300 | + (kDigitBits == 32 && length() % 2 == 1 ? 1 : 0); | ||
| 2301 | + } | ||
| 2302 | + | ||
| 2303 | + void BigInt::ToWordsArray64(int* sign_bit, int* words64_count, | ||
| 2304 | + uint64_t* words) { | ||
| 2305 | + DCHECK_NE(sign_bit, nullptr); | ||
| 2306 | + DCHECK_NE(words64_count, nullptr); | ||
| 2307 | + *sign_bit = sign(); | ||
| 2308 | + int available_words = *words64_count; | ||
| 2309 | + *words64_count = Words64Count(); | ||
| 2310 | + if (available_words == 0) return; | ||
| 2311 | + DCHECK_NE(words, nullptr); | ||
| 2312 | + | ||
| 2313 | + int len = length(); | ||
| 2314 | + if (kDigitBits == 64) { | ||
| 2315 | + for (int i = 0; i < len && i < available_words; ++i) words[i] = digit(i); | ||
| 2316 | + } else { | ||
| 2317 | + for (int i = 0; i < len && available_words > 0; i += 2) { | ||
| 2318 | + uint64_t lo = digit(i); | ||
| 2319 | + uint64_t hi = (i + 1) < len ? digit(i + 1) : 0; | ||
| 2320 | + words[i / 2] = lo | (hi << 32); | ||
| 2321 | + available_words--; | ||
| 2322 | + } | ||
| 2323 | + } | ||
| 2324 | + } | ||
| 2325 | + | ||
| 2262 | 2326 | uint64_t MutableBigInt::GetRawBits(BigIntBase* x, bool* lossless) { | |
| 2263 | 2327 | if (lossless != nullptr) *lossless = true; | |
| 2264 | 2328 | if (x->is_zero()) return 0; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -144,8 +144,13 @@ class V8_EXPORT_PRIVATE BigInt : public BigIntBase { | |||
| 144 | 144 | ||
| 145 | 145 | static Handle<BigInt> FromInt64(Isolate* isolate, int64_t n); | |
| 146 | 146 | static Handle<BigInt> FromUint64(Isolate* isolate, uint64_t n); | |
| 147 | + static MaybeHandle<BigInt> FromWords64(Isolate* isolate, int sign_bit, | ||
| 148 | + int words64_count, | ||
| 149 | + const uint64_t* words); | ||
| 147 | 150 | int64_t AsInt64(bool* lossless = nullptr); | |
| 148 | 151 | uint64_t AsUint64(bool* lossless = nullptr); | |
| 152 | + int Words64Count(); | ||
| 153 | + void ToWordsArray64(int* sign_bit, int* words64_count, uint64_t* words); | ||
| 149 | 154 | ||
| 150 | 155 | DECL_CAST(BigInt) | |
| 151 | 156 | DECL_VERIFIER(BigInt) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -27805,3 +27805,117 @@ TEST(WasmStreamingAbortNoReject) { | |||
| 27805 | 27805 | streaming.Abort({}); | |
| 27806 | 27806 | CHECK_EQ(streaming.GetPromise()->State(), v8::Promise::kPending); | |
| 27807 | 27807 | } | |
| 27808 | + | ||
| 27809 | + TEST(BigIntAPI) { | ||
| 27810 | + LocalContext env; | ||
| 27811 | + v8::Isolate* isolate = env->GetIsolate(); | ||
| 27812 | + v8::HandleScope scope(isolate); | ||
| 27813 | + bool lossless; | ||
| 27814 | + uint64_t words1[10]; | ||
| 27815 | + uint64_t words2[10]; | ||
| 27816 | + | ||
| 27817 | + { | ||
| 27818 | + Local<Value> bi = CompileRun("12n"); | ||
| 27819 | + CHECK(bi->IsBigInt()); | ||
| 27820 | + | ||
| 27821 | + CHECK_EQ(bi.As<v8::BigInt>()->Uint64Value(), 12); | ||
| 27822 | + CHECK_EQ(bi.As<v8::BigInt>()->Uint64Value(&lossless), 12); | ||
| 27823 | + CHECK_EQ(lossless, true); | ||
| 27824 | + CHECK_EQ(bi.As<v8::BigInt>()->Int64Value(), 12); | ||
| 27825 | + CHECK_EQ(bi.As<v8::BigInt>()->Int64Value(&lossless), 12); | ||
| 27826 | + CHECK_EQ(lossless, true); | ||
| 27827 | + } | ||
| 27828 | + | ||
| 27829 | + { | ||
| 27830 | + Local<Value> bi = CompileRun("-12n"); | ||
| 27831 | + CHECK(bi->IsBigInt()); | ||
| 27832 | + | ||
| 27833 | + CHECK_EQ(bi.As<v8::BigInt>()->Uint64Value(), static_cast<uint64_t>(-12)); | ||
| 27834 | + CHECK_EQ(bi.As<v8::BigInt>()->Uint64Value(&lossless), | ||
| 27835 | + static_cast<uint64_t>(-12)); | ||
| 27836 | + CHECK_EQ(lossless, false); | ||
| 27837 | + CHECK_EQ(bi.As<v8::BigInt>()->Int64Value(), -12); | ||
| 27838 | + CHECK_EQ(bi.As<v8::BigInt>()->Int64Value(&lossless), -12); | ||
| 27839 | + CHECK_EQ(lossless, true); | ||
| 27840 | + } | ||
| 27841 | + | ||
| 27842 | + { | ||
| 27843 | + Local<Value> bi = CompileRun("123456789012345678901234567890n"); | ||
| 27844 | + CHECK(bi->IsBigInt()); | ||
| 27845 | + | ||
| 27846 | + CHECK_EQ(bi.As<v8::BigInt>()->Uint64Value(), 14083847773837265618ULL); | ||
| 27847 | + CHECK_EQ(bi.As<v8::BigInt>()->Uint64Value(&lossless), | ||
| 27848 | + 14083847773837265618ULL); | ||
| 27849 | + CHECK_EQ(lossless, false); | ||
| 27850 | + CHECK_EQ(bi.As<v8::BigInt>()->Int64Value(), -4362896299872285998LL); | ||
| 27851 | + CHECK_EQ(bi.As<v8::BigInt>()->Int64Value(&lossless), | ||
| 27852 | + -4362896299872285998LL); | ||
| 27853 | + CHECK_EQ(lossless, false); | ||
| 27854 | + } | ||
| 27855 | + | ||
| 27856 | + { | ||
| 27857 | + Local<Value> bi = CompileRun("-123456789012345678901234567890n"); | ||
| 27858 | + CHECK(bi->IsBigInt()); | ||
| 27859 | + | ||
| 27860 | + CHECK_EQ(bi.As<v8::BigInt>()->Uint64Value(), 4362896299872285998LL); | ||
| 27861 | + CHECK_EQ(bi.As<v8::BigInt>()->Uint64Value(&lossless), | ||
| 27862 | + 4362896299872285998LL); | ||
| 27863 | + CHECK_EQ(lossless, false); | ||
| 27864 | + CHECK_EQ(bi.As<v8::BigInt>()->Int64Value(), 4362896299872285998LL); | ||
| 27865 | + CHECK_EQ(bi.As<v8::BigInt>()->Int64Value(&lossless), 4362896299872285998LL); | ||
| 27866 | + CHECK_EQ(lossless, false); | ||
| 27867 | + } | ||
| 27868 | + | ||
| 27869 | + { | ||
| 27870 | + Local<v8::BigInt> bi = | ||
| 27871 | + v8::BigInt::NewFromWords(env.local(), 0, 0, words1).ToLocalChecked(); | ||
| 27872 | + CHECK_EQ(bi->Uint64Value(), 0); | ||
| 27873 | + CHECK_EQ(bi->WordCount(), 0); | ||
| 27874 | + } | ||
| 27875 | + | ||
| 27876 | + { | ||
| 27877 | + TryCatch try_catch(isolate); | ||
| 27878 | + v8::MaybeLocal<v8::BigInt> bi = v8::BigInt::NewFromWords( | ||
| 27879 | + env.local(), 0, std::numeric_limits<int>::max(), words1); | ||
| 27880 | + CHECK(bi.IsEmpty()); | ||
| 27881 | + CHECK(try_catch.HasCaught()); | ||
| 27882 | + } | ||
| 27883 | + | ||
| 27884 | + { | ||
| 27885 | + TryCatch try_catch(isolate); | ||
| 27886 | + v8::MaybeLocal<v8::BigInt> bi = | ||
| 27887 | + v8::BigInt::NewFromWords(env.local(), 0, -1, words1); | ||
| 27888 | + CHECK(bi.IsEmpty()); | ||
| 27889 | + CHECK(try_catch.HasCaught()); | ||
| 27890 | + } | ||
| 27891 | + | ||
| 27892 | + { | ||
| 27893 | + TryCatch try_catch(isolate); | ||
| 27894 | + v8::MaybeLocal<v8::BigInt> bi = | ||
| 27895 | + v8::BigInt::NewFromWords(env.local(), 0, 1 << 30, words1); | ||
| 27896 | + CHECK(bi.IsEmpty()); | ||
| 27897 | + CHECK(try_catch.HasCaught()); | ||
| 27898 | + } | ||
| 27899 | + | ||
| 27900 | + for (int sign_bit = 0; sign_bit <= 1; sign_bit++) { | ||
| 27901 | + words1[0] = 0xffffffff00000000ULL; | ||
| 27902 | + words1[1] = 0x00000000ffffffffULL; | ||
| 27903 | + v8::Local<v8::BigInt> bi = | ||
| 27904 | + v8::BigInt::NewFromWords(env.local(), sign_bit, 2, words1) | ||
| 27905 | + .ToLocalChecked(); | ||
| 27906 | + CHECK_EQ(bi->Uint64Value(&lossless), | ||
| 27907 | + sign_bit ? static_cast<uint64_t>(-static_cast<int64_t>(words1[0])) | ||
| 27908 | + : words1[0]); | ||
| 27909 | + CHECK_EQ(lossless, false); | ||
| 27910 | + CHECK_EQ(bi->Int64Value(&lossless), sign_bit | ||
| 27911 | + ? -static_cast<int64_t>(words1[0]) | ||
| 27912 | + : static_cast<int64_t>(words1[0])); | ||
| 27913 | + CHECK_EQ(lossless, false); | ||
| 27914 | + CHECK_EQ(bi->WordCount(), 2); | ||
| 27915 | + int real_sign_bit; | ||
| 27916 | + int word_count = arraysize(words2); | ||
| 27917 | + bi->ToWordsArray(&real_sign_bit, &word_count, words2); | ||
| 27918 | + CHECK_EQ(real_sign_bit, sign_bit); | ||
| 27919 | + CHECK_EQ(word_count, 2); | ||
| 27920 | + } | ||
| 27921 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments