// 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.

#include "test/unittests/compiler/graph-unittest.h"

#include "src/compiler/js-heap-copy-reducer.h"
#include "src/compiler/node-properties.h"
#include "src/heap/factory.h"
#include "src/objects/objects-inl.h"  // TODO(everyone): Make typer.h IWYU compliant.
#include "test/unittests/compiler/node-test-utils.h"

namespace v8 {
namespace internal {
namespace compiler {

GraphTest::GraphTest(int num_parameters)
    : canonical_(isolate()),
      common_(zone()),
      graph_(zone()),
      broker_(isolate(), zone(), FLAG_trace_heap_broker),
      source_positions_(&graph_),
      node_origins_(&graph_) {
  graph()->SetStart(graph()->NewNode(common()->Start(num_parameters)));
  graph()->SetEnd(graph()->NewNode(common()->End(1), graph()->start()));
  broker()->SetNativeContextRef();
}

GraphTest::~GraphTest() = default;


Node* GraphTest::Parameter(int32_t index) {
  return graph()->NewNode(common()->Parameter(index), graph()->start());
}

Node* GraphTest::Parameter(Type type, int32_t index) {
  Node* node = GraphTest::Parameter(index);
  NodeProperties::SetType(node, type);
  return node;
}

Node* GraphTest::Float32Constant(volatile float value) {
  return graph()->NewNode(common()->Float32Constant(value));
}


Node* GraphTest::Float64Constant(volatile double value) {
  return graph()->NewNode(common()->Float64Constant(value));
}


Node* GraphTest::Int32Constant(int32_t value) {
  return graph()->NewNode(common()->Int32Constant(value));
}


Node* GraphTest::Int64Constant(int64_t value) {
  return graph()->NewNode(common()->Int64Constant(value));
}


Node* GraphTest::NumberConstant(volatile double value) {
  return graph()->NewNode(common()->NumberConstant(value));
}


Node* GraphTest::HeapConstant(const Handle<HeapObject>& value) {
  Node* node = graph()->NewNode(common()->HeapConstant(value));
  Type type = Type::NewConstant(broker(), value, zone());
  NodeProperties::SetType(node, type);
  return node;
}


Node* GraphTest::FalseConstant() {
  return HeapConstant(factory()->false_value());
}


Node* GraphTest::TrueConstant() {
  return HeapConstant(factory()->true_value());
}


Node* GraphTest::UndefinedConstant() {
  return HeapConstant(factory()->undefined_value());
}


Node* GraphTest::EmptyFrameState() {
  Node* state_values =
      graph()->NewNode(common()->StateValues(0, SparseInputMask::Dense()));
  return graph()->NewNode(
      common()->FrameState(BailoutId::None(), OutputFrameStateCombine::Ignore(),
                           nullptr),
      state_values, state_values, state_values, NumberConstant(0),
      UndefinedConstant(), graph()->start());
}


Matcher<Node*> GraphTest::IsFalseConstant() {
  return IsHeapConstant(factory()->false_value());
}


Matcher<Node*> GraphTest::IsTrueConstant() {
  return IsHeapConstant(factory()->true_value());
}

Matcher<Node*> GraphTest::IsNullConstant() {
  return IsHeapConstant(factory()->null_value());
}

Matcher<Node*> GraphTest::IsUndefinedConstant() {
  return IsHeapConstant(factory()->undefined_value());
}

TypedGraphTest::TypedGraphTest(int num_parameters)
    : GraphTest(num_parameters),
      typer_(broker(), Typer::kNoFlags, graph(), tick_counter()) {}

TypedGraphTest::~TypedGraphTest() = default;

namespace graph_unittest {

const Operator kDummyOperator(0, Operator::kNoProperties, "Dummy", 0, 0, 0, 1,
                              0, 0);


TEST_F(GraphTest, NewNode) {
  Node* n0 = graph()->NewNode(&kDummyOperator);
  Node* n1 = graph()->NewNode(&kDummyOperator);
  EXPECT_NE(n0, n1);
  EXPECT_LT(0u, n0->id());
  EXPECT_LT(0u, n1->id());
  EXPECT_NE(n0->id(), n1->id());
  EXPECT_EQ(&kDummyOperator, n0->op());
  EXPECT_EQ(&kDummyOperator, n1->op());
}

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