File: bigint.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (80 lines) | stat: -rw-r--r-- 2,575 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_BIGINT_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_BIGINT_H_

#include <optional>

#include "base/compiler_specific.h"
#include "third_party/abseil-cpp/absl/numeric/int128.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "v8/include/v8-context.h"
#include "v8/include/v8-forward.h"
#include "v8/include/v8-local-handle.h"
#include "v8/include/v8-primitive.h"
#include "v8/include/v8-value.h"

namespace blink {

class ExceptionState;

class PLATFORM_EXPORT BigInt final {
 public:
  BigInt() = default;
  explicit BigInt(v8::Local<v8::BigInt> bigint) {
    int word_count = bigint->WordCount();
    words_.resize(word_count);
    bigint->ToWordsArray(&sign_bit_, &word_count, words_.data());
  }

  bool IsNegative() const { return sign_bit_ != 0; }
  bool FitsIn128Bits() const { return words_.size() <= 2; }

  v8::Local<v8::BigInt> ToV8(v8::Local<v8::Context> context) const {
    return v8::BigInt::NewFromWords(context, sign_bit_, words_.size(),
                                    words_.data())
        .ToLocalChecked();
  }

  // Will return nullopt if this is negative or will not fit in 128 bits.
  std::optional<absl::uint128> ToUInt128() const {
    if (IsNegative() || !FitsIn128Bits()) {
      return std::nullopt;
    }
    if (words_.size() == 0) {
      return 0;
    }
    if (words_.size() == 1) {
      return words_[0];
    }
    return absl::MakeUint128(words_[1], words_[0]);
  }

 private:
  Vector<uint64_t> words_;  // least significant at the front
  int sign_bit_ = 0;        // 0 for positive/zero, 1 for negative
};

// Convert a value to a BigInt. This can fail depending on the input type
// and value.
// https://webidl.spec.whatwg.org/#es-bigint
PLATFORM_EXPORT BigInt ToBigIntSlow(v8::Isolate*,
                                    v8::Local<v8::Value>,
                                    ExceptionState&);
inline BigInt ToBigInt(v8::Isolate* isolate,
                       v8::Local<v8::Value> value,
                       ExceptionState& exception_state) {
  // Fast case. The value is already a BigInt.
  if (value->IsBigInt()) [[likely]] {
    return BigInt(value.As<v8::BigInt>());
  }

  return ToBigIntSlow(isolate, value, exception_state);
}

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_BIGINT_H_