1 // Copyright 2017 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_OBJECTS_JS_ARRAY_H_ 6 #define V8_OBJECTS_JS_ARRAY_H_ 7 8 #include "src/objects.h" 9 #include "src/objects/fixed-array.h" 10 11 // Has to be the last include (doesn't have include guards): 12 #include "src/objects/object-macros.h" 13 14 namespace v8 { 15 namespace internal { 16 17 // The JSArray describes JavaScript Arrays 18 // Such an array can be in one of two modes: 19 // - fast, backing storage is a FixedArray and length <= elements.length(); 20 // Please note: push and pop can be used to grow and shrink the array. 21 // - slow, backing storage is a HashTable with numbers as keys. 22 class JSArray : public JSObject { 23 public: 24 // [length]: The length property. 25 DECL_ACCESSORS(length, Object) 26 27 // Overload the length setter to skip write barrier when the length 28 // is set to a smi. This matches the set function on FixedArray. 29 inline void set_length(Smi* length); 30 31 static bool HasReadOnlyLength(Handle<JSArray> array); 32 static bool WouldChangeReadOnlyLength(Handle<JSArray> array, uint32_t index); 33 34 // Initialize the array with the given capacity. The function may 35 // fail due to out-of-memory situations, but only if the requested 36 // capacity is non-zero. 37 static void Initialize(Handle<JSArray> array, int capacity, int length = 0); 38 39 // If the JSArray has fast elements, and new_length would result in 40 // normalization, returns true. 41 bool SetLengthWouldNormalize(uint32_t new_length); 42 static inline bool SetLengthWouldNormalize(Heap* heap, uint32_t new_length); 43 44 // Initializes the array to a certain length. 45 inline bool AllowsSetLength(); 46 47 static void SetLength(Handle<JSArray> array, uint32_t length); 48 49 // Set the content of the array to the content of storage. 50 static inline void SetContent(Handle<JSArray> array, 51 Handle<FixedArrayBase> storage); 52 53 // ES6 9.4.2.1 54 V8_WARN_UNUSED_RESULT static Maybe<bool> DefineOwnProperty( 55 Isolate* isolate, Handle<JSArray> o, Handle<Object> name, 56 PropertyDescriptor* desc, ShouldThrow should_throw); 57 58 static bool AnythingToArrayLength(Isolate* isolate, 59 Handle<Object> length_object, 60 uint32_t* output); 61 V8_WARN_UNUSED_RESULT static Maybe<bool> ArraySetLength( 62 Isolate* isolate, Handle<JSArray> a, PropertyDescriptor* desc, 63 ShouldThrow should_throw); 64 65 // Checks whether the Array has the current realm's Array.prototype as its 66 // prototype. This function is best-effort and only gives a conservative 67 // approximation, erring on the side of false, in particular with respect 68 // to Proxies and objects with a hidden prototype. 69 inline bool HasArrayPrototype(Isolate* isolate); 70 71 DECL_CAST(JSArray) 72 73 // Dispatched behavior. 74 DECL_PRINTER(JSArray) 75 DECL_VERIFIER(JSArray) 76 77 // Number of element slots to pre-allocate for an empty array. 78 static const int kPreallocatedArrayElements = 4; 79 80 // Layout description. 81 static const int kLengthOffset = JSObject::kHeaderSize; 82 static const int kSize = kLengthOffset + kPointerSize; 83 84 static const int kLengthDescriptorIndex = 0; 85 86 // Max. number of elements being copied in Array builtins. 87 static const int kMaxCopyElements = 100; 88 89 // This constant is somewhat arbitrary. Any large enough value would work. 90 static const uint32_t kMaxFastArrayLength = 32 * 1024 * 1024; 91 92 static const int kInitialMaxFastElementArray = 93 (kMaxRegularHeapObjectSize - FixedArray::kHeaderSize - kSize - 94 AllocationMemento::kSize) >> 95 kDoubleSizeLog2; 96 97 // Valid array indices range from +0 <= i < 2^32 - 1 (kMaxUInt32). 98 static const uint32_t kMaxArrayIndex = kMaxUInt32 - 1; 99 100 private: 101 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArray); 102 }; 103 104 Handle<Object> CacheInitialJSArrayMaps(Handle<Context> native_context, 105 Handle<Map> initial_map); 106 107 // The JSArrayIterator describes JavaScript Array Iterators Objects, as 108 // defined in ES section #sec-array-iterator-objects. 109 class JSArrayIterator : public JSObject { 110 public: 111 DECL_PRINTER(JSArrayIterator) 112 DECL_VERIFIER(JSArrayIterator) 113 114 DECL_CAST(JSArrayIterator) 115 116 // [iterated_object]: the [[IteratedObject]] inobject property. 117 DECL_ACCESSORS(iterated_object, Object) 118 119 // [next_index]: The [[ArrayIteratorNextIndex]] inobject property. 120 // The next_index is always a positive integer, and it points to 121 // the next index that is to be returned by this iterator. It's 122 // possible range is fixed depending on the [[iterated_object]]: 123 // 124 // 1. For JSArray's the next_index is always in Unsigned32 125 // range, and when the iterator reaches the end it's set 126 // to kMaxUInt32 to indicate that this iterator should 127 // never produce values anymore even if the "length" 128 // property of the JSArray changes at some later point. 129 // 2. For JSTypedArray's the next_index is always in 130 // UnsignedSmall range, and when the iterator terminates 131 // it's set to Smi::kMaxValue. 132 // 3. For all other JSReceiver's it's always between 0 and 133 // kMaxSafeInteger, and the latter value is used to mark 134 // termination. 135 // 136 // It's important that for 1. and 2. the value fits into the 137 // Unsigned32 range (UnsignedSmall is a subset of Unsigned32), 138 // since we use this knowledge in the fast-path for the array 139 // iterator next calls in TurboFan (in the JSCallReducer) to 140 // keep the index in Word32 representation. This invariant is 141 // checked in JSArrayIterator::JSArrayIteratorVerify(). 142 DECL_ACCESSORS(next_index, Object) 143 144 // [kind]: the [[ArrayIterationKind]] inobject property. 145 inline IterationKind kind() const; 146 inline void set_kind(IterationKind kind); 147 148 static const int kIteratedObjectOffset = JSObject::kHeaderSize; 149 static const int kNextIndexOffset = kIteratedObjectOffset + kPointerSize; 150 static const int kKindOffset = kNextIndexOffset + kPointerSize; 151 static const int kSize = kKindOffset + kPointerSize; 152 153 private: 154 DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayIterator); 155 }; 156 157 } // namespace internal 158 } // namespace v8 159 160 #include "src/objects/object-macros-undef.h" 161 162 #endif // V8_OBJECTS_JS_ARRAY_H_ 163