// Copyright 2015 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-context-relaxation.h"
#include "src/compiler/js-graph.h"
#include "test/unittests/compiler/graph-unittest.h"
#include "test/unittests/compiler/node-test-utils.h"

namespace v8 {
namespace internal {
namespace compiler {

class JSContextRelaxationTest : public GraphTest {
 public:
  JSContextRelaxationTest() : GraphTest(3), javascript_(zone()) {}
  ~JSContextRelaxationTest() override {}

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

  Node* EmptyFrameState() {
    MachineOperatorBuilder machine(zone());
    JSGraph jsgraph(isolate(), graph(), common(), javascript(), nullptr,
                    &machine);
    return jsgraph.EmptyFrameState();
  }

  Node* ShallowFrameStateChain(Node* outer_context,
                               ContextCallingMode context_calling_mode) {
    const FrameStateFunctionInfo* const frame_state_function_info =
        common()->CreateFrameStateFunctionInfo(
            FrameStateType::kJavaScriptFunction, 3, 0,
            Handle<SharedFunctionInfo>(), context_calling_mode);
    const Operator* op = common()->FrameState(BailoutId::None(),
                                              OutputFrameStateCombine::Ignore(),
                                              frame_state_function_info);
    return graph()->NewNode(op, graph()->start(), graph()->start(),
                            graph()->start(), outer_context, graph()->start(),
                            graph()->start());
  }

  Node* DeepFrameStateChain(Node* outer_context,
                            ContextCallingMode context_calling_mode) {
    const FrameStateFunctionInfo* const frame_state_function_info =
        common()->CreateFrameStateFunctionInfo(
            FrameStateType::kJavaScriptFunction, 3, 0,
            Handle<SharedFunctionInfo>(), context_calling_mode);
    const Operator* op = common()->FrameState(BailoutId::None(),
                                              OutputFrameStateCombine::Ignore(),
                                              frame_state_function_info);
    Node* shallow_frame_state =
        ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT);
    return graph()->NewNode(op, graph()->start(), graph()->start(),
                            graph()->start(), graph()->start(),
                            graph()->start(), shallow_frame_state);
  }

  JSOperatorBuilder* javascript() { return &javascript_; }

 private:
  JSOperatorBuilder javascript_;
};


TEST_F(JSContextRelaxationTest,
       RelaxJSCallFunctionShallowFrameStateChainNoCrossCtx) {
  Node* const input0 = Parameter(0);
  Node* const input1 = Parameter(1);
  Node* const context = Parameter(2);
  Node* const outer_context = Parameter(3);
  Node* const frame_state =
      ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT);
  Node* const effect = graph()->start();
  Node* const control = graph()->start();
  Node* node = graph()->NewNode(
      javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1,
      context, frame_state, frame_state, effect, control);
  Reduction const r = Reduce(node);
  EXPECT_TRUE(r.Changed());
  EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node));
}

TEST_F(JSContextRelaxationTest,
       RelaxJSCallFunctionShallowFrameStateChainCrossCtx) {
  Node* const input0 = Parameter(0);
  Node* const input1 = Parameter(1);
  Node* const context = Parameter(2);
  Node* const outer_context = Parameter(3);
  Node* const frame_state =
      ShallowFrameStateChain(outer_context, CALL_CHANGES_NATIVE_CONTEXT);
  Node* const effect = graph()->start();
  Node* const control = graph()->start();
  Node* node = graph()->NewNode(
      javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1,
      context, frame_state, frame_state, effect, control);
  Reduction const r = Reduce(node);
  EXPECT_FALSE(r.Changed());
  EXPECT_EQ(context, NodeProperties::GetContextInput(node));
}

TEST_F(JSContextRelaxationTest,
       RelaxJSCallFunctionDeepFrameStateChainNoCrossCtx) {
  Node* const input0 = Parameter(0);
  Node* const input1 = Parameter(1);
  Node* const context = Parameter(2);
  Node* const outer_context = Parameter(3);
  Node* const frame_state =
      DeepFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT);
  Node* const effect = graph()->start();
  Node* const control = graph()->start();
  Node* node = graph()->NewNode(
      javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1,
      context, frame_state, frame_state, effect, control);
  Reduction const r = Reduce(node);
  EXPECT_TRUE(r.Changed());
  EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node));
}

TEST_F(JSContextRelaxationTest,
       RelaxJSCallFunctionDeepFrameStateChainCrossCtx) {
  Node* const input0 = Parameter(0);
  Node* const input1 = Parameter(1);
  Node* const context = Parameter(2);
  Node* const outer_context = Parameter(3);
  Node* const frame_state =
      DeepFrameStateChain(outer_context, CALL_CHANGES_NATIVE_CONTEXT);
  Node* const effect = graph()->start();
  Node* const control = graph()->start();
  Node* node = graph()->NewNode(
      javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1,
      context, frame_state, frame_state, effect, control);
  Reduction const r = Reduce(node);
  EXPECT_FALSE(r.Changed());
  EXPECT_EQ(context, NodeProperties::GetContextInput(node));
}

