xref: /third_party/node/deps/v8/src/objects/js-array.h (revision 1cb0ef41)
11cb0ef41Sopenharmony_ci// Copyright 2017 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#ifndef V8_OBJECTS_JS_ARRAY_H_
61cb0ef41Sopenharmony_ci#define V8_OBJECTS_JS_ARRAY_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include "src/objects/allocation-site.h"
91cb0ef41Sopenharmony_ci#include "src/objects/fixed-array.h"
101cb0ef41Sopenharmony_ci#include "src/objects/js-objects.h"
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ci// Has to be the last include (doesn't have include guards):
131cb0ef41Sopenharmony_ci#include "src/objects/object-macros.h"
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_cinamespace v8 {
161cb0ef41Sopenharmony_cinamespace internal {
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ci#include "torque-generated/src/objects/js-array-tq.inc"
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_ci// The JSArray describes JavaScript Arrays
211cb0ef41Sopenharmony_ci//  Such an array can be in one of two modes:
221cb0ef41Sopenharmony_ci//    - fast, backing storage is a FixedArray and length <= elements.length();
231cb0ef41Sopenharmony_ci//       Please note: push and pop can be used to grow and shrink the array.
241cb0ef41Sopenharmony_ci//    - slow, backing storage is a HashTable with numbers as keys.
251cb0ef41Sopenharmony_ciclass JSArray : public TorqueGeneratedJSArray<JSArray, JSObject> {
261cb0ef41Sopenharmony_ci public:
271cb0ef41Sopenharmony_ci  // [length]: The length property.
281cb0ef41Sopenharmony_ci  DECL_ACCESSORS(length, Object)
291cb0ef41Sopenharmony_ci  DECL_RELAXED_GETTER(length, Object)
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_ci  // Acquire/release semantics on this field are explicitly forbidden to avoid
321cb0ef41Sopenharmony_ci  // confusion, since the default setter uses relaxed semantics. If
331cb0ef41Sopenharmony_ci  // acquire/release semantics ever become necessary, the default setter should
341cb0ef41Sopenharmony_ci  // be reverted to non-atomic behavior, and setters with explicit tags
351cb0ef41Sopenharmony_ci  // introduced and used when required.
361cb0ef41Sopenharmony_ci  Object length(PtrComprCageBase cage_base, AcquireLoadTag tag) const = delete;
371cb0ef41Sopenharmony_ci  void set_length(Object value, ReleaseStoreTag tag,
381cb0ef41Sopenharmony_ci                  WriteBarrierMode mode = UPDATE_WRITE_BARRIER) = delete;
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci  // Overload the length setter to skip write barrier when the length
411cb0ef41Sopenharmony_ci  // is set to a smi. This matches the set function on FixedArray.
421cb0ef41Sopenharmony_ci  inline void set_length(Smi length);
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ci  static bool MayHaveReadOnlyLength(Map js_array_map);
451cb0ef41Sopenharmony_ci  static bool HasReadOnlyLength(Handle<JSArray> array);
461cb0ef41Sopenharmony_ci  static bool WouldChangeReadOnlyLength(Handle<JSArray> array, uint32_t index);
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ci  // Initialize the array with the given capacity. The function may
491cb0ef41Sopenharmony_ci  // fail due to out-of-memory situations, but only if the requested
501cb0ef41Sopenharmony_ci  // capacity is non-zero.
511cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE static void Initialize(Handle<JSArray> array, int capacity,
521cb0ef41Sopenharmony_ci                                           int length = 0);
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci  // If the JSArray has fast elements, and new_length would result in
551cb0ef41Sopenharmony_ci  // normalization, returns true.
561cb0ef41Sopenharmony_ci  bool SetLengthWouldNormalize(uint32_t new_length);
571cb0ef41Sopenharmony_ci  static inline bool SetLengthWouldNormalize(Heap* heap, uint32_t new_length);
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_ci  // Initializes the array to a certain length.
601cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE static Maybe<bool> SetLength(Handle<JSArray> array,
611cb0ef41Sopenharmony_ci                                                 uint32_t length);
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_ci  // Set the content of the array to the content of storage.
641cb0ef41Sopenharmony_ci  static inline void SetContent(Handle<JSArray> array,
651cb0ef41Sopenharmony_ci                                Handle<FixedArrayBase> storage);
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci  // ES6 9.4.2.1
681cb0ef41Sopenharmony_ci  V8_WARN_UNUSED_RESULT static Maybe<bool> DefineOwnProperty(
691cb0ef41Sopenharmony_ci      Isolate* isolate, Handle<JSArray> o, Handle<Object> name,
701cb0ef41Sopenharmony_ci      PropertyDescriptor* desc, Maybe<ShouldThrow> should_throw);
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ci  static bool AnythingToArrayLength(Isolate* isolate,
731cb0ef41Sopenharmony_ci                                    Handle<Object> length_object,
741cb0ef41Sopenharmony_ci                                    uint32_t* output);
751cb0ef41Sopenharmony_ci  V8_WARN_UNUSED_RESULT static Maybe<bool> ArraySetLength(
761cb0ef41Sopenharmony_ci      Isolate* isolate, Handle<JSArray> a, PropertyDescriptor* desc,
771cb0ef41Sopenharmony_ci      Maybe<ShouldThrow> should_throw);
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ci  // Support for Array.prototype.join().
801cb0ef41Sopenharmony_ci  // Writes a fixed array of strings and separators to a single destination
811cb0ef41Sopenharmony_ci  // string. This helpers assumes the fixed array encodes separators in two
821cb0ef41Sopenharmony_ci  // ways:
831cb0ef41Sopenharmony_ci  //   1) Explicitly with a smi, whos value represents the number of repeated
841cb0ef41Sopenharmony_ci  //      separators.
851cb0ef41Sopenharmony_ci  //   2) Implicitly between two consecutive strings a single separator.
861cb0ef41Sopenharmony_ci  //
871cb0ef41Sopenharmony_ci  // Here are some input/output examples given the separator string is ',':
881cb0ef41Sopenharmony_ci  //
891cb0ef41Sopenharmony_ci  //   [1, 'hello', 2, 'world', 1] => ',hello,,world,'
901cb0ef41Sopenharmony_ci  //   ['hello', 'world']          => 'hello,world'
911cb0ef41Sopenharmony_ci  //
921cb0ef41Sopenharmony_ci  // To avoid any allocations, this helper assumes the destination string is the
931cb0ef41Sopenharmony_ci  // exact length necessary to write the strings and separators from the fixed
941cb0ef41Sopenharmony_ci  // array.
951cb0ef41Sopenharmony_ci  // Since this is called via ExternalReferences, it uses raw Address values:
961cb0ef41Sopenharmony_ci  // - {raw_fixed_array} is a tagged FixedArray pointer.
971cb0ef41Sopenharmony_ci  // - {raw_separator} and {raw_dest} are tagged String pointers.
981cb0ef41Sopenharmony_ci  // - Returns a tagged String pointer.
991cb0ef41Sopenharmony_ci  static Address ArrayJoinConcatToSequentialString(Isolate* isolate,
1001cb0ef41Sopenharmony_ci                                                   Address raw_fixed_array,
1011cb0ef41Sopenharmony_ci                                                   intptr_t length,
1021cb0ef41Sopenharmony_ci                                                   Address raw_separator,
1031cb0ef41Sopenharmony_ci                                                   Address raw_dest);
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_ci  // Checks whether the Array has the current realm's Array.prototype as its
1061cb0ef41Sopenharmony_ci  // prototype. This function is best-effort and only gives a conservative
1071cb0ef41Sopenharmony_ci  // approximation, erring on the side of false, in particular with respect
1081cb0ef41Sopenharmony_ci  // to Proxies and objects with a hidden prototype.
1091cb0ef41Sopenharmony_ci  inline bool HasArrayPrototype(Isolate* isolate);
1101cb0ef41Sopenharmony_ci
1111cb0ef41Sopenharmony_ci  // Dispatched behavior.
1121cb0ef41Sopenharmony_ci  DECL_PRINTER(JSArray)
1131cb0ef41Sopenharmony_ci  DECL_VERIFIER(JSArray)
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_ci  // Number of element slots to pre-allocate for an empty array.
1161cb0ef41Sopenharmony_ci  static const int kPreallocatedArrayElements = 4;
1171cb0ef41Sopenharmony_ci
1181cb0ef41Sopenharmony_ci  static const int kLengthDescriptorIndex = 0;
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ci  // Max. number of elements being copied in Array builtins.
1211cb0ef41Sopenharmony_ci  static const int kMaxCopyElements = 100;
1221cb0ef41Sopenharmony_ci
1231cb0ef41Sopenharmony_ci  // Valid array indices range from +0 <= i < 2^32 - 1 (kMaxUInt32).
1241cb0ef41Sopenharmony_ci  static constexpr uint32_t kMaxArrayLength = JSObject::kMaxElementCount;
1251cb0ef41Sopenharmony_ci  static constexpr uint32_t kMaxArrayIndex = JSObject::kMaxElementIndex;
1261cb0ef41Sopenharmony_ci  STATIC_ASSERT(kMaxArrayLength == kMaxUInt32);
1271cb0ef41Sopenharmony_ci  STATIC_ASSERT(kMaxArrayIndex == kMaxUInt32 - 1);
1281cb0ef41Sopenharmony_ci
1291cb0ef41Sopenharmony_ci  // This constant is somewhat arbitrary. Any large enough value would work.
1301cb0ef41Sopenharmony_ci  static constexpr uint32_t kMaxFastArrayLength = 32 * 1024 * 1024;
1311cb0ef41Sopenharmony_ci  STATIC_ASSERT(kMaxFastArrayLength <= kMaxArrayLength);
1321cb0ef41Sopenharmony_ci
1331cb0ef41Sopenharmony_ci  // Min. stack size for detecting an Array.prototype.join() call cycle.
1341cb0ef41Sopenharmony_ci  static const uint32_t kMinJoinStackSize = 2;
1351cb0ef41Sopenharmony_ci
1361cb0ef41Sopenharmony_ci  static const int kInitialMaxFastElementArray =
1371cb0ef41Sopenharmony_ci      (kMaxRegularHeapObjectSize - FixedArray::kHeaderSize - kHeaderSize -
1381cb0ef41Sopenharmony_ci       AllocationMemento::kSize) >>
1391cb0ef41Sopenharmony_ci      kDoubleSizeLog2;
1401cb0ef41Sopenharmony_ci
1411cb0ef41Sopenharmony_ci  TQ_OBJECT_CONSTRUCTORS(JSArray)
1421cb0ef41Sopenharmony_ci};
1431cb0ef41Sopenharmony_ci
1441cb0ef41Sopenharmony_ci// The JSArrayIterator describes JavaScript Array Iterators Objects, as
1451cb0ef41Sopenharmony_ci// defined in ES section #sec-array-iterator-objects.
1461cb0ef41Sopenharmony_ciclass JSArrayIterator
1471cb0ef41Sopenharmony_ci    : public TorqueGeneratedJSArrayIterator<JSArrayIterator, JSObject> {
1481cb0ef41Sopenharmony_ci public:
1491cb0ef41Sopenharmony_ci  DECL_PRINTER(JSArrayIterator)
1501cb0ef41Sopenharmony_ci  DECL_VERIFIER(JSArrayIterator)
1511cb0ef41Sopenharmony_ci
1521cb0ef41Sopenharmony_ci  // [kind]: the [[ArrayIterationKind]] inobject property.
1531cb0ef41Sopenharmony_ci  inline IterationKind kind() const;
1541cb0ef41Sopenharmony_ci  inline void set_kind(IterationKind kind);
1551cb0ef41Sopenharmony_ci
1561cb0ef41Sopenharmony_ci private:
1571cb0ef41Sopenharmony_ci  DECL_INT_ACCESSORS(raw_kind)
1581cb0ef41Sopenharmony_ci
1591cb0ef41Sopenharmony_ci  TQ_OBJECT_CONSTRUCTORS(JSArrayIterator)
1601cb0ef41Sopenharmony_ci};
1611cb0ef41Sopenharmony_ci
1621cb0ef41Sopenharmony_ci}  // namespace internal
1631cb0ef41Sopenharmony_ci}  // namespace v8
1641cb0ef41Sopenharmony_ci
1651cb0ef41Sopenharmony_ci#include "src/objects/object-macros-undef.h"
1661cb0ef41Sopenharmony_ci
1671cb0ef41Sopenharmony_ci#endif  // V8_OBJECTS_JS_ARRAY_H_
168