// 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/v8.h"
#include "test/cctest/cctest.h"

#include "src/compiler/code-generator.h"
#include "src/compiler/common-operator.h"
#include "src/compiler/graph.h"
#include "src/compiler/instruction-selector.h"
#include "src/compiler/machine-operator.h"
#include "src/compiler/node.h"
#include "src/compiler/operator.h"
#include "src/compiler/raw-machine-assembler.h"
#include "src/compiler/register-allocator.h"
#include "src/compiler/schedule.h"

#include "src/ast-numbering.h"
#include "src/full-codegen.h"
#include "src/parser.h"
#include "src/rewriter.h"

#include "test/cctest/compiler/c-signature.h"
#include "test/cctest/compiler/function-tester.h"

using namespace v8::internal;
using namespace v8::internal::compiler;


#if V8_TURBOFAN_TARGET

typedef RawMachineAssembler::Label MLabel;
typedef v8::internal::compiler::InstructionSequence TestInstrSeq;

static Handle<JSFunction> NewFunction(const char* source) {
  return v8::Utils::OpenHandle(
      *v8::Handle<v8::Function>::Cast(CompileRun(source)));
}


class DeoptCodegenTester {
 public:
  explicit DeoptCodegenTester(HandleAndZoneScope* scope, const char* src)
      : scope_(scope),
        function(NewFunction(src)),
        info(function, scope->main_zone()),
        bailout_id(-1) {
    CHECK(Parser::Parse(&info));
    info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
    CHECK(Compiler::Analyze(&info));
    CHECK(Compiler::EnsureDeoptimizationSupport(&info));

    DCHECK(info.shared_info()->has_deoptimization_support());

    graph = new (scope_->main_zone()) Graph(scope_->main_zone());
  }

  virtual ~DeoptCodegenTester() {}

  void GenerateCodeFromSchedule(Schedule* schedule) {
    OFStream os(stdout);
    if (FLAG_trace_turbo) {
      os << *schedule;
    }
    result_code = Pipeline::GenerateCodeForTesting(&info, graph, schedule);
#ifdef OBJECT_PRINT
    if (FLAG_print_opt_code || FLAG_trace_turbo) {
      result_code->Print();
    }
#endif
  }

  Zone* zone() { return scope_->main_zone(); }

  HandleAndZoneScope* scope_;
  Handle<JSFunction> function;
  CompilationInfo info;
  BailoutId bailout_id;
  Handle<Code> result_code;
  TestInstrSeq* code;
  Graph* graph;
};


class TrivialDeoptCodegenTester : public DeoptCodegenTester {
 public:
  explicit TrivialDeoptCodegenTester(HandleAndZoneScope* scope)
      : DeoptCodegenTester(scope,
                           "function foo() { deopt(); return 42; }; foo") {}

  void GenerateCode() {
    GenerateCodeFromSchedule(BuildGraphAndSchedule(graph));
  }

  Schedule* BuildGraphAndSchedule(Graph* graph) {
    CommonOperatorBuilder common(zone());

    // Manually construct a schedule for the function below:
    // function foo() {
    //   deopt();
    // }

    CSignature1<Object*, Object*> sig;
    RawMachineAssembler m(graph, &sig);

    Handle<JSFunction> deopt_function =
        NewFunction("function deopt() { %DeoptimizeFunction(foo); }; deopt");
    Unique<JSFunction> deopt_fun_constant =
        Unique<JSFunction>::CreateUninitialized(deopt_function);
    Node* deopt_fun_node = m.NewNode(common.HeapConstant(deopt_fun_constant));

    Handle<Context> caller_context(function->context(), CcTest::i_isolate());
    Unique<Context> caller_context_constant =
        Unique<Context>::CreateUninitialized(caller_context);
    Node* caller_context_node =
        m.NewNode(common.HeapConstant(caller_context_constant));

    bailout_id = GetCallBailoutId();
    Node* parameters = m.NewNode(common.StateValues(1), m.UndefinedConstant());
    Node* locals = m.NewNode(common.StateValues(0));
    Node* stack = m.NewNode(common.StateValues(0));

    Node* state_node = m.NewNode(
        common.FrameState(JS_FRAME, bailout_id,
                          OutputFrameStateCombine::Ignore()),
        parameters, locals, stack, caller_context_node, m.UndefinedConstant());

    Handle<Context> context(deopt_function->context(), CcTest::i_isolate());
    Unique<Context> context_constant =
        Unique<Context>::CreateUninitialized(context);
    Node* context_node = m.NewNode(common.HeapConstant(context_constant));

    m.CallJS0(deopt_fun_node, m.UndefinedConstant(), context_node, state_node);

    m.Return(m.UndefinedConstant());

    // Schedule the graph:
    Schedule* schedule = m.Export();

    return schedule;
  }

