// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "platform/globals.h"

#include "platform/assert.h"
#include "vm/ast.h"
#include "vm/class_finalizer.h"
#include "vm/compiler/assembler/assembler.h"
#include "vm/compiler/jit/compiler.h"
#include "vm/dart_entry.h"
#include "vm/globals.h"
#include "vm/native_entry.h"
#include "vm/native_entry_test.h"
#include "vm/runtime_entry.h"
#include "vm/symbols.h"
#include "vm/unit_test.h"
#include "vm/virtual_memory.h"

namespace dart {

static const TokenPosition kPos = TokenPosition::kMinSource;

CODEGEN_TEST_GENERATE(SimpleReturnCodegen, test) {
  test->node_sequence()->Add(new ReturnNode(kPos));
}
CODEGEN_TEST_RUN(SimpleReturnCodegen, Instance::null())

CODEGEN_TEST_GENERATE(SmiReturnCodegen, test) {
  LiteralNode* l = new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(3)));
  test->node_sequence()->Add(new ReturnNode(kPos, l));
}
CODEGEN_TEST_RUN(SmiReturnCodegen, Smi::New(3))

CODEGEN_TEST2_GENERATE(SimpleStaticCallCodegen, function, test) {
  // Wrap the SmiReturnCodegen test above as a static function and call it.
  ArgumentListNode* no_arguments = new ArgumentListNode(kPos);
  test->node_sequence()->Add(
      new ReturnNode(kPos, new StaticCallNode(kPos, function, no_arguments)));
}
CODEGEN_TEST2_RUN(SimpleStaticCallCodegen, SmiReturnCodegen, Smi::New(3))

// Helper to allocate and return a LocalVariable.
static LocalVariable* NewTestLocalVariable(const char* name) {
  const String& variable_name =
      String::ZoneHandle(Symbols::New(Thread::Current(), name));
  const Type& variable_type = Type::ZoneHandle(Type::DynamicType());
  return new LocalVariable(kPos, kPos, variable_name, variable_type);
}

CODEGEN_TEST_GENERATE(ReturnParameterCodegen, test) {
  SequenceNode* node_seq = test->node_sequence();
  const int num_params = 1;
  LocalVariable* parameter = NewTestLocalVariable("parameter");
  LocalScope* local_scope = node_seq->scope();
  local_scope->InsertParameterAt(0, parameter);
  ASSERT(local_scope->num_variables() == num_params);
  const Function& function = test->function();
  function.set_num_fixed_parameters(num_params);
  ASSERT(!function.HasOptionalParameters());
  node_seq->Add(new ReturnNode(kPos, new LoadLocalNode(kPos, parameter)));
}

CODEGEN_TEST2_GENERATE(StaticCallReturnParameterCodegen, function, test) {
  // Wrap and call the ReturnParameterCodegen test above as a static function.
  SequenceNode* node_seq = test->node_sequence();
  ArgumentListNode* arguments = new ArgumentListNode(kPos);
  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(3))));
  node_seq->Add(
      new ReturnNode(kPos, new StaticCallNode(kPos, function, arguments)));
}
CODEGEN_TEST2_RUN(StaticCallReturnParameterCodegen,
                  ReturnParameterCodegen,
                  Smi::New(3))

CODEGEN_TEST_GENERATE(SmiParamSumCodegen, test) {
  SequenceNode* node_seq = test->node_sequence();
  const int num_params = 2;
  LocalVariable* param1 = NewTestLocalVariable("param1");
  LocalVariable* param2 = NewTestLocalVariable("param2");
  const int num_locals = 1;
  LocalVariable* sum = NewTestLocalVariable("sum");
  LocalScope* local_scope = node_seq->scope();
  local_scope->InsertParameterAt(0, param1);
  local_scope->InsertParameterAt(1, param2);
  local_scope->AddVariable(sum);
  ASSERT(local_scope->num_variables() == num_params + num_locals);
  const Function& function = test->function();
  function.set_num_fixed_parameters(num_params);
  ASSERT(!function.HasOptionalParameters());
  BinaryOpNode* add =
      new BinaryOpNode(kPos, Token::kADD, new LoadLocalNode(kPos, param1),
                       new LoadLocalNode(kPos, param2));
  node_seq->Add(new StoreLocalNode(kPos, sum, add));
  node_seq->Add(new ReturnNode(kPos, new LoadLocalNode(kPos, sum)));
}

