11cb0ef41Sopenharmony_ci// Copyright 2014 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#include "src/compiler/js-generic-lowering.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include "src/ast/ast.h"
81cb0ef41Sopenharmony_ci#include "src/builtins/builtins-constructor.h"
91cb0ef41Sopenharmony_ci#include "src/codegen/code-factory.h"
101cb0ef41Sopenharmony_ci#include "src/codegen/interface-descriptors-inl.h"
111cb0ef41Sopenharmony_ci#include "src/compiler/access-builder.h"
121cb0ef41Sopenharmony_ci#include "src/compiler/common-operator.h"
131cb0ef41Sopenharmony_ci#include "src/compiler/js-graph.h"
141cb0ef41Sopenharmony_ci#include "src/compiler/js-heap-broker.h"
151cb0ef41Sopenharmony_ci#include "src/compiler/machine-operator.h"
161cb0ef41Sopenharmony_ci#include "src/compiler/node-matchers.h"
171cb0ef41Sopenharmony_ci#include "src/compiler/node-properties.h"
181cb0ef41Sopenharmony_ci#include "src/compiler/operator-properties.h"
191cb0ef41Sopenharmony_ci#include "src/compiler/processed-feedback.h"
201cb0ef41Sopenharmony_ci#include "src/compiler/simplified-operator.h"
211cb0ef41Sopenharmony_ci#include "src/objects/feedback-cell.h"
221cb0ef41Sopenharmony_ci#include "src/objects/feedback-vector.h"
231cb0ef41Sopenharmony_ci#include "src/objects/scope-info.h"
241cb0ef41Sopenharmony_ci#include "src/objects/template-objects-inl.h"
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_cinamespace v8 {
271cb0ef41Sopenharmony_cinamespace internal {
281cb0ef41Sopenharmony_cinamespace compiler {
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_cinamespace {
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ciCallDescriptor::Flags FrameStateFlagForCall(Node* node) {
331cb0ef41Sopenharmony_ci  return OperatorProperties::HasFrameStateInput(node->op())
341cb0ef41Sopenharmony_ci             ? CallDescriptor::kNeedsFrameState
351cb0ef41Sopenharmony_ci             : CallDescriptor::kNoFlags;
361cb0ef41Sopenharmony_ci}
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ci}  // namespace
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ciJSGenericLowering::JSGenericLowering(JSGraph* jsgraph, Editor* editor,
411cb0ef41Sopenharmony_ci                                     JSHeapBroker* broker)
421cb0ef41Sopenharmony_ci    : AdvancedReducer(editor), jsgraph_(jsgraph), broker_(broker) {}
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ciJSGenericLowering::~JSGenericLowering() = default;
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ciReduction JSGenericLowering::Reduce(Node* node) {
481cb0ef41Sopenharmony_ci  switch (node->opcode()) {
491cb0ef41Sopenharmony_ci#define DECLARE_CASE(x, ...) \
501cb0ef41Sopenharmony_ci  case IrOpcode::k##x:       \
511cb0ef41Sopenharmony_ci    Lower##x(node);          \
521cb0ef41Sopenharmony_ci    break;
531cb0ef41Sopenharmony_ci    JS_OP_LIST(DECLARE_CASE)
541cb0ef41Sopenharmony_ci#undef DECLARE_CASE
551cb0ef41Sopenharmony_ci    default:
561cb0ef41Sopenharmony_ci      // Nothing to see.
571cb0ef41Sopenharmony_ci      return NoChange();
581cb0ef41Sopenharmony_ci  }
591cb0ef41Sopenharmony_ci  return Changed(node);
601cb0ef41Sopenharmony_ci}
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ci#define REPLACE_STUB_CALL(Name)                       \
631cb0ef41Sopenharmony_ci  void JSGenericLowering::LowerJS##Name(Node* node) { \
641cb0ef41Sopenharmony_ci    ReplaceWithBuiltinCall(node, Builtin::k##Name);   \
651cb0ef41Sopenharmony_ci  }
661cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(ToLength)
671cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(ToNumber)
681cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(ToNumberConvertBigInt)
691cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(ToNumeric)
701cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(ToName)
711cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(ToObject)
721cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(ToString)
731cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(ForInEnumerate)
741cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(AsyncFunctionEnter)
751cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(AsyncFunctionReject)
761cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(AsyncFunctionResolve)
771cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(FulfillPromise)
781cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(PerformPromiseThen)
791cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(PromiseResolve)
801cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(RejectPromise)
811cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(ResolvePromise)
821cb0ef41Sopenharmony_ci#undef REPLACE_STUB_CALL
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_civoid JSGenericLowering::ReplaceWithBuiltinCall(Node* node, Builtin builtin) {
851cb0ef41Sopenharmony_ci  CallDescriptor::Flags flags = FrameStateFlagForCall(node);
861cb0ef41Sopenharmony_ci  Callable callable = Builtins::CallableFor(isolate(), builtin);
871cb0ef41Sopenharmony_ci  ReplaceWithBuiltinCall(node, callable, flags);
881cb0ef41Sopenharmony_ci}
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_civoid JSGenericLowering::ReplaceWithBuiltinCall(Node* node, Callable callable,
911cb0ef41Sopenharmony_ci                                               CallDescriptor::Flags flags) {
921cb0ef41Sopenharmony_ci  ReplaceWithBuiltinCall(node, callable, flags, node->op()->properties());
931cb0ef41Sopenharmony_ci}
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_civoid JSGenericLowering::ReplaceWithBuiltinCall(
961cb0ef41Sopenharmony_ci    Node* node, Callable callable, CallDescriptor::Flags flags,
971cb0ef41Sopenharmony_ci    Operator::Properties properties) {
981cb0ef41Sopenharmony_ci  const CallInterfaceDescriptor& descriptor = callable.descriptor();
991cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
1001cb0ef41Sopenharmony_ci      zone(), descriptor, descriptor.GetStackParameterCount(), flags,
1011cb0ef41Sopenharmony_ci      properties);
1021cb0ef41Sopenharmony_ci  Node* stub_code = jsgraph()->HeapConstant(callable.code());
1031cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 0, stub_code);
1041cb0ef41Sopenharmony_ci  NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
1051cb0ef41Sopenharmony_ci}
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_civoid JSGenericLowering::ReplaceWithRuntimeCall(Node* node,
1081cb0ef41Sopenharmony_ci                                               Runtime::FunctionId f,
1091cb0ef41Sopenharmony_ci                                               int nargs_override) {
1101cb0ef41Sopenharmony_ci  CallDescriptor::Flags flags = FrameStateFlagForCall(node);
1111cb0ef41Sopenharmony_ci  Operator::Properties properties = node->op()->properties();
1121cb0ef41Sopenharmony_ci  const Runtime::Function* fun = Runtime::FunctionForId(f);
1131cb0ef41Sopenharmony_ci  int nargs = (nargs_override < 0) ? fun->nargs : nargs_override;
1141cb0ef41Sopenharmony_ci  auto call_descriptor =
1151cb0ef41Sopenharmony_ci      Linkage::GetRuntimeCallDescriptor(zone(), f, nargs, properties, flags);
1161cb0ef41Sopenharmony_ci  Node* ref = jsgraph()->ExternalConstant(ExternalReference::Create(f));
1171cb0ef41Sopenharmony_ci  Node* arity = jsgraph()->Int32Constant(nargs);
1181cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 0, jsgraph()->CEntryStubConstant(fun->result_size));
1191cb0ef41Sopenharmony_ci  node->InsertInput(zone(), nargs + 1, ref);
1201cb0ef41Sopenharmony_ci  node->InsertInput(zone(), nargs + 2, arity);
1211cb0ef41Sopenharmony_ci  NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
1221cb0ef41Sopenharmony_ci}
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_civoid JSGenericLowering::ReplaceUnaryOpWithBuiltinCall(
1251cb0ef41Sopenharmony_ci    Node* node, Builtin builtin_without_feedback,
1261cb0ef41Sopenharmony_ci    Builtin builtin_with_feedback) {
1271cb0ef41Sopenharmony_ci  DCHECK(JSOperator::IsUnaryWithFeedback(node->opcode()));
1281cb0ef41Sopenharmony_ci  const FeedbackParameter& p = FeedbackParameterOf(node->op());
1291cb0ef41Sopenharmony_ci  if (CollectFeedbackInGenericLowering() && p.feedback().IsValid()) {
1301cb0ef41Sopenharmony_ci    Callable callable = Builtins::CallableFor(isolate(), builtin_with_feedback);
1311cb0ef41Sopenharmony_ci    Node* slot = jsgraph()->UintPtrConstant(p.feedback().slot.ToInt());
1321cb0ef41Sopenharmony_ci    const CallInterfaceDescriptor& descriptor = callable.descriptor();
1331cb0ef41Sopenharmony_ci    CallDescriptor::Flags flags = FrameStateFlagForCall(node);
1341cb0ef41Sopenharmony_ci    auto call_descriptor = Linkage::GetStubCallDescriptor(
1351cb0ef41Sopenharmony_ci        zone(), descriptor, descriptor.GetStackParameterCount(), flags,
1361cb0ef41Sopenharmony_ci        node->op()->properties());
1371cb0ef41Sopenharmony_ci    Node* stub_code = jsgraph()->HeapConstant(callable.code());
1381cb0ef41Sopenharmony_ci    STATIC_ASSERT(JSUnaryOpNode::ValueIndex() == 0);
1391cb0ef41Sopenharmony_ci    STATIC_ASSERT(JSUnaryOpNode::FeedbackVectorIndex() == 1);
1401cb0ef41Sopenharmony_ci    DCHECK_EQ(node->op()->ValueInputCount(), 2);
1411cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 0, stub_code);
1421cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 2, slot);
1431cb0ef41Sopenharmony_ci    NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
1441cb0ef41Sopenharmony_ci  } else {
1451cb0ef41Sopenharmony_ci    node->RemoveInput(JSUnaryOpNode::FeedbackVectorIndex());
1461cb0ef41Sopenharmony_ci    ReplaceWithBuiltinCall(node, builtin_without_feedback);
1471cb0ef41Sopenharmony_ci  }
1481cb0ef41Sopenharmony_ci}
1491cb0ef41Sopenharmony_ci
1501cb0ef41Sopenharmony_ci#define DEF_UNARY_LOWERING(Name)                                    \
1511cb0ef41Sopenharmony_ci  void JSGenericLowering::LowerJS##Name(Node* node) {               \
1521cb0ef41Sopenharmony_ci    ReplaceUnaryOpWithBuiltinCall(node, Builtin::k##Name,           \
1531cb0ef41Sopenharmony_ci                                  Builtin::k##Name##_WithFeedback); \
1541cb0ef41Sopenharmony_ci  }
1551cb0ef41Sopenharmony_ciDEF_UNARY_LOWERING(BitwiseNot)
1561cb0ef41Sopenharmony_ciDEF_UNARY_LOWERING(Decrement)
1571cb0ef41Sopenharmony_ciDEF_UNARY_LOWERING(Increment)
1581cb0ef41Sopenharmony_ciDEF_UNARY_LOWERING(Negate)
1591cb0ef41Sopenharmony_ci#undef DEF_UNARY_LOWERING
1601cb0ef41Sopenharmony_ci
1611cb0ef41Sopenharmony_civoid JSGenericLowering::ReplaceBinaryOpWithBuiltinCall(
1621cb0ef41Sopenharmony_ci    Node* node, Builtin builtin_without_feedback,
1631cb0ef41Sopenharmony_ci    Builtin builtin_with_feedback) {
1641cb0ef41Sopenharmony_ci  DCHECK(JSOperator::IsBinaryWithFeedback(node->opcode()));
1651cb0ef41Sopenharmony_ci  Builtin builtin;
1661cb0ef41Sopenharmony_ci  const FeedbackParameter& p = FeedbackParameterOf(node->op());
1671cb0ef41Sopenharmony_ci  if (CollectFeedbackInGenericLowering() && p.feedback().IsValid()) {
1681cb0ef41Sopenharmony_ci    Node* slot = jsgraph()->UintPtrConstant(p.feedback().slot.ToInt());
1691cb0ef41Sopenharmony_ci    STATIC_ASSERT(JSBinaryOpNode::LeftIndex() == 0);
1701cb0ef41Sopenharmony_ci    STATIC_ASSERT(JSBinaryOpNode::RightIndex() == 1);
1711cb0ef41Sopenharmony_ci    STATIC_ASSERT(JSBinaryOpNode::FeedbackVectorIndex() == 2);
1721cb0ef41Sopenharmony_ci    DCHECK_EQ(node->op()->ValueInputCount(), 3);
1731cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 2, slot);
1741cb0ef41Sopenharmony_ci    builtin = builtin_with_feedback;
1751cb0ef41Sopenharmony_ci  } else {
1761cb0ef41Sopenharmony_ci    node->RemoveInput(JSBinaryOpNode::FeedbackVectorIndex());
1771cb0ef41Sopenharmony_ci    builtin = builtin_without_feedback;
1781cb0ef41Sopenharmony_ci  }
1791cb0ef41Sopenharmony_ci
1801cb0ef41Sopenharmony_ci  ReplaceWithBuiltinCall(node, builtin);
1811cb0ef41Sopenharmony_ci}
1821cb0ef41Sopenharmony_ci
1831cb0ef41Sopenharmony_ci#define DEF_BINARY_LOWERING(Name)                                    \
1841cb0ef41Sopenharmony_ci  void JSGenericLowering::LowerJS##Name(Node* node) {                \
1851cb0ef41Sopenharmony_ci    ReplaceBinaryOpWithBuiltinCall(node, Builtin::k##Name,           \
1861cb0ef41Sopenharmony_ci                                   Builtin::k##Name##_WithFeedback); \
1871cb0ef41Sopenharmony_ci  }
1881cb0ef41Sopenharmony_ci// Binary ops.
1891cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(Add)
1901cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(BitwiseAnd)
1911cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(BitwiseOr)
1921cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(BitwiseXor)
1931cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(Divide)
1941cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(Exponentiate)
1951cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(Modulus)
1961cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(Multiply)
1971cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(ShiftLeft)
1981cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(ShiftRight)
1991cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(ShiftRightLogical)
2001cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(Subtract)
2011cb0ef41Sopenharmony_ci// Compare ops.
2021cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(Equal)
2031cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(GreaterThan)
2041cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(GreaterThanOrEqual)
2051cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(InstanceOf)
2061cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(LessThan)
2071cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(LessThanOrEqual)
2081cb0ef41Sopenharmony_ci#undef DEF_BINARY_LOWERING
2091cb0ef41Sopenharmony_ci
2101cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSStrictEqual(Node* node) {
2111cb0ef41Sopenharmony_ci  // The === operator doesn't need the current context.
2121cb0ef41Sopenharmony_ci  NodeProperties::ReplaceContextInput(node, jsgraph()->NoContextConstant());
2131cb0ef41Sopenharmony_ci  DCHECK_EQ(node->op()->ControlInputCount(), 1);
2141cb0ef41Sopenharmony_ci  node->RemoveInput(NodeProperties::FirstControlIndex(node));
2151cb0ef41Sopenharmony_ci
2161cb0ef41Sopenharmony_ci  Builtin builtin;
2171cb0ef41Sopenharmony_ci  const FeedbackParameter& p = FeedbackParameterOf(node->op());
2181cb0ef41Sopenharmony_ci  if (CollectFeedbackInGenericLowering() && p.feedback().IsValid()) {
2191cb0ef41Sopenharmony_ci    Node* slot = jsgraph()->UintPtrConstant(p.feedback().slot.ToInt());
2201cb0ef41Sopenharmony_ci    STATIC_ASSERT(JSStrictEqualNode::LeftIndex() == 0);
2211cb0ef41Sopenharmony_ci    STATIC_ASSERT(JSStrictEqualNode::RightIndex() == 1);
2221cb0ef41Sopenharmony_ci    STATIC_ASSERT(JSStrictEqualNode::FeedbackVectorIndex() == 2);
2231cb0ef41Sopenharmony_ci    DCHECK_EQ(node->op()->ValueInputCount(), 3);
2241cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 2, slot);
2251cb0ef41Sopenharmony_ci    builtin = Builtin::kStrictEqual_WithFeedback;
2261cb0ef41Sopenharmony_ci  } else {
2271cb0ef41Sopenharmony_ci    node->RemoveInput(JSStrictEqualNode::FeedbackVectorIndex());
2281cb0ef41Sopenharmony_ci    builtin = Builtin::kStrictEqual;
2291cb0ef41Sopenharmony_ci  }
2301cb0ef41Sopenharmony_ci
2311cb0ef41Sopenharmony_ci  Callable callable = Builtins::CallableFor(isolate(), builtin);
2321cb0ef41Sopenharmony_ci  ReplaceWithBuiltinCall(node, callable, CallDescriptor::kNoFlags,
2331cb0ef41Sopenharmony_ci                         Operator::kEliminatable);
2341cb0ef41Sopenharmony_ci}
2351cb0ef41Sopenharmony_ci
2361cb0ef41Sopenharmony_cinamespace {
2371cb0ef41Sopenharmony_ci
2381cb0ef41Sopenharmony_ci// The megamorphic load builtin can be used as a performance optimization in
2391cb0ef41Sopenharmony_ci// some cases - unlike the full builtin, the megamorphic builtin does fewer
2401cb0ef41Sopenharmony_ci// checks and does not collect feedback.
2411cb0ef41Sopenharmony_cibool ShouldUseMegamorphicLoadBuiltin(FeedbackSource const& source,
2421cb0ef41Sopenharmony_ci                                     base::Optional<NameRef> name,
2431cb0ef41Sopenharmony_ci                                     JSHeapBroker* broker) {
2441cb0ef41Sopenharmony_ci  ProcessedFeedback const& feedback =
2451cb0ef41Sopenharmony_ci      broker->GetFeedbackForPropertyAccess(source, AccessMode::kLoad, name);
2461cb0ef41Sopenharmony_ci
2471cb0ef41Sopenharmony_ci  if (feedback.kind() == ProcessedFeedback::kElementAccess) {
2481cb0ef41Sopenharmony_ci    return feedback.AsElementAccess().transition_groups().empty();
2491cb0ef41Sopenharmony_ci  } else if (feedback.kind() == ProcessedFeedback::kNamedAccess) {
2501cb0ef41Sopenharmony_ci    return feedback.AsNamedAccess().maps().empty();
2511cb0ef41Sopenharmony_ci  } else if (feedback.kind() == ProcessedFeedback::kInsufficient) {
2521cb0ef41Sopenharmony_ci    return false;
2531cb0ef41Sopenharmony_ci  }
2541cb0ef41Sopenharmony_ci  UNREACHABLE();
2551cb0ef41Sopenharmony_ci}
2561cb0ef41Sopenharmony_ci
2571cb0ef41Sopenharmony_ci}  // namespace
2581cb0ef41Sopenharmony_ci
2591cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSHasProperty(Node* node) {
2601cb0ef41Sopenharmony_ci  JSHasPropertyNode n(node);
2611cb0ef41Sopenharmony_ci  const PropertyAccess& p = n.Parameters();
2621cb0ef41Sopenharmony_ci  if (!p.feedback().IsValid()) {
2631cb0ef41Sopenharmony_ci    node->RemoveInput(JSHasPropertyNode::FeedbackVectorIndex());
2641cb0ef41Sopenharmony_ci    ReplaceWithBuiltinCall(node, Builtin::kHasProperty);
2651cb0ef41Sopenharmony_ci  } else {
2661cb0ef41Sopenharmony_ci    STATIC_ASSERT(n.FeedbackVectorIndex() == 2);
2671cb0ef41Sopenharmony_ci    n->InsertInput(zone(), 2,
2681cb0ef41Sopenharmony_ci                   jsgraph()->TaggedIndexConstant(p.feedback().index()));
2691cb0ef41Sopenharmony_ci    ReplaceWithBuiltinCall(node, Builtin::kKeyedHasIC);
2701cb0ef41Sopenharmony_ci  }
2711cb0ef41Sopenharmony_ci}
2721cb0ef41Sopenharmony_ci
2731cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSLoadProperty(Node* node) {
2741cb0ef41Sopenharmony_ci  JSLoadPropertyNode n(node);
2751cb0ef41Sopenharmony_ci  const PropertyAccess& p = n.Parameters();
2761cb0ef41Sopenharmony_ci  FrameState frame_state = n.frame_state();
2771cb0ef41Sopenharmony_ci  Node* outer_state = frame_state.outer_frame_state();
2781cb0ef41Sopenharmony_ci  STATIC_ASSERT(n.FeedbackVectorIndex() == 2);
2791cb0ef41Sopenharmony_ci  if (outer_state->opcode() != IrOpcode::kFrameState) {
2801cb0ef41Sopenharmony_ci    n->RemoveInput(n.FeedbackVectorIndex());
2811cb0ef41Sopenharmony_ci    n->InsertInput(zone(), 2,
2821cb0ef41Sopenharmony_ci                   jsgraph()->TaggedIndexConstant(p.feedback().index()));
2831cb0ef41Sopenharmony_ci    ReplaceWithBuiltinCall(
2841cb0ef41Sopenharmony_ci        node, ShouldUseMegamorphicLoadBuiltin(p.feedback(), {}, broker())
2851cb0ef41Sopenharmony_ci                  ? Builtin::kKeyedLoadICTrampoline_Megamorphic
2861cb0ef41Sopenharmony_ci                  : Builtin::kKeyedLoadICTrampoline);
2871cb0ef41Sopenharmony_ci  } else {
2881cb0ef41Sopenharmony_ci    n->InsertInput(zone(), 2,
2891cb0ef41Sopenharmony_ci                   jsgraph()->TaggedIndexConstant(p.feedback().index()));
2901cb0ef41Sopenharmony_ci    ReplaceWithBuiltinCall(
2911cb0ef41Sopenharmony_ci        node, ShouldUseMegamorphicLoadBuiltin(p.feedback(), {}, broker())
2921cb0ef41Sopenharmony_ci                  ? Builtin::kKeyedLoadIC_Megamorphic
2931cb0ef41Sopenharmony_ci                  : Builtin::kKeyedLoadIC);
2941cb0ef41Sopenharmony_ci  }
2951cb0ef41Sopenharmony_ci}
2961cb0ef41Sopenharmony_ci
2971cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSLoadNamed(Node* node) {
2981cb0ef41Sopenharmony_ci  JSLoadNamedNode n(node);
2991cb0ef41Sopenharmony_ci  NamedAccess const& p = n.Parameters();
3001cb0ef41Sopenharmony_ci  FrameState frame_state = n.frame_state();
3011cb0ef41Sopenharmony_ci  Node* outer_state = frame_state.outer_frame_state();
3021cb0ef41Sopenharmony_ci  STATIC_ASSERT(n.FeedbackVectorIndex() == 1);
3031cb0ef41Sopenharmony_ci  if (!p.feedback().IsValid()) {
3041cb0ef41Sopenharmony_ci    n->RemoveInput(n.FeedbackVectorIndex());
3051cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 1, jsgraph()->Constant(p.name(broker())));
3061cb0ef41Sopenharmony_ci    ReplaceWithBuiltinCall(node, Builtin::kGetProperty);
3071cb0ef41Sopenharmony_ci  } else if (outer_state->opcode() != IrOpcode::kFrameState) {
3081cb0ef41Sopenharmony_ci    n->RemoveInput(n.FeedbackVectorIndex());
3091cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 1, jsgraph()->Constant(p.name(broker())));
3101cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 2,
3111cb0ef41Sopenharmony_ci                      jsgraph()->TaggedIndexConstant(p.feedback().index()));
3121cb0ef41Sopenharmony_ci    ReplaceWithBuiltinCall(node, ShouldUseMegamorphicLoadBuiltin(
3131cb0ef41Sopenharmony_ci                                     p.feedback(), p.name(broker()), broker())
3141cb0ef41Sopenharmony_ci                                     ? Builtin::kLoadICTrampoline_Megamorphic
3151cb0ef41Sopenharmony_ci                                     : Builtin::kLoadICTrampoline);
3161cb0ef41Sopenharmony_ci  } else {
3171cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 1, jsgraph()->Constant(p.name(broker())));
3181cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 2,
3191cb0ef41Sopenharmony_ci                      jsgraph()->TaggedIndexConstant(p.feedback().index()));
3201cb0ef41Sopenharmony_ci    ReplaceWithBuiltinCall(node, ShouldUseMegamorphicLoadBuiltin(
3211cb0ef41Sopenharmony_ci                                     p.feedback(), p.name(broker()), broker())
3221cb0ef41Sopenharmony_ci                                     ? Builtin::kLoadIC_Megamorphic
3231cb0ef41Sopenharmony_ci                                     : Builtin::kLoadIC);
3241cb0ef41Sopenharmony_ci  }
3251cb0ef41Sopenharmony_ci}
3261cb0ef41Sopenharmony_ci
3271cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSLoadNamedFromSuper(Node* node) {
3281cb0ef41Sopenharmony_ci  JSLoadNamedFromSuperNode n(node);
3291cb0ef41Sopenharmony_ci  NamedAccess const& p = n.Parameters();
3301cb0ef41Sopenharmony_ci  Node* effect = NodeProperties::GetEffectInput(node);
3311cb0ef41Sopenharmony_ci  Node* control = NodeProperties::GetControlInput(node);
3321cb0ef41Sopenharmony_ci  // Node inputs: receiver, home object, FeedbackVector.
3331cb0ef41Sopenharmony_ci  // LoadSuperIC expects: receiver, lookup start object, name, slot,
3341cb0ef41Sopenharmony_ci  // FeedbackVector.
3351cb0ef41Sopenharmony_ci  Node* home_object_map = effect = graph()->NewNode(
3361cb0ef41Sopenharmony_ci      jsgraph()->simplified()->LoadField(AccessBuilder::ForMap()),
3371cb0ef41Sopenharmony_ci      n.home_object(), effect, control);
3381cb0ef41Sopenharmony_ci  Node* home_object_proto = effect = graph()->NewNode(
3391cb0ef41Sopenharmony_ci      jsgraph()->simplified()->LoadField(AccessBuilder::ForMapPrototype()),
3401cb0ef41Sopenharmony_ci      home_object_map, effect, control);
3411cb0ef41Sopenharmony_ci  n->ReplaceInput(n.HomeObjectIndex(), home_object_proto);
3421cb0ef41Sopenharmony_ci  NodeProperties::ReplaceEffectInput(node, effect);
3431cb0ef41Sopenharmony_ci  STATIC_ASSERT(n.FeedbackVectorIndex() == 2);
3441cb0ef41Sopenharmony_ci  // If the code below will be used for the invalid feedback case, it needs to
3451cb0ef41Sopenharmony_ci  // be double-checked that the FeedbackVector parameter will be the
3461cb0ef41Sopenharmony_ci  // UndefinedConstant.
3471cb0ef41Sopenharmony_ci  DCHECK(p.feedback().IsValid());
3481cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 2, jsgraph()->Constant(p.name(broker())));
3491cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 3,
3501cb0ef41Sopenharmony_ci                    jsgraph()->TaggedIndexConstant(p.feedback().index()));
3511cb0ef41Sopenharmony_ci  ReplaceWithBuiltinCall(node, Builtin::kLoadSuperIC);
3521cb0ef41Sopenharmony_ci}
3531cb0ef41Sopenharmony_ci
3541cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSLoadGlobal(Node* node) {
3551cb0ef41Sopenharmony_ci  JSLoadGlobalNode n(node);
3561cb0ef41Sopenharmony_ci  const LoadGlobalParameters& p = n.Parameters();
3571cb0ef41Sopenharmony_ci  CallDescriptor::Flags flags = FrameStateFlagForCall(node);
3581cb0ef41Sopenharmony_ci  FrameState frame_state = n.frame_state();
3591cb0ef41Sopenharmony_ci  Node* outer_state = frame_state.outer_frame_state();
3601cb0ef41Sopenharmony_ci  STATIC_ASSERT(n.FeedbackVectorIndex() == 0);
3611cb0ef41Sopenharmony_ci  if (outer_state->opcode() != IrOpcode::kFrameState) {
3621cb0ef41Sopenharmony_ci    n->RemoveInput(n.FeedbackVectorIndex());
3631cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 0, jsgraph()->Constant(p.name(broker())));
3641cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 1,
3651cb0ef41Sopenharmony_ci                      jsgraph()->TaggedIndexConstant(p.feedback().index()));
3661cb0ef41Sopenharmony_ci    Callable callable = CodeFactory::LoadGlobalIC(isolate(), p.typeof_mode());
3671cb0ef41Sopenharmony_ci    ReplaceWithBuiltinCall(node, callable, flags);
3681cb0ef41Sopenharmony_ci  } else {
3691cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 0, jsgraph()->Constant(p.name(broker())));
3701cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 1,
3711cb0ef41Sopenharmony_ci                      jsgraph()->TaggedIndexConstant(p.feedback().index()));
3721cb0ef41Sopenharmony_ci    Callable callable =
3731cb0ef41Sopenharmony_ci        CodeFactory::LoadGlobalICInOptimizedCode(isolate(), p.typeof_mode());
3741cb0ef41Sopenharmony_ci    ReplaceWithBuiltinCall(node, callable, flags);
3751cb0ef41Sopenharmony_ci  }
3761cb0ef41Sopenharmony_ci}
3771cb0ef41Sopenharmony_ci
3781cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSGetIterator(Node* node) {
3791cb0ef41Sopenharmony_ci  // TODO(v8:9625): Currently, the GetIterator operator is desugared in the
3801cb0ef41Sopenharmony_ci  // native context specialization phase. Thus, the following generic lowering
3811cb0ef41Sopenharmony_ci  // is not reachable unless that phase is disabled (e.g. for
3821cb0ef41Sopenharmony_ci  // native-context-independent code).
3831cb0ef41Sopenharmony_ci  // We can add a check in native context specialization to avoid desugaring
3841cb0ef41Sopenharmony_ci  // the GetIterator operator when feedback is megamorphic. This would reduce
3851cb0ef41Sopenharmony_ci  // the size of the compiled code as it would insert 1 call to the builtin
3861cb0ef41Sopenharmony_ci  // instead of 2 calls resulting from the generic lowering of the LoadNamed
3871cb0ef41Sopenharmony_ci  // and Call operators.
3881cb0ef41Sopenharmony_ci
3891cb0ef41Sopenharmony_ci  JSGetIteratorNode n(node);
3901cb0ef41Sopenharmony_ci  GetIteratorParameters const& p = n.Parameters();
3911cb0ef41Sopenharmony_ci  Node* load_slot =
3921cb0ef41Sopenharmony_ci      jsgraph()->TaggedIndexConstant(p.loadFeedback().slot.ToInt());
3931cb0ef41Sopenharmony_ci  Node* call_slot =
3941cb0ef41Sopenharmony_ci      jsgraph()->TaggedIndexConstant(p.callFeedback().slot.ToInt());
3951cb0ef41Sopenharmony_ci  STATIC_ASSERT(n.FeedbackVectorIndex() == 1);
3961cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 1, load_slot);
3971cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 2, call_slot);
3981cb0ef41Sopenharmony_ci
3991cb0ef41Sopenharmony_ci  ReplaceWithBuiltinCall(node, Builtin::kGetIteratorWithFeedback);
4001cb0ef41Sopenharmony_ci}
4011cb0ef41Sopenharmony_ci
4021cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSSetKeyedProperty(Node* node) {
4031cb0ef41Sopenharmony_ci  JSSetKeyedPropertyNode n(node);
4041cb0ef41Sopenharmony_ci  const PropertyAccess& p = n.Parameters();
4051cb0ef41Sopenharmony_ci  FrameState frame_state = n.frame_state();
4061cb0ef41Sopenharmony_ci  Node* outer_state = frame_state.outer_frame_state();
4071cb0ef41Sopenharmony_ci  STATIC_ASSERT(n.FeedbackVectorIndex() == 3);
4081cb0ef41Sopenharmony_ci  if (outer_state->opcode() != IrOpcode::kFrameState) {
4091cb0ef41Sopenharmony_ci    n->RemoveInput(n.FeedbackVectorIndex());
4101cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 3,
4111cb0ef41Sopenharmony_ci                      jsgraph()->TaggedIndexConstant(p.feedback().index()));
4121cb0ef41Sopenharmony_ci
4131cb0ef41Sopenharmony_ci    // KeyedStoreIC is currently a base class for multiple keyed property store
4141cb0ef41Sopenharmony_ci    // operations and contains mixed logic for set and define operations,
4151cb0ef41Sopenharmony_ci    // the paths are controlled by feedback.
4161cb0ef41Sopenharmony_ci    // TODO(v8:12548): refactor SetKeyedIC as a subclass of KeyedStoreIC, which
4171cb0ef41Sopenharmony_ci    // can be called here.
4181cb0ef41Sopenharmony_ci    ReplaceWithBuiltinCall(node, Builtin::kKeyedStoreICTrampoline);
4191cb0ef41Sopenharmony_ci  } else {
4201cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 3,
4211cb0ef41Sopenharmony_ci                      jsgraph()->TaggedIndexConstant(p.feedback().index()));
4221cb0ef41Sopenharmony_ci    ReplaceWithBuiltinCall(node, Builtin::kKeyedStoreIC);
4231cb0ef41Sopenharmony_ci  }
4241cb0ef41Sopenharmony_ci}
4251cb0ef41Sopenharmony_ci
4261cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSDefineKeyedOwnProperty(Node* node) {
4271cb0ef41Sopenharmony_ci  JSDefineKeyedOwnPropertyNode n(node);
4281cb0ef41Sopenharmony_ci  const PropertyAccess& p = n.Parameters();
4291cb0ef41Sopenharmony_ci  FrameState frame_state = n.frame_state();
4301cb0ef41Sopenharmony_ci  Node* outer_state = frame_state.outer_frame_state();
4311cb0ef41Sopenharmony_ci  STATIC_ASSERT(n.FeedbackVectorIndex() == 3);
4321cb0ef41Sopenharmony_ci  if (outer_state->opcode() != IrOpcode::kFrameState) {
4331cb0ef41Sopenharmony_ci    n->RemoveInput(n.FeedbackVectorIndex());
4341cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 3,
4351cb0ef41Sopenharmony_ci                      jsgraph()->TaggedIndexConstant(p.feedback().index()));
4361cb0ef41Sopenharmony_ci    ReplaceWithBuiltinCall(node, Builtin::kDefineKeyedOwnICTrampoline);
4371cb0ef41Sopenharmony_ci  } else {
4381cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 3,
4391cb0ef41Sopenharmony_ci                      jsgraph()->TaggedIndexConstant(p.feedback().index()));
4401cb0ef41Sopenharmony_ci    ReplaceWithBuiltinCall(node, Builtin::kDefineKeyedOwnIC);
4411cb0ef41Sopenharmony_ci  }
4421cb0ef41Sopenharmony_ci}
4431cb0ef41Sopenharmony_ci
4441cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSSetNamedProperty(Node* node) {
4451cb0ef41Sopenharmony_ci  JSSetNamedPropertyNode n(node);
4461cb0ef41Sopenharmony_ci  NamedAccess const& p = n.Parameters();
4471cb0ef41Sopenharmony_ci  FrameState frame_state = n.frame_state();
4481cb0ef41Sopenharmony_ci  Node* outer_state = frame_state.outer_frame_state();
4491cb0ef41Sopenharmony_ci  STATIC_ASSERT(n.FeedbackVectorIndex() == 2);
4501cb0ef41Sopenharmony_ci  if (!p.feedback().IsValid()) {
4511cb0ef41Sopenharmony_ci    n->RemoveInput(n.FeedbackVectorIndex());
4521cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 1, jsgraph()->Constant(p.name(broker())));
4531cb0ef41Sopenharmony_ci    ReplaceWithRuntimeCall(node, Runtime::kSetNamedProperty);
4541cb0ef41Sopenharmony_ci  } else if (outer_state->opcode() != IrOpcode::kFrameState) {
4551cb0ef41Sopenharmony_ci    n->RemoveInput(n.FeedbackVectorIndex());
4561cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 1, jsgraph()->Constant(p.name(broker())));
4571cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 3,
4581cb0ef41Sopenharmony_ci                      jsgraph()->TaggedIndexConstant(p.feedback().index()));
4591cb0ef41Sopenharmony_ci    // StoreIC is currently a base class for multiple property store operations
4601cb0ef41Sopenharmony_ci    // and contains mixed logic for named and keyed, set and define operations,
4611cb0ef41Sopenharmony_ci    // the paths are controlled by feedback.
4621cb0ef41Sopenharmony_ci    // TODO(v8:12548): refactor SetNamedIC as a subclass of StoreIC, which can
4631cb0ef41Sopenharmony_ci    // be called here.
4641cb0ef41Sopenharmony_ci    ReplaceWithBuiltinCall(node, Builtin::kStoreICTrampoline);
4651cb0ef41Sopenharmony_ci  } else {
4661cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 1, jsgraph()->Constant(p.name(broker())));
4671cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 3,
4681cb0ef41Sopenharmony_ci                      jsgraph()->TaggedIndexConstant(p.feedback().index()));
4691cb0ef41Sopenharmony_ci    ReplaceWithBuiltinCall(node, Builtin::kStoreIC);
4701cb0ef41Sopenharmony_ci  }
4711cb0ef41Sopenharmony_ci}
4721cb0ef41Sopenharmony_ci
4731cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSDefineNamedOwnProperty(Node* node) {
4741cb0ef41Sopenharmony_ci  CallDescriptor::Flags flags = FrameStateFlagForCall(node);
4751cb0ef41Sopenharmony_ci  JSDefineNamedOwnPropertyNode n(node);
4761cb0ef41Sopenharmony_ci  DefineNamedOwnPropertyParameters const& p = n.Parameters();
4771cb0ef41Sopenharmony_ci  FrameState frame_state = n.frame_state();
4781cb0ef41Sopenharmony_ci  Node* outer_state = frame_state.outer_frame_state();
4791cb0ef41Sopenharmony_ci  STATIC_ASSERT(n.FeedbackVectorIndex() == 2);
4801cb0ef41Sopenharmony_ci  if (outer_state->opcode() != IrOpcode::kFrameState) {
4811cb0ef41Sopenharmony_ci    n->RemoveInput(n.FeedbackVectorIndex());
4821cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 1, jsgraph()->Constant(p.name(broker())));
4831cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 3,
4841cb0ef41Sopenharmony_ci                      jsgraph()->TaggedIndexConstant(p.feedback().index()));
4851cb0ef41Sopenharmony_ci    Callable callable = CodeFactory::DefineNamedOwnIC(isolate());
4861cb0ef41Sopenharmony_ci    ReplaceWithBuiltinCall(node, callable, flags);
4871cb0ef41Sopenharmony_ci  } else {
4881cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 1, jsgraph()->Constant(p.name(broker())));
4891cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 3,
4901cb0ef41Sopenharmony_ci                      jsgraph()->TaggedIndexConstant(p.feedback().index()));
4911cb0ef41Sopenharmony_ci    Callable callable = CodeFactory::DefineNamedOwnICInOptimizedCode(isolate());
4921cb0ef41Sopenharmony_ci    ReplaceWithBuiltinCall(node, callable, flags);
4931cb0ef41Sopenharmony_ci  }
4941cb0ef41Sopenharmony_ci}
4951cb0ef41Sopenharmony_ci
4961cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSStoreGlobal(Node* node) {
4971cb0ef41Sopenharmony_ci  JSStoreGlobalNode n(node);
4981cb0ef41Sopenharmony_ci  const StoreGlobalParameters& p = n.Parameters();
4991cb0ef41Sopenharmony_ci  FrameState frame_state = n.frame_state();
5001cb0ef41Sopenharmony_ci  Node* outer_state = frame_state.outer_frame_state();
5011cb0ef41Sopenharmony_ci  STATIC_ASSERT(n.FeedbackVectorIndex() == 1);
5021cb0ef41Sopenharmony_ci  if (outer_state->opcode() != IrOpcode::kFrameState) {
5031cb0ef41Sopenharmony_ci    n->RemoveInput(n.FeedbackVectorIndex());
5041cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 0, jsgraph()->Constant(p.name(broker())));
5051cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 2,
5061cb0ef41Sopenharmony_ci                      jsgraph()->TaggedIndexConstant(p.feedback().index()));
5071cb0ef41Sopenharmony_ci    ReplaceWithBuiltinCall(node, Builtin::kStoreGlobalICTrampoline);
5081cb0ef41Sopenharmony_ci  } else {
5091cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 0, jsgraph()->Constant(p.name(broker())));
5101cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 2,
5111cb0ef41Sopenharmony_ci                      jsgraph()->TaggedIndexConstant(p.feedback().index()));
5121cb0ef41Sopenharmony_ci    ReplaceWithBuiltinCall(node, Builtin::kStoreGlobalIC);
5131cb0ef41Sopenharmony_ci  }
5141cb0ef41Sopenharmony_ci}
5151cb0ef41Sopenharmony_ci
5161cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSDefineKeyedOwnPropertyInLiteral(Node* node) {
5171cb0ef41Sopenharmony_ci  JSDefineKeyedOwnPropertyInLiteralNode n(node);
5181cb0ef41Sopenharmony_ci  FeedbackParameter const& p = n.Parameters();
5191cb0ef41Sopenharmony_ci  STATIC_ASSERT(n.FeedbackVectorIndex() == 4);
5201cb0ef41Sopenharmony_ci  RelaxControls(node);
5211cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 5,
5221cb0ef41Sopenharmony_ci                    jsgraph()->TaggedIndexConstant(p.feedback().index()));
5231cb0ef41Sopenharmony_ci  ReplaceWithRuntimeCall(node, Runtime::kDefineKeyedOwnPropertyInLiteral);
5241cb0ef41Sopenharmony_ci}
5251cb0ef41Sopenharmony_ci
5261cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSStoreInArrayLiteral(Node* node) {
5271cb0ef41Sopenharmony_ci  JSStoreInArrayLiteralNode n(node);
5281cb0ef41Sopenharmony_ci  FeedbackParameter const& p = n.Parameters();
5291cb0ef41Sopenharmony_ci  STATIC_ASSERT(n.FeedbackVectorIndex() == 3);
5301cb0ef41Sopenharmony_ci  RelaxControls(node);
5311cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 3,
5321cb0ef41Sopenharmony_ci                    jsgraph()->TaggedIndexConstant(p.feedback().index()));
5331cb0ef41Sopenharmony_ci  ReplaceWithBuiltinCall(node, Builtin::kStoreInArrayLiteralIC);
5341cb0ef41Sopenharmony_ci}
5351cb0ef41Sopenharmony_ci
5361cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSDeleteProperty(Node* node) {
5371cb0ef41Sopenharmony_ci  ReplaceWithBuiltinCall(node, Builtin::kDeleteProperty);
5381cb0ef41Sopenharmony_ci}
5391cb0ef41Sopenharmony_ci
5401cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSGetSuperConstructor(Node* node) {
5411cb0ef41Sopenharmony_ci  Node* active_function = NodeProperties::GetValueInput(node, 0);
5421cb0ef41Sopenharmony_ci  Node* effect = NodeProperties::GetEffectInput(node);
5431cb0ef41Sopenharmony_ci  Node* control = NodeProperties::GetControlInput(node);
5441cb0ef41Sopenharmony_ci
5451cb0ef41Sopenharmony_ci  Node* function_map = effect = graph()->NewNode(
5461cb0ef41Sopenharmony_ci      jsgraph()->simplified()->LoadField(AccessBuilder::ForMap()),
5471cb0ef41Sopenharmony_ci      active_function, effect, control);
5481cb0ef41Sopenharmony_ci
5491cb0ef41Sopenharmony_ci  RelaxControls(node);
5501cb0ef41Sopenharmony_ci  node->ReplaceInput(0, function_map);
5511cb0ef41Sopenharmony_ci  node->ReplaceInput(1, effect);
5521cb0ef41Sopenharmony_ci  node->ReplaceInput(2, control);
5531cb0ef41Sopenharmony_ci  node->TrimInputCount(3);
5541cb0ef41Sopenharmony_ci  NodeProperties::ChangeOp(node, jsgraph()->simplified()->LoadField(
5551cb0ef41Sopenharmony_ci                                     AccessBuilder::ForMapPrototype()));
5561cb0ef41Sopenharmony_ci}
5571cb0ef41Sopenharmony_ci
5581cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSHasInPrototypeChain(Node* node) {
5591cb0ef41Sopenharmony_ci  ReplaceWithRuntimeCall(node, Runtime::kHasInPrototypeChain);
5601cb0ef41Sopenharmony_ci}
5611cb0ef41Sopenharmony_ci
5621cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSOrdinaryHasInstance(Node* node) {
5631cb0ef41Sopenharmony_ci  ReplaceWithBuiltinCall(node, Builtin::kOrdinaryHasInstance);
5641cb0ef41Sopenharmony_ci}
5651cb0ef41Sopenharmony_ci
5661cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSHasContextExtension(Node* node) {
5671cb0ef41Sopenharmony_ci  UNREACHABLE();  // Eliminated in typed lowering.
5681cb0ef41Sopenharmony_ci}
5691cb0ef41Sopenharmony_ci
5701cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSLoadContext(Node* node) {
5711cb0ef41Sopenharmony_ci  UNREACHABLE();  // Eliminated in typed lowering.
5721cb0ef41Sopenharmony_ci}
5731cb0ef41Sopenharmony_ci
5741cb0ef41Sopenharmony_ci
5751cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSStoreContext(Node* node) {
5761cb0ef41Sopenharmony_ci  UNREACHABLE();  // Eliminated in typed lowering.
5771cb0ef41Sopenharmony_ci}
5781cb0ef41Sopenharmony_ci
5791cb0ef41Sopenharmony_ci
5801cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreate(Node* node) {
5811cb0ef41Sopenharmony_ci  ReplaceWithBuiltinCall(node, Builtin::kFastNewObject);
5821cb0ef41Sopenharmony_ci}
5831cb0ef41Sopenharmony_ci
5841cb0ef41Sopenharmony_ci
5851cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateArguments(Node* node) {
5861cb0ef41Sopenharmony_ci  CreateArgumentsType const type = CreateArgumentsTypeOf(node->op());
5871cb0ef41Sopenharmony_ci  switch (type) {
5881cb0ef41Sopenharmony_ci    case CreateArgumentsType::kMappedArguments:
5891cb0ef41Sopenharmony_ci      ReplaceWithRuntimeCall(node, Runtime::kNewSloppyArguments);
5901cb0ef41Sopenharmony_ci      break;
5911cb0ef41Sopenharmony_ci    case CreateArgumentsType::kUnmappedArguments:
5921cb0ef41Sopenharmony_ci      ReplaceWithRuntimeCall(node, Runtime::kNewStrictArguments);
5931cb0ef41Sopenharmony_ci      break;
5941cb0ef41Sopenharmony_ci    case CreateArgumentsType::kRestParameter:
5951cb0ef41Sopenharmony_ci      ReplaceWithRuntimeCall(node, Runtime::kNewRestParameter);
5961cb0ef41Sopenharmony_ci      break;
5971cb0ef41Sopenharmony_ci  }
5981cb0ef41Sopenharmony_ci}
5991cb0ef41Sopenharmony_ci
6001cb0ef41Sopenharmony_ci
6011cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateArray(Node* node) {
6021cb0ef41Sopenharmony_ci  CreateArrayParameters const& p = CreateArrayParametersOf(node->op());
6031cb0ef41Sopenharmony_ci  int const arity = static_cast<int>(p.arity());
6041cb0ef41Sopenharmony_ci  auto interface_descriptor = ArrayConstructorDescriptor{};
6051cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
6061cb0ef41Sopenharmony_ci      zone(), interface_descriptor, arity + 1, CallDescriptor::kNeedsFrameState,
6071cb0ef41Sopenharmony_ci      node->op()->properties());
6081cb0ef41Sopenharmony_ci  // If this fails, we might need to update the parameter reordering code
6091cb0ef41Sopenharmony_ci  // to ensure that the additional arguments passed via stack are pushed
6101cb0ef41Sopenharmony_ci  // between top of stack and JS arguments.
6111cb0ef41Sopenharmony_ci  DCHECK_EQ(interface_descriptor.GetStackParameterCount(), 0);
6121cb0ef41Sopenharmony_ci  Node* stub_code = jsgraph()->ArrayConstructorStubConstant();
6131cb0ef41Sopenharmony_ci  Node* stub_arity = jsgraph()->Int32Constant(JSParameterCount(arity));
6141cb0ef41Sopenharmony_ci  base::Optional<AllocationSiteRef> const site = p.site(broker());
6151cb0ef41Sopenharmony_ci  Node* type_info = site.has_value() ? jsgraph()->Constant(site.value())
6161cb0ef41Sopenharmony_ci                                     : jsgraph()->UndefinedConstant();
6171cb0ef41Sopenharmony_ci  Node* receiver = jsgraph()->UndefinedConstant();
6181cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 0, stub_code);
6191cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 3, stub_arity);
6201cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 4, type_info);
6211cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 5, receiver);
6221cb0ef41Sopenharmony_ci  NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
6231cb0ef41Sopenharmony_ci}
6241cb0ef41Sopenharmony_ci
6251cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateArrayIterator(Node* node) {
6261cb0ef41Sopenharmony_ci  UNREACHABLE();  // Eliminated in typed lowering.
6271cb0ef41Sopenharmony_ci}
6281cb0ef41Sopenharmony_ci
6291cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateAsyncFunctionObject(Node* node) {
6301cb0ef41Sopenharmony_ci  UNREACHABLE();  // Eliminated in typed lowering.
6311cb0ef41Sopenharmony_ci}
6321cb0ef41Sopenharmony_ci
6331cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateCollectionIterator(Node* node) {
6341cb0ef41Sopenharmony_ci  UNREACHABLE();  // Eliminated in typed lowering.
6351cb0ef41Sopenharmony_ci}
6361cb0ef41Sopenharmony_ci
6371cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateBoundFunction(Node* node) {
6381cb0ef41Sopenharmony_ci  UNREACHABLE();  // Eliminated in typed lowering.
6391cb0ef41Sopenharmony_ci}
6401cb0ef41Sopenharmony_ci
6411cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSObjectIsArray(Node* node) {
6421cb0ef41Sopenharmony_ci  UNREACHABLE();  // Eliminated in typed lowering.
6431cb0ef41Sopenharmony_ci}
6441cb0ef41Sopenharmony_ci
6451cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateObject(Node* node) {
6461cb0ef41Sopenharmony_ci  ReplaceWithBuiltinCall(node, Builtin::kCreateObjectWithoutProperties);
6471cb0ef41Sopenharmony_ci}
6481cb0ef41Sopenharmony_ci
6491cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSParseInt(Node* node) {
6501cb0ef41Sopenharmony_ci  ReplaceWithBuiltinCall(node, Builtin::kParseInt);
6511cb0ef41Sopenharmony_ci}
6521cb0ef41Sopenharmony_ci
6531cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSRegExpTest(Node* node) {
6541cb0ef41Sopenharmony_ci  ReplaceWithBuiltinCall(node, Builtin::kRegExpPrototypeTestFast);
6551cb0ef41Sopenharmony_ci}
6561cb0ef41Sopenharmony_ci
6571cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateClosure(Node* node) {
6581cb0ef41Sopenharmony_ci  JSCreateClosureNode n(node);
6591cb0ef41Sopenharmony_ci  CreateClosureParameters const& p = n.Parameters();
6601cb0ef41Sopenharmony_ci  SharedFunctionInfoRef shared_info = p.shared_info(broker());
6611cb0ef41Sopenharmony_ci  STATIC_ASSERT(n.FeedbackCellIndex() == 0);
6621cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 0, jsgraph()->Constant(shared_info));
6631cb0ef41Sopenharmony_ci  node->RemoveInput(4);  // control
6641cb0ef41Sopenharmony_ci
6651cb0ef41Sopenharmony_ci  // Use the FastNewClosure builtin only for functions allocated in new space.
6661cb0ef41Sopenharmony_ci  if (p.allocation() == AllocationType::kYoung) {
6671cb0ef41Sopenharmony_ci    ReplaceWithBuiltinCall(node, Builtin::kFastNewClosure);
6681cb0ef41Sopenharmony_ci  } else {
6691cb0ef41Sopenharmony_ci    ReplaceWithRuntimeCall(node, Runtime::kNewClosure_Tenured);
6701cb0ef41Sopenharmony_ci  }
6711cb0ef41Sopenharmony_ci}
6721cb0ef41Sopenharmony_ci
6731cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateFunctionContext(Node* node) {
6741cb0ef41Sopenharmony_ci  const CreateFunctionContextParameters& parameters =
6751cb0ef41Sopenharmony_ci      CreateFunctionContextParametersOf(node->op());
6761cb0ef41Sopenharmony_ci  ScopeInfoRef scope_info = parameters.scope_info(broker());
6771cb0ef41Sopenharmony_ci  int slot_count = parameters.slot_count();
6781cb0ef41Sopenharmony_ci  ScopeType scope_type = parameters.scope_type();
6791cb0ef41Sopenharmony_ci  CallDescriptor::Flags flags = FrameStateFlagForCall(node);
6801cb0ef41Sopenharmony_ci
6811cb0ef41Sopenharmony_ci  if (slot_count <= ConstructorBuiltins::MaximumFunctionContextSlots()) {
6821cb0ef41Sopenharmony_ci    Callable callable =
6831cb0ef41Sopenharmony_ci        CodeFactory::FastNewFunctionContext(isolate(), scope_type);
6841cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 0, jsgraph()->Constant(scope_info));
6851cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 1, jsgraph()->Int32Constant(slot_count));
6861cb0ef41Sopenharmony_ci    ReplaceWithBuiltinCall(node, callable, flags);
6871cb0ef41Sopenharmony_ci  } else {
6881cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 0, jsgraph()->Constant(scope_info));
6891cb0ef41Sopenharmony_ci    ReplaceWithRuntimeCall(node, Runtime::kNewFunctionContext);
6901cb0ef41Sopenharmony_ci  }
6911cb0ef41Sopenharmony_ci}
6921cb0ef41Sopenharmony_ci
6931cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateGeneratorObject(Node* node) {
6941cb0ef41Sopenharmony_ci  node->RemoveInput(4);  // control
6951cb0ef41Sopenharmony_ci  ReplaceWithBuiltinCall(node, Builtin::kCreateGeneratorObject);
6961cb0ef41Sopenharmony_ci}
6971cb0ef41Sopenharmony_ci
6981cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateIterResultObject(Node* node) {
6991cb0ef41Sopenharmony_ci  ReplaceWithBuiltinCall(node, Builtin::kCreateIterResultObject);
7001cb0ef41Sopenharmony_ci}
7011cb0ef41Sopenharmony_ci
7021cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateStringIterator(Node* node) {
7031cb0ef41Sopenharmony_ci  UNREACHABLE();  // Eliminated in typed lowering.
7041cb0ef41Sopenharmony_ci}
7051cb0ef41Sopenharmony_ci
7061cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateKeyValueArray(Node* node) {
7071cb0ef41Sopenharmony_ci  UNREACHABLE();  // Eliminated in typed lowering.
7081cb0ef41Sopenharmony_ci}
7091cb0ef41Sopenharmony_ci
7101cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreatePromise(Node* node) {
7111cb0ef41Sopenharmony_ci  UNREACHABLE();  // Eliminated in typed lowering.
7121cb0ef41Sopenharmony_ci}
7131cb0ef41Sopenharmony_ci
7141cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateTypedArray(Node* node) {
7151cb0ef41Sopenharmony_ci  ReplaceWithBuiltinCall(node, Builtin::kCreateTypedArray);
7161cb0ef41Sopenharmony_ci}
7171cb0ef41Sopenharmony_ci
7181cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateLiteralArray(Node* node) {
7191cb0ef41Sopenharmony_ci  JSCreateLiteralArrayNode n(node);
7201cb0ef41Sopenharmony_ci  CreateLiteralParameters const& p = n.Parameters();
7211cb0ef41Sopenharmony_ci  STATIC_ASSERT(n.FeedbackVectorIndex() == 0);
7221cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 1,
7231cb0ef41Sopenharmony_ci                    jsgraph()->TaggedIndexConstant(p.feedback().index()));
7241cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 2, jsgraph()->Constant(p.constant(broker())));
7251cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags()));
7261cb0ef41Sopenharmony_ci
7271cb0ef41Sopenharmony_ci  // Use the CreateShallowArrayLiteral builtin only for shallow boilerplates
7281cb0ef41Sopenharmony_ci  // without properties up to the number of elements that the stubs can handle.
7291cb0ef41Sopenharmony_ci  if ((p.flags() & AggregateLiteral::kIsShallow) != 0 &&
7301cb0ef41Sopenharmony_ci      p.length() < ConstructorBuiltins::kMaximumClonedShallowArrayElements) {
7311cb0ef41Sopenharmony_ci    ReplaceWithBuiltinCall(node, Builtin::kCreateShallowArrayLiteral);
7321cb0ef41Sopenharmony_ci  } else {
7331cb0ef41Sopenharmony_ci    ReplaceWithRuntimeCall(node, Runtime::kCreateArrayLiteral);
7341cb0ef41Sopenharmony_ci  }
7351cb0ef41Sopenharmony_ci}
7361cb0ef41Sopenharmony_ci
7371cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSGetTemplateObject(Node* node) {
7381cb0ef41Sopenharmony_ci  JSGetTemplateObjectNode n(node);
7391cb0ef41Sopenharmony_ci  GetTemplateObjectParameters const& p = n.Parameters();
7401cb0ef41Sopenharmony_ci  SharedFunctionInfoRef shared = p.shared(broker());
7411cb0ef41Sopenharmony_ci  TemplateObjectDescriptionRef description = p.description(broker());
7421cb0ef41Sopenharmony_ci
7431cb0ef41Sopenharmony_ci  DCHECK_EQ(node->op()->ControlInputCount(), 1);
7441cb0ef41Sopenharmony_ci  node->RemoveInput(NodeProperties::FirstControlIndex(node));
7451cb0ef41Sopenharmony_ci
7461cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSGetTemplateObjectNode::FeedbackVectorIndex() == 0);
7471cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 0, jsgraph()->Constant(shared));
7481cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 1, jsgraph()->Constant(description));
7491cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 2,
7501cb0ef41Sopenharmony_ci                    jsgraph()->UintPtrConstant(p.feedback().index()));
7511cb0ef41Sopenharmony_ci
7521cb0ef41Sopenharmony_ci  ReplaceWithBuiltinCall(node, Builtin::kGetTemplateObject);
7531cb0ef41Sopenharmony_ci}
7541cb0ef41Sopenharmony_ci
7551cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateEmptyLiteralArray(Node* node) {
7561cb0ef41Sopenharmony_ci  JSCreateEmptyLiteralArrayNode n(node);
7571cb0ef41Sopenharmony_ci  FeedbackParameter const& p = n.Parameters();
7581cb0ef41Sopenharmony_ci  STATIC_ASSERT(n.FeedbackVectorIndex() == 0);
7591cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 1,
7601cb0ef41Sopenharmony_ci                    jsgraph()->TaggedIndexConstant(p.feedback().index()));
7611cb0ef41Sopenharmony_ci  node->RemoveInput(4);  // control
7621cb0ef41Sopenharmony_ci  ReplaceWithBuiltinCall(node, Builtin::kCreateEmptyArrayLiteral);
7631cb0ef41Sopenharmony_ci}
7641cb0ef41Sopenharmony_ci
7651cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateArrayFromIterable(Node* node) {
7661cb0ef41Sopenharmony_ci  ReplaceWithBuiltinCall(node, Builtin::kIterableToListWithSymbolLookup);
7671cb0ef41Sopenharmony_ci}
7681cb0ef41Sopenharmony_ci
7691cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateLiteralObject(Node* node) {
7701cb0ef41Sopenharmony_ci  JSCreateLiteralObjectNode n(node);
7711cb0ef41Sopenharmony_ci  CreateLiteralParameters const& p = n.Parameters();
7721cb0ef41Sopenharmony_ci  STATIC_ASSERT(n.FeedbackVectorIndex() == 0);
7731cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 1,
7741cb0ef41Sopenharmony_ci                    jsgraph()->TaggedIndexConstant(p.feedback().index()));
7751cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 2, jsgraph()->Constant(p.constant(broker())));
7761cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags()));
7771cb0ef41Sopenharmony_ci
7781cb0ef41Sopenharmony_ci  // Use the CreateShallowObjectLiteratal builtin only for shallow boilerplates
7791cb0ef41Sopenharmony_ci  // without elements up to the number of properties that the stubs can handle.
7801cb0ef41Sopenharmony_ci  if ((p.flags() & AggregateLiteral::kIsShallow) != 0 &&
7811cb0ef41Sopenharmony_ci      p.length() <=
7821cb0ef41Sopenharmony_ci          ConstructorBuiltins::kMaximumClonedShallowObjectProperties) {
7831cb0ef41Sopenharmony_ci    ReplaceWithBuiltinCall(node, Builtin::kCreateShallowObjectLiteral);
7841cb0ef41Sopenharmony_ci  } else {
7851cb0ef41Sopenharmony_ci    ReplaceWithRuntimeCall(node, Runtime::kCreateObjectLiteral);
7861cb0ef41Sopenharmony_ci  }
7871cb0ef41Sopenharmony_ci}
7881cb0ef41Sopenharmony_ci
7891cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCloneObject(Node* node) {
7901cb0ef41Sopenharmony_ci  JSCloneObjectNode n(node);
7911cb0ef41Sopenharmony_ci  CloneObjectParameters const& p = n.Parameters();
7921cb0ef41Sopenharmony_ci  STATIC_ASSERT(n.FeedbackVectorIndex() == 1);
7931cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.flags()));
7941cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 2,
7951cb0ef41Sopenharmony_ci                    jsgraph()->TaggedIndexConstant(p.feedback().index()));
7961cb0ef41Sopenharmony_ci  ReplaceWithBuiltinCall(node, Builtin::kCloneObjectIC);
7971cb0ef41Sopenharmony_ci}
7981cb0ef41Sopenharmony_ci
7991cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateEmptyLiteralObject(Node* node) {
8001cb0ef41Sopenharmony_ci  ReplaceWithBuiltinCall(node, Builtin::kCreateEmptyLiteralObject);
8011cb0ef41Sopenharmony_ci}
8021cb0ef41Sopenharmony_ci
8031cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateLiteralRegExp(Node* node) {
8041cb0ef41Sopenharmony_ci  JSCreateLiteralRegExpNode n(node);
8051cb0ef41Sopenharmony_ci  CreateLiteralParameters const& p = n.Parameters();
8061cb0ef41Sopenharmony_ci  STATIC_ASSERT(n.FeedbackVectorIndex() == 0);
8071cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 1,
8081cb0ef41Sopenharmony_ci                    jsgraph()->TaggedIndexConstant(p.feedback().index()));
8091cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 2, jsgraph()->Constant(p.constant(broker())));
8101cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags()));
8111cb0ef41Sopenharmony_ci  ReplaceWithBuiltinCall(node, Builtin::kCreateRegExpLiteral);
8121cb0ef41Sopenharmony_ci}
8131cb0ef41Sopenharmony_ci
8141cb0ef41Sopenharmony_ci
8151cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateCatchContext(Node* node) {
8161cb0ef41Sopenharmony_ci  ScopeInfoRef scope_info = ScopeInfoOf(broker(), node->op());
8171cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 1, jsgraph()->Constant(scope_info));
8181cb0ef41Sopenharmony_ci  ReplaceWithRuntimeCall(node, Runtime::kPushCatchContext);
8191cb0ef41Sopenharmony_ci}
8201cb0ef41Sopenharmony_ci
8211cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateWithContext(Node* node) {
8221cb0ef41Sopenharmony_ci  ScopeInfoRef scope_info = ScopeInfoOf(broker(), node->op());
8231cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 1, jsgraph()->Constant(scope_info));
8241cb0ef41Sopenharmony_ci  ReplaceWithRuntimeCall(node, Runtime::kPushWithContext);
8251cb0ef41Sopenharmony_ci}
8261cb0ef41Sopenharmony_ci
8271cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateBlockContext(Node* node) {
8281cb0ef41Sopenharmony_ci  ScopeInfoRef scope_info = ScopeInfoOf(broker(), node->op());
8291cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 0, jsgraph()->Constant(scope_info));
8301cb0ef41Sopenharmony_ci  ReplaceWithRuntimeCall(node, Runtime::kPushBlockContext);
8311cb0ef41Sopenharmony_ci}
8321cb0ef41Sopenharmony_ci
8331cb0ef41Sopenharmony_ci// TODO(jgruber,v8:8888): Should this collect feedback?
8341cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSConstructForwardVarargs(Node* node) {
8351cb0ef41Sopenharmony_ci  ConstructForwardVarargsParameters p =
8361cb0ef41Sopenharmony_ci      ConstructForwardVarargsParametersOf(node->op());
8371cb0ef41Sopenharmony_ci  int const arg_count = static_cast<int>(p.arity() - 2);
8381cb0ef41Sopenharmony_ci  CallDescriptor::Flags flags = FrameStateFlagForCall(node);
8391cb0ef41Sopenharmony_ci  Callable callable = CodeFactory::ConstructForwardVarargs(isolate());
8401cb0ef41Sopenharmony_ci  // If this fails, we might need to update the parameter reordering code
8411cb0ef41Sopenharmony_ci  // to ensure that the additional arguments passed via stack are pushed
8421cb0ef41Sopenharmony_ci  // between top of stack and JS arguments.
8431cb0ef41Sopenharmony_ci  DCHECK_EQ(callable.descriptor().GetStackParameterCount(), 0);
8441cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
8451cb0ef41Sopenharmony_ci      zone(), callable.descriptor(), arg_count + 1, flags);
8461cb0ef41Sopenharmony_ci  Node* stub_code = jsgraph()->HeapConstant(callable.code());
8471cb0ef41Sopenharmony_ci  Node* stub_arity = jsgraph()->Int32Constant(JSParameterCount(arg_count));
8481cb0ef41Sopenharmony_ci  Node* start_index = jsgraph()->Uint32Constant(p.start_index());
8491cb0ef41Sopenharmony_ci  Node* receiver = jsgraph()->UndefinedConstant();
8501cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 0, stub_code);
8511cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 3, stub_arity);
8521cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 4, start_index);
8531cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 5, receiver);
8541cb0ef41Sopenharmony_ci  NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
8551cb0ef41Sopenharmony_ci}
8561cb0ef41Sopenharmony_ci
8571cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSConstruct(Node* node) {
8581cb0ef41Sopenharmony_ci  JSConstructNode n(node);
8591cb0ef41Sopenharmony_ci  ConstructParameters const& p = n.Parameters();
8601cb0ef41Sopenharmony_ci  int const arg_count = p.arity_without_implicit_args();
8611cb0ef41Sopenharmony_ci  CallDescriptor::Flags flags = FrameStateFlagForCall(node);
8621cb0ef41Sopenharmony_ci
8631cb0ef41Sopenharmony_ci  static constexpr int kReceiver = 1;
8641cb0ef41Sopenharmony_ci
8651cb0ef41Sopenharmony_ci  const int stack_argument_count = arg_count + kReceiver;
8661cb0ef41Sopenharmony_ci  Callable callable = Builtins::CallableFor(isolate(), Builtin::kConstruct);
8671cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
8681cb0ef41Sopenharmony_ci      zone(), callable.descriptor(), stack_argument_count, flags);
8691cb0ef41Sopenharmony_ci  Node* stub_code = jsgraph()->HeapConstant(callable.code());
8701cb0ef41Sopenharmony_ci  Node* stub_arity = jsgraph()->Int32Constant(JSParameterCount(arg_count));
8711cb0ef41Sopenharmony_ci  Node* receiver = jsgraph()->UndefinedConstant();
8721cb0ef41Sopenharmony_ci  node->RemoveInput(n.FeedbackVectorIndex());
8731cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 0, stub_code);
8741cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 3, stub_arity);
8751cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 4, receiver);
8761cb0ef41Sopenharmony_ci
8771cb0ef41Sopenharmony_ci  // After: {code, target, new_target, arity, receiver, ...args}.
8781cb0ef41Sopenharmony_ci
8791cb0ef41Sopenharmony_ci  NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
8801cb0ef41Sopenharmony_ci}
8811cb0ef41Sopenharmony_ci
8821cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSConstructWithArrayLike(Node* node) {
8831cb0ef41Sopenharmony_ci  JSConstructWithArrayLikeNode n(node);
8841cb0ef41Sopenharmony_ci  ConstructParameters const& p = n.Parameters();
8851cb0ef41Sopenharmony_ci  CallDescriptor::Flags flags = FrameStateFlagForCall(node);
8861cb0ef41Sopenharmony_ci  const int arg_count = p.arity_without_implicit_args();
8871cb0ef41Sopenharmony_ci  DCHECK_EQ(arg_count, 1);
8881cb0ef41Sopenharmony_ci
8891cb0ef41Sopenharmony_ci  static constexpr int kReceiver = 1;
8901cb0ef41Sopenharmony_ci  static constexpr int kArgumentList = 1;
8911cb0ef41Sopenharmony_ci
8921cb0ef41Sopenharmony_ci  const int stack_argument_count = arg_count - kArgumentList + kReceiver;
8931cb0ef41Sopenharmony_ci  Callable callable =
8941cb0ef41Sopenharmony_ci      Builtins::CallableFor(isolate(), Builtin::kConstructWithArrayLike);
8951cb0ef41Sopenharmony_ci  // If this fails, we might need to update the parameter reordering code
8961cb0ef41Sopenharmony_ci  // to ensure that the additional arguments passed via stack are pushed
8971cb0ef41Sopenharmony_ci  // between top of stack and JS arguments.
8981cb0ef41Sopenharmony_ci  DCHECK_EQ(callable.descriptor().GetStackParameterCount(), 0);
8991cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
9001cb0ef41Sopenharmony_ci      zone(), callable.descriptor(), stack_argument_count, flags);
9011cb0ef41Sopenharmony_ci  Node* stub_code = jsgraph()->HeapConstant(callable.code());
9021cb0ef41Sopenharmony_ci  Node* receiver = jsgraph()->UndefinedConstant();
9031cb0ef41Sopenharmony_ci  node->RemoveInput(n.FeedbackVectorIndex());
9041cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 0, stub_code);
9051cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 4, receiver);
9061cb0ef41Sopenharmony_ci
9071cb0ef41Sopenharmony_ci  // After: {code, target, new_target, arguments_list, receiver}.
9081cb0ef41Sopenharmony_ci
9091cb0ef41Sopenharmony_ci  NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
9101cb0ef41Sopenharmony_ci}
9111cb0ef41Sopenharmony_ci
9121cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSConstructWithSpread(Node* node) {
9131cb0ef41Sopenharmony_ci  JSConstructWithSpreadNode n(node);
9141cb0ef41Sopenharmony_ci  ConstructParameters const& p = n.Parameters();
9151cb0ef41Sopenharmony_ci  int const arg_count = p.arity_without_implicit_args();
9161cb0ef41Sopenharmony_ci  DCHECK_GE(arg_count, 1);
9171cb0ef41Sopenharmony_ci  CallDescriptor::Flags flags = FrameStateFlagForCall(node);
9181cb0ef41Sopenharmony_ci
9191cb0ef41Sopenharmony_ci  static constexpr int kReceiver = 1;
9201cb0ef41Sopenharmony_ci  static constexpr int kTheSpread = 1;  // Included in `arg_count`.
9211cb0ef41Sopenharmony_ci
9221cb0ef41Sopenharmony_ci  const int stack_argument_count = arg_count + kReceiver - kTheSpread;
9231cb0ef41Sopenharmony_ci  Callable callable = CodeFactory::ConstructWithSpread(isolate());
9241cb0ef41Sopenharmony_ci  // If this fails, we might need to update the parameter reordering code
9251cb0ef41Sopenharmony_ci  // to ensure that the additional arguments passed via stack are pushed
9261cb0ef41Sopenharmony_ci  // between top of stack and JS arguments.
9271cb0ef41Sopenharmony_ci  DCHECK_EQ(callable.descriptor().GetStackParameterCount(), 0);
9281cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
9291cb0ef41Sopenharmony_ci      zone(), callable.descriptor(), stack_argument_count, flags);
9301cb0ef41Sopenharmony_ci  Node* stub_code = jsgraph()->HeapConstant(callable.code());
9311cb0ef41Sopenharmony_ci
9321cb0ef41Sopenharmony_ci  // We pass the spread in a register, not on the stack.
9331cb0ef41Sopenharmony_ci  Node* stub_arity =
9341cb0ef41Sopenharmony_ci      jsgraph()->Int32Constant(JSParameterCount(arg_count - kTheSpread));
9351cb0ef41Sopenharmony_ci  Node* receiver = jsgraph()->UndefinedConstant();
9361cb0ef41Sopenharmony_ci  DCHECK(n.FeedbackVectorIndex() > n.LastArgumentIndex());
9371cb0ef41Sopenharmony_ci  node->RemoveInput(n.FeedbackVectorIndex());
9381cb0ef41Sopenharmony_ci  Node* spread = node->RemoveInput(n.LastArgumentIndex());
9391cb0ef41Sopenharmony_ci
9401cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 0, stub_code);
9411cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 3, stub_arity);
9421cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 4, spread);
9431cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 5, receiver);
9441cb0ef41Sopenharmony_ci
9451cb0ef41Sopenharmony_ci  // After: {code, target, new_target, arity, spread, receiver, ...args}.
9461cb0ef41Sopenharmony_ci
9471cb0ef41Sopenharmony_ci  NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
9481cb0ef41Sopenharmony_ci}
9491cb0ef41Sopenharmony_ci
9501cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCallForwardVarargs(Node* node) {
9511cb0ef41Sopenharmony_ci  CallForwardVarargsParameters p = CallForwardVarargsParametersOf(node->op());
9521cb0ef41Sopenharmony_ci  int const arg_count = static_cast<int>(p.arity() - 2);
9531cb0ef41Sopenharmony_ci  CallDescriptor::Flags flags = FrameStateFlagForCall(node);
9541cb0ef41Sopenharmony_ci  Callable callable = CodeFactory::CallForwardVarargs(isolate());
9551cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
9561cb0ef41Sopenharmony_ci      zone(), callable.descriptor(), arg_count + 1, flags);
9571cb0ef41Sopenharmony_ci  Node* stub_code = jsgraph()->HeapConstant(callable.code());
9581cb0ef41Sopenharmony_ci  Node* stub_arity = jsgraph()->Int32Constant(JSParameterCount(arg_count));
9591cb0ef41Sopenharmony_ci  Node* start_index = jsgraph()->Uint32Constant(p.start_index());
9601cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 0, stub_code);
9611cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 2, stub_arity);
9621cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 3, start_index);
9631cb0ef41Sopenharmony_ci  NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
9641cb0ef41Sopenharmony_ci}
9651cb0ef41Sopenharmony_ci
9661cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCall(Node* node) {
9671cb0ef41Sopenharmony_ci  JSCallNode n(node);
9681cb0ef41Sopenharmony_ci  CallParameters const& p = n.Parameters();
9691cb0ef41Sopenharmony_ci  int const arg_count = p.arity_without_implicit_args();
9701cb0ef41Sopenharmony_ci  ConvertReceiverMode const mode = p.convert_mode();
9711cb0ef41Sopenharmony_ci
9721cb0ef41Sopenharmony_ci  node->RemoveInput(n.FeedbackVectorIndex());
9731cb0ef41Sopenharmony_ci
9741cb0ef41Sopenharmony_ci  Callable callable = CodeFactory::Call(isolate(), mode);
9751cb0ef41Sopenharmony_ci  CallDescriptor::Flags flags = FrameStateFlagForCall(node);
9761cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
9771cb0ef41Sopenharmony_ci      zone(), callable.descriptor(), arg_count + 1, flags);
9781cb0ef41Sopenharmony_ci  Node* stub_code = jsgraph()->HeapConstant(callable.code());
9791cb0ef41Sopenharmony_ci  Node* stub_arity = jsgraph()->Int32Constant(JSParameterCount(arg_count));
9801cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 0, stub_code);
9811cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 2, stub_arity);
9821cb0ef41Sopenharmony_ci  NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
9831cb0ef41Sopenharmony_ci}
9841cb0ef41Sopenharmony_ci
9851cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCallWithArrayLike(Node* node) {
9861cb0ef41Sopenharmony_ci  JSCallWithArrayLikeNode n(node);
9871cb0ef41Sopenharmony_ci  CallParameters const& p = n.Parameters();
9881cb0ef41Sopenharmony_ci  const int arg_count = p.arity_without_implicit_args();
9891cb0ef41Sopenharmony_ci  DCHECK_EQ(arg_count, 1);  // The arraylike object.
9901cb0ef41Sopenharmony_ci  CallDescriptor::Flags flags = FrameStateFlagForCall(node);
9911cb0ef41Sopenharmony_ci
9921cb0ef41Sopenharmony_ci  static constexpr int kArgumentsList = 1;
9931cb0ef41Sopenharmony_ci  static constexpr int kReceiver = 1;
9941cb0ef41Sopenharmony_ci
9951cb0ef41Sopenharmony_ci  const int stack_argument_count = arg_count - kArgumentsList + kReceiver;
9961cb0ef41Sopenharmony_ci  Callable callable = CodeFactory::CallWithArrayLike(isolate());
9971cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
9981cb0ef41Sopenharmony_ci      zone(), callable.descriptor(), stack_argument_count, flags);
9991cb0ef41Sopenharmony_ci  Node* stub_code = jsgraph()->HeapConstant(callable.code());
10001cb0ef41Sopenharmony_ci  Node* receiver = n.receiver();
10011cb0ef41Sopenharmony_ci  Node* arguments_list = n.Argument(0);
10021cb0ef41Sopenharmony_ci
10031cb0ef41Sopenharmony_ci  // Shuffling inputs.
10041cb0ef41Sopenharmony_ci  // Before: {target, receiver, arguments_list, vector}.
10051cb0ef41Sopenharmony_ci
10061cb0ef41Sopenharmony_ci  node->RemoveInput(n.FeedbackVectorIndex());
10071cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 0, stub_code);
10081cb0ef41Sopenharmony_ci  node->ReplaceInput(2, arguments_list);
10091cb0ef41Sopenharmony_ci  node->ReplaceInput(3, receiver);
10101cb0ef41Sopenharmony_ci
10111cb0ef41Sopenharmony_ci  // After: {code, target, arguments_list, receiver}.
10121cb0ef41Sopenharmony_ci
10131cb0ef41Sopenharmony_ci  NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
10141cb0ef41Sopenharmony_ci}
10151cb0ef41Sopenharmony_ci
10161cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCallWithSpread(Node* node) {
10171cb0ef41Sopenharmony_ci  JSCallWithSpreadNode n(node);
10181cb0ef41Sopenharmony_ci  CallParameters const& p = n.Parameters();
10191cb0ef41Sopenharmony_ci  int const arg_count = p.arity_without_implicit_args();
10201cb0ef41Sopenharmony_ci  DCHECK_GE(arg_count, 1);  // At least the spread.
10211cb0ef41Sopenharmony_ci  CallDescriptor::Flags flags = FrameStateFlagForCall(node);
10221cb0ef41Sopenharmony_ci
10231cb0ef41Sopenharmony_ci  static constexpr int kReceiver = 1;
10241cb0ef41Sopenharmony_ci  static constexpr int kTheSpread = 1;
10251cb0ef41Sopenharmony_ci
10261cb0ef41Sopenharmony_ci  const int stack_argument_count = arg_count - kTheSpread + kReceiver;
10271cb0ef41Sopenharmony_ci  Callable callable = CodeFactory::CallWithSpread(isolate());
10281cb0ef41Sopenharmony_ci  // If this fails, we might need to update the parameter reordering code
10291cb0ef41Sopenharmony_ci  // to ensure that the additional arguments passed via stack are pushed
10301cb0ef41Sopenharmony_ci  // between top of stack and JS arguments.
10311cb0ef41Sopenharmony_ci  DCHECK_EQ(callable.descriptor().GetStackParameterCount(), 0);
10321cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
10331cb0ef41Sopenharmony_ci      zone(), callable.descriptor(), stack_argument_count, flags);
10341cb0ef41Sopenharmony_ci  Node* stub_code = jsgraph()->HeapConstant(callable.code());
10351cb0ef41Sopenharmony_ci
10361cb0ef41Sopenharmony_ci  // We pass the spread in a register, not on the stack.
10371cb0ef41Sopenharmony_ci  Node* stub_arity =
10381cb0ef41Sopenharmony_ci      jsgraph()->Int32Constant(JSParameterCount(arg_count - kTheSpread));
10391cb0ef41Sopenharmony_ci
10401cb0ef41Sopenharmony_ci  // Shuffling inputs.
10411cb0ef41Sopenharmony_ci  // Before: {target, receiver, ...args, spread, vector}.
10421cb0ef41Sopenharmony_ci
10431cb0ef41Sopenharmony_ci  node->RemoveInput(n.FeedbackVectorIndex());
10441cb0ef41Sopenharmony_ci  Node* spread = node->RemoveInput(n.LastArgumentIndex());
10451cb0ef41Sopenharmony_ci
10461cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 0, stub_code);
10471cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 2, stub_arity);
10481cb0ef41Sopenharmony_ci  node->InsertInput(zone(), 3, spread);
10491cb0ef41Sopenharmony_ci
10501cb0ef41Sopenharmony_ci  // After: {code, target, arity, spread, receiver, ...args}.
10511cb0ef41Sopenharmony_ci
10521cb0ef41Sopenharmony_ci  NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
10531cb0ef41Sopenharmony_ci}
10541cb0ef41Sopenharmony_ci
10551cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCallRuntime(Node* node) {
10561cb0ef41Sopenharmony_ci  const CallRuntimeParameters& p = CallRuntimeParametersOf(node->op());
10571cb0ef41Sopenharmony_ci  ReplaceWithRuntimeCall(node, p.id(), static_cast<int>(p.arity()));
10581cb0ef41Sopenharmony_ci}
10591cb0ef41Sopenharmony_ci
10601cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
10611cb0ef41Sopenharmony_ci// Will be lowered in SimplifiedLowering.
10621cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSWasmCall(Node* node) {}
10631cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
10641cb0ef41Sopenharmony_ci
10651cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSForInPrepare(Node* node) {
10661cb0ef41Sopenharmony_ci  JSForInPrepareNode n(node);
10671cb0ef41Sopenharmony_ci  Effect effect(node);            // {node} is kept in the effect chain.
10681cb0ef41Sopenharmony_ci  Control control = n.control();  // .. but not in the control chain.
10691cb0ef41Sopenharmony_ci  Node* enumerator = n.enumerator();
10701cb0ef41Sopenharmony_ci  Node* slot =
10711cb0ef41Sopenharmony_ci      jsgraph()->UintPtrConstant(n.Parameters().feedback().slot.ToInt());
10721cb0ef41Sopenharmony_ci
10731cb0ef41Sopenharmony_ci  std::vector<Edge> use_edges;
10741cb0ef41Sopenharmony_ci  for (Edge edge : node->use_edges()) use_edges.push_back(edge);
10751cb0ef41Sopenharmony_ci
10761cb0ef41Sopenharmony_ci  // {node} will be changed to a builtin call (see below). The returned value
10771cb0ef41Sopenharmony_ci  // is a fixed array containing {cache_array} and {cache_length}.
10781cb0ef41Sopenharmony_ci  // TODO(jgruber): This is awkward; what we really want is two return values,
10791cb0ef41Sopenharmony_ci  // the {cache_array} and {cache_length}, or better yet three return values
10801cb0ef41Sopenharmony_ci  // s.t. we can avoid the graph rewrites below. Builtin support for multiple
10811cb0ef41Sopenharmony_ci  // return types is unclear though.
10821cb0ef41Sopenharmony_ci
10831cb0ef41Sopenharmony_ci  Node* result_fixed_array = node;
10841cb0ef41Sopenharmony_ci  Node* cache_type = enumerator;  // Just to clarify the rename.
10851cb0ef41Sopenharmony_ci  Node* cache_array;
10861cb0ef41Sopenharmony_ci  Node* cache_length;
10871cb0ef41Sopenharmony_ci
10881cb0ef41Sopenharmony_ci  cache_array = effect = graph()->NewNode(
10891cb0ef41Sopenharmony_ci      machine()->Load(MachineType::AnyTagged()), result_fixed_array,
10901cb0ef41Sopenharmony_ci      jsgraph()->IntPtrConstant(FixedArray::OffsetOfElementAt(0) -
10911cb0ef41Sopenharmony_ci                                kHeapObjectTag),
10921cb0ef41Sopenharmony_ci      effect, control);
10931cb0ef41Sopenharmony_ci  cache_length = effect = graph()->NewNode(
10941cb0ef41Sopenharmony_ci      machine()->Load(MachineType::AnyTagged()), result_fixed_array,
10951cb0ef41Sopenharmony_ci      jsgraph()->IntPtrConstant(FixedArray::OffsetOfElementAt(1) -
10961cb0ef41Sopenharmony_ci                                kHeapObjectTag),
10971cb0ef41Sopenharmony_ci      effect, control);
10981cb0ef41Sopenharmony_ci
10991cb0ef41Sopenharmony_ci  // Update the uses of {node}.
11001cb0ef41Sopenharmony_ci  for (Edge edge : use_edges) {
11011cb0ef41Sopenharmony_ci    Node* const user = edge.from();
11021cb0ef41Sopenharmony_ci    if (NodeProperties::IsEffectEdge(edge)) {
11031cb0ef41Sopenharmony_ci      edge.UpdateTo(effect);
11041cb0ef41Sopenharmony_ci    } else if (NodeProperties::IsControlEdge(edge)) {
11051cb0ef41Sopenharmony_ci      edge.UpdateTo(control);
11061cb0ef41Sopenharmony_ci    } else {
11071cb0ef41Sopenharmony_ci      DCHECK(NodeProperties::IsValueEdge(edge));
11081cb0ef41Sopenharmony_ci      switch (ProjectionIndexOf(user->op())) {
11091cb0ef41Sopenharmony_ci        case 0:
11101cb0ef41Sopenharmony_ci          Replace(user, cache_type);
11111cb0ef41Sopenharmony_ci          break;
11121cb0ef41Sopenharmony_ci        case 1:
11131cb0ef41Sopenharmony_ci          Replace(user, cache_array);
11141cb0ef41Sopenharmony_ci          break;
11151cb0ef41Sopenharmony_ci        case 2:
11161cb0ef41Sopenharmony_ci          Replace(user, cache_length);
11171cb0ef41Sopenharmony_ci          break;
11181cb0ef41Sopenharmony_ci        default:
11191cb0ef41Sopenharmony_ci          UNREACHABLE();
11201cb0ef41Sopenharmony_ci      }
11211cb0ef41Sopenharmony_ci    }
11221cb0ef41Sopenharmony_ci  }
11231cb0ef41Sopenharmony_ci
11241cb0ef41Sopenharmony_ci  // Finally, change the original node into a builtin call. This happens here,
11251cb0ef41Sopenharmony_ci  // after graph rewrites, since the Call does not have a control output and
11261cb0ef41Sopenharmony_ci  // thus must not have any control uses. Any previously existing control
11271cb0ef41Sopenharmony_ci  // outputs have been replaced by the graph rewrite above.
11281cb0ef41Sopenharmony_ci  node->InsertInput(zone(), n.FeedbackVectorIndex(), slot);
11291cb0ef41Sopenharmony_ci  ReplaceWithBuiltinCall(node, Builtin::kForInPrepare);
11301cb0ef41Sopenharmony_ci}
11311cb0ef41Sopenharmony_ci
11321cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSForInNext(Node* node) {
11331cb0ef41Sopenharmony_ci  JSForInNextNode n(node);
11341cb0ef41Sopenharmony_ci  node->InsertInput(
11351cb0ef41Sopenharmony_ci      zone(), 0,
11361cb0ef41Sopenharmony_ci      jsgraph()->UintPtrConstant(n.Parameters().feedback().slot.ToInt()));
11371cb0ef41Sopenharmony_ci  ReplaceWithBuiltinCall(node, Builtin::kForInNext);
11381cb0ef41Sopenharmony_ci}
11391cb0ef41Sopenharmony_ci
11401cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSLoadMessage(Node* node) {
11411cb0ef41Sopenharmony_ci  UNREACHABLE();  // Eliminated in typed lowering.
11421cb0ef41Sopenharmony_ci}
11431cb0ef41Sopenharmony_ci
11441cb0ef41Sopenharmony_ci
11451cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSStoreMessage(Node* node) {
11461cb0ef41Sopenharmony_ci  UNREACHABLE();  // Eliminated in typed lowering.
11471cb0ef41Sopenharmony_ci}
11481cb0ef41Sopenharmony_ci
11491cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSLoadModule(Node* node) {
11501cb0ef41Sopenharmony_ci  UNREACHABLE();  // Eliminated in typed lowering.
11511cb0ef41Sopenharmony_ci}
11521cb0ef41Sopenharmony_ci
11531cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSStoreModule(Node* node) {
11541cb0ef41Sopenharmony_ci  UNREACHABLE();  // Eliminated in typed lowering.
11551cb0ef41Sopenharmony_ci}
11561cb0ef41Sopenharmony_ci
11571cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSGetImportMeta(Node* node) {
11581cb0ef41Sopenharmony_ci  ReplaceWithRuntimeCall(node, Runtime::kGetImportMetaObject);
11591cb0ef41Sopenharmony_ci}
11601cb0ef41Sopenharmony_ci
11611cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSGeneratorStore(Node* node) {
11621cb0ef41Sopenharmony_ci  UNREACHABLE();  // Eliminated in typed lowering.
11631cb0ef41Sopenharmony_ci}
11641cb0ef41Sopenharmony_ci
11651cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSGeneratorRestoreContinuation(Node* node) {
11661cb0ef41Sopenharmony_ci  UNREACHABLE();  // Eliminated in typed lowering.
11671cb0ef41Sopenharmony_ci}
11681cb0ef41Sopenharmony_ci
11691cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSGeneratorRestoreContext(Node* node) {
11701cb0ef41Sopenharmony_ci  UNREACHABLE();  // Eliminated in typed lowering.
11711cb0ef41Sopenharmony_ci}
11721cb0ef41Sopenharmony_ci
11731cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSGeneratorRestoreInputOrDebugPos(Node* node) {
11741cb0ef41Sopenharmony_ci  UNREACHABLE();  // Eliminated in typed lowering.
11751cb0ef41Sopenharmony_ci}
11761cb0ef41Sopenharmony_ci
11771cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSGeneratorRestoreRegister(Node* node) {
11781cb0ef41Sopenharmony_ci  UNREACHABLE();  // Eliminated in typed lowering.
11791cb0ef41Sopenharmony_ci}
11801cb0ef41Sopenharmony_ci
11811cb0ef41Sopenharmony_cinamespace {
11821cb0ef41Sopenharmony_ci
11831cb0ef41Sopenharmony_ciStackCheckKind StackCheckKindOfJSStackCheck(const Operator* op) {
11841cb0ef41Sopenharmony_ci  DCHECK(op->opcode() == IrOpcode::kJSStackCheck);
11851cb0ef41Sopenharmony_ci  return OpParameter<StackCheckKind>(op);
11861cb0ef41Sopenharmony_ci}
11871cb0ef41Sopenharmony_ci
11881cb0ef41Sopenharmony_ci}  // namespace
11891cb0ef41Sopenharmony_ci
11901cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSStackCheck(Node* node) {
11911cb0ef41Sopenharmony_ci  Node* effect = NodeProperties::GetEffectInput(node);
11921cb0ef41Sopenharmony_ci  Node* control = NodeProperties::GetControlInput(node);
11931cb0ef41Sopenharmony_ci
11941cb0ef41Sopenharmony_ci  Node* limit = effect =
11951cb0ef41Sopenharmony_ci      graph()->NewNode(machine()->Load(MachineType::Pointer()),
11961cb0ef41Sopenharmony_ci                       jsgraph()->ExternalConstant(
11971cb0ef41Sopenharmony_ci                           ExternalReference::address_of_jslimit(isolate())),
11981cb0ef41Sopenharmony_ci                       jsgraph()->IntPtrConstant(0), effect, control);
11991cb0ef41Sopenharmony_ci
12001cb0ef41Sopenharmony_ci  StackCheckKind stack_check_kind = StackCheckKindOfJSStackCheck(node->op());
12011cb0ef41Sopenharmony_ci  Node* check = effect = graph()->NewNode(
12021cb0ef41Sopenharmony_ci      machine()->StackPointerGreaterThan(stack_check_kind), limit, effect);
12031cb0ef41Sopenharmony_ci  Node* branch =
12041cb0ef41Sopenharmony_ci      graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
12051cb0ef41Sopenharmony_ci
12061cb0ef41Sopenharmony_ci  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
12071cb0ef41Sopenharmony_ci  Node* etrue = effect;
12081cb0ef41Sopenharmony_ci
12091cb0ef41Sopenharmony_ci  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
12101cb0ef41Sopenharmony_ci  NodeProperties::ReplaceControlInput(node, if_false);
12111cb0ef41Sopenharmony_ci  NodeProperties::ReplaceEffectInput(node, effect);
12121cb0ef41Sopenharmony_ci  Node* efalse = if_false = node;
12131cb0ef41Sopenharmony_ci
12141cb0ef41Sopenharmony_ci  Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
12151cb0ef41Sopenharmony_ci  Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge);
12161cb0ef41Sopenharmony_ci
12171cb0ef41Sopenharmony_ci  // Wire the new diamond into the graph, {node} can still throw.
12181cb0ef41Sopenharmony_ci  NodeProperties::ReplaceUses(node, node, ephi, merge, merge);
12191cb0ef41Sopenharmony_ci  NodeProperties::ReplaceControlInput(merge, if_false, 1);
12201cb0ef41Sopenharmony_ci  NodeProperties::ReplaceEffectInput(ephi, efalse, 1);
12211cb0ef41Sopenharmony_ci
12221cb0ef41Sopenharmony_ci  // This iteration cuts out potential {IfSuccess} or {IfException} projection
12231cb0ef41Sopenharmony_ci  // uses of the original node and places them inside the diamond, so that we
12241cb0ef41Sopenharmony_ci  // can change the original {node} into the slow-path runtime call.
12251cb0ef41Sopenharmony_ci  for (Edge edge : merge->use_edges()) {
12261cb0ef41Sopenharmony_ci    if (!NodeProperties::IsControlEdge(edge)) continue;
12271cb0ef41Sopenharmony_ci    if (edge.from()->opcode() == IrOpcode::kIfSuccess) {
12281cb0ef41Sopenharmony_ci      NodeProperties::ReplaceUses(edge.from(), nullptr, nullptr, merge);
12291cb0ef41Sopenharmony_ci      NodeProperties::ReplaceControlInput(merge, edge.from(), 1);
12301cb0ef41Sopenharmony_ci      edge.UpdateTo(node);
12311cb0ef41Sopenharmony_ci    }
12321cb0ef41Sopenharmony_ci    if (edge.from()->opcode() == IrOpcode::kIfException) {
12331cb0ef41Sopenharmony_ci      NodeProperties::ReplaceEffectInput(edge.from(), node);
12341cb0ef41Sopenharmony_ci      edge.UpdateTo(node);
12351cb0ef41Sopenharmony_ci    }
12361cb0ef41Sopenharmony_ci  }
12371cb0ef41Sopenharmony_ci
12381cb0ef41Sopenharmony_ci  // Turn the stack check into a runtime call. At function entry, the runtime
12391cb0ef41Sopenharmony_ci  // function takes an offset argument which is subtracted from the stack
12401cb0ef41Sopenharmony_ci  // pointer prior to the stack check (i.e. the check is `sp - offset >=
12411cb0ef41Sopenharmony_ci  // limit`).
12421cb0ef41Sopenharmony_ci  if (stack_check_kind == StackCheckKind::kJSFunctionEntry) {
12431cb0ef41Sopenharmony_ci    node->InsertInput(zone(), 0,
12441cb0ef41Sopenharmony_ci                      graph()->NewNode(machine()->LoadStackCheckOffset()));
12451cb0ef41Sopenharmony_ci    ReplaceWithRuntimeCall(node, Runtime::kStackGuardWithGap);
12461cb0ef41Sopenharmony_ci  } else {
12471cb0ef41Sopenharmony_ci    ReplaceWithRuntimeCall(node, Runtime::kStackGuard);
12481cb0ef41Sopenharmony_ci  }
12491cb0ef41Sopenharmony_ci}
12501cb0ef41Sopenharmony_ci
12511cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSDebugger(Node* node) {
12521cb0ef41Sopenharmony_ci  ReplaceWithRuntimeCall(node, Runtime::kHandleDebuggerStatement);
12531cb0ef41Sopenharmony_ci}
12541cb0ef41Sopenharmony_ci
12551cb0ef41Sopenharmony_ciZone* JSGenericLowering::zone() const { return graph()->zone(); }
12561cb0ef41Sopenharmony_ci
12571cb0ef41Sopenharmony_ci
12581cb0ef41Sopenharmony_ciIsolate* JSGenericLowering::isolate() const { return jsgraph()->isolate(); }
12591cb0ef41Sopenharmony_ci
12601cb0ef41Sopenharmony_ci
12611cb0ef41Sopenharmony_ciGraph* JSGenericLowering::graph() const { return jsgraph()->graph(); }
12621cb0ef41Sopenharmony_ci
12631cb0ef41Sopenharmony_ci
12641cb0ef41Sopenharmony_ciCommonOperatorBuilder* JSGenericLowering::common() const {
12651cb0ef41Sopenharmony_ci  return jsgraph()->common();
12661cb0ef41Sopenharmony_ci}
12671cb0ef41Sopenharmony_ci
12681cb0ef41Sopenharmony_ci
12691cb0ef41Sopenharmony_ciMachineOperatorBuilder* JSGenericLowering::machine() const {
12701cb0ef41Sopenharmony_ci  return jsgraph()->machine();
12711cb0ef41Sopenharmony_ci}
12721cb0ef41Sopenharmony_ci
12731cb0ef41Sopenharmony_ci}  // namespace compiler
12741cb0ef41Sopenharmony_ci}  // namespace internal
12751cb0ef41Sopenharmony_ci}  // namespace v8
1276