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/Allocator.h"
13 #include "gc/GCProbes.h"
14 #include "vm/StringType.h"
15
16 #include "vm/JSObject-inl.h"
17 #include "vm/ObjectOperations-inl.h" // js::GetElement
18
19 namespace js {
20
createArrayInternal(JSContext * cx,gc::AllocKind kind,gc::InitialHeap heap,HandleShape shape,AutoSetNewObjectMetadata &,gc::AllocSite * site)21 /* static */ inline ArrayObject* ArrayObject::createArrayInternal(
22 JSContext* cx, gc::AllocKind kind, gc::InitialHeap heap, HandleShape shape,
23 AutoSetNewObjectMetadata&, gc::AllocSite* site) {
24 const JSClass* clasp = shape->getObjectClass();
25 MOZ_ASSERT(shape);
26 MOZ_ASSERT(clasp == &ArrayObject::class_);
27 MOZ_ASSERT(clasp->isNativeObject());
28 MOZ_ASSERT_IF(clasp->hasFinalize(), heap == gc::TenuredHeap);
29
30 // Arrays can use their fixed slots to store elements, so can't have shapes
31 // which allow named properties to be stored in the fixed slots.
32 MOZ_ASSERT(shape->numFixedSlots() == 0);
33
34 size_t nDynamicSlots = calculateDynamicSlots(0, shape->slotSpan(), clasp);
35 JSObject* obj =
36 js::AllocateObject(cx, kind, nDynamicSlots, heap, clasp, site);
37 if (!obj) {
38 return nullptr;
39 }
40
41 ArrayObject* aobj = static_cast<ArrayObject*>(obj);
42 aobj->initShape(shape);
43 // NOTE: Dynamic slots are created internally by Allocate<JSObject>.
44 if (!nDynamicSlots) {
45 aobj->initEmptyDynamicSlots();
46 }
47
48 MOZ_ASSERT(clasp->shouldDelayMetadataBuilder());
49 cx->realm()->setObjectPendingMetadata(cx, aobj);
50
51 return aobj;
52 }
53
finishCreateArray(ArrayObject * obj,HandleShape shape,AutoSetNewObjectMetadata & metadata)54 /* static */ inline ArrayObject* ArrayObject::finishCreateArray(
55 ArrayObject* obj, HandleShape shape, AutoSetNewObjectMetadata& metadata) {
56 size_t span = shape->slotSpan();
57 if (span) {
58 obj->initializeSlotRange(0, span);
59 }
60
61 gc::gcprobes::CreateObject(obj);
62
63 return obj;
64 }
65
createArray(JSContext * cx,gc::AllocKind kind,gc::InitialHeap heap,HandleShape shape,uint32_t length,AutoSetNewObjectMetadata & metadata,gc::AllocSite * site)66 /* static */ inline ArrayObject* ArrayObject::createArray(
67 JSContext* cx, gc::AllocKind kind, gc::InitialHeap heap, HandleShape shape,
68 uint32_t length, AutoSetNewObjectMetadata& metadata, gc::AllocSite* site) {
69 ArrayObject* obj = createArrayInternal(cx, kind, heap, shape, metadata, site);
70 if (!obj) {
71 return nullptr;
72 }
73
74 uint32_t capacity =
75 gc::GetGCKindSlots(kind) - ObjectElements::VALUES_PER_HEADER;
76
77 obj->setFixedElements();
78 new (obj->getElementsHeader()) ObjectElements(capacity, length);
79
80 return finishCreateArray(obj, shape, metadata);
81 }
82
83 } // namespace js
84
85 #endif // vm_ArrayObject_inl_h
86