CODEGEN_TEST2_GENERATE(StaticCallSmiParamSumCodegen, function, test) {
  // Wrap and call the SmiParamSumCodegen test above as a static function.
  SequenceNode* node_seq = test->node_sequence();
  ArgumentListNode* arguments = new ArgumentListNode(kPos);
  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(3))));
  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(2))));
  node_seq->Add(
      new ReturnNode(kPos, new StaticCallNode(kPos, function, arguments)));
}
CODEGEN_TEST2_RUN(StaticCallSmiParamSumCodegen, SmiParamSumCodegen, Smi::New(5))

CODEGEN_TEST_GENERATE(SmiAddCodegen, test) {
  SequenceNode* node_seq = test->node_sequence();
  LiteralNode* a = new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(3)));
  LiteralNode* b = new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(2)));
  BinaryOpNode* add_node = new BinaryOpNode(kPos, Token::kADD, a, b);
  node_seq->Add(new ReturnNode(kPos, add_node));
}
CODEGEN_TEST_RUN(SmiAddCodegen, Smi::New(5))

CODEGEN_TEST_GENERATE(GenericAddCodegen, test) {
  SequenceNode* node_seq = test->node_sequence();
  LiteralNode* a =
      new LiteralNode(kPos, Double::ZoneHandle(Double::New(12.2, Heap::kOld)));
  LiteralNode* b = new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(2)));
  BinaryOpNode* add_node_1 = new BinaryOpNode(kPos, Token::kADD, a, b);
  LiteralNode* c =
      new LiteralNode(kPos, Double::ZoneHandle(Double::New(0.8, Heap::kOld)));
  BinaryOpNode* add_node_2 = new BinaryOpNode(kPos, Token::kADD, add_node_1, c);
  node_seq->Add(new ReturnNode(kPos, add_node_2));
}
CODEGEN_TEST_RUN(GenericAddCodegen, Double::New(15.0))

CODEGEN_TEST_GENERATE(SmiBinaryOpCodegen, test) {
  SequenceNode* node_seq = test->node_sequence();
  LiteralNode* a = new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(4)));
  LiteralNode* b = new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(2)));
  LiteralNode* c = new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(3)));
  BinaryOpNode* sub_node =
      new BinaryOpNode(kPos, Token::kSUB, a, b);  // 4 - 2 -> 2.
  BinaryOpNode* mul_node =
      new BinaryOpNode(kPos, Token::kMUL, sub_node, c);  // 2 * 3 -> 6.
  BinaryOpNode* div_node =
      new BinaryOpNode(kPos, Token::kTRUNCDIV, mul_node, b);  // 6 ~/ 2 -> 3.
  node_seq->Add(new ReturnNode(kPos, div_node));
}
CODEGEN_TEST_RUN(SmiBinaryOpCodegen, Smi::New(3))

CODEGEN_TEST_GENERATE(BoolNotCodegen, test) {
  SequenceNode* node_seq = test->node_sequence();
  LiteralNode* b = new LiteralNode(kPos, Bool::False());
  UnaryOpNode* not_node = new UnaryOpNode(kPos, Token::kNOT, b);
  node_seq->Add(new ReturnNode(kPos, not_node));
}
CODEGEN_TEST_RUN(BoolNotCodegen, Bool::True().raw())

CODEGEN_TEST_GENERATE(BoolAndCodegen, test) {
  SequenceNode* node_seq = test->node_sequence();
  LiteralNode* a = new LiteralNode(kPos, Bool::True());
  LiteralNode* b = new LiteralNode(kPos, Bool::False());
  BinaryOpNode* and_node = new BinaryOpNode(kPos, Token::kAND, a, b);
  node_seq->Add(new ReturnNode(kPos, and_node));
}
CODEGEN_TEST_RUN(BoolAndCodegen, Bool::False().raw())

