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_List_h 8 #define vm_List_h 9 10 #include "NamespaceImports.h" 11 #include "js/Value.h" 12 #include "vm/NativeObject.h" 13 14 namespace js { 15 16 /** 17 * The List specification type, ECMA-262 6.2.1. 18 * <https://tc39.github.io/ecma262/#sec-list-and-record-specification-type> 19 * 20 * Lists are simple mutable sequences of values. Many standards use them. 21 * Abstractly, they're not objects; they don't have properties or prototypes; 22 * they're for internal specification use only. ListObject is our most direct 23 * implementation of a List: store the values in the slots of a JSObject. 24 * 25 * We often implement Lists in other ways. For example, builtin/Utilities.js 26 * contains a completely unrelated List constructor that's used in self-hosted 27 * code. And AsyncGeneratorObject optimizes away the ListObject in the common 28 * case where its internal queue never holds more than one element. 29 * 30 * ListObjects must not be exposed to content scripts. 31 */ 32 class ListObject : public NativeObject { 33 public: 34 static const JSClass class_; 35 36 [[nodiscard]] inline static ListObject* create(JSContext* cx); 37 length()38 uint32_t length() const { return getDenseInitializedLength(); } 39 isEmpty()40 bool isEmpty() const { return length() == 0; } 41 get(uint32_t index)42 const Value& get(uint32_t index) const { return getDenseElement(index); } 43 44 template <class T> getAs(uint32_t index)45 T& getAs(uint32_t index) const { 46 return get(index).toObject().as<T>(); 47 } 48 49 /** 50 * Add an element to the end of the list. Returns false on OOM. 51 */ 52 [[nodiscard]] inline bool append(JSContext* cx, HandleValue value); 53 54 /** 55 * Adds |value| and |size| elements to a list consisting of (value, size) 56 * pairs stored in successive elements. 57 * 58 * This function is intended for use by streams code's queue-with-sizes data 59 * structure and related operations. See builtin/streams/QueueWithSizes*. 60 * (You *could* use this on any list of even length without issue, but it's 61 * hard to imagine realistic situations where you'd want to...) 62 */ 63 [[nodiscard]] inline bool appendValueAndSize(JSContext* cx, HandleValue value, 64 double size); 65 66 /** 67 * Remove and return the first element of the list. 68 * 69 * Precondition: This list is not empty. 70 */ 71 inline JS::Value popFirst(JSContext* cx); 72 73 /** 74 * Remove the first two elements from a nonempty list of (value, size) pairs 75 * of elements. 76 */ 77 inline void popFirstPair(JSContext* cx); 78 79 /** 80 * Remove and return the first element of the list. 81 * 82 * Precondition: This list is not empty, and the first element 83 * is an object of class T. 84 */ 85 template <class T> 86 inline T& popFirstAs(JSContext* cx); 87 }; 88 89 } // namespace js 90 91 #endif // vm_List_h 92