tor-browser

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

ArrayObject.h (3195B)


      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 #ifndef vm_ArrayObject_h
      8 #define vm_ArrayObject_h
      9 
     10 #include "vm/JSContext.h"
     11 #include "vm/NativeObject.h"
     12 
     13 namespace js {
     14 
     15 class AutoSetNewObjectMetadata;
     16 
     17 class ArrayObject : public NativeObject {
     18 public:
     19  // Array(x) eagerly allocates dense elements if x <= this value.
     20  // This number was chosen so that the elements, the elements header,
     21  // and the MediumBuffer header all fit within MaxMediumAllocSize.
     22  static const uint32_t EagerAllocationMaxLength =
     23      (1 << 16) - ObjectElements::VALUES_PER_HEADER - 1;
     24 
     25  static const JSClass class_;
     26 
     27  bool lengthIsWritable() const {
     28    return !getElementsHeader()->hasNonwritableArrayLength();
     29  }
     30 
     31  uint32_t length() const { return getElementsHeader()->length; }
     32 
     33  void setNonWritableLength(JSContext* cx) {
     34    shrinkCapacityToInitializedLength(cx);
     35    assertInt32LengthFuse(cx);
     36    getElementsHeader()->setNonwritableArrayLength();
     37  }
     38 
     39  void setLengthToInitializedLength() {
     40    MOZ_ASSERT(lengthIsWritable());
     41    MOZ_ASSERT_IF(length() != getElementsHeader()->length,
     42                  !denseElementsAreFrozen());
     43    getElementsHeader()->length = getDenseInitializedLength();
     44    static_assert(MAX_DENSE_ELEMENTS_COUNT <= INT32_MAX,
     45                  "No need to check HasSeenArrayExceedsInt32LengthFuse");
     46  }
     47 
     48  void setLength(JSContext* cx, uint32_t length) {
     49    MOZ_ASSERT(lengthIsWritable());
     50    MOZ_ASSERT_IF(length != getElementsHeader()->length,
     51                  !denseElementsAreFrozen());
     52    assertInt32LengthFuse(cx);
     53    NativeObject::elementsSizeMustNotOverflow();
     54    if (MOZ_UNLIKELY(length > INT32_MAX)) {
     55      cx->runtime()
     56          ->runtimeFuses.ref()
     57          .hasSeenArrayExceedsInt32LengthFuse.popFuse(cx);
     58    }
     59    getElementsHeader()->length = length;
     60  }
     61 
     62  void assertInt32LengthFuse(JSContext* cx) {
     63    MOZ_ASSERT_IF(length() > INT32_MAX,
     64                  !cx->runtime()
     65                       ->runtimeFuses.ref()
     66                       .hasSeenArrayExceedsInt32LengthFuse.intact());
     67  }
     68 
     69  // Try to add a new dense element to this array. The array must be extensible.
     70  //
     71  // Returns DenseElementResult::Incomplete if `index >= length`, if the array
     72  // has sparse elements, if we're adding a sparse element, or if the array
     73  // already contains a dense element at this index.
     74  inline DenseElementResult addDenseElementNoLengthChange(JSContext* cx,
     75                                                          uint32_t index,
     76                                                          const Value& val);
     77 
     78  // Make an array object with the specified initial state.
     79  static MOZ_ALWAYS_INLINE ArrayObject* create(
     80      JSContext* cx, gc::AllocKind kind, gc::Heap heap,
     81      Handle<SharedShape*> shape, uint32_t length, uint32_t slotSpan,
     82      AutoSetNewObjectMetadata& metadata, gc::AllocSite* site = nullptr);
     83 };
     84 
     85 }  // namespace js
     86 
     87 #endif  // vm_ArrayObject_h