TEST_F(JSContextRelaxationTest,
       RelaxJSCallFunctionDeepContextChainFullRelaxForCatch) {
  Node* const input0 = Parameter(0);
  Node* const input1 = Parameter(1);
  Node* const context = Parameter(2);
  Node* const outer_context = Parameter(3);
  const Operator* op = javascript()->CreateCatchContext(Handle<String>());
  Node* const effect = graph()->start();
  Node* const control = graph()->start();
  Node* nested_context = graph()->NewNode(
      op, graph()->start(), graph()->start(), outer_context, effect, control);
  Node* const frame_state_2 =
      ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT);
  Node* node = graph()->NewNode(
      javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1,
      context, frame_state_2, frame_state_2, effect, control);
  Reduction const r = Reduce(node);
  EXPECT_TRUE(r.Changed());
  EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node));
}


TEST_F(JSContextRelaxationTest,
       RelaxJSCallFunctionDeepContextChainFullRelaxForWith) {
  Node* const input0 = Parameter(0);
  Node* const input1 = Parameter(1);
  Node* const context = Parameter(2);
  Node* const outer_context = Parameter(3);
  const Operator* op = javascript()->CreateWithContext();
  Node* const effect = graph()->start();
  Node* const control = graph()->start();
  Node* nested_context = graph()->NewNode(
      op, graph()->start(), graph()->start(), outer_context, effect, control);
  Node* const frame_state_2 =
      ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT);
  Node* node = graph()->NewNode(
      javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1,
      context, frame_state_2, frame_state_2, effect, control);
  Reduction const r = Reduce(node);
  EXPECT_TRUE(r.Changed());
  EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node));
}


TEST_F(JSContextRelaxationTest,
       RelaxJSCallFunctionDeepContextChainFullRelaxForBlock) {
  Node* const input0 = Parameter(0);
  Node* const input1 = Parameter(1);
  Node* const context = Parameter(2);
  Node* const outer_context = Parameter(3);
  Handle<ScopeInfo> scope_info = Handle<ScopeInfo>::null();
  const Operator* op = javascript()->CreateBlockContext(scope_info);
  Node* const effect = graph()->start();
  Node* const control = graph()->start();
  Node* nested_context =
      graph()->NewNode(op, graph()->start(), outer_context, effect, control);
  Node* const frame_state_2 =
      ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT);
  Node* node = graph()->NewNode(
      javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1,
      context, frame_state_2, frame_state_2, effect, control);
  Reduction const r = Reduce(node);
  EXPECT_TRUE(r.Changed());
  EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node));
}


TEST_F(JSContextRelaxationTest,
       RelaxJSCallFunctionDeepContextChainPartialRelaxForScript) {
  Node* const input0 = Parameter(0);
  Node* const input1 = Parameter(1);
  Node* const context = Parameter(2);
  Node* const outer_context = Parameter(3);
  Handle<ScopeInfo> scope_info = Handle<ScopeInfo>::null();
  const Operator* op = javascript()->CreateScriptContext(scope_info);
  Node* const frame_state_1 =
      ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT);
  Node* const effect = graph()->start();
  Node* const control = graph()->start();
  Node* nested_context = graph()->NewNode(op, graph()->start(), outer_context,
                                          frame_state_1, effect, control);
  Node* const frame_state_2 =
      ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT);
  Node* node = graph()->NewNode(
      javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1,
      context, frame_state_2, frame_state_2, effect, control);
  Reduction const r = Reduce(node);
  EXPECT_TRUE(r.Changed());
  EXPECT_EQ(nested_context, NodeProperties::GetContextInput(node));
}


TEST_F(JSContextRelaxationTest,
       RelaxJSCallFunctionDeepContextChainPartialRelaxForModule) {
  Node* const input0 = Parameter(0);
  Node* const input1 = Parameter(1);
  Node* const context = Parameter(2);
  Node* const outer_context = Parameter(3);
  const Operator* op = javascript()->CreateModuleContext();
  Node* const effect = graph()->start();
  Node* const control = graph()->start();
  Node* nested_context = graph()->NewNode(
      op, graph()->start(), graph()->start(), outer_context, effect, control);
  Node* const frame_state_2 =
      ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT);
  Node* node = graph()->NewNode(
      javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1,
      context, frame_state_2, frame_state_2, effect, control);
  Reduction const r = Reduce(node);
  EXPECT_TRUE(r.Changed());
  EXPECT_EQ(nested_context, NodeProperties::GetContextInput(node));
}


TEST_F(JSContextRelaxationTest,
       RelaxJSCallFunctionDeepContextChainPartialNoRelax) {
  Node* const input0 = Parameter(0);
  Node* const input1 = Parameter(1);
  Node* const context = Parameter(2);
  Node* const outer_context = Parameter(3);
  const Operator* op = javascript()->CreateFunctionContext(0);
  Node* const effect = graph()->start();
  Node* const control = graph()->start();
  Node* nested_context =
      graph()->NewNode(op, graph()->start(), outer_context, effect, control);
  Node* const frame_state_2 =
      ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT);
  Node* node = graph()->NewNode(
      javascript()->CallFunction(2, STRICT, VectorSlotPair()), input0, input1,
      context, frame_state_2, frame_state_2, effect, control);
  Reduction const r = Reduce(node);
  EXPECT_FALSE(r.Changed());
  EXPECT_EQ(context, NodeProperties::GetContextInput(node));
}

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