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

#ifndef V8_CCTEST_COMPILER_GRAPH_BUILDER_TESTER_H_
#define V8_CCTEST_COMPILER_GRAPH_BUILDER_TESTER_H_

#include "src/assembler.h"
#include "src/compiler/backend/instruction-selector.h"
#include "src/compiler/common-operator.h"
#include "src/compiler/linkage.h"
#include "src/compiler/machine-operator.h"
#include "src/compiler/operator-properties.h"
#include "src/compiler/pipeline.h"
#include "src/compiler/simplified-operator.h"
#include "src/optimized-compilation-info.h"
#include "test/cctest/cctest.h"
#include "test/cctest/compiler/call-tester.h"

namespace v8 {
namespace internal {
namespace compiler {

class GraphAndBuilders {
 public:
  explicit GraphAndBuilders(Zone* zone)
      : main_graph_(new (zone) Graph(zone)),
        main_common_(zone),
        main_machine_(zone, MachineType::PointerRepresentation(),
                      InstructionSelector::SupportedMachineOperatorFlags(),
                      InstructionSelector::AlignmentRequirements()),
        main_simplified_(zone) {}

  Graph* graph() const { return main_graph_; }
  Zone* zone() const { return graph()->zone(); }
  CommonOperatorBuilder* common() { return &main_common_; }
  MachineOperatorBuilder* machine() { return &main_machine_; }
  SimplifiedOperatorBuilder* simplified() { return &main_simplified_; }

