Index: runtime/vm/code_generator_x64_test.cc |
=================================================================== |
--- runtime/vm/code_generator_x64_test.cc (revision 0) |
+++ runtime/vm/code_generator_x64_test.cc (revision 0) |
@@ -0,0 +1,500 @@ |
+// Copyright (c) 2011, 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 "vm/globals.h" |
+#if defined(TARGET_ARCH_X64) |
+ |
+#include "vm/code_generator.h" |
+ |
+#include "vm/ast.h" |
+#include "vm/assembler.h" |
+#include "vm/assert.h" |
+#include "vm/class_finalizer.h" |
+#include "vm/compiler.h" |
+#include "vm/dart_entry.h" |
+#include "vm/native_entry.h" |
+#include "vm/native_entry_test.h" |
+#include "vm/unit_test.h" |
+#include "vm/virtual_memory.h" |
+ |
+namespace dart { |
+ |
+#define __ assembler_-> |
+ |
+ |
+static const intptr_t kPos = 1; // Dummy token index in non-existing source. |
+ |
+ |
+// Helper to allocate and return a LocalVariable. |
+static LocalVariable* NewTestLocalVariable(const char* name) { |
+ const String& variable_name = String::ZoneHandle(String::New(name)); |
+ const Type& variable_type = Type::ZoneHandle(Type::DynamicType()); |
+ return new LocalVariable(kPos, variable_name, variable_type); |
+} |
+ |
+ |
+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)) |
+ |
+ |
+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.num_optional_parameters() == 0); |
+ 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.num_optional_parameters() == 0); |
+ 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))); |
+ 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))); |
+ 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(); |
+ const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
+ 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()) |
+ |
+ |
+CODEGEN_TEST_GENERATE(BoolAndCodegen, test) { |
+ SequenceNode* node_seq = test->node_sequence(); |
+ const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
+ const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
+ 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()) |
+ |
+ |
+CODEGEN_TEST_GENERATE(BinaryOpCodegen, test) { |
+ SequenceNode* node_seq = test->node_sequence(); |
+ LiteralNode* a = new LiteralNode(kPos, Double::ZoneHandle(Double::New(12))); |
+ LiteralNode* b = new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(2))); |
+ LiteralNode* c = new LiteralNode(kPos, Double::ZoneHandle(Double::New(0.5))); |
+ 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_num_fixed_parameters(num_fixed_params); |
+ function.set_num_optional_parameters(num_opt_params); |
+ const bool has_opt_params = true; |
+ const String& native_name = |
+ String::ZoneHandle(String::NewSymbol("TestSmiSub")); |
+ NativeFunction native_function = |
+ reinterpret_cast<NativeFunction>(NATIVE_ENTRY_FUNCTION(TestSmiSub)); |
+ node_seq->Add(new ReturnNode(kPos, |
+ new NativeBodyNode(kPos, |
+ native_name, |
+ native_function, |
+ num_params, |
+ has_opt_params))); |
+} |
+ |
+ |
+// 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::kSUB, 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))); |
+ UnaryOpNode* neg_node = new UnaryOpNode(kPos, Token::kSUB, 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(String::NewSymbol(url)); |
+ Library& lib = Library::ZoneHandle(Library::New(lib_url)); |
+ lib.Register(); |
+ return lib; |
+} |
+ |
+ |
+static RawClass* LookupClass(const Library& lib, const char* name) { |
+ const String& cls_name = String::ZoneHandle(String::NewSymbol(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::kSource)); |
+ Library& lib = MakeTestLibrary("TestLib"); |
+ EXPECT(CompilerTest::TestCompileScript(lib, script)); |
+ 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::kSource)); |
+ Library& lib = MakeTestLibrary("TestLib"); |
+ EXPECT(CompilerTest::TestCompileScript(lib, script)); |
+ EXPECT(ClassFinalizer::FinalizePendingClasses()); |
+ 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(String::NewSymbol("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_num_fixed_parameters(num_fixed_params); |
+ function.set_num_optional_parameters(num_opt_params); |
+ 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 - 1; i++) { |
+ function.SetParameterTypeAt(i, param_type); |
+ } |
+ const bool has_opt_params = true; |
+ const String& native_name = |
+ String::ZoneHandle(String::NewSymbol("TestSmiSum")); |
+ NativeFunction native_function = |
+ reinterpret_cast<NativeFunction>(NATIVE_ENTRY_FUNCTION(TestSmiSum)); |
+ node_seq->Add(new ReturnNode(kPos, |
+ new NativeBodyNode(kPos, |
+ native_name, |
+ native_function, |
+ num_params, |
+ has_opt_params))); |
+} |
+ |
+ |
+// 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)) |
+ |
+ |
+// 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::kSource)); |
+ Library& lib = MakeTestLibrary("TestLib"); |
+ EXPECT(CompilerTest::TestCompileScript(lib, script)); |
+ EXPECT(ClassFinalizer::FinalizePendingClasses()); |
+ 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) { |
+ GrowableArray<const Object*> arguments; |
+ const Array& kNoArgumentNames = Array::Handle(); |
+ Instance& result = Instance::Handle(); |
+ result = DartEntry::InvokeStatic(function, arguments, kNoArgumentNames); |
+ const Library& app_lib = Library::Handle( |
+ Isolate::Current()->object_store()->registered_libraries()); |
+ const Class& cls = Class::Handle( |
+ app_lib.LookupClass(String::Handle(String::NewSymbol("A")))); |
+ EXPECT_EQ(cls.raw(), result.clazz()); |
+} |
+ |
+} // namespace dart |
+ |
+#endif // defined TARGET_ARCH_X64 |