  BailoutId GetCallBailoutId() {
    ZoneList<Statement*>* body = info.function()->body();
    for (int i = 0; i < body->length(); i++) {
      if (body->at(i)->IsExpressionStatement() &&
          body->at(i)->AsExpressionStatement()->expression()->IsCall()) {
        return body->at(i)->AsExpressionStatement()->expression()->id();
      }
    }
    CHECK(false);
    return BailoutId(-1);
  }
};


TEST(TurboTrivialDeoptCodegen) {
  HandleAndZoneScope scope;
  InitializedHandleScope handles;

  FLAG_allow_natives_syntax = true;
  FLAG_turbo_deoptimization = true;

  TrivialDeoptCodegenTester t(&scope);
  t.GenerateCode();

  DeoptimizationInputData* data =
      DeoptimizationInputData::cast(t.result_code->deoptimization_data());

  // TODO(jarin) Find a way to test the safepoint.

  // Check that we deoptimize to the right AST id.
  CHECK_EQ(1, data->DeoptCount());
  CHECK_EQ(t.bailout_id.ToInt(), data->AstId(0).ToInt());
}


TEST(TurboTrivialDeoptCodegenAndRun) {
  HandleAndZoneScope scope;
  InitializedHandleScope handles;

  FLAG_allow_natives_syntax = true;
  FLAG_turbo_deoptimization = true;

  TrivialDeoptCodegenTester t(&scope);
  t.GenerateCode();

  t.function->ReplaceCode(*t.result_code);
  t.info.context()->native_context()->AddOptimizedCode(*t.result_code);

  Isolate* isolate = scope.main_isolate();
  Handle<Object> result;
  bool has_pending_exception =
      !Execution::Call(isolate, t.function,
                       isolate->factory()->undefined_value(), 0, NULL,
                       false).ToHandle(&result);
  CHECK(!has_pending_exception);
  CHECK(result->SameValue(Smi::FromInt(42)));
}


class TrivialRuntimeDeoptCodegenTester : public DeoptCodegenTester {
 public:
  explicit TrivialRuntimeDeoptCodegenTester(HandleAndZoneScope* scope)
      : DeoptCodegenTester(
            scope,
            "function foo() { %DeoptimizeFunction(foo); return 42; }; foo") {}

  void GenerateCode() {
    GenerateCodeFromSchedule(BuildGraphAndSchedule(graph));
  }

  Schedule* BuildGraphAndSchedule(Graph* graph) {
    CommonOperatorBuilder common(zone());

    // Manually construct a schedule for the function below:
    // function foo() {
    //   %DeoptimizeFunction(foo);
    // }

    CSignature1<Object*, Object*> sig;
    RawMachineAssembler m(graph, &sig);

    Unique<HeapObject> this_fun_constant =
        Unique<HeapObject>::CreateUninitialized(function);
    Node* this_fun_node = m.NewNode(common.HeapConstant(this_fun_constant));

    Handle<Context> context(function->context(), CcTest::i_isolate());
    Unique<HeapObject> context_constant =
        Unique<HeapObject>::CreateUninitialized(context);
    Node* context_node = m.NewNode(common.HeapConstant(context_constant));

    bailout_id = GetCallBailoutId();
    Node* parameters = m.NewNode(common.StateValues(1), m.UndefinedConstant());
    Node* locals = m.NewNode(common.StateValues(0));
    Node* stack = m.NewNode(common.StateValues(0));

    Node* state_node = m.NewNode(
        common.FrameState(JS_FRAME, bailout_id,
                          OutputFrameStateCombine::Ignore()),
        parameters, locals, stack, context_node, m.UndefinedConstant());

    m.CallRuntime1(Runtime::kDeoptimizeFunction, this_fun_node, context_node,
                   state_node);

    m.Return(m.UndefinedConstant());

    // Schedule the graph:
    Schedule* schedule = m.Export();

    return schedule;
  }

  BailoutId GetCallBailoutId() {
    ZoneList<Statement*>* body = info.function()->body();
    for (int i = 0; i < body->length(); i++) {
      if (body->at(i)->IsExpressionStatement() &&
          body->at(i)->AsExpressionStatement()->expression()->IsCallRuntime()) {
        return body->at(i)->AsExpressionStatement()->expression()->id();
      }
    }
    CHECK(false);
    return BailoutId(-1);
  }
};


TEST(TurboTrivialRuntimeDeoptCodegenAndRun) {
  HandleAndZoneScope scope;
  InitializedHandleScope handles;

  FLAG_allow_natives_syntax = true;
  FLAG_turbo_deoptimization = true;

  TrivialRuntimeDeoptCodegenTester t(&scope);
  t.GenerateCode();

  t.function->ReplaceCode(*t.result_code);
  t.info.context()->native_context()->AddOptimizedCode(*t.result_code);

  Isolate* isolate = scope.main_isolate();
  Handle<Object> result;
  bool has_pending_exception =
      !Execution::Call(isolate, t.function,
                       isolate->factory()->undefined_value(), 0, NULL,
                       false).ToHandle(&result);
  CHECK(!has_pending_exception);
  CHECK(result->SameValue(Smi::FromInt(42)));
}

#endif
