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_BUILTINS_BUILTINS_ARRAY_GEN_H_
6#define V8_BUILTINS_BUILTINS_ARRAY_GEN_H_
7
8#include "src/codegen/code-stub-assembler.h"
9
10namespace v8 {
11namespace internal {
12
13class ArrayBuiltinsAssembler : public CodeStubAssembler {
14 public:
15  explicit ArrayBuiltinsAssembler(compiler::CodeAssemblerState* state);
16
17  using BuiltinResultGenerator =
18      std::function<void(ArrayBuiltinsAssembler* masm)>;
19
20  using CallResultProcessor = std::function<TNode<Object>(
21      ArrayBuiltinsAssembler* masm, TNode<Object> k_value, TNode<UintPtrT> k)>;
22
23  void TypedArrayMapResultGenerator();
24
25  // See tc39.github.io/ecma262/#sec-%typedarray%.prototype.map.
26  TNode<Object> TypedArrayMapProcessor(TNode<Object> k_value,
27                                       TNode<UintPtrT> k);
28
29  TNode<String> CallJSArrayArrayJoinConcatToSequentialString(
30      TNode<FixedArray> fixed_array, TNode<IntPtrT> length, TNode<String> sep,
31      TNode<String> dest) {
32    TNode<ExternalReference> func = ExternalConstant(
33        ExternalReference::jsarray_array_join_concat_to_sequential_string());
34    TNode<ExternalReference> isolate_ptr =
35        ExternalConstant(ExternalReference::isolate_address(isolate()));
36    return UncheckedCast<String>(
37        CallCFunction(func,
38                      MachineType::AnyTagged(),  // <return> String
39                      std::make_pair(MachineType::Pointer(), isolate_ptr),
40                      std::make_pair(MachineType::AnyTagged(), fixed_array),
41                      std::make_pair(MachineType::IntPtr(), length),
42                      std::make_pair(MachineType::AnyTagged(), sep),
43                      std::make_pair(MachineType::AnyTagged(), dest)));
44  }
45
46 protected:
47  TNode<Context> context() { return context_; }
48  TNode<Object> receiver() { return receiver_; }
49  TNode<IntPtrT> argc() { return argc_; }
50  TNode<JSReceiver> o() { return o_; }
51  TNode<UintPtrT> len() { return len_; }
52  TNode<Object> callbackfn() { return callbackfn_; }
53  TNode<Object> this_arg() { return this_arg_; }
54  TNode<UintPtrT> k() { return k_.value(); }
55  TNode<Object> a() { return a_.value(); }
56
57  void ReturnFromBuiltin(TNode<Object> value);
58
59  void InitIteratingArrayBuiltinBody(TNode<Context> context,
60                                     TNode<Object> receiver,
61                                     TNode<Object> callbackfn,
62                                     TNode<Object> this_arg,
63                                     TNode<IntPtrT> argc);
64
65  void GenerateIteratingTypedArrayBuiltinBody(
66      const char* name, const BuiltinResultGenerator& generator,
67      const CallResultProcessor& processor,
68      ForEachDirection direction = ForEachDirection::kForward);
69
70  void TailCallArrayConstructorStub(
71      const Callable& callable, TNode<Context> context,
72      TNode<JSFunction> target, TNode<HeapObject> allocation_site_or_undefined,
73      TNode<Int32T> argc);
74
75  void GenerateDispatchToArrayStub(
76      TNode<Context> context, TNode<JSFunction> target, TNode<Int32T> argc,
77      AllocationSiteOverrideMode mode,
78      base::Optional<TNode<AllocationSite>> allocation_site = base::nullopt);
79
80  void CreateArrayDispatchNoArgument(
81      TNode<Context> context, TNode<JSFunction> target, TNode<Int32T> argc,
82      AllocationSiteOverrideMode mode,
83      base::Optional<TNode<AllocationSite>> allocation_site);
84
85  void CreateArrayDispatchSingleArgument(
86      TNode<Context> context, TNode<JSFunction> target, TNode<Int32T> argc,
87      AllocationSiteOverrideMode mode,
88      base::Optional<TNode<AllocationSite>> allocation_site);
89
90  void GenerateConstructor(TNode<Context> context,
91                           TNode<HeapObject> array_function,
92                           TNode<Map> array_map, TNode<Object> array_size,
93                           TNode<HeapObject> allocation_site,
94                           ElementsKind elements_kind, AllocationSiteMode mode);
95  void GenerateArrayNoArgumentConstructor(ElementsKind kind,
96                                          AllocationSiteOverrideMode mode);
97  void GenerateArraySingleArgumentConstructor(ElementsKind kind,
98                                              AllocationSiteOverrideMode mode);
99  void GenerateArrayNArgumentsConstructor(
100      TNode<Context> context, TNode<JSFunction> target,
101      TNode<Object> new_target, TNode<Int32T> argc,
102      TNode<HeapObject> maybe_allocation_site);
103
104 private:
105  void VisitAllTypedArrayElements(TNode<JSArrayBuffer> array_buffer,
106                                  const CallResultProcessor& processor,
107                                  ForEachDirection direction,
108                                  TNode<JSTypedArray> typed_array,
109                                  bool can_shrink);
110
111  TNode<Object> callbackfn_;
112  TNode<JSReceiver> o_;
113  TNode<Object> this_arg_;
114  TNode<UintPtrT> len_;
115  TNode<Context> context_;
116  TNode<Object> receiver_;
117  TNode<IntPtrT> argc_;
118  TNode<BoolT> fast_typed_array_target_;
119  const char* name_ = nullptr;
120  TVariable<UintPtrT> k_;
121  TVariable<Object> a_;
122  Label fully_spec_compliant_;
123  ElementsKind source_elements_kind_ = ElementsKind::NO_ELEMENTS;
124};
125
126}  // namespace internal
127}  // namespace v8
128
129#endif  // V8_BUILTINS_BUILTINS_ARRAY_GEN_H_
130