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