CODEGEN_TEST_GENERATE(BinaryOpCodegen, test) {
  SequenceNode* node_seq = test->node_sequence();
  LiteralNode* a =
      new LiteralNode(kPos, Double::ZoneHandle(Double::New(12, Heap::kOld)));
  LiteralNode* b = new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(2)));
  LiteralNode* c =
      new LiteralNode(kPos, Double::ZoneHandle(Double::New(0.5, Heap::kOld)));
  BinaryOpNode* sub_node = new BinaryOpNode(kPos, Token::kSUB, a, b);
  BinaryOpNode* mul_node = new BinaryOpNode(kPos, Token::kMUL, sub_node, c);
  BinaryOpNode* div_node = new BinaryOpNode(kPos, Token::kDIV, mul_node, b);
  node_seq->Add(new ReturnNode(kPos, div_node));
}
CODEGEN_TEST_RUN(BinaryOpCodegen, Double::New(2.5));

CODEGEN_TEST_GENERATE(SmiUnaryOpCodegen, test) {
  SequenceNode* node_seq = test->node_sequence();
  LiteralNode* a = new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(12)));
  UnaryOpNode* neg_node = new UnaryOpNode(kPos, Token::kNEGATE, a);
  node_seq->Add(new ReturnNode(kPos, neg_node));
}
CODEGEN_TEST_RUN(SmiUnaryOpCodegen, Smi::New(-12))

CODEGEN_TEST_GENERATE(DoubleUnaryOpCodegen, test) {
  SequenceNode* node_seq = test->node_sequence();
  LiteralNode* a =
      new LiteralNode(kPos, Double::ZoneHandle(Double::New(12.0, Heap::kOld)));
  UnaryOpNode* neg_node = new UnaryOpNode(kPos, Token::kNEGATE, a);
  node_seq->Add(new ReturnNode(kPos, neg_node));
}
CODEGEN_TEST_RUN(DoubleUnaryOpCodegen, Double::New(-12.0))

static Library& MakeTestLibrary(const char* url) {
  Thread* thread = Thread::Current();
  Zone* zone = thread->zone();

  const String& lib_url = String::ZoneHandle(zone, Symbols::New(thread, url));
  Library& lib = Library::ZoneHandle(zone, Library::New(lib_url));
  lib.Register(thread);
  Library& core_lib = Library::Handle(zone, Library::CoreLibrary());
  ASSERT(!core_lib.IsNull());
  const Namespace& core_ns = Namespace::Handle(
      zone, Namespace::New(core_lib, Array::Handle(zone), Array::Handle(zone)));
  lib.AddImport(core_ns);
  return lib;
}

static RawClass* LookupClass(const Library& lib, const char* name) {
  const String& cls_name =
      String::ZoneHandle(Symbols::New(Thread::Current(), name));
  return lib.LookupClass(cls_name);
}

CODEGEN_TEST_GENERATE(StaticCallCodegen, test) {
  const char* kScriptChars =
      "class A {\n"
      "  static bar() { return 42; }\n"
      "  static fly() { return 5; }\n"
      "}\n";

  String& url = String::Handle(String::New("dart-test:CompileScript"));
  String& source = String::Handle(String::New(kScriptChars));
  Script& script =
      Script::Handle(Script::New(url, source, RawScript::kScriptTag));
  Library& lib = MakeTestLibrary("TestLib");
  EXPECT(CompilerTest::TestCompileScript(lib, script));
  EXPECT(ClassFinalizer::ProcessPendingClasses());
  Class& cls = Class::Handle(LookupClass(lib, "A"));
  EXPECT(!cls.IsNull());

  // 'bar' will not be compiled.
  String& function_bar_name = String::Handle(String::New("bar"));
  Function& function_bar =
      Function::ZoneHandle(cls.LookupStaticFunction(function_bar_name));
  EXPECT(!function_bar.IsNull());
  EXPECT(!function_bar.HasCode());

  // 'fly' will be compiled.
  String& function_fly_name = String::Handle(String::New("fly"));
  Function& function_fly =
      Function::ZoneHandle(cls.LookupStaticFunction(function_fly_name));
  EXPECT(!function_fly.IsNull());
  EXPECT(CompilerTest::TestCompileFunction(function_fly));
  EXPECT(function_fly.HasCode());

  ArgumentListNode* no_arguments = new ArgumentListNode(kPos);
  StaticCallNode* call_bar =
      new StaticCallNode(kPos, function_bar, no_arguments);
  StaticCallNode* call_fly =
      new StaticCallNode(kPos, function_fly, no_arguments);

  BinaryOpNode* add_node =
      new BinaryOpNode(kPos, Token::kADD, call_bar, call_fly);

  test->node_sequence()->Add(new ReturnNode(kPos, add_node));
}
CODEGEN_TEST_RUN(StaticCallCodegen, Smi::New(42 + 5))

