tor-browser

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

ArrayObject-inl.h (2854B)


      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_inl_h
      8 #define vm_ArrayObject_inl_h
      9 
     10 #include "vm/ArrayObject.h"
     11 
     12 #include "gc/GCProbes.h"
     13 
     14 #include "vm/JSContext-inl.h"
     15 #include "vm/JSObject-inl.h"
     16 #include "vm/NativeObject-inl.h"
     17 
     18 namespace js {
     19 
     20 /* static */ MOZ_ALWAYS_INLINE ArrayObject* ArrayObject::create(
     21    JSContext* cx, gc::AllocKind kind, gc::Heap heap,
     22    Handle<SharedShape*> shape, uint32_t length, uint32_t slotSpan,
     23    AutoSetNewObjectMetadata& metadata, gc::AllocSite* site) {
     24  debugCheckNewObject(shape, kind, heap);
     25 
     26  const JSClass* clasp = &ArrayObject::class_;
     27  MOZ_ASSERT(shape);
     28  MOZ_ASSERT(shape->getObjectClass() == clasp);
     29  MOZ_ASSERT(clasp->isNativeObject());
     30  MOZ_ASSERT(!clasp->hasFinalize());
     31  MOZ_ASSERT(!IsFinalizedKind(kind));
     32 
     33  // Note: the slot span is passed as argument to allow more constant folding
     34  // below for the common case of slotSpan == 0.
     35  MOZ_ASSERT(shape->slotSpan() == slotSpan);
     36 
     37  // Arrays can use their fixed slots to store elements, so can't have shapes
     38  // which allow named properties to be stored in the fixed slots.
     39  MOZ_ASSERT(shape->numFixedSlots() == 0);
     40 
     41  size_t nDynamicSlots = calculateDynamicSlots(0, slotSpan, clasp);
     42  ArrayObject* aobj = cx->newCell<ArrayObject>(kind, heap, clasp, site);
     43  if (!aobj) {
     44    return nullptr;
     45  }
     46 
     47  aobj->initShape(shape);
     48  aobj->initFixedElements(kind, length);
     49 
     50  if (MOZ_UNLIKELY(length > INT32_MAX)) {
     51    cx->runtime()
     52        ->runtimeFuses.ref()
     53        .hasSeenArrayExceedsInt32LengthFuse.popFuse(cx);
     54  }
     55 
     56  if (!nDynamicSlots) {
     57    aobj->initEmptyDynamicSlots();
     58  } else if (!aobj->allocateInitialSlots(cx, nDynamicSlots)) {
     59    return nullptr;
     60  }
     61 
     62  MOZ_ASSERT(clasp->shouldDelayMetadataBuilder());
     63  cx->realm()->setObjectPendingMetadata(aobj);
     64 
     65  if (slotSpan > 0) {
     66    aobj->initDynamicSlots(slotSpan);
     67  }
     68 
     69  gc::gcprobes::CreateObject(aobj);
     70  return aobj;
     71 }
     72 
     73 inline DenseElementResult ArrayObject::addDenseElementNoLengthChange(
     74    JSContext* cx, uint32_t index, const Value& val) {
     75  MOZ_ASSERT(isExtensible());
     76 
     77  // Only support the `index < length` case so that we don't have to increase
     78  // the array's .length value below.
     79  if (index >= length() || containsDenseElement(index) || isIndexed()) {
     80    return DenseElementResult::Incomplete;
     81  }
     82 
     83  DenseElementResult res = ensureDenseElements(cx, index, 1);
     84  if (MOZ_UNLIKELY(res != DenseElementResult::Success)) {
     85    return res;
     86  }
     87 
     88  initDenseElement(index, val);
     89  return DenseElementResult::Success;
     90 }
     91 
     92 }  // namespace js
     93 
     94 #endif  // vm_ArrayObject_inl_h