• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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