tor-browser

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

ValueArray.h (4266B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      3 * This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 /** GC-safe representations of consecutive JS::Value in memory. */
      8 
      9 #ifndef js_ValueArray_h
     10 #define js_ValueArray_h
     11 
     12 #include "mozilla/Assertions.h"  // MOZ_ASSERT
     13 #include "mozilla/Attributes.h"  // MOZ_IMPLICIT, MOZ_RAII
     14 
     15 #include "js/CallArgs.h"    // JS::CallArgs
     16 #include "js/GCVector.h"    // JS::RootedVector
     17 #include "js/RootingAPI.h"  // JS::AutoGCRooter, JS::{,Mutable}Handle
     18 #include "js/Value.h"       // JS::Value
     19 
     20 namespace js {
     21 JS_PUBLIC_API void TraceValueArray(JSTracer* trc, size_t length,
     22                                   JS::Value* elements);
     23 }  // namespace js
     24 
     25 namespace JS {
     26 
     27 /* A fixed-size array of values, for use inside Rooted<>. */
     28 template <size_t N>
     29 struct ValueArray {
     30  Value elements[N];
     31  void trace(JSTracer* trc) { js::TraceValueArray(trc, N, elements); }
     32 };
     33 
     34 /** RootedValueArray roots an internal fixed-size array of Values. */
     35 template <size_t N>
     36 using RootedValueArray = Rooted<ValueArray<N>>;
     37 
     38 /**
     39 * A generic handle to an array of rooted values.
     40 *
     41 * The rooted array refernced can take several forms, therfore this is not the
     42 * same as Handle<js::ValueArray>.
     43 */
     44 class HandleValueArray {
     45  const size_t length_;
     46  const Value* const elements_;
     47 
     48  HandleValueArray(size_t len, const Value* elements)
     49      : length_(len), elements_(elements) {}
     50 
     51 public:
     52  explicit HandleValueArray(Handle<Value> value)
     53      : length_(1), elements_(value.address()) {}
     54 
     55  MOZ_IMPLICIT HandleValueArray(const RootedVector<Value>& values)
     56      : length_(values.length()), elements_(values.begin()) {}
     57 
     58  MOZ_IMPLICIT HandleValueArray(const PersistentRootedVector<Value>& values)
     59      : length_(values.length()), elements_(values.begin()) {}
     60 
     61  template <size_t N>
     62  MOZ_IMPLICIT HandleValueArray(const RootedValueArray<N>& values)
     63      : length_(N), elements_(values.begin()) {}
     64 
     65  /** CallArgs must already be rooted somewhere up the stack. */
     66  MOZ_IMPLICIT HandleValueArray(const JS::CallArgs& args)
     67      : length_(args.length()), elements_(args.array()) {}
     68 
     69  /** Use with care! Only call this if the data is guaranteed to be marked. */
     70  static HandleValueArray fromMarkedLocation(size_t len,
     71                                             const Value* elements) {
     72    return HandleValueArray(len, elements);
     73  }
     74 
     75  static HandleValueArray subarray(const HandleValueArray& values,
     76                                   size_t startIndex, size_t len) {
     77    MOZ_ASSERT(startIndex + len <= values.length());
     78    return HandleValueArray(len, values.begin() + startIndex);
     79  }
     80 
     81  static HandleValueArray empty() { return HandleValueArray(0, nullptr); }
     82 
     83  size_t length() const { return length_; }
     84  const Value* begin() const { return elements_; }
     85 
     86  Handle<Value> operator[](size_t i) const {
     87    MOZ_ASSERT(i < length_);
     88    return Handle<Value>::fromMarkedLocation(&elements_[i]);
     89  }
     90 };
     91 
     92 }  // namespace JS
     93 
     94 namespace js {
     95 
     96 template <size_t N, typename Container>
     97 class WrappedPtrOperations<JS::ValueArray<N>, Container> {
     98  const JS::ValueArray<N>& array() const {
     99    return static_cast<const Container*>(this)->get();
    100  }
    101 
    102 public:
    103  size_t length() const { return N; }
    104  const JS::Value* begin() const { return array().elements; }
    105 
    106  JS::HandleValue operator[](size_t i) const {
    107    MOZ_ASSERT(i < N);
    108    return JS::HandleValue::fromMarkedLocation(&array().elements[i]);
    109  }
    110 };
    111 
    112 template <size_t N, typename Container>
    113 class MutableWrappedPtrOperations<JS::ValueArray<N>, Container>
    114    : public WrappedPtrOperations<JS::ValueArray<N>, Container> {
    115  using Base = WrappedPtrOperations<JS::ValueArray<N>, Container>;
    116  JS::ValueArray<N>& array() { return static_cast<Container*>(this)->get(); }
    117 
    118 public:
    119  using Base::begin;
    120  JS::Value* begin() { return array().elements; }
    121 
    122  using Base::operator[];
    123  JS::MutableHandleValue operator[](size_t i) {
    124    MOZ_ASSERT(i < N);
    125    return JS::MutableHandleValue::fromMarkedLocation(&array().elements[i]);
    126  }
    127 };
    128 
    129 }  // namespace js
    130 
    131 #endif  // js_ValueArray_h