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

#include "src/torque/csa-generator.h"

#include "src/common/globals.h"
#include "src/torque/type-oracle.h"
#include "src/torque/utils.h"

namespace v8 {
namespace internal {
namespace torque {

base::Optional<Stack<std::string>> CSAGenerator::EmitGraph(
    Stack<std::string> parameters) {
  for (Block* block : cfg_.blocks()) {
    out_ << "  compiler::CodeAssemblerParameterizedLabel<";
    PrintCommaSeparatedList(out_, block->InputTypes(), [](const Type* t) {
      return t->GetGeneratedTNodeTypeName();
    });
    out_ << "> " << BlockName(block) << "(&ca_, compiler::CodeAssemblerLabel::"
         << (block->IsDeferred() ? "kDeferred" : "kNonDeferred") << ");\n";
  }

  EmitInstruction(GotoInstruction{cfg_.start()}, &parameters);
  for (Block* block : cfg_.blocks()) {
    if (cfg_.end() && *cfg_.end() == block) continue;
    out_ << "\n  if (" << BlockName(block) << ".is_used()) {\n";
    EmitBlock(block);
    out_ << "  }\n";
  }
  if (cfg_.end()) {
    out_ << "\n";
    return EmitBlock(*cfg_.end());
  }
  return base::nullopt;
}

Stack<std::string> CSAGenerator::EmitBlock(const Block* block) {
  Stack<std::string> stack;
  for (const Type* t : block->InputTypes()) {
    stack.Push(FreshNodeName());
    out_ << "    compiler::TNode<" << t->GetGeneratedTNodeTypeName() << "> "
         << stack.Top() << ";\n";
  }
  out_ << "    ca_.Bind(&" << BlockName(block);
  for (const std::string& name : stack) {
    out_ << ", &" << name;
  }
  out_ << ");\n";
  for (const Instruction& instruction : block->instructions()) {
    EmitInstruction(instruction, &stack);
  }
  return stack;
}

void CSAGenerator::EmitSourcePosition(SourcePosition pos, bool always_emit) {
  const std::string& file = SourceFileMap::GetSource(pos.source);
  if (always_emit || !previous_position_.CompareStartIgnoreColumn(pos)) {
    // Lines in Torque SourcePositions are zero-based, while the
    // CodeStubAssembler and downwind systems are one-based.
    out_ << "    ca_.SetSourcePosition(\"" << file << "\", "
         << (pos.start.line + 1) << ");\n";
    previous_position_ = pos;
  }
}

void CSAGenerator::EmitInstruction(const Instruction& instruction,
                                   Stack<std::string>* stack) {
  EmitSourcePosition(instruction->pos);
  switch (instruction.kind()) {
#define ENUM_ITEM(T)          \
  case InstructionKind::k##T: \
    return EmitInstruction(instruction.Cast<T>(), stack);
    TORQUE_INSTRUCTION_LIST(ENUM_ITEM)
#undef ENUM_ITEM
  }
}

void CSAGenerator::EmitInstruction(const PeekInstruction& instruction,
                                   Stack<std::string>* stack) {
  stack->Push(stack->Peek(instruction.slot));
}

void CSAGenerator::EmitInstruction(const PokeInstruction& instruction,
                                   Stack<std::string>* stack) {
  stack->Poke(instruction.slot, stack->Top());
  stack->Pop();
}

void CSAGenerator::EmitInstruction(const DeleteRangeInstruction& instruction,
                                   Stack<std::string>* stack) {
  stack->DeleteRange(instruction.range);
}

void CSAGenerator::EmitInstruction(
    const PushUninitializedInstruction& instruction,
    Stack<std::string>* stack) {
  // TODO(tebbi): This can trigger an error in CSA if it is used. Instead, we
  // should prevent usage of uninitialized in the type system. This
  // requires "if constexpr" being evaluated at Torque time.
  stack->Push("ca_.Uninitialized<" +
              instruction.type->GetGeneratedTNodeTypeName() + ">()");
}

void CSAGenerator::EmitInstruction(
    const PushBuiltinPointerInstruction& instruction,
    Stack<std::string>* stack) {
  stack->Push("ca_.UncheckedCast<BuiltinPtr>(ca_.SmiConstant(Builtins::k" +
              instruction.external_name + "))");
}

void CSAGenerator::EmitInstruction(
    const NamespaceConstantInstruction& instruction,
    Stack<std::string>* stack) {
  const Type* type = instruction.constant->type();
  std::vector<std::string> results;
  for (const Type* lowered : LowerType(type)) {
    results.push_back(FreshNodeName());
    stack->Push(results.back());
    out_ << "    compiler::TNode<" << lowered->GetGeneratedTNodeTypeName()
         << "> " << stack->Top() << ";\n";
    out_ << "    USE(" << stack->Top() << ");\n";
  }
  out_ << "    ";
  if (type->IsStructType()) {
    out_ << "std::tie(";
    PrintCommaSeparatedList(out_, results);
    out_ << ") = ";
  } else if (results.size() == 1) {
    out_ << results[0] << " = ";
  }
  out_ << instruction.constant->ExternalAssemblerName() << "(state_)."
       << instruction.constant->name()->value << "()";
  if (type->IsStructType()) {
    out_ << ".Flatten();\n";
  } else {
    out_ << ";\n";
  }
}

void CSAGenerator::ProcessArgumentsCommon(
    const TypeVector& parameter_types, std::vector<std::string>* args,
    std::vector<std::string>* constexpr_arguments, Stack<std::string>* stack) {
  for (auto it = parameter_types.rbegin(); it != parameter_types.rend(); ++it) {
    const Type* type = *it;
    VisitResult arg;
    if (type->IsConstexpr()) {
      args->push_back(std::move(constexpr_arguments->back()));
      constexpr_arguments->pop_back();
    } else {
      std::stringstream s;
      size_t slot_count = LoweredSlotCount(type);
      VisitResult arg = VisitResult(type, stack->TopRange(slot_count));
      EmitCSAValue(arg, *stack, s);
      args->push_back(s.str());
      stack->PopMany(slot_count);
    }
  }
  std::reverse(args->begin(), args->end());
}

void CSAGenerator::EmitInstruction(const CallIntrinsicInstruction& instruction,
                                   Stack<std::string>* stack) {
  std::vector<std::string> constexpr_arguments =
      instruction.constexpr_arguments;
  std::vector<std::string> args;
  TypeVector parameter_types =
      instruction.intrinsic->signature().parameter_types.types;
  ProcessArgumentsCommon(parameter_types, &args, &constexpr_arguments, stack);

  Stack<std::string> pre_call_stack = *stack;
  const Type* return_type = instruction.intrinsic->signature().return_type;
  std::vector<std::string> results;
  for (const Type* type : LowerType(return_type)) {
    results.push_back(FreshNodeName());
    stack->Push(results.back());
    out_ << "    compiler::TNode<" << type->GetGeneratedTNodeTypeName() << "> "
         << stack->Top() << ";\n";
    out_ << "    USE(" << stack->Top() << ");\n";
  }
  out_ << "    ";

  if (return_type->IsStructType()) {
    out_ << "std::tie(";
    PrintCommaSeparatedList(out_, results);
    out_ << ") = ";
  } else {
    if (results.size() == 1) {
      out_ << results[0] << " = ";
    }
  }

  if (instruction.intrinsic->ExternalName() == "%RawDownCast") {
    if (parameter_types.size() != 1) {
      ReportError("%RawDownCast must take a single parameter");
    }
    if (!return_type->IsSubtypeOf(parameter_types[0])) {
      ReportError("%RawDownCast error: ", *return_type, " is not a subtype of ",
                  *parameter_types[0]);
    }
    if (return_type->IsSubtypeOf(TypeOracle::GetTaggedType())) {
      if (return_type->GetGeneratedTNodeTypeName() !=
          parameter_types[0]->GetGeneratedTNodeTypeName()) {
        out_ << "TORQUE_CAST";
      }
    }
  } else if (instruction.intrinsic->ExternalName() == "%FromConstexpr") {
    if (parameter_types.size() != 1 || !parameter_types[0]->IsConstexpr()) {
      ReportError(
          "%FromConstexpr must take a single parameter with constexpr "
          "type");
    }
    if (return_type->IsConstexpr()) {
      ReportError("%FromConstexpr must return a non-constexpr type");
    }
    if (return_type->IsSubtypeOf(TypeOracle::GetSmiType())) {
      out_ << "ca_.SmiConstant";
    } else if (return_type->IsSubtypeOf(TypeOracle::GetNumberType())) {
      out_ << "ca_.NumberConstant";
    } else if (return_type->IsSubtypeOf(TypeOracle::GetStringType())) {
      out_ << "ca_.StringConstant";
    } else if (return_type->IsSubtypeOf(TypeOracle::GetObjectType())) {
      ReportError(
          "%FromConstexpr cannot cast to subclass of HeapObject unless it's a "
          "String or Number");
    } else if (return_type->IsSubtypeOf(TypeOracle::GetIntPtrType())) {
      out_ << "ca_.IntPtrConstant";
    } else if (return_type->IsSubtypeOf(TypeOracle::GetUIntPtrType())) {
      out_ << "ca_.UintPtrConstant";
    } else if (return_type->IsSubtypeOf(TypeOracle::GetInt32Type())) {
      out_ << "ca_.Int32Constant";
    } else {
      std::stringstream s;
      s << "%FromConstexpr does not support return type " << *return_type;
      ReportError(s.str());
    }
  } else if (instruction.intrinsic->ExternalName() ==
             "%GetAllocationBaseSize") {
    if (instruction.specialization_types.size() != 1) {
      ReportError(
          "incorrect number of specialization classes for "
          "%GetAllocationBaseSize (should be one)");
    }
    const ClassType* class_type =
        ClassType::cast(instruction.specialization_types[0]);
    // Special case classes that may not always have a fixed size (e.g.
    // JSObjects). Their size must be fetched from the map.
    if (class_type != TypeOracle::GetJSObjectType()) {
      out_ << "CodeStubAssembler(state_).IntPtrConstant((";
      args[0] = std::to_string(class_type->size());
    } else {
      out_ << "CodeStubAssembler(state_).TimesTaggedSize(CodeStubAssembler("
              "state_).LoadMapInstanceSizeInWords(";
    }
  } else if (instruction.intrinsic->ExternalName() == "%Allocate") {
    out_ << "ca_.UncheckedCast<" << return_type->GetGeneratedTNodeTypeName()
         << ">(CodeStubAssembler(state_).Allocate";
  } else if (instruction.intrinsic->ExternalName() ==
             "%AllocateInternalClass") {
    out_ << "CodeStubAssembler(state_).AllocateUninitializedFixedArray";
  } else {
    ReportError("no built in intrinsic with name " +
                instruction.intrinsic->ExternalName());
  }

  out_ << "(";
  PrintCommaSeparatedList(out_, args);
  if (instruction.intrinsic->ExternalName() == "%Allocate") out_ << ")";
  if (instruction.intrinsic->ExternalName() == "%GetAllocationBaseSize")
    out_ << "))";
  if (return_type->IsStructType()) {
    out_ << ").Flatten();\n";
  } else {
    out_ << ");\n";
  }
  if (instruction.intrinsic->ExternalName() == "%Allocate") {
    out_ << "    CodeStubAssembler(state_).InitializeFieldsWithRoot("
         << results[0] << ", ";
    out_ << "CodeStubAssembler(state_).IntPtrConstant("
         << std::to_string(ClassType::cast(return_type)->size()) << "), ";
    PrintCommaSeparatedList(out_, args);
    out_ << ", RootIndex::kUndefinedValue);\n";
  }
}

void CSAGenerator::EmitInstruction(const CallCsaMacroInstruction& instruction,
                                   Stack<std::string>* stack) {
  std::vector<std::string> constexpr_arguments =
      instruction.constexpr_arguments;
  std::vector<std::string> args;
  TypeVector parameter_types =
      instruction.macro->signature().parameter_types.types;
  ProcessArgumentsCommon(parameter_types, &args, &constexpr_arguments, stack);

  Stack<std::string> pre_call_stack = *stack;
  const Type* return_type = instruction.macro->signature().return_type;
  std::vector<std::string> results;
  for (const Type* type : LowerType(return_type)) {
    results.push_back(FreshNodeName());
    stack->Push(results.back());
    out_ << "    compiler::TNode<" << type->GetGeneratedTNodeTypeName() << "> "
         << stack->Top() << ";\n";
    out_ << "    USE(" << stack->Top() << ");\n";
  }
  std::string catch_name =
      PreCallableExceptionPreparation(instruction.catch_block);
  out_ << "    ";
  bool needs_flattening =
      return_type->IsStructType() || return_type->IsReferenceType();
  if (needs_flattening) {
    out_ << "std::tie(";
    PrintCommaSeparatedList(out_, results);
    out_ << ") = ";
  } else {
    if (results.size() == 1) {
      out_ << results[0] << " = ca_.UncheckedCast<"
           << return_type->GetGeneratedTNodeTypeName() << ">(";
    } else {
      DCHECK_EQ(0, results.size());
    }
  }
  out_ << instruction.macro->external_assembler_name() << "(state_)."
       << instruction.macro->ExternalName() << "(";
  PrintCommaSeparatedList(out_, args);
  if (needs_flattening) {
    out_ << ").Flatten();\n";
  } else {
    if (results.size() == 1) out_ << ")";
    out_ << ");\n";
  }
  PostCallableExceptionPreparation(catch_name, return_type,
                                   instruction.catch_block, &pre_call_stack);
}

void CSAGenerator::EmitInstruction(
    const CallCsaMacroAndBranchInstruction& instruction,
    Stack<std::string>* stack) {
  std::vector<std::string> constexpr_arguments =
      instruction.constexpr_arguments;
  std::vector<std::string> args;
  TypeVector parameter_types =
      instruction.macro->signature().parameter_types.types;
  ProcessArgumentsCommon(parameter_types, &args, &constexpr_arguments, stack);

  Stack<std::string> pre_call_stack = *stack;
  std::vector<std::string> results;
  const Type* return_type = instruction.macro->signature().return_type;
  if (return_type != TypeOracle::GetNeverType()) {
    for (const Type* type :
         LowerType(instruction.macro->signature().return_type)) {
      results.push_back(FreshNodeName());
      out_ << "    compiler::TNode<" << type->GetGeneratedTNodeTypeName()
           << "> " << results.back() << ";\n";
      out_ << "    USE(" << results.back() << ");\n";
    }
  }

  std::vector<std::string> label_names;
  std::vector<std::vector<std::string>> var_names;
  const LabelDeclarationVector& labels = instruction.macro->signature().labels;
  DCHECK_EQ(labels.size(), instruction.label_blocks.size());
  for (size_t i = 0; i < labels.size(); ++i) {
    TypeVector label_parameters = labels[i].types;
    label_names.push_back("label" + std::to_string(i));
    var_names.push_back({});
    for (size_t j = 0; j < label_parameters.size(); ++j) {
      var_names[i].push_back("result_" + std::to_string(i) + "_" +
                             std::to_string(j));
      out_ << "    compiler::TypedCodeAssemblerVariable<"
           << label_parameters[j]->GetGeneratedTNodeTypeName() << "> "
           << var_names[i][j] << "(&ca_);\n";
    }
    out_ << "    compiler::CodeAssemblerLabel " << label_names[i]
         << "(&ca_);\n";
  }

  std::string catch_name =
      PreCallableExceptionPreparation(instruction.catch_block);
  out_ << "    ";
  if (results.size() == 1) {
    out_ << results[0] << " = ";
  } else if (results.size() > 1) {
    out_ << "std::tie(";
    PrintCommaSeparatedList(out_, results);
    out_ << ") = ";
  }
  out_ << instruction.macro->external_assembler_name() << "(state_)."
       << instruction.macro->ExternalName() << "(";
  PrintCommaSeparatedList(out_, args);
  bool first = args.empty();
  for (size_t i = 0; i < label_names.size(); ++i) {
    if (!first) out_ << ", ";
    out_ << "&" << label_names[i];
    first = false;
    for (size_t j = 0; j < var_names[i].size(); ++j) {
      out_ << ", &" << var_names[i][j];
    }
  }
  if (return_type->IsStructType()) {
    out_ << ").Flatten();\n";
  } else {
    out_ << ");\n";
  }

  PostCallableExceptionPreparation(catch_name, return_type,
                                   instruction.catch_block, &pre_call_stack);

  if (instruction.return_continuation) {
    out_ << "    ca_.Goto(&" << BlockName(*instruction.return_continuation);
    for (const std::string& value : *stack) {
      out_ << ", " << value;
    }
    for (const std::string& result : results) {
      out_ << ", " << result;
    }
    out_ << ");\n";
  }
  for (size_t i = 0; i < label_names.size(); ++i) {
    out_ << "    if (" << label_names[i] << ".is_used()) {\n";
    out_ << "      ca_.Bind(&" << label_names[i] << ");\n";
    out_ << "      ca_.Goto(&" << BlockName(instruction.label_blocks[i]);
    for (const std::string& value : *stack) {
      out_ << ", " << value;
    }
    for (const std::string& var : var_names[i]) {
      out_ << ", " << var << ".value()";
    }
    out_ << ");\n";

    out_ << "    }\n";
  }
}

void CSAGenerator::EmitInstruction(const CallBuiltinInstruction& instruction,
                                   Stack<std::string>* stack) {
  std::vector<std::string> arguments = stack->PopMany(instruction.argc);
  std::vector<const Type*> result_types =
      LowerType(instruction.builtin->signature().return_type);
  if (instruction.is_tailcall) {
    out_ << "   CodeStubAssembler(state_).TailCallBuiltin(Builtins::k"
         << instruction.builtin->ExternalName() << ", ";
    PrintCommaSeparatedList(out_, arguments);
    out_ << ");\n";
  } else {
    std::string result_name = FreshNodeName();
    if (result_types.size() == 1) {
      out_ << "    compiler::TNode<"
           << result_types[0]->GetGeneratedTNodeTypeName() << "> "
           << result_name << ";\n";
    }
    std::string catch_name =
        PreCallableExceptionPreparation(instruction.catch_block);
    Stack<std::string> pre_call_stack = *stack;
    if (result_types.size() == 1) {
      std::string generated_type = result_types[0]->GetGeneratedTNodeTypeName();
      stack->Push(result_name);
      out_ << "    " << result_name << " = ";
      if (generated_type != "Object") out_ << "TORQUE_CAST(";
      out_ << "CodeStubAssembler(state_).CallBuiltin(Builtins::k"
           << instruction.builtin->ExternalName() << ", ";
      PrintCommaSeparatedList(out_, arguments);
      if (generated_type != "Object") out_ << ")";
      out_ << ");\n";
      out_ << "    USE(" << result_name << ");\n";
    } else {
      DCHECK_EQ(0, result_types.size());
      // TODO(tebbi): Actually, builtins have to return a value, so we should
      // not have to handle this case.
      out_ << "    CodeStubAssembler(state_).CallBuiltin(Builtins::k"
           << instruction.builtin->ExternalName() << ", ";
      PrintCommaSeparatedList(out_, arguments);
      out_ << ");\n";
    }
    PostCallableExceptionPreparation(
        catch_name,
        result_types.size() == 0 ? TypeOracle::GetVoidType() : result_types[0],
        instruction.catch_block, &pre_call_stack);
  }
}

void CSAGenerator::EmitInstruction(
    const CallBuiltinPointerInstruction& instruction,
    Stack<std::string>* stack) {
  std::vector<std::string> function_and_arguments =
      stack->PopMany(1 + instruction.argc);
  std::vector<const Type*> result_types =
      LowerType(instruction.type->return_type());
  if (result_types.size() != 1) {
    ReportError("builtins must have exactly one result");
  }
  if (instruction.is_tailcall) {
    ReportError("tail-calls to builtin pointers are not supported");
  }

  stack->Push(FreshNodeName());
  std::string generated_type = result_types[0]->GetGeneratedTNodeTypeName();
  out_ << "    compiler::TNode<" << generated_type << "> " << stack->Top()
       << " = ";
  if (generated_type != "Object") out_ << "TORQUE_CAST(";
  out_ << "CodeStubAssembler(state_).CallBuiltinPointer(Builtins::"
          "CallableFor(ca_."
          "isolate(),"
          "ExampleBuiltinForTorqueFunctionPointerType("
       << instruction.type->function_pointer_type_id() << ")).descriptor(), ";
  PrintCommaSeparatedList(out_, function_and_arguments);
  out_ << ")";
  if (generated_type != "Object") out_ << ")";
  out_ << "; \n";
  out_ << "    USE(" << stack->Top() << ");\n";
}

std::string CSAGenerator::PreCallableExceptionPreparation(
    base::Optional<Block*> catch_block) {
  std::string catch_name;
  if (catch_block) {
    catch_name = FreshCatchName();
    out_ << "    compiler::CodeAssemblerExceptionHandlerLabel " << catch_name
         << "_label(&ca_, compiler::CodeAssemblerLabel::kDeferred);\n";
    out_ << "    { compiler::CodeAssemblerScopedExceptionHandler s(&ca_, &"
         << catch_name << "_label);\n";
  }
  return catch_name;
}

void CSAGenerator::PostCallableExceptionPreparation(
    const std::string& catch_name, const Type* return_type,
    base::Optional<Block*> catch_block, Stack<std::string>* stack) {
  if (catch_block) {
    std::string block_name = BlockName(*catch_block);
    out_ << "    }\n";
    out_ << "    if (" << catch_name << "_label.is_used()) {\n";
    out_ << "      compiler::CodeAssemblerLabel " << catch_name
         << "_skip(&ca_);\n";
    if (!return_type->IsNever()) {
      out_ << "      ca_.Goto(&" << catch_name << "_skip);\n";
    }
    out_ << "      compiler::TNode<Object> " << catch_name
         << "_exception_object;\n";
    out_ << "      ca_.Bind(&" << catch_name << "_label, &" << catch_name
         << "_exception_object);\n";
    out_ << "      ca_.Goto(&" << block_name;
    for (size_t i = 0; i < stack->Size(); ++i) {
      out_ << ", " << stack->begin()[i];
    }
    out_ << ", " << catch_name << "_exception_object);\n";
    if (!return_type->IsNever()) {
      out_ << "      ca_.Bind(&" << catch_name << "_skip);\n";
    }
    out_ << "    }\n";
  }
}

void CSAGenerator::EmitInstruction(const CallRuntimeInstruction& instruction,
                                   Stack<std::string>* stack) {
  std::vector<std::string> arguments = stack->PopMany(instruction.argc);
  const Type* return_type =
      instruction.runtime_function->signature().return_type;
  std::vector<const Type*> result_types;
  if (return_type != TypeOracle::GetNeverType()) {
    result_types = LowerType(return_type);
  }
  if (result_types.size() > 1) {
    ReportError("runtime function must have at most one result");
  }
  if (instruction.is_tailcall) {
    out_ << "    CodeStubAssembler(state_).TailCallRuntime(Runtime::k"
         << instruction.runtime_function->ExternalName() << ", ";
    PrintCommaSeparatedList(out_, arguments);
    out_ << ");\n";
  } else {
    std::string result_name = FreshNodeName();
    if (result_types.size() == 1) {
      out_ << "    compiler::TNode<"
           << result_types[0]->GetGeneratedTNodeTypeName() << "> "
           << result_name << ";\n";
    }
    std::string catch_name =
        PreCallableExceptionPreparation(instruction.catch_block);
    Stack<std::string> pre_call_stack = *stack;
    if (result_types.size() == 1) {
      std::string generated_type = result_types[0]->GetGeneratedTNodeTypeName();
      stack->Push(result_name);
      out_ << "    " << result_name << " = ";
      if (generated_type != "Object") out_ << "TORQUE_CAST(";
      out_ << "CodeStubAssembler(state_).CallRuntime(Runtime::k"
           << instruction.runtime_function->ExternalName() << ", ";
      PrintCommaSeparatedList(out_, arguments);
      out_ << ")";
      if (generated_type != "Object") out_ << ")";
      out_ << "; \n";
      out_ << "    USE(" << result_name << ");\n";
    } else {
      DCHECK_EQ(0, result_types.size());
      out_ << "    CodeStubAssembler(state_).CallRuntime(Runtime::k"
           << instruction.runtime_function->ExternalName() << ", ";
      PrintCommaSeparatedList(out_, arguments);
      out_ << ");\n";
      if (return_type == TypeOracle::GetNeverType()) {
        out_ << "    CodeStubAssembler(state_).Unreachable();\n";
      } else {
        DCHECK(return_type == TypeOracle::GetVoidType());
      }
    }
    PostCallableExceptionPreparation(catch_name, return_type,
                                     instruction.catch_block, &pre_call_stack);
  }
}

void CSAGenerator::EmitInstruction(const BranchInstruction& instruction,
                                   Stack<std::string>* stack) {
  out_ << "    ca_.Branch(" << stack->Pop() << ", &"
       << BlockName(instruction.if_true) << ", &"
       << BlockName(instruction.if_false);
  for (const std::string& value : *stack) {
    out_ << ", " << value;
  }
  out_ << ");\n";
}

void CSAGenerator::EmitInstruction(
    const ConstexprBranchInstruction& instruction, Stack<std::string>* stack) {
  out_ << "    if ((" << instruction.condition << ")) {\n";
  out_ << "      ca_.Goto(&" << BlockName(instruction.if_true);
  for (const std::string& value : *stack) {
    out_ << ", " << value;
  }
  out_ << ");\n";
  out_ << "    } else {\n";
  out_ << "      ca_.Goto(&" << BlockName(instruction.if_false);
  for (const std::string& value : *stack) {
    out_ << ", " << value;
  }
  out_ << ");\n";

  out_ << "    }\n";
}

void CSAGenerator::EmitInstruction(const GotoInstruction& instruction,
                                   Stack<std::string>* stack) {
  out_ << "    ca_.Goto(&" << BlockName(instruction.destination);
  for (const std::string& value : *stack) {
    out_ << ", " << value;
  }
  out_ << ");\n";
}

void CSAGenerator::EmitInstruction(const GotoExternalInstruction& instruction,
                                   Stack<std::string>* stack) {
  for (auto it = instruction.variable_names.rbegin();
       it != instruction.variable_names.rend(); ++it) {
    out_ << "    *" << *it << " = " << stack->Pop() << ";\n";
  }
  out_ << "    ca_.Goto(" << instruction.destination << ");\n";
}

void CSAGenerator::EmitInstruction(const ReturnInstruction& instruction,
                                   Stack<std::string>* stack) {
  if (*linkage_ == Builtin::kVarArgsJavaScript) {
    out_ << "    " << ARGUMENTS_VARIABLE_STRING << ".PopAndReturn(";
  } else {
    out_ << "    CodeStubAssembler(state_).Return(";
  }
  out_ << stack->Pop() << ");\n";
}

void CSAGenerator::EmitInstruction(
    const PrintConstantStringInstruction& instruction,
    Stack<std::string>* stack) {
  out_ << "    CodeStubAssembler(state_).Print("
       << StringLiteralQuote(instruction.message) << ");\n";
}

void CSAGenerator::EmitInstruction(const AbortInstruction& instruction,
                                   Stack<std::string>* stack) {
  switch (instruction.kind) {
    case AbortInstruction::Kind::kUnreachable:
      DCHECK(instruction.message.empty());
      out_ << "    CodeStubAssembler(state_).Unreachable();\n";
      break;
    case AbortInstruction::Kind::kDebugBreak:
      DCHECK(instruction.message.empty());
      out_ << "    CodeStubAssembler(state_).DebugBreak();\n";
      break;
    case AbortInstruction::Kind::kAssertionFailure: {
      std::string file =
          StringLiteralQuote(SourceFileMap::GetSource(instruction.pos.source));
      out_ << "    CodeStubAssembler(state_).FailAssert("
           << StringLiteralQuote(instruction.message) << ", " << file << ", "
           << instruction.pos.start.line + 1 << ");\n";
      break;
    }
  }
}

void CSAGenerator::EmitInstruction(const UnsafeCastInstruction& instruction,
                                   Stack<std::string>* stack) {
  stack->Poke(stack->AboveTop() - 1,
              "ca_.UncheckedCast<" +
                  instruction.destination_type->GetGeneratedTNodeTypeName() +
                  ">(" + stack->Top() + ")");
}

void CSAGenerator::EmitInstruction(
    const CreateFieldReferenceInstruction& instruction,
    Stack<std::string>* stack) {
  const Field& field =
      instruction.class_type->LookupField(instruction.field_name);
  std::string offset_name = FreshNodeName();
  stack->Push(offset_name);

  out_ << "    compiler::TNode<IntPtrT> " << offset_name
       << " = ca_.IntPtrConstant(";
  if (instruction.class_type->IsExtern()) {
    out_ << field.aggregate->GetGeneratedTNodeTypeName() << "::k"
         << CamelifyString(field.name_and_type.name) << "Offset";
  } else {
    out_ << "FixedArray::kHeaderSize + " << field.offset;
  }
  out_ << ");\n"
       << "    USE(" << stack->Top() << ");\n";
}

void CSAGenerator::EmitInstruction(const LoadReferenceInstruction& instruction,
                                   Stack<std::string>* stack) {
  std::string result_name = FreshNodeName();

  std::string offset = stack->Pop();
  std::string object = stack->Pop();
  stack->Push(result_name);

  out_ << "    " << instruction.type->GetGeneratedTypeName() << result_name
       << " = CodeStubAssembler(state_).LoadReference<"
       << instruction.type->GetGeneratedTNodeTypeName()
       << ">(CodeStubAssembler::Reference{" << object << ", " << offset
       << "});\n";
}

void CSAGenerator::EmitInstruction(const StoreReferenceInstruction& instruction,
                                   Stack<std::string>* stack) {
  std::string value = stack->Pop();
  std::string offset = stack->Pop();
  std::string object = stack->Pop();

  out_ << "    CodeStubAssembler(state_).StoreReference(CodeStubAssembler::"
          "Reference{"
       << object << ", " << offset << "}, " << value << ");\n";
}

// static
void CSAGenerator::EmitCSAValue(VisitResult result,
                                const Stack<std::string>& values,
                                std::ostream& out) {
  if (!result.IsOnStack()) {
    out << result.constexpr_value();
  } else if (auto* struct_type = StructType::DynamicCast(result.type())) {
    out << struct_type->GetGeneratedTypeName() << "{";
    bool first = true;
    for (auto& field : struct_type->fields()) {
      if (!first) {
        out << ", ";
      }
      first = false;
      EmitCSAValue(ProjectStructField(result, field.name_and_type.name), values,
                   out);
    }
    out << "}";
  } else if (result.type()->IsReferenceType()) {
    DCHECK_EQ(2, result.stack_range().Size());
    size_t offset = result.stack_range().begin().offset;
    out << "CodeStubAssembler::Reference{" << values.Peek(BottomOffset{offset})
        << ", " << values.Peek(BottomOffset{offset + 1}) << "}";
  } else {
    DCHECK_EQ(1, result.stack_range().Size());
    out << "compiler::TNode<" << result.type()->GetGeneratedTNodeTypeName()
        << ">{" << values.Peek(result.stack_range().begin()) << "}";
  }
}

}  // namespace torque
}  // namespace internal
}  // namespace v8
