// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_OBJECTS_JS_ARRAY_H_
#define V8_OBJECTS_JS_ARRAY_H_

#include "src/objects/allocation-site.h"
#include "src/objects/fixed-array.h"
#include "src/objects/js-objects.h"

// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"

namespace v8 {
namespace internal {

#include "torque-generated/src/objects/js-array-tq.inc"

// The JSArray describes JavaScript Arrays
//  Such an array can be in one of two modes:
//    - fast, backing storage is a FixedArray and length <= elements.length();
//       Please note: push and pop can be used to grow and shrink the array.
//    - slow, backing storage is a HashTable with numbers as keys.
class JSArray : public TorqueGeneratedJSArray<JSArray, JSObject> {
 public:
  // [length]: The length property.
  DECL_ACCESSORS(length, Tagged<Object>)
  DECL_RELAXED_GETTER(length, Tagged<Object>)

  // Acquire/release semantics on this field are explicitly forbidden to avoid
  // confusion, since the default setter uses relaxed semantics. If
  // acquire/release semantics ever become necessary, the default setter should
  // be reverted to non-atomic behavior, and setters with explicit tags
  // introduced and used when required.
  Tagged<Object> length(PtrComprCageBase cage_base,
                        AcquireLoadTag tag) const = delete;
  void set_length(Tagged<Object> value, ReleaseStoreTag tag,
                  WriteBarrierMode mode = UPDATE_WRITE_BARRIER) = delete;

  // Overload the length setter to skip write barrier when the length
  // is set to a smi. This matches the set function on FixedArray.
  inline void set_length(Tagged<Smi> length);

  static bool MayHaveReadOnlyLength(Tagged<Map> js_array_map);
  static bool HasReadOnlyLength(Handle<JSArray> array);
  static bool WouldChangeReadOnlyLength(Handle<JSArray> array, uint32_t index);

  // Initialize the array with the given capacity. The function may
  // fail due to out-of-memory situations, but only if the requested
  // capacity is non-zero.
  V8_EXPORT_PRIVATE static void Initialize(Handle<JSArray> array, int capacity,
                                           int length = 0);

  // If the JSArray has fast elements, and new_length would result in
  // normalization, returns true.
  bool SetLengthWouldNormalize(uint32_t new_length);
  static inline bool SetLengthWouldNormalize(Heap* heap, uint32_t new_length);

  // Initializes the array to a certain length.
  V8_EXPORT_PRIVATE static Maybe<bool> SetLength(Handle<JSArray> array,
                                                 uint32_t length);

  // Set the content of the array to the content of storage.
  static inline void SetContent(Handle<JSArray> array,
                                Handle<FixedArrayBase> storage);

  // ES6 9.4.2.1
  V8_WARN_UNUSED_RESULT static Maybe<bool> DefineOwnProperty(
      Isolate* isolate, Handle<JSArray> o, Handle<Object> name,
      PropertyDescriptor* desc, Maybe<ShouldThrow> should_throw);

  static bool AnythingToArrayLength(Isolate* isolate,
                                    Handle<Object> length_object,
                                    uint32_t* output);
  V8_WARN_UNUSED_RESULT static Maybe<bool> ArraySetLength(
      Isolate* isolate, Handle<JSArray> a, PropertyDescriptor* desc,
      Maybe<ShouldThrow> should_throw);

  // Support for Array.prototype.join().
  // Writes a fixed array of strings and separators to a single destination
  // string. This helpers assumes the fixed array encodes separators in two
  // ways:
  //   1) Explicitly with a smi, whos value represents the number of repeated
  //      separators.
  //   2) Implicitly between two consecutive strings a single separator.
  //
  // In addition repeated strings are represented by a negative smi, indicating
  // how many times the previously written string has to be repeated.
  //
  // Here are some input/output examples given the separator string is ',':
  //
  //   [1, 'hello', 2, 'world', 1] => ',hello,,world,'
  //   ['hello', 'world']          => 'hello,world'
  //   ['hello', -2, 'world']      => 'hello,hello,hello,world'
  //
  // To avoid any allocations, this helper assumes the destination string is the
  // exact length necessary to write the strings and separators from the fixed
  // array.
  // Since this is called via ExternalReferences, it uses raw Address values:
  // - {raw_fixed_array} is a tagged FixedArray pointer.
  // - {raw_separator} and {raw_dest} are tagged String pointers.
  // - Returns a tagged String pointer.
  static Address ArrayJoinConcatToSequentialString(Isolate* isolate,
                                                   Address raw_fixed_array,
                                                   intptr_t length,
                                                   Address raw_separator,
                                                   Address raw_dest);

  // Checks whether the Array has the current realm's Array.prototype as its
  // prototype. This function is best-effort and only gives a conservative
  // approximation, erring on the side of false, in particular with respect
  // to Proxies and objects with a hidden prototype.
  inline bool HasArrayPrototype(Isolate* isolate);

  // Dispatched behavior.
  DECL_PRINTER(JSArray)
  DECL_VERIFIER(JSArray)

  // Number of element slots to pre-allocate for an empty array.
  static const int kPreallocatedArrayElements = 4;

  static const int kLengthDescriptorIndex = 0;

  // Max. number of elements being copied in Array builtins.
  static const int kMaxCopyElements = 100;

  // Valid array indices range from +0 <= i < 2^32 - 1 (kMaxUInt32).
  static constexpr uint32_t kMaxArrayLength = JSObject::kMaxElementCount;
  static constexpr uint32_t kMaxArrayIndex = JSObject::kMaxElementIndex;
  static_assert(kMaxArrayLength == kMaxUInt32);
  static_assert(kMaxArrayIndex == kMaxUInt32 - 1);

  // This constant is somewhat arbitrary. Any large enough value would work.
  static constexpr uint32_t kMaxFastArrayLength = 32 * 1024 * 1024;
  static_assert(kMaxFastArrayLength <= kMaxArrayLength);

  // Min. stack size for detecting an Array.prototype.join() call cycle.
  static const uint32_t kMinJoinStackSize = 2;

  static const int kInitialMaxFastElementArray =
      (kMaxRegularHeapObjectSize - FixedArray::kHeaderSize - kHeaderSize -
       AllocationMemento::kSize) >>
      kDoubleSizeLog2;

  TQ_OBJECT_CONSTRUCTORS(JSArray)
};

// The JSArrayIterator describes JavaScript Array Iterators Objects, as
// defined in ES section #sec-array-iterator-objects.
class JSArrayIterator
    : public TorqueGeneratedJSArrayIterator<JSArrayIterator, JSObject> {
 public:
  DECL_PRINTER(JSArrayIterator)
  DECL_VERIFIER(JSArrayIterator)

  // [kind]: the [[ArrayIterationKind]] inobject property.
  inline IterationKind kind() const;
  inline void set_kind(IterationKind kind);

 private:
  DECL_INT_ACCESSORS(raw_kind)

  TQ_OBJECT_CONSTRUCTORS(JSArrayIterator)
};

// Helper class for JSArrays that are template literal objects
class TemplateLiteralObject
    : public TorqueGeneratedTemplateLiteralObject<TemplateLiteralObject,
                                                  JSArray> {
 public:
  DECL_CAST(TemplateLiteralObject)

 private:
  TQ_OBJECT_CONSTRUCTORS(TemplateLiteralObject)
};

}  // namespace internal
}  // namespace v8

#include "src/objects/object-macros-undef.h"

#endif  // V8_OBJECTS_JS_ARRAY_H_
