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/. */
12 #include "mozilla/Assertions.h" // MOZ_ASSERT
14 #include <stdint.h> // uint32_t
16 #include "js/RootingAPI.h" // JS::Handle, JS::Rooted
17 #include "js/Value.h" // JS::Value, JS::ObjectValue
18 #include "vm/JSContext.h" // JSContext
19 #include "vm/NativeObject.h" // js::NativeObject
21 #include "vm/Compartment-inl.h" // JS::Compartment::wrap
22 #include "vm/JSObject-inl.h" // js::NewObjectWithGivenProto
23 #include "vm/NativeObject-inl.h" // js::NativeObject::*
24 #include "vm/Realm-inl.h" // js::AutoRealm
26 inline /* static */ js::ListObject
* js::ListObject::create(JSContext
* cx
) {
27 return NewObjectWithGivenProto
<ListObject
>(cx
, nullptr);
30 inline bool js::ListObject::append(JSContext
* cx
, JS::Handle
<JS::Value
> value
) {
31 uint32_t len
= length();
33 if (!ensureElements(cx
, len
+ 1)) {
37 ensureDenseInitializedLength(len
, 1);
38 setDenseElement(len
, value
);
42 inline bool js::ListObject::appendValueAndSize(JSContext
* cx
,
43 JS::Handle
<JS::Value
> value
,
45 uint32_t len
= length();
47 if (!ensureElements(cx
, len
+ 2)) {
51 ensureDenseInitializedLength(len
, 2);
52 setDenseElement(len
, value
);
53 setDenseElement(len
+ 1, JS::DoubleValue(size
));
57 inline JS::Value
js::ListObject::popFirst(JSContext
* cx
) {
58 uint32_t len
= length();
61 JS::Value entry
= get(0);
62 if (!tryShiftDenseElements(1)) {
63 moveDenseElements(0, 1, len
- 1);
64 setDenseInitializedLength(len
- 1);
65 shrinkElements(cx
, len
- 1);
68 MOZ_ASSERT(length() == len
- 1);
72 inline void js::ListObject::popFirstPair(JSContext
* cx
) {
73 uint32_t len
= length();
75 MOZ_ASSERT((len
% 2) == 0);
77 if (!tryShiftDenseElements(2)) {
78 moveDenseElements(0, 2, len
- 2);
79 setDenseInitializedLength(len
- 2);
80 shrinkElements(cx
, len
- 2);
83 MOZ_ASSERT(length() == len
- 2);
87 inline T
& js::ListObject::popFirstAs(JSContext
* cx
) {
88 return popFirst(cx
).toObject().as
<T
>();
94 * Stores an empty ListObject in the given fixed slot of |obj|.
96 [[nodiscard
]] inline bool StoreNewListInFixedSlot(JSContext
* cx
,
97 JS::Handle
<NativeObject
*> obj
,
99 AutoRealm
ar(cx
, obj
);
100 ListObject
* list
= ListObject::create(cx
);
105 obj
->setFixedSlot(slot
, JS::ObjectValue(*list
));
110 * Given an object |obj| whose fixed slot |slot| contains a ListObject, append
111 * |toAppend| to that list.
113 [[nodiscard
]] inline bool AppendToListInFixedSlot(
114 JSContext
* cx
, JS::Handle
<NativeObject
*> obj
, uint32_t slot
,
115 JS::Handle
<JSObject
*> toAppend
) {
116 JS::Rooted
<ListObject
*> list(
117 cx
, &obj
->getFixedSlot(slot
).toObject().as
<ListObject
>());
119 AutoRealm
ar(cx
, list
);
120 JS::Rooted
<JS::Value
> val(cx
, JS::ObjectValue(*toAppend
));
121 if (!cx
->compartment()->wrap(cx
, &val
)) {
124 return list
->append(cx
, val
);
129 #endif // vm_List_inl_h