// 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 "src/compiler/js-builtin-reducer.h"
#include "src/compiler/js-graph.h"
#include "src/compiler/node-properties.h"
#include "src/compiler/simplified-operator.h"
#include "src/compiler/typer.h"
#include "src/isolate-inl.h"
#include "test/unittests/compiler/graph-unittest.h"
#include "test/unittests/compiler/node-test-utils.h"
#include "testing/gmock-support.h"

using testing::BitEq;
using testing::Capture;

namespace v8 {
namespace internal {
namespace compiler {

class JSBuiltinReducerTest : public TypedGraphTest {
 public:
  JSBuiltinReducerTest() : javascript_(zone()) {}

 protected:
  Reduction Reduce(Node* node, MachineOperatorBuilder::Flags flags =
                                   MachineOperatorBuilder::Flag::kNoFlags) {
    MachineOperatorBuilder machine(zone(), MachineType::PointerRepresentation(),
                                   flags);
    SimplifiedOperatorBuilder simplified(zone());
    JSGraph jsgraph(isolate(), graph(), common(), javascript(), &simplified,
                    &machine);
    // TODO(titzer): mock the GraphReducer here for better unit testing.
    GraphReducer graph_reducer(zone(), graph());
    JSBuiltinReducer reducer(&graph_reducer, &jsgraph);
    return reducer.Reduce(node);
  }

  Node* MathFunction(const char* name) {
    Handle<Object> m =
        JSObject::GetProperty(isolate()->global_object(),
                              isolate()->factory()->NewStringFromAsciiChecked(
                                  "Math")).ToHandleChecked();
    Handle<JSFunction> f = Handle<JSFunction>::cast(
        JSObject::GetProperty(
            m, isolate()->factory()->NewStringFromAsciiChecked(name))
            .ToHandleChecked());
    return HeapConstant(f);
  }

  JSOperatorBuilder* javascript() { return &javascript_; }

 private:
  JSOperatorBuilder javascript_;
};


namespace {

Type* const kIntegral32Types[] = {Type::UnsignedSmall(), Type::Negative32(),
                                  Type::Unsigned31(),    Type::SignedSmall(),
                                  Type::Signed32(),      Type::Unsigned32(),
                                  Type::Integral32()};


const LanguageMode kLanguageModes[] = {SLOPPY, STRICT, STRONG};


// TODO(mstarzinger): Find a common place and unify with test-js-typed-lowering.
Type* const kNumberTypes[] = {
    Type::UnsignedSmall(), Type::Negative32(),  Type::Unsigned31(),
    Type::SignedSmall(),   Type::Signed32(),    Type::Unsigned32(),
    Type::Integral32(),    Type::MinusZero(),   Type::NaN(),
    Type::OrderedNumber(), Type::PlainNumber(), Type::Number()};

}  // namespace


// -----------------------------------------------------------------------------
// Math.max


TEST_F(JSBuiltinReducerTest, MathMax0) {
  Node* function = MathFunction("max");

  Node* effect = graph()->start();
  Node* control = graph()->start();
  Node* context = UndefinedConstant();
  Node* frame_state = graph()->start();
  TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
    Node* call = graph()->NewNode(javascript()->CallFunction(2, language_mode),
                                  function, UndefinedConstant(), context,
                                  frame_state, frame_state, effect, control);
    Reduction r = Reduce(call);

    ASSERT_TRUE(r.Changed());
    EXPECT_THAT(r.replacement(), IsNumberConstant(-V8_INFINITY));
  }
}


TEST_F(JSBuiltinReducerTest, MathMax1) {
  Node* function = MathFunction("max");

  Node* effect = graph()->start();
  Node* control = graph()->start();
  Node* context = UndefinedConstant();
  Node* frame_state = graph()->start();
  TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
    TRACED_FOREACH(Type*, t0, kNumberTypes) {
      Node* p0 = Parameter(t0, 0);
      Node* call =
          graph()->NewNode(javascript()->CallFunction(3, language_mode),
                           function, UndefinedConstant(), p0, context,
                           frame_state, frame_state, effect, control);
      Reduction r = Reduce(call);

      ASSERT_TRUE(r.Changed());
      EXPECT_THAT(r.replacement(), p0);
    }
  }
}


TEST_F(JSBuiltinReducerTest, MathMax2) {
  Node* function = MathFunction("max");

  Node* effect = graph()->start();
  Node* control = graph()->start();
  Node* context = UndefinedConstant();
  Node* frame_state = graph()->start();
  TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
    TRACED_FOREACH(Type*, t0, kIntegral32Types) {
      TRACED_FOREACH(Type*, t1, kIntegral32Types) {
        Node* p0 = Parameter(t0, 0);
        Node* p1 = Parameter(t1, 1);
        Node* call =
            graph()->NewNode(javascript()->CallFunction(4, language_mode),
                             function, UndefinedConstant(), p0, p1, context,
                             frame_state, frame_state, effect, control);
        Reduction r = Reduce(call);

        ASSERT_TRUE(r.Changed());
        EXPECT_THAT(r.replacement(),
                    IsSelect(MachineRepresentation::kNone,
                             IsNumberLessThan(p1, p0), p0, p1));
      }
    }
  }
}


// -----------------------------------------------------------------------------
// Math.imul


TEST_F(JSBuiltinReducerTest, MathImul) {
  Node* function = MathFunction("imul");

  Node* effect = graph()->start();
  Node* control = graph()->start();
  Node* context = UndefinedConstant();
  Node* frame_state = graph()->start();
  TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
    TRACED_FOREACH(Type*, t0, kIntegral32Types) {
      TRACED_FOREACH(Type*, t1, kIntegral32Types) {
        Node* p0 = Parameter(t0, 0);
        Node* p1 = Parameter(t1, 1);
        Node* call =
            graph()->NewNode(javascript()->CallFunction(4, language_mode),
                             function, UndefinedConstant(), p0, p1, context,
                             frame_state, frame_state, effect, control);
        Reduction r = Reduce(call);

        ASSERT_TRUE(r.Changed());
        EXPECT_THAT(r.replacement(), IsInt32Mul(p0, p1));
      }
    }
  }
}


// -----------------------------------------------------------------------------
// Math.fround


TEST_F(JSBuiltinReducerTest, MathFround) {
  Node* function = MathFunction("fround");

  Node* effect = graph()->start();
  Node* control = graph()->start();
  Node* context = UndefinedConstant();
  Node* frame_state = graph()->start();
  TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) {
    TRACED_FOREACH(Type*, t0, kNumberTypes) {
      Node* p0 = Parameter(t0, 0);
      Node* call =
          graph()->NewNode(javascript()->CallFunction(3, language_mode),
                           function, UndefinedConstant(), p0, context,
                           frame_state, frame_state, effect, control);
      Reduction r = Reduce(call);

      ASSERT_TRUE(r.Changed());
      EXPECT_THAT(r.replacement(), IsTruncateFloat64ToFloat32(p0));
    }
  }
}

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