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