// 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/globals.h"
#include "vm/ast.h"
#include "vm/assembler.h"
#include "vm/class_finalizer.h"
#include "vm/code_generator.h"
#include "vm/compiler.h"
#include "vm/dart_entry.h"
#include "vm/native_entry.h"
#include "vm/native_entry_test.h"
#include "vm/symbols.h"
#include "vm/unit_test.h"
#include "vm/virtual_memory.h"

namespace dart {

static const intptr_t kPos = 0;


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(name));
  const Type& variable_type = Type::ZoneHandle(Type::DynamicType());
  return new LocalVariable(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) {
  const String& lib_url = String::ZoneHandle(Symbols::New(url));
  Library& lib = Library::ZoneHandle(Library::New(lib_url));
  lib.Register();
  Library& core_lib = Library::Handle(Library::CoreLibrary());
  ASSERT(!core_lib.IsNull());
  const Namespace& core_ns = Namespace::Handle(
      Namespace::New(core_lib, Array::Handle(), Array::Handle()));
  lib.AddImport(core_ns);
  return lib;
}


static RawClass* LookupClass(const Library& lib, const char* name) {
  const String& cls_name = String::ZoneHandle(Symbols::New(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("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("A"))));
  EXPECT_EQ(cls.raw(), result.clazz());
}

}  // namespace dart
