// 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/instructions.h"
#include "src/torque/cfg.h"
#include "src/torque/type-oracle.h"

namespace v8 {
namespace internal {
namespace torque {

#define TORQUE_INSTRUCTION_BOILERPLATE_DEFINITIONS(Name)        \
  const InstructionKind Name::kKind = InstructionKind::k##Name; \
  std::unique_ptr<InstructionBase> Name::Clone() const {        \
    return std::unique_ptr<InstructionBase>(new Name(*this));   \
  }                                                             \
  void Name::Assign(const InstructionBase& other) {             \
    *this = static_cast<const Name&>(other);                    \
  }
TORQUE_INSTRUCTION_LIST(TORQUE_INSTRUCTION_BOILERPLATE_DEFINITIONS)
#undef TORQUE_INSTRUCTION_BOILERPLATE_DEFINITIONS

namespace {
void ExpectType(const Type* expected, const Type* actual) {
  if (expected != actual) {
    ReportError("expected type ", *expected, " but found ", *actual);
  }
}
void ExpectSubtype(const Type* subtype, const Type* supertype) {
  if (!subtype->IsSubtypeOf(supertype)) {
    ReportError("type ", *subtype, " is not a subtype of ", *supertype);
  }
}
}  // namespace

void PeekInstruction::TypeInstruction(Stack<const Type*>* stack,
                                      ControlFlowGraph* cfg) const {
  const Type* type = stack->Peek(slot);
  if (widened_type) {
    if (type->IsTopType()) {
      const TopType* top_type = TopType::cast(type);
      ReportError("use of " + top_type->reason());
    }
    ExpectSubtype(type, *widened_type);
    type = *widened_type;
  }
  stack->Push(type);
}

void PokeInstruction::TypeInstruction(Stack<const Type*>* stack,
                                      ControlFlowGraph* cfg) const {
  const Type* type = stack->Top();
  if (widened_type) {
    ExpectSubtype(type, *widened_type);
    type = *widened_type;
  }
  stack->Poke(slot, type);
  stack->Pop();
}

void DeleteRangeInstruction::TypeInstruction(Stack<const Type*>* stack,
                                             ControlFlowGraph* cfg) const {
  stack->DeleteRange(range);
}

void PushUninitializedInstruction::TypeInstruction(
    Stack<const Type*>* stack, ControlFlowGraph* cfg) const {
  stack->Push(type);
}

void PushBuiltinPointerInstruction::TypeInstruction(
    Stack<const Type*>* stack, ControlFlowGraph* cfg) const {
  stack->Push(type);
}

void NamespaceConstantInstruction::TypeInstruction(
    Stack<const Type*>* stack, ControlFlowGraph* cfg) const {
  stack->PushMany(LowerType(constant->type()));
}

void InstructionBase::InvalidateTransientTypes(
    Stack<const Type*>* stack) const {
  auto current = stack->begin();
  while (current != stack->end()) {
    if ((*current)->IsTransient()) {
      std::stringstream stream;
      stream << "type " << **current
             << " is made invalid by transitioning callable invocation at "
             << PositionAsString(pos);
      *current = TypeOracle::GetTopType(stream.str(), *current);
    }
    ++current;
  }
}

void CallIntrinsicInstruction::TypeInstruction(Stack<const Type*>* stack,
                                               ControlFlowGraph* cfg) const {
  std::vector<const Type*> parameter_types =
      LowerParameterTypes(intrinsic->signature().parameter_types);
  for (intptr_t i = parameter_types.size() - 1; i >= 0; --i) {
    const Type* arg_type = stack->Pop();
    const Type* parameter_type = parameter_types.back();
    parameter_types.pop_back();
    if (arg_type != parameter_type) {
      ReportError("parameter ", i, ": expected type ", *parameter_type,
                  " but found type ", *arg_type);
    }
  }
  if (intrinsic->IsTransitioning()) {
    InvalidateTransientTypes(stack);
  }
  stack->PushMany(LowerType(intrinsic->signature().return_type));
}

void CallCsaMacroInstruction::TypeInstruction(Stack<const Type*>* stack,
                                              ControlFlowGraph* cfg) const {
  std::vector<const Type*> parameter_types =
      LowerParameterTypes(macro->signature().parameter_types);
  for (intptr_t i = parameter_types.size() - 1; i >= 0; --i) {
    const Type* arg_type = stack->Pop();
    const Type* parameter_type = parameter_types.back();
    parameter_types.pop_back();
    if (arg_type != parameter_type) {
      ReportError("parameter ", i, ": expected type ", *parameter_type,
                  " but found type ", *arg_type);
    }
  }

  if (macro->IsTransitioning()) {
    InvalidateTransientTypes(stack);
  }

  if (catch_block) {
    Stack<const Type*> catch_stack = *stack;
    catch_stack.Push(TypeOracle::GetObjectType());
    (*catch_block)->SetInputTypes(catch_stack);
  }

  stack->PushMany(LowerType(macro->signature().return_type));
}

void CallCsaMacroAndBranchInstruction::TypeInstruction(
    Stack<const Type*>* stack, ControlFlowGraph* cfg) const {
  std::vector<const Type*> parameter_types =
      LowerParameterTypes(macro->signature().parameter_types);
  for (intptr_t i = parameter_types.size() - 1; i >= 0; --i) {
    const Type* arg_type = stack->Pop();
    const Type* parameter_type = parameter_types.back();
    parameter_types.pop_back();
    if (arg_type != parameter_type) {
      ReportError("parameter ", i, ": expected type ", *parameter_type,
                  " but found type ", *arg_type);
    }
  }

  if (label_blocks.size() != macro->signature().labels.size()) {
    ReportError("wrong number of labels");
  }
  for (size_t i = 0; i < label_blocks.size(); ++i) {
    Stack<const Type*> continuation_stack = *stack;
    continuation_stack.PushMany(
        LowerParameterTypes(macro->signature().labels[i].types));
    label_blocks[i]->SetInputTypes(std::move(continuation_stack));
  }

  if (macro->IsTransitioning()) {
    InvalidateTransientTypes(stack);
  }

  if (catch_block) {
    Stack<const Type*> catch_stack = *stack;
    catch_stack.Push(TypeOracle::GetObjectType());
    (*catch_block)->SetInputTypes(catch_stack);
  }

  if (macro->signature().return_type != TypeOracle::GetNeverType()) {
    Stack<const Type*> return_stack = *stack;
    return_stack.PushMany(LowerType(macro->signature().return_type));
    if (return_continuation == base::nullopt) {
      ReportError("missing return continuation.");
    }
    (*return_continuation)->SetInputTypes(return_stack);
  } else {
    if (return_continuation != base::nullopt) {
      ReportError("unreachable return continuation.");
    }
  }
}

void CallBuiltinInstruction::TypeInstruction(Stack<const Type*>* stack,
                                             ControlFlowGraph* cfg) const {
  std::vector<const Type*> argument_types = stack->PopMany(argc);
  if (argument_types !=
      LowerParameterTypes(builtin->signature().parameter_types)) {
    ReportError("wrong argument types");
  }
  if (builtin->IsTransitioning()) {
    InvalidateTransientTypes(stack);
  }

  if (catch_block) {
    Stack<const Type*> catch_stack = *stack;
    catch_stack.Push(TypeOracle::GetObjectType());
    (*catch_block)->SetInputTypes(catch_stack);
  }

  stack->PushMany(LowerType(builtin->signature().return_type));
}

void CallBuiltinPointerInstruction::TypeInstruction(
    Stack<const Type*>* stack, ControlFlowGraph* cfg) const {
  std::vector<const Type*> argument_types = stack->PopMany(argc);
  const BuiltinPointerType* f = BuiltinPointerType::DynamicCast(stack->Pop());
  if (!f) ReportError("expected function pointer type");
  if (argument_types != LowerParameterTypes(f->parameter_types())) {
    ReportError("wrong argument types");
  }
  // TODO(tebbi): Only invalidate transient types if the function pointer type
  // is transitioning.
  InvalidateTransientTypes(stack);
  stack->PushMany(LowerType(f->return_type()));
}

void CallRuntimeInstruction::TypeInstruction(Stack<const Type*>* stack,
                                             ControlFlowGraph* cfg) const {
  std::vector<const Type*> argument_types = stack->PopMany(argc);
  if (argument_types !=
      LowerParameterTypes(runtime_function->signature().parameter_types,
                          argc)) {
    ReportError("wrong argument types");
  }
  if (runtime_function->IsTransitioning()) {
    InvalidateTransientTypes(stack);
  }

  if (catch_block) {
    Stack<const Type*> catch_stack = *stack;
    catch_stack.Push(TypeOracle::GetObjectType());
    (*catch_block)->SetInputTypes(catch_stack);
  }

  const Type* return_type = runtime_function->signature().return_type;
  if (return_type != TypeOracle::GetNeverType()) {
    stack->PushMany(LowerType(return_type));
  }
}

void BranchInstruction::TypeInstruction(Stack<const Type*>* stack,
                                        ControlFlowGraph* cfg) const {
  const Type* condition_type = stack->Pop();
  if (condition_type != TypeOracle::GetBoolType()) {
    ReportError("condition has to have type bool");
  }
  if_true->SetInputTypes(*stack);
  if_false->SetInputTypes(*stack);
}

void ConstexprBranchInstruction::TypeInstruction(Stack<const Type*>* stack,
                                                 ControlFlowGraph* cfg) const {
  if_true->SetInputTypes(*stack);
  if_false->SetInputTypes(*stack);
}

void GotoInstruction::TypeInstruction(Stack<const Type*>* stack,
                                      ControlFlowGraph* cfg) const {
  destination->SetInputTypes(*stack);
}

void GotoExternalInstruction::TypeInstruction(Stack<const Type*>* stack,
                                              ControlFlowGraph* cfg) const {
  if (variable_names.size() != stack->Size()) {
    ReportError("goto external label with wrong parameter count.");
  }
}

void ReturnInstruction::TypeInstruction(Stack<const Type*>* stack,
                                        ControlFlowGraph* cfg) const {
  cfg->SetReturnType(stack->Pop());
}

void PrintConstantStringInstruction::TypeInstruction(
    Stack<const Type*>* stack, ControlFlowGraph* cfg) const {}

void AbortInstruction::TypeInstruction(Stack<const Type*>* stack,
                                       ControlFlowGraph* cfg) const {}

void UnsafeCastInstruction::TypeInstruction(Stack<const Type*>* stack,
                                            ControlFlowGraph* cfg) const {
  stack->Poke(stack->AboveTop() - 1, destination_type);
}

void CreateFieldReferenceInstruction::TypeInstruction(
    Stack<const Type*>* stack, ControlFlowGraph* cfg) const {
  ExpectSubtype(stack->Pop(), class_type);
  stack->Push(TypeOracle::GetHeapObjectType());
  stack->Push(TypeOracle::GetIntPtrType());
}

void LoadReferenceInstruction::TypeInstruction(Stack<const Type*>* stack,
                                               ControlFlowGraph* cfg) const {
  ExpectType(TypeOracle::GetIntPtrType(), stack->Pop());
  ExpectType(TypeOracle::GetHeapObjectType(), stack->Pop());
  DCHECK_EQ(std::vector<const Type*>{type}, LowerType(type));
  stack->Push(type);
}

void StoreReferenceInstruction::TypeInstruction(Stack<const Type*>* stack,
                                                ControlFlowGraph* cfg) const {
  ExpectSubtype(stack->Pop(), type);
  ExpectType(TypeOracle::GetIntPtrType(), stack->Pop());
  ExpectType(TypeOracle::GetHeapObjectType(), stack->Pop());
}

bool CallRuntimeInstruction::IsBlockTerminator() const {
  return is_tailcall || runtime_function->signature().return_type ==
                            TypeOracle::GetNeverType();
}

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