 protected:
  // Prefixed with main_ to avoid naming conflicts.
  Graph* main_graph_;
  CommonOperatorBuilder main_common_;
  MachineOperatorBuilder main_machine_;
  SimplifiedOperatorBuilder main_simplified_;
};


template <typename ReturnType>
class GraphBuilderTester : public HandleAndZoneScope,
                           public GraphAndBuilders,
                           public CallHelper<ReturnType> {
 public:
  template <typename... ParamMachTypes>
  explicit GraphBuilderTester(ParamMachTypes... p)
      : GraphAndBuilders(main_zone()),
        CallHelper<ReturnType>(
            main_isolate(),
            CSignature::New(main_zone(), MachineTypeForC<ReturnType>(), p...)),
        effect_(nullptr),
        return_(nullptr),
        parameters_(main_zone()->template NewArray<Node*>(parameter_count())) {
    Begin(static_cast<int>(parameter_count()));
    InitParameters();
  }
  ~GraphBuilderTester() override = default;

  void GenerateCode() { Generate(); }
  Node* Parameter(size_t index) {
    CHECK_LT(index, parameter_count());
    return parameters_[index];
  }

  Isolate* isolate() { return main_isolate(); }
  Factory* factory() { return isolate()->factory(); }

  // Initialize graph and builder.
  void Begin(int num_parameters) {
    CHECK_NULL(graph()->start());
    Node* start = graph()->NewNode(common()->Start(num_parameters + 3));
    graph()->SetStart(start);
    effect_ = start;
  }

  void Return(Node* value) {
    Node* zero = graph()->NewNode(common()->Int32Constant(0));
    return_ = graph()->NewNode(common()->Return(), zero, value, effect_,
                               graph()->start());
    effect_ = nullptr;
  }

  // Close the graph.
  void End() {
    Node* end = graph()->NewNode(common()->End(1), return_);
    graph()->SetEnd(end);
  }

  Node* PointerConstant(void* value) {
    intptr_t intptr_value = reinterpret_cast<intptr_t>(value);
    return kSystemPointerSize == 8
               ? NewNode(common()->Int64Constant(intptr_value))
               : Int32Constant(static_cast<int>(intptr_value));
  }
  Node* Int32Constant(int32_t value) {
    return NewNode(common()->Int32Constant(value));
  }
  Node* HeapConstant(Handle<HeapObject> object) {
    return NewNode(common()->HeapConstant(object));
  }

  Node* BooleanNot(Node* a) { return NewNode(simplified()->BooleanNot(), a); }

  Node* NumberEqual(Node* a, Node* b) {
    return NewNode(simplified()->NumberEqual(), a, b);
  }
  Node* NumberLessThan(Node* a, Node* b) {
    return NewNode(simplified()->NumberLessThan(), a, b);
  }
  Node* NumberLessThanOrEqual(Node* a, Node* b) {
    return NewNode(simplified()->NumberLessThanOrEqual(), a, b);
  }
  Node* NumberAdd(Node* a, Node* b) {
    return NewNode(simplified()->NumberAdd(), a, b);
  }
  Node* NumberSubtract(Node* a, Node* b) {
    return NewNode(simplified()->NumberSubtract(), a, b);
  }
  Node* NumberMultiply(Node* a, Node* b) {
    return NewNode(simplified()->NumberMultiply(), a, b);
  }
  Node* NumberDivide(Node* a, Node* b) {
    return NewNode(simplified()->NumberDivide(), a, b);
  }
  Node* NumberModulus(Node* a, Node* b) {
    return NewNode(simplified()->NumberModulus(), a, b);
  }
  Node* NumberToInt32(Node* a) {
    return NewNode(simplified()->NumberToInt32(), a);
  }
  Node* NumberToUint32(Node* a) {
    return NewNode(simplified()->NumberToUint32(), a);
  }

  Node* StringEqual(Node* a, Node* b) {
    return NewNode(simplified()->StringEqual(), a, b);
  }
  Node* StringLessThan(Node* a, Node* b) {
    return NewNode(simplified()->StringLessThan(), a, b);
  }
  Node* StringLessThanOrEqual(Node* a, Node* b) {
    return NewNode(simplified()->StringLessThanOrEqual(), a, b);
  }

  Node* ChangeTaggedToInt32(Node* a) {
    return NewNode(simplified()->ChangeTaggedToInt32(), a);
  }
  Node* ChangeTaggedToUint32(Node* a) {
    return NewNode(simplified()->ChangeTaggedToUint32(), a);
  }
  Node* ChangeTaggedToFloat64(Node* a) {
    return NewNode(simplified()->ChangeTaggedToFloat64(), a);
  }
  Node* ChangeInt32ToTagged(Node* a) {
    return NewNode(simplified()->ChangeInt32ToTagged(), a);
  }
  Node* ChangeUint32ToTagged(Node* a) {
    return NewNode(simplified()->ChangeUint32ToTagged(), a);
  }
  Node* ChangeTaggedToBit(Node* a) {
    return NewNode(simplified()->ChangeTaggedToBit(), a);
  }
  Node* ChangeBitToTagged(Node* a) {
    return NewNode(simplified()->ChangeBitToTagged(), a);
  }

  Node* LoadField(const FieldAccess& access, Node* object) {
    return NewNode(simplified()->LoadField(access), object);
  }
  Node* StoreField(const FieldAccess& access, Node* object, Node* value) {
    return NewNode(simplified()->StoreField(access), object, value);
  }
  Node* LoadElement(const ElementAccess& access, Node* object, Node* index) {
    return NewNode(simplified()->LoadElement(access), object, index);
  }
  Node* StoreElement(const ElementAccess& access, Node* object, Node* index,
                     Node* value) {
    return NewNode(simplified()->StoreElement(access), object, index, value);
  }

  template <typename... NodePtrs>
  Node* NewNode(const Operator* op, NodePtrs... n) {
    std::array<Node*, sizeof...(n)> inputs{{n...}};
    return MakeNode(op, inputs.size(), inputs.data());
  }

  Node* NewNode(const Operator* op, int value_input_count,
                Node** value_inputs) {
    return MakeNode(op, value_input_count, value_inputs);
  }

  Handle<Code> GetCode() {
    Generate();
    return code_.ToHandleChecked();
  }

 protected:
  Node* MakeNode(const Operator* op, int value_input_count,
                 Node** value_inputs) {
    CHECK_EQ(op->ValueInputCount(), value_input_count);

    CHECK(!OperatorProperties::HasContextInput(op));
    CHECK(!OperatorProperties::HasFrameStateInput(op));
    bool has_control = op->ControlInputCount() == 1;
    bool has_effect = op->EffectInputCount() == 1;

    CHECK_LT(op->ControlInputCount(), 2);
    CHECK_LT(op->EffectInputCount(), 2);

    Node* result = nullptr;
    if (!has_control && !has_effect) {
      result = graph()->NewNode(op, value_input_count, value_inputs);
    } else {
      int input_count_with_deps = value_input_count;
      if (has_control) ++input_count_with_deps;
      if (has_effect) ++input_count_with_deps;
      Node** buffer = zone()->template NewArray<Node*>(input_count_with_deps);
      memcpy(buffer, value_inputs, kSystemPointerSize * value_input_count);
      Node** current_input = buffer + value_input_count;
      if (has_effect) {
        *current_input++ = effect_;
      }
      if (has_control) {
        *current_input++ = graph()->start();
      }
      result = graph()->NewNode(op, input_count_with_deps, buffer);
      if (has_effect) {
        effect_ = result;
      }
      // This graph builder does not support control flow.
      CHECK_EQ(0, op->ControlOutputCount());
    }

    return result;
  }

  Address Generate() override {
    if (code_.is_null()) {
      Zone* zone = graph()->zone();
      auto call_descriptor =
          Linkage::GetSimplifiedCDescriptor(zone, this->csig_);
      OptimizedCompilationInfo info(ArrayVector("testing"), main_zone(),
                                    Code::STUB);
      code_ = Pipeline::GenerateCodeForTesting(
          &info, main_isolate(), call_descriptor, graph(),
          AssemblerOptions::Default(main_isolate()));
#ifdef ENABLE_DISASSEMBLER
      if (!code_.is_null() && FLAG_print_opt_code) {
        StdoutStream os;
        code_.ToHandleChecked()->Disassemble("test code", os);
      }
#endif
    }
    return code_.ToHandleChecked()->entry();
  }

  void InitParameters() {
    int param_count = static_cast<int>(parameter_count());
    for (int i = 0; i < param_count; ++i) {
      parameters_[i] = this->NewNode(common()->Parameter(i), graph()->start());
    }
  }

  size_t parameter_count() const { return this->csig_->parameter_count(); }

 private:
  Node* effect_;
  Node* return_;
  Node** parameters_;
  MaybeHandle<Code> code_;
};

}  // namespace compiler
}  // namespace internal
}  // namespace v8

#endif  // V8_CCTEST_COMPILER_GRAPH_BUILDER_TESTER_H_
