tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

VectorShim.h (6578B)


      1 // Copyright 2014 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_UTIL_VECTOR_H_
      6 #define V8_UTIL_VECTOR_H_
      7 
      8 #include <cstring>
      9 
     10 #include "js/AllocPolicy.h"
     11 #include "js/Utility.h"
     12 #include "js/Vector.h"
     13 
     14 namespace v8 {
     15 namespace internal {
     16 
     17 //////////////////////////////////////////////////
     18 
     19 // Adapted from:
     20 // https://github.com/v8/v8/blob/5f69bbc233c2d1baf149faf869a7901603929914/src/utils/allocation.h#L36-L58
     21 
     22 template <typename T>
     23 T* NewArray(size_t size) {
     24  static_assert(std::is_trivially_copyable_v<T>);
     25  js::AutoEnterOOMUnsafeRegion oomUnsafe;
     26  T* result = js_pod_malloc<T>(size);
     27  if (!result) {
     28    oomUnsafe.crash("Irregexp NewArray");
     29  }
     30  return result;
     31 }
     32 
     33 template <typename T>
     34 void DeleteArray(T* array) {
     35  static_assert(std::is_trivially_destructible_v<T>);
     36  js_free(array);
     37 }
     38 
     39 }  // namespace internal
     40 
     41 namespace base {
     42 
     43 //////////////////////////////////////////////////
     44 
     45 // A non-resizable vector containing a pointer and a length.
     46 // The Vector may or may not own the pointer, depending on context.
     47 // Origin:
     48 // https://github.com/v8/v8/blob/5f69bbc233c2d1baf149faf869a7901603929914/src/utils/vector.h#L20-L134
     49 
     50 template <typename T>
     51 class Vector {
     52 public:
     53  constexpr Vector() : start_(nullptr), length_(0) {}
     54 
     55  constexpr Vector(T* data, size_t length) : start_(data), length_(length) {
     56    MOZ_ASSERT_IF(length != 0, data != nullptr);
     57  }
     58 
     59  static Vector<T> New(size_t length) {
     60    return Vector<T>(v8::internal::NewArray<T>(length), length);
     61  }
     62 
     63  // Returns a vector using the same backing storage as this one,
     64  // spanning from and including 'from', to but not including 'to'.
     65  Vector<T> SubVector(size_t from, size_t to) const {
     66    MOZ_ASSERT(from <= to);
     67    MOZ_ASSERT(to <= length_);
     68    return Vector<T>(begin() + from, to - from);
     69  }
     70 
     71  // Returns the length of the vector. Only use this if you really need an
     72  // integer return value. Use {size()} otherwise.
     73  int length() const {
     74    MOZ_ASSERT(length_ <= static_cast<size_t>(std::numeric_limits<int>::max()));
     75    return static_cast<int>(length_);
     76  }
     77 
     78  // Returns the length of the vector as a size_t.
     79  constexpr size_t size() const { return length_; }
     80 
     81  // Returns whether or not the vector is empty.
     82  constexpr bool empty() const { return length_ == 0; }
     83 
     84  // Access individual vector elements - checks bounds in debug mode.
     85  T& operator[](size_t index) const {
     86    MOZ_ASSERT(index < length_);
     87    return start_[index];
     88  }
     89 
     90  const T& at(size_t index) const { return operator[](index); }
     91 
     92  T& first() { return start_[0]; }
     93 
     94  T& last() {
     95    MOZ_ASSERT(length_ > 0);
     96    return start_[length_ - 1];
     97  }
     98 
     99  // Returns a pointer to the start of the data in the vector.
    100  constexpr T* begin() const { return start_; }
    101 
    102  // Returns a pointer past the end of the data in the vector.
    103  constexpr T* end() const { return start_ + length_; }
    104 
    105  // Returns a clone of this vector with a new backing store.
    106  Vector<T> Clone() const {
    107    T* result = v8::internal::NewArray<T>(length_);
    108    for (size_t i = 0; i < length_; i++) result[i] = start_[i];
    109    return Vector<T>(result, length_);
    110  }
    111 
    112  void Truncate(size_t length) {
    113    MOZ_ASSERT(length <= length_);
    114    length_ = length;
    115  }
    116 
    117  // Releases the array underlying this vector. Once disposed the
    118  // vector is empty.
    119  void Dispose() {
    120    DeleteArray(start_);
    121    start_ = nullptr;
    122    length_ = 0;
    123  }
    124 
    125  Vector<T> operator+(size_t offset) const {
    126    MOZ_ASSERT(offset <= length_);
    127    return Vector<T>(start_ + offset, length_ - offset);
    128  }
    129 
    130  Vector<T> operator+=(size_t offset) {
    131    MOZ_ASSERT(offset <= length_);
    132    start_ += offset;
    133    length_ -= offset;
    134    return *this;
    135  }
    136 
    137  // Implicit conversion from Vector<T> to Vector<const T>.
    138  inline operator Vector<const T>() const {
    139    return Vector<const T>::cast(*this);
    140  }
    141 
    142  template <typename S>
    143  static constexpr Vector<T> cast(Vector<S> input) {
    144    return Vector<T>(reinterpret_cast<T*>(input.begin()),
    145                     input.length() * sizeof(S) / sizeof(T));
    146  }
    147 
    148  bool operator==(const Vector<const T> other) const {
    149    if (length_ != other.length_) return false;
    150    if (start_ == other.start_) return true;
    151    for (size_t i = 0; i < length_; ++i) {
    152      if (start_[i] != other.start_[i]) {
    153        return false;
    154      }
    155    }
    156    return true;
    157  }
    158 
    159 private:
    160  T* start_;
    161  size_t length_;
    162 };
    163 
    164 // The resulting vector does not contain a null-termination byte. If you want
    165 // the null byte, use ArrayVector("foo").
    166 inline Vector<const char> CStrVector(const char* data) {
    167  return Vector<const char>(data, strlen(data));
    168 }
    169 
    170 // Construct a Vector from a start pointer and a size.
    171 template <typename T>
    172 inline constexpr Vector<T> VectorOf(T* start, size_t size) {
    173  return {start, size};
    174 }
    175 
    176 class DefaultAllocator {
    177 public:
    178  using Policy = js::SystemAllocPolicy;
    179  Policy policy() const { return js::SystemAllocPolicy(); }
    180 };
    181 
    182 // SmallVector uses inline storage first, and reallocates when full.
    183 // It is basically equivalent to js::Vector, and is implemented
    184 // as a thin wrapper.
    185 // V8's implementation:
    186 // https://github.com/v8/v8/blob/main/src/base/small-vector.h
    187 template <typename T, size_t kSize, typename Allocator = DefaultAllocator>
    188 class SmallVector {
    189 public:
    190  explicit SmallVector(const Allocator& allocator = DefaultAllocator())
    191      : inner_(allocator.policy()) {}
    192  SmallVector(size_t size) { resize(size); }
    193 
    194  inline bool empty() const { return inner_.empty(); }
    195  inline const T& back() const { return inner_.back(); }
    196  inline void pop_back() { inner_.popBack(); };
    197  template <typename... Args>
    198  inline void emplace_back(Args&&... args) {
    199    js::AutoEnterOOMUnsafeRegion oomUnsafe;
    200    if (!inner_.emplaceBack(args...)) {
    201      oomUnsafe.crash("Irregexp SmallVector emplace_back");
    202    }
    203  };
    204  inline size_t size() const { return inner_.length(); }
    205  inline const T& at(size_t index) const { return inner_[index]; }
    206  T* data() { return inner_.begin(); }
    207  T* begin() { return inner_.begin(); }
    208 
    209  T& operator[](size_t index) { return inner_[index]; }
    210  const T& operator[](size_t index) const { return inner_[index]; }
    211 
    212  inline void clear() { inner_.clear(); }
    213 
    214  void resize(size_t new_size) {
    215    js::AutoEnterOOMUnsafeRegion oomUnsafe;
    216    if (!inner_.resize(new_size)) {
    217      oomUnsafe.crash("Irregexp SmallVector resize");
    218    }
    219  }
    220 
    221 private:
    222  js::Vector<T, kSize, typename Allocator::Policy> inner_;
    223 };
    224 
    225 }  // namespace base
    226 
    227 }  // namespace v8
    228 
    229 #endif  // V8_UTIL_VECTOR_H_