162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// Copyright 2017 the V8 project authors. All rights reserved.
262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// found in the LICENSE file.
462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/builtins/builtins-arguments.h"
662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/builtins/builtins-utils.h"
762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/builtins/builtins.h"
862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/code-factory.h"
962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/code-stub-assembler.h"
1062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/interface-descriptors.h"
1162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/objects-inl.h"
1262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
1362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochnamespace v8 {
1462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochnamespace internal {
1562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
1662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtypedef compiler::Node Node;
1762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
1862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochstd::tuple<Node*, Node*, Node*>
1962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochArgumentsBuiltinsAssembler::GetArgumentsFrameAndCount(Node* function,
2062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                      ParameterMode mode) {
2162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CSA_ASSERT(this, HasInstanceType(function, JS_FUNCTION_TYPE));
2262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
2362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Variable frame_ptr(this, MachineType::PointerRepresentation());
2462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  frame_ptr.Bind(LoadParentFramePointer());
2562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CSA_ASSERT(this,
2662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch             WordEqual(function,
2762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                       LoadBufferObject(frame_ptr.value(),
2862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                        StandardFrameConstants::kFunctionOffset,
2962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                        MachineType::Pointer())));
3062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Variable argument_count(this, ParameterRepresentation(mode));
3162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  VariableList list({&frame_ptr, &argument_count}, zone());
3262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label done_argument_count(this, list);
3362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
3462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Determine the number of passed parameters, which is either the count stored
3562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // in an arguments adapter frame or fetched from the shared function info.
3662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* frame_ptr_above = LoadBufferObject(
3762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      frame_ptr.value(), StandardFrameConstants::kCallerFPOffset,
3862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      MachineType::Pointer());
3962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* shared =
4062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      LoadObjectField(function, JSFunction::kSharedFunctionInfoOffset);
4162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* formal_parameter_count = LoadSharedFunctionInfoSpecialField(
4262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      shared, SharedFunctionInfo::kFormalParameterCountOffset, mode);
4362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  argument_count.Bind(formal_parameter_count);
4462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* marker_or_function = LoadBufferObject(
4562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      frame_ptr_above, CommonFrameConstants::kContextOrFrameTypeOffset);
4662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  GotoIf(
4762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      MarkerIsNotFrameType(marker_or_function, StackFrame::ARGUMENTS_ADAPTOR),
4862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      &done_argument_count);
4962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* adapted_parameter_count = LoadBufferObject(
5062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      frame_ptr_above, ArgumentsAdaptorFrameConstants::kLengthOffset);
5162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  frame_ptr.Bind(frame_ptr_above);
5262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  argument_count.Bind(TaggedToParameter(adapted_parameter_count, mode));
5362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Goto(&done_argument_count);
5462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
5562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&done_argument_count);
5662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return std::tuple<Node*, Node*, Node*>(
5762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      frame_ptr.value(), argument_count.value(), formal_parameter_count);
5862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
5962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
6062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochstd::tuple<Node*, Node*, Node*>
6162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochArgumentsBuiltinsAssembler::AllocateArgumentsObject(Node* map,
6262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                    Node* arguments_count,
6362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                    Node* parameter_map_count,
6462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                    ParameterMode mode,
6562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                    int base_size) {
6662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Allocate the parameter object (either a Rest parameter object, a strict
6762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // argument object or a sloppy arguments object) and the elements/mapped
6862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // arguments together.
6962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int elements_offset = base_size;
7062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* element_count = arguments_count;
7162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (parameter_map_count != nullptr) {
7262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    base_size += FixedArray::kHeaderSize;
7362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    element_count = IntPtrOrSmiAdd(element_count, parameter_map_count, mode);
7462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
7562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool empty = IsIntPtrOrSmiConstantZero(arguments_count);
7662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_IMPLIES(empty, parameter_map_count == nullptr);
7762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* size =
7862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      empty ? IntPtrConstant(base_size)
7962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            : ElementOffsetFromIndex(element_count, FAST_ELEMENTS, mode,
8062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                     base_size + FixedArray::kHeaderSize);
8162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* result = Allocate(size);
8262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Comment("Initialize arguments object");
8362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StoreMapNoWriteBarrier(result, map);
8462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* empty_fixed_array = LoadRoot(Heap::kEmptyFixedArrayRootIndex);
8562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StoreObjectField(result, JSArray::kPropertiesOffset, empty_fixed_array);
8662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* smi_arguments_count = ParameterToTagged(arguments_count, mode);
8762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StoreObjectFieldNoWriteBarrier(result, JSArray::kLengthOffset,
8862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                 smi_arguments_count);
8962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* arguments = nullptr;
9062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!empty) {
9162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    arguments = InnerAllocate(result, elements_offset);
9262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StoreObjectFieldNoWriteBarrier(arguments, FixedArray::kLengthOffset,
9362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                   smi_arguments_count);
9462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* fixed_array_map = LoadRoot(Heap::kFixedArrayMapRootIndex);
9562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StoreMapNoWriteBarrier(arguments, fixed_array_map);
9662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
9762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* parameter_map = nullptr;
9862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (parameter_map_count != nullptr) {
9962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* parameter_map_offset = ElementOffsetFromIndex(
10062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        arguments_count, FAST_ELEMENTS, mode, FixedArray::kHeaderSize);
10162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    parameter_map = InnerAllocate(arguments, parameter_map_offset);
10262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StoreObjectFieldNoWriteBarrier(result, JSArray::kElementsOffset,
10362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                   parameter_map);
10462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* sloppy_elements_map =
10562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        LoadRoot(Heap::kSloppyArgumentsElementsMapRootIndex);
10662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StoreMapNoWriteBarrier(parameter_map, sloppy_elements_map);
10762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    parameter_map_count = ParameterToTagged(parameter_map_count, mode);
10862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StoreObjectFieldNoWriteBarrier(parameter_map, FixedArray::kLengthOffset,
10962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                   parameter_map_count);
11062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else {
11162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (empty) {
11262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      StoreObjectFieldNoWriteBarrier(result, JSArray::kElementsOffset,
11362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                     empty_fixed_array);
11462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    } else {
11562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      StoreObjectFieldNoWriteBarrier(result, JSArray::kElementsOffset,
11662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                     arguments);
11762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
11862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
11962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return std::tuple<Node*, Node*, Node*>(result, arguments, parameter_map);
12062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
12162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
12262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* ArgumentsBuiltinsAssembler::ConstructParametersObjectFromArgs(
12362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* map, Node* frame_ptr, Node* arg_count, Node* first_arg,
12462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* rest_count, ParameterMode param_mode, int base_size) {
12562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Allocate the parameter object (either a Rest parameter object, a strict
12662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // argument object or a sloppy arguments object) and the elements together and
12762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // fill in the contents with the arguments above |formal_parameter_count|.
12862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* result;
12962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* elements;
13062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* unused;
13162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  std::tie(result, elements, unused) =
13262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      AllocateArgumentsObject(map, rest_count, nullptr, param_mode, base_size);
13362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK(unused == nullptr);
13462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CodeStubArguments arguments(this, arg_count, frame_ptr, param_mode);
13562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Variable offset(this, MachineType::PointerRepresentation());
13662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  offset.Bind(IntPtrConstant(FixedArrayBase::kHeaderSize - kHeapObjectTag));
13762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  VariableList list({&offset}, zone());
13862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  arguments.ForEach(list,
13962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                    [this, elements, &offset](Node* arg) {
14062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                      StoreNoWriteBarrier(MachineRepresentation::kTagged,
14162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                          elements, offset.value(), arg);
14262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                      Increment(offset, kPointerSize);
14362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                    },
14462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                    first_arg, nullptr, param_mode);
14562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return result;
14662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
14762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
14862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* ArgumentsBuiltinsAssembler::EmitFastNewRestParameter(Node* context,
14962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                           Node* function) {
15062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* frame_ptr;
15162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* argument_count;
15262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* formal_parameter_count;
15362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
15462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ParameterMode mode = OptimalParameterMode();
15562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* zero = IntPtrOrSmiConstant(0, mode);
15662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
15762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  std::tie(frame_ptr, argument_count, formal_parameter_count) =
15862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      GetArgumentsFrameAndCount(function, mode);
15962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
16062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Variable result(this, MachineRepresentation::kTagged);
16162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label no_rest_parameters(this), runtime(this, Label::kDeferred),
16262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      done(this, &result);
16362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
16462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* rest_count =
16562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      IntPtrOrSmiSub(argument_count, formal_parameter_count, mode);
16662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* const native_context = LoadNativeContext(context);
16762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* const array_map = LoadJSArrayElementsMap(FAST_ELEMENTS, native_context);
16862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  GotoIf(IntPtrOrSmiLessThanOrEqual(rest_count, zero, mode),
16962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch         &no_rest_parameters);
17062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
17162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  GotoIfFixedArraySizeDoesntFitInNewSpace(
17262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      rest_count, &runtime, JSArray::kSize + FixedArray::kHeaderSize, mode);
17362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
17462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Allocate the Rest JSArray and the elements together and fill in the
17562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // contents with the arguments above |formal_parameter_count|.
17662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  result.Bind(ConstructParametersObjectFromArgs(
17762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      array_map, frame_ptr, argument_count, formal_parameter_count, rest_count,
17862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      mode, JSArray::kSize));
17962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Goto(&done);
18062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
18162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&no_rest_parameters);
18262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
18362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* arguments;
18462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* elements;
18562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* unused;
18662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    std::tie(arguments, elements, unused) =
18762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        AllocateArgumentsObject(array_map, zero, nullptr, mode, JSArray::kSize);
18862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    result.Bind(arguments);
18962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Goto(&done);
19062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
19162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
19262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&runtime);
19362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
19462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    result.Bind(CallRuntime(Runtime::kNewRestParameter, context, function));
19562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Goto(&done);
19662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
19762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
19862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&done);
19962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return result.value();
20062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
20162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
20262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochTF_BUILTIN(FastNewRestParameter, ArgumentsBuiltinsAssembler) {
20362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* function = Parameter(FastNewArgumentsDescriptor::kFunction);
20462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* context = Parameter(FastNewArgumentsDescriptor::kContext);
20562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Return(EmitFastNewRestParameter(context, function));
20662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
20762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
20862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* ArgumentsBuiltinsAssembler::EmitFastNewStrictArguments(Node* context,
20962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                             Node* function) {
21062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Variable result(this, MachineRepresentation::kTagged);
21162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label done(this, &result), empty(this), runtime(this, Label::kDeferred);
21262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
21362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* frame_ptr;
21462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* argument_count;
21562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* formal_parameter_count;
21662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
21762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ParameterMode mode = OptimalParameterMode();
21862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* zero = IntPtrOrSmiConstant(0, mode);
21962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
22062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  std::tie(frame_ptr, argument_count, formal_parameter_count) =
22162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      GetArgumentsFrameAndCount(function, mode);
22262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
22362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  GotoIfFixedArraySizeDoesntFitInNewSpace(
22462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      argument_count, &runtime,
22562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      JSStrictArgumentsObject::kSize + FixedArray::kHeaderSize, mode);
22662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
22762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* const native_context = LoadNativeContext(context);
22862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* const map =
22962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      LoadContextElement(native_context, Context::STRICT_ARGUMENTS_MAP_INDEX);
23062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  GotoIf(WordEqual(argument_count, zero), &empty);
23162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
23262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  result.Bind(ConstructParametersObjectFromArgs(
23362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      map, frame_ptr, argument_count, zero, argument_count, mode,
23462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      JSStrictArgumentsObject::kSize));
23562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Goto(&done);
23662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
23762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&empty);
23862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
23962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* arguments;
24062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* elements;
24162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* unused;
24262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    std::tie(arguments, elements, unused) = AllocateArgumentsObject(
24362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        map, zero, nullptr, mode, JSStrictArgumentsObject::kSize);
24462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    result.Bind(arguments);
24562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Goto(&done);
24662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
24762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
24862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&runtime);
24962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
25062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    result.Bind(CallRuntime(Runtime::kNewStrictArguments, context, function));
25162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Goto(&done);
25262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
25362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
25462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&done);
25562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return result.value();
25662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
25762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
25862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochTF_BUILTIN(FastNewStrictArguments, ArgumentsBuiltinsAssembler) {
25962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* function = Parameter(FastNewArgumentsDescriptor::kFunction);
26062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* context = Parameter(FastNewArgumentsDescriptor::kContext);
26162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Return(EmitFastNewStrictArguments(context, function));
26262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
26362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
26462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* ArgumentsBuiltinsAssembler::EmitFastNewSloppyArguments(Node* context,
26562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                             Node* function) {
26662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* frame_ptr;
26762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* argument_count;
26862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* formal_parameter_count;
26962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Variable result(this, MachineRepresentation::kTagged);
27062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
27162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ParameterMode mode = OptimalParameterMode();
27262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* zero = IntPtrOrSmiConstant(0, mode);
27362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
27462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label done(this, &result), empty(this), no_parameters(this),
27562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      runtime(this, Label::kDeferred);
27662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
27762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  std::tie(frame_ptr, argument_count, formal_parameter_count) =
27862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      GetArgumentsFrameAndCount(function, mode);
27962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
28062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  GotoIf(WordEqual(argument_count, zero), &empty);
28162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
28262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  GotoIf(WordEqual(formal_parameter_count, zero), &no_parameters);
28362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
28462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
28562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Comment("Mapped parameter JSSloppyArgumentsObject");
28662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
28762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* mapped_count =
28862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        IntPtrOrSmiMin(argument_count, formal_parameter_count, mode);
28962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
29062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* parameter_map_size =
29162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        IntPtrOrSmiAdd(mapped_count, IntPtrOrSmiConstant(2, mode), mode);
29262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
29362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Verify that the overall allocation will fit in new space.
29462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* elements_allocated =
29562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        IntPtrOrSmiAdd(argument_count, parameter_map_size, mode);
29662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    GotoIfFixedArraySizeDoesntFitInNewSpace(
29762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        elements_allocated, &runtime,
29862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        JSSloppyArgumentsObject::kSize + FixedArray::kHeaderSize * 2, mode);
29962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
30062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* const native_context = LoadNativeContext(context);
30162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* const map = LoadContextElement(
30262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        native_context, Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX);
30362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* argument_object;
30462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* elements;
30562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* map_array;
30662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    std::tie(argument_object, elements, map_array) =
30762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        AllocateArgumentsObject(map, argument_count, parameter_map_size, mode,
30862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                JSSloppyArgumentsObject::kSize);
30962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StoreObjectFieldNoWriteBarrier(
31062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        argument_object, JSSloppyArgumentsObject::kCalleeOffset, function);
31162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StoreFixedArrayElement(map_array, 0, context, SKIP_WRITE_BARRIER);
31262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StoreFixedArrayElement(map_array, 1, elements, SKIP_WRITE_BARRIER);
31362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
31462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Comment("Fill in non-mapped parameters");
31562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* argument_offset =
31662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        ElementOffsetFromIndex(argument_count, FAST_ELEMENTS, mode,
31762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                               FixedArray::kHeaderSize - kHeapObjectTag);
31862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* mapped_offset =
31962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        ElementOffsetFromIndex(mapped_count, FAST_ELEMENTS, mode,
32062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                               FixedArray::kHeaderSize - kHeapObjectTag);
32162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    CodeStubArguments arguments(this, argument_count, frame_ptr, mode);
32262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Variable current_argument(this, MachineType::PointerRepresentation());
32362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    current_argument.Bind(arguments.AtIndexPtr(argument_count, mode));
32462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    VariableList var_list1({&current_argument}, zone());
32562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    mapped_offset = BuildFastLoop(
32662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        var_list1, argument_offset, mapped_offset,
32762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        [this, elements, &current_argument](Node* offset) {
32862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          Increment(current_argument, kPointerSize);
32962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          Node* arg = LoadBufferObject(current_argument.value(), 0);
33062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          StoreNoWriteBarrier(MachineRepresentation::kTagged, elements, offset,
33162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                              arg);
33262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        },
33362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        -kPointerSize, INTPTR_PARAMETERS);
33462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
33562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Copy the parameter slots and the holes in the arguments.
33662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // We need to fill in mapped_count slots. They index the context,
33762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // where parameters are stored in reverse order, at
33862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    //   MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+argument_count-1
33962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // The mapped parameter thus need to get indices
34062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    //   MIN_CONTEXT_SLOTS+parameter_count-1 ..
34162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    //       MIN_CONTEXT_SLOTS+argument_count-mapped_count
34262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // We loop from right to left.
34362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Comment("Fill in mapped parameters");
34462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Variable context_index(this, OptimalParameterRepresentation());
34562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    context_index.Bind(IntPtrOrSmiSub(
34662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        IntPtrOrSmiAdd(IntPtrOrSmiConstant(Context::MIN_CONTEXT_SLOTS, mode),
34762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                       formal_parameter_count, mode),
34862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        mapped_count, mode));
34962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* the_hole = TheHoleConstant();
35062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    VariableList var_list2({&context_index}, zone());
35162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    const int kParameterMapHeaderSize =
35262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        FixedArray::kHeaderSize + 2 * kPointerSize;
35362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* adjusted_map_array = IntPtrAdd(
35462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        BitcastTaggedToWord(map_array),
35562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        IntPtrConstant(kParameterMapHeaderSize - FixedArray::kHeaderSize));
35662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* zero_offset = ElementOffsetFromIndex(
35762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        zero, FAST_ELEMENTS, mode, FixedArray::kHeaderSize - kHeapObjectTag);
35862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    BuildFastLoop(var_list2, mapped_offset, zero_offset,
35962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                  [this, the_hole, elements, adjusted_map_array, &context_index,
36062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                   mode](Node* offset) {
36162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                    StoreNoWriteBarrier(MachineRepresentation::kTagged,
36262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                        elements, offset, the_hole);
36362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                    StoreNoWriteBarrier(
36462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                        MachineRepresentation::kTagged, adjusted_map_array,
36562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                        offset, ParameterToTagged(context_index.value(), mode));
36662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                    Increment(context_index, 1, mode);
36762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                  },
36862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                  -kPointerSize, INTPTR_PARAMETERS);
36962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
37062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    result.Bind(argument_object);
37162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Goto(&done);
37262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
37362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
37462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&no_parameters);
37562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
37662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Comment("No parameters JSSloppyArgumentsObject");
37762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    GotoIfFixedArraySizeDoesntFitInNewSpace(
37862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        argument_count, &runtime,
37962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        JSSloppyArgumentsObject::kSize + FixedArray::kHeaderSize, mode);
38062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* const native_context = LoadNativeContext(context);
38162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* const map =
38262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        LoadContextElement(native_context, Context::SLOPPY_ARGUMENTS_MAP_INDEX);
38362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    result.Bind(ConstructParametersObjectFromArgs(
38462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        map, frame_ptr, argument_count, zero, argument_count, mode,
38562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        JSSloppyArgumentsObject::kSize));
38662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StoreObjectFieldNoWriteBarrier(
38762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        result.value(), JSSloppyArgumentsObject::kCalleeOffset, function);
38862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Goto(&done);
38962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
39062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
39162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&empty);
39262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
39362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Comment("Empty JSSloppyArgumentsObject");
39462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* const native_context = LoadNativeContext(context);
39562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* const map =
39662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        LoadContextElement(native_context, Context::SLOPPY_ARGUMENTS_MAP_INDEX);
39762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* arguments;
39862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* elements;
39962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Node* unused;
40062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    std::tie(arguments, elements, unused) = AllocateArgumentsObject(
40162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        map, zero, nullptr, mode, JSSloppyArgumentsObject::kSize);
40262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    result.Bind(arguments);
40362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StoreObjectFieldNoWriteBarrier(
40462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        result.value(), JSSloppyArgumentsObject::kCalleeOffset, function);
40562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Goto(&done);
40662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
40762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
40862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&runtime);
40962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
41062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    result.Bind(CallRuntime(Runtime::kNewSloppyArguments, context, function));
41162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Goto(&done);
41262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
41362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
41462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Bind(&done);
41562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return result.value();
41662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
41762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
41862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochTF_BUILTIN(FastNewSloppyArguments, ArgumentsBuiltinsAssembler) {
41962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* function = Parameter(FastNewArgumentsDescriptor::kFunction);
42062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* context = Parameter(FastNewArgumentsDescriptor::kContext);
42162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Return(EmitFastNewSloppyArguments(context, function));
42262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
42362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
42462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}  // namespace internal
42562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}  // namespace v8
426