// 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/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 = Scanner::kDummyTokenIndex;


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->AddVariable(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->AddVariable(param1);
  local_scope->AddVariable(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));


// Tested Dart code:
//   int dec(int a, [int b = 1]) native: "TestSmiSub";
// The native entry TestSmiSub implements dec natively.
CODEGEN_TEST_GENERATE(NativeDecCodegen, test) {
  // A NativeBodyNode, preceded by an EnterNode and followed by a ReturnNode,
  // implements the body of a native Dart function. Let's take this native
  // function as an example: int dec(int a, int b = 1) native;
  // Since this function has an optional parameter, its prologue will copy
  // incoming parameters to locals.
  SequenceNode* node_seq = test->node_sequence();
  const int num_fixed_params = 1;
  const int num_opt_params = 1;
  const int num_params = num_fixed_params + num_opt_params;
  LocalScope* local_scope = node_seq->scope();
  local_scope->AddVariable(NewTestLocalVariable("a"));
  local_scope->AddVariable(NewTestLocalVariable("b"));
  ASSERT(local_scope->num_variables() == num_params);
  const Array& default_values = Array::ZoneHandle(Array::New(num_opt_params));
  default_values.SetAt(0, Smi::ZoneHandle(Smi::New(1)));  // b = 1.
  test->set_default_parameter_values(default_values);
  const Function& function = test->function();
  function.set_is_native(true);
  function.set_num_fixed_parameters(num_fixed_params);
  function.SetNumOptionalParameters(num_opt_params, true);
  const String& native_name =
      String::ZoneHandle(Symbols::New("TestSmiSub"));
  NativeFunction native_function =
      reinterpret_cast<NativeFunction>(TestSmiSub);
  node_seq->Add(
      new ReturnNode(kPos,
                     new NativeBodyNode(kPos,
                                        function,
                                        native_name,
                                        native_function,
                                        local_scope,
                                        false /* not bootstrap native */)));
}


// Tested Dart code:
//   return dec(5);
CODEGEN_TEST2_GENERATE(StaticDecCallCodegen, function, test) {
  SequenceNode* node_seq = test->node_sequence();
  ArgumentListNode* arguments = new ArgumentListNode(kPos);
  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(5))));
  node_seq->Add(new ReturnNode(kPos,
                               new StaticCallNode(kPos, function, arguments)));
}
CODEGEN_TEST2_RUN(StaticDecCallCodegen, NativeDecCodegen, Smi::New(4))


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));
  String& ambiguity_error_msg = String::Handle();
  return lib.LookupClass(cls_name, &ambiguity_error_msg);
}


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::FinalizePendingClasses());
  Class& cls = Class::Handle(LookupClass(lib, "A"));
  EXPECT(!cls.IsNull());  // No ambiguity error expected.

  // '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::FinalizePendingClasses());
  Class& cls = Class::ZoneHandle(LookupClass(lib, "A"));
  EXPECT(!cls.IsNull());  // No ambiguity error expected.

  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))


// Tested Dart code:
//   int sum(int a, int b,
//           [int c = 10, int d = 21, int e = -32]) native: "TestSmiSum";
// The native entry TestSmiSum implements sum natively.
CODEGEN_TEST_GENERATE(NativeSumCodegen, test) {
  SequenceNode* node_seq = test->node_sequence();
  const int num_fixed_params = 2;
  const int num_opt_params = 3;
  const int num_params = num_fixed_params + num_opt_params;
  LocalScope* local_scope = node_seq->scope();
  local_scope->AddVariable(NewTestLocalVariable("a"));
  local_scope->AddVariable(NewTestLocalVariable("b"));
  local_scope->AddVariable(NewTestLocalVariable("c"));
  local_scope->AddVariable(NewTestLocalVariable("d"));
  local_scope->AddVariable(NewTestLocalVariable("e"));
  ASSERT(local_scope->num_variables() == num_params);
  const Array& default_values = Array::ZoneHandle(Array::New(num_opt_params));
  default_values.SetAt(0, Smi::ZoneHandle(Smi::New(10)));
  default_values.SetAt(1, Smi::ZoneHandle(Smi::New(21)));
  default_values.SetAt(2, Smi::ZoneHandle(Smi::New(-32)));
  test->set_default_parameter_values(default_values);
  const Function& function = test->function();
  function.set_is_native(true);
  function.set_num_fixed_parameters(num_fixed_params);
  function.SetNumOptionalParameters(num_opt_params, true);
  function.set_parameter_types(Array::Handle(Array::New(num_params)));
  function.set_parameter_names(Array::Handle(Array::New(num_params)));
  const Type& param_type = Type::Handle(Type::DynamicType());
  for (int i = 0; i < num_params; i++) {
    function.SetParameterTypeAt(i, param_type);
  }
  const String& native_name =
      String::ZoneHandle(Symbols::New("TestSmiSum"));
  NativeFunction native_function =
      reinterpret_cast<NativeFunction>(TestSmiSum);
  node_seq->Add(
      new ReturnNode(kPos,
                     new NativeBodyNode(kPos,
                                        function,
                                        native_name,
                                        native_function,
                                        local_scope,
                                        false /* Not bootstrap native */)));
}