CODEGEN_TEST_GENERATE(InstanceCallCodegen, test) {
  const char* kScriptChars =
      "class A {\n"
      "  A() {}\n"
      "  int bar() { return 42; }\n"
      "}\n";

  String& url = String::Handle(String::New("dart-test:CompileScript"));
  String& source = String::Handle(String::New(kScriptChars));
  Script& script =
      Script::Handle(Script::New(url, source, RawScript::kScriptTag));
  Library& lib = MakeTestLibrary("TestLib");
  EXPECT(CompilerTest::TestCompileScript(lib, script));
  EXPECT(ClassFinalizer::ProcessPendingClasses());
  Class& cls = Class::ZoneHandle(LookupClass(lib, "A"));
  EXPECT(!cls.IsNull());

  String& constructor_name = String::Handle(String::New("A."));
  Function& constructor =
      Function::ZoneHandle(cls.LookupConstructor(constructor_name));
  EXPECT(!constructor.IsNull());

  // The unit test creates an instance of class A and calls function 'bar'.
  String& function_bar_name =
      String::ZoneHandle(Symbols::New(Thread::Current(), "bar"));
  ArgumentListNode* no_arguments = new ArgumentListNode(kPos);
  const TypeArguments& no_type_arguments = TypeArguments::ZoneHandle();
  InstanceCallNode* call_bar =
      new InstanceCallNode(kPos,
                           new ConstructorCallNode(kPos, no_type_arguments,
                                                   constructor, no_arguments),
                           function_bar_name, no_arguments);

  test->node_sequence()->Add(new ReturnNode(kPos, call_bar));
}
CODEGEN_TEST_RUN(InstanceCallCodegen, Smi::New(42))

// Test allocation of dart objects.
CODEGEN_TEST_GENERATE(AllocateNewObjectCodegen, test) {
  const char* kScriptChars =
      "class A {\n"
      "  A() {}\n"
      "  static bar() { return 42; }\n"
      "}\n";

  String& url = String::Handle(String::New("dart-test:CompileScript"));
  String& source = String::Handle(String::New(kScriptChars));
  Script& script =
      Script::Handle(Script::New(url, source, RawScript::kScriptTag));
  Library& lib = MakeTestLibrary("TestLib");
  EXPECT(CompilerTest::TestCompileScript(lib, script));
  EXPECT(ClassFinalizer::ProcessPendingClasses());
  Class& cls = Class::ZoneHandle(LookupClass(lib, "A"));
  EXPECT(!cls.IsNull());

  String& constructor_name = String::Handle(String::New("A."));
  Function& constructor =
      Function::ZoneHandle(cls.LookupConstructor(constructor_name));
  EXPECT(!constructor.IsNull());

  const TypeArguments& no_type_arguments = TypeArguments::ZoneHandle();
  ArgumentListNode* no_arguments = new ArgumentListNode(kPos);
  test->node_sequence()->Add(
      new ReturnNode(kPos, new ConstructorCallNode(kPos, no_type_arguments,
                                                   constructor, no_arguments)));
}

CODEGEN_TEST_RAW_RUN(AllocateNewObjectCodegen, function) {
  const Object& result = Object::Handle(
      DartEntry::InvokeFunction(function, Object::empty_array()));
  EXPECT(!result.IsError());
  const GrowableObjectArray& libs = GrowableObjectArray::Handle(
      Isolate::Current()->object_store()->libraries());
  ASSERT(!libs.IsNull());
  // App lib is the last one that was loaded.
  intptr_t num_libs = libs.Length();
  Library& app_lib = Library::Handle();
  app_lib ^= libs.At(num_libs - 1);
  ASSERT(!app_lib.IsNull());
  const Class& cls = Class::Handle(app_lib.LookupClass(
      String::Handle(Symbols::New(Thread::Current(), "A"))));
  EXPECT_EQ(cls.raw(), result.clazz());
}

}  // namespace dart
