blob: 6b8c704038fe39e752e46c45ef53951417f86f48 [file] [log] [blame]
// 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_BUILTINS_BUILTINS_ARRAY_GEN_H_
#define V8_BUILTINS_BUILTINS_ARRAY_GEN_H_
#include "src/codegen/code-stub-assembler.h"
namespace v8 {
namespace internal {
class ArrayBuiltinsAssembler : public CodeStubAssembler {
public:
explicit ArrayBuiltinsAssembler(compiler::CodeAssemblerState* state);
using BuiltinResultGenerator =
std::function<void(ArrayBuiltinsAssembler* masm)>;
using CallResultProcessor = std::function<Node*(ArrayBuiltinsAssembler* masm,
Node* k_value, Node* k)>;
using PostLoopAction = std::function<void(ArrayBuiltinsAssembler* masm)>;
void FindResultGenerator();
Node* FindProcessor(Node* k_value, Node* k);
void FindIndexResultGenerator();
Node* FindIndexProcessor(Node* k_value, Node* k);
void ForEachResultGenerator();
Node* ForEachProcessor(Node* k_value, Node* k);
void SomeResultGenerator();
Node* SomeProcessor(Node* k_value, Node* k);
void EveryResultGenerator();
Node* EveryProcessor(Node* k_value, Node* k);
void ReduceResultGenerator();
Node* ReduceProcessor(Node* k_value, Node* k);
void ReducePostLoopAction();
void TypedArrayMapResultGenerator();
Node* SpecCompliantMapProcessor(Node* k_value, Node* k);
Node* FastMapProcessor(Node* k_value, Node* k);
// See tc39.github.io/ecma262/#sec-%typedarray%.prototype.map.
Node* TypedArrayMapProcessor(Node* k_value, Node* k);
void NullPostLoopAction();
// Uses memset to effectively initialize the given FixedArray with Smi zeroes.
void FillFixedArrayWithSmiZero(TNode<FixedArray> array,
TNode<Smi> smi_length);
TNode<String> CallJSArrayArrayJoinConcatToSequentialString(
TNode<FixedArray> fixed_array, TNode<IntPtrT> length, TNode<String> sep,
TNode<String> dest) {
TNode<ExternalReference> func = ExternalConstant(
ExternalReference::jsarray_array_join_concat_to_sequential_string());
TNode<ExternalReference> isolate_ptr =
ExternalConstant(ExternalReference::isolate_address(isolate()));
return UncheckedCast<String>(
CallCFunction(func,
MachineType::AnyTagged(), // <return> String
std::make_pair(MachineType::Pointer(), isolate_ptr),
std::make_pair(MachineType::AnyTagged(), fixed_array),
std::make_pair(MachineType::IntPtr(), length),
std::make_pair(MachineType::AnyTagged(), sep),
std::make_pair(MachineType::AnyTagged(), dest)));
}
protected:
TNode<Context> context() { return context_; }
TNode<Object> receiver() { return receiver_; }
TNode<IntPtrT> argc() { return argc_; }
TNode<JSReceiver> o() { return o_; }
TNode<Number> len() { return len_; }
Node* callbackfn() { return callbackfn_; }
Node* this_arg() { return this_arg_; }
TNode<Number> k() { return CAST(k_.value()); }
Node* a() { return a_.value(); }
void ReturnFromBuiltin(Node* value);
void InitIteratingArrayBuiltinBody(TNode<Context> context,
TNode<Object> receiver, Node* callbackfn,
Node* this_arg, TNode<IntPtrT> argc);
void GenerateIteratingTypedArrayBuiltinBody(
const char* name, const BuiltinResultGenerator& generator,
const CallResultProcessor& processor, const PostLoopAction& action,
ForEachDirection direction = ForEachDirection::kForward);
void TailCallArrayConstructorStub(
const Callable& callable, TNode<Context> context,
TNode<JSFunction> target, TNode<HeapObject> allocation_site_or_undefined,
TNode<Int32T> argc);
void GenerateDispatchToArrayStub(
TNode<Context> context, TNode<JSFunction> target, TNode<Int32T> argc,
AllocationSiteOverrideMode mode,
TNode<AllocationSite> allocation_site = TNode<AllocationSite>());
void CreateArrayDispatchNoArgument(
TNode<Context> context, TNode<JSFunction> target, TNode<Int32T> argc,
AllocationSiteOverrideMode mode,
TNode<AllocationSite> allocation_site = TNode<AllocationSite>());
void CreateArrayDispatchSingleArgument(
TNode<Context> context, TNode<JSFunction> target, TNode<Int32T> argc,
AllocationSiteOverrideMode mode,
TNode<AllocationSite> allocation_site = TNode<AllocationSite>());
void GenerateConstructor(Node* context, Node* array_function, Node* array_map,
Node* array_size, Node* allocation_site,
ElementsKind elements_kind, AllocationSiteMode mode);
void GenerateArrayNoArgumentConstructor(ElementsKind kind,
AllocationSiteOverrideMode mode);
void GenerateArraySingleArgumentConstructor(ElementsKind kind,
AllocationSiteOverrideMode mode);
void GenerateArrayNArgumentsConstructor(
TNode<Context> context, TNode<JSFunction> target,
TNode<Object> new_target, TNode<Int32T> argc,
TNode<HeapObject> maybe_allocation_site);
private:
static ElementsKind ElementsKindForInstanceType(InstanceType type);
void VisitAllTypedArrayElements(Node* array_buffer,
const CallResultProcessor& processor,
Label* detached, ForEachDirection direction,
TNode<JSTypedArray> typed_array);
// Perform ArraySpeciesCreate (ES6 #sec-arrayspeciescreate).
// This version is specialized to create a zero length array
// of the elements kind of the input array.
void GenerateArraySpeciesCreate();
// Perform ArraySpeciesCreate (ES6 #sec-arrayspeciescreate).
void GenerateArraySpeciesCreate(TNode<Number> len);
Node* callbackfn_ = nullptr;
TNode<JSReceiver> o_;
Node* this_arg_ = nullptr;
TNode<Number> len_;
TNode<Context> context_;
TNode<Object> receiver_;
TNode<IntPtrT> argc_;
Node* fast_typed_array_target_ = nullptr;
const char* name_ = nullptr;
Variable k_;
Variable a_;
Variable to_;
Label fully_spec_compliant_;
ElementsKind source_elements_kind_ = ElementsKind::NO_ELEMENTS;
};
} // namespace internal
} // namespace v8
#endif // V8_BUILTINS_BUILTINS_ARRAY_GEN_H_