// Tested Dart code, calling function sum declared above:
//   return sum(1, 3);
// Optional arguments are not passed and hence are set to their default values.
CODEGEN_TEST2_GENERATE(StaticSumCallNoOptCodegen, function, test) {
  SequenceNode* node_seq = test->node_sequence();
  ArgumentListNode* arguments = new ArgumentListNode(kPos);
  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(1))));
  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(3))));
  node_seq->Add(new ReturnNode(kPos,
                               new StaticCallNode(kPos, function, arguments)));
}
CODEGEN_TEST2_RUN(StaticSumCallNoOptCodegen,
                  NativeSumCodegen,
                  Smi::New(1 + 3 + 10 + 21 - 32))


// Tested Dart code, calling function sum declared above:
//   return sum(1, 3, 5);
// Only one out of three optional arguments is passed in; the second and third
// arguments are hence set to their default values.
CODEGEN_TEST2_GENERATE(StaticSumCallOneOptCodegen, function, test) {
  SequenceNode* node_seq = test->node_sequence();
  ArgumentListNode* arguments = new ArgumentListNode(kPos);
  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(1))));
  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(3))));
  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(5))));
  node_seq->Add(new ReturnNode(kPos,
                               new StaticCallNode(kPos, function, arguments)));
}
CODEGEN_TEST2_RUN(StaticSumCallOneOptCodegen,
                  NativeSumCodegen,
                  Smi::New(1 + 3 + 5 + 21 - 32))


// Tested Dart code, calling function sum declared above:
//   return sum(0, 1, 1, 2, 3);
// Optional arguments are passed in.
CODEGEN_TEST2_GENERATE(StaticSumCallTenFiboCodegen, function, test) {
  SequenceNode* node_seq = test->node_sequence();
  ArgumentListNode* arguments = new ArgumentListNode(kPos);
  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(0))));
  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(1))));
  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(1))));
  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(2))));
  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(3))));
  node_seq->Add(new ReturnNode(kPos,
                               new StaticCallNode(kPos, function, arguments)));
}
CODEGEN_TEST2_RUN(
    StaticSumCallTenFiboCodegen,
    NativeSumCodegen,
    Smi::New(0 + 1 + 1 + 2 + 3))


// Tested Dart code:
//   int sum(a, b, c) native: "TestNonNullSmiSum";
// The native entry TestNonNullSmiSum implements sum natively.
CODEGEN_TEST_GENERATE(NativeNonNullSumCodegen, test) {
  SequenceNode* node_seq = test->node_sequence();
  const int num_params = 3;
  LocalScope* local_scope = node_seq->scope();
  local_scope->AddVariable(NewTestLocalVariable("a"));
  local_scope->AddVariable(NewTestLocalVariable("b"));
  local_scope->AddVariable(NewTestLocalVariable("c"));
  ASSERT(local_scope->num_variables() == num_params);
  const Function& function = test->function();
  function.set_is_native(true);
  function.set_num_fixed_parameters(num_params);
  ASSERT(!function.HasOptionalParameters());
  function.set_parameter_types(Array::Handle(Array::New(num_params)));
  function.set_parameter_names(Array::Handle(Array::New(num_params)));
  const Type& param_type = Type::Handle(Type::DynamicType());
  for (int i = 0; i < num_params; i++) {
    function.SetParameterTypeAt(i, param_type);
  }
  const String& native_name =
      String::ZoneHandle(Symbols::New("TestNonNullSmiSum"));
  NativeFunction native_function =
      reinterpret_cast<NativeFunction>(TestNonNullSmiSum);
  node_seq->Add(
      new ReturnNode(kPos,
                     new NativeBodyNode(kPos,
                                        function,
                                        native_name,
                                        native_function,
                                        local_scope,
                                        false /* Not bootstrap native */)));
}


// Tested Dart code, calling function sum declared above:
//   return sum(1, null, 3);
CODEGEN_TEST2_GENERATE(StaticNonNullSumCallCodegen, function, test) {
  SequenceNode* node_seq = test->node_sequence();
  ArgumentListNode* arguments = new ArgumentListNode(kPos);
  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(1))));
  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle()));
  arguments->Add(new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(3))));
  node_seq->Add(new ReturnNode(kPos,
                               new StaticCallNode(kPos, function, arguments)));
}
CODEGEN_TEST2_RUN(StaticNonNullSumCallCodegen,
                  NativeNonNullSumCodegen,
                  Smi::New(1 + 3))


// 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::FinalizePendingClasses());
  Class& cls = Class::ZoneHandle(LookupClass(lib, "A"));
  EXPECT(!cls.IsNull());  // No ambiguity error expected.

  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());
  String& ambiguity_error_msg = String::Handle();
  const Class& cls = Class::Handle(
      app_lib.LookupClass(String::Handle(Symbols::New("A")),
                          &ambiguity_error_msg));
  EXPECT_EQ(cls.raw(), result.clazz());  // No ambiguity error expected.
}

}  // namespace dart
