| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/assert.h" | 5 #include "platform/assert.h" |
| 6 #include "vm/assembler.h" | 6 #include "vm/assembler.h" |
| 7 #include "vm/class_finalizer.h" | 7 #include "vm/class_finalizer.h" |
| 8 #include "vm/compiler.h" | 8 #include "vm/compiler.h" |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/object.h" | 10 #include "vm/object.h" |
| 11 #include "vm/resolver.h" | 11 #include "vm/resolver.h" |
| 12 #include "vm/symbols.h" | 12 #include "vm/symbols.h" |
| 13 #include "vm/unit_test.h" | 13 #include "vm/unit_test.h" |
| 14 | 14 |
| 15 namespace dart { | 15 namespace dart { |
| 16 | 16 |
| 17 // Setup function for invocation. | 17 // Setup function for invocation. |
| 18 static void SetupFunction(const char* test_library_name, | 18 static void SetupFunction(const char* test_library_name, |
| 19 const char* test_class_name, | 19 const char* test_class_name, |
| 20 const char* test_static_function_name, | 20 const char* test_static_function_name, |
| 21 bool is_static) { | 21 bool is_static) { |
| 22 Thread* thread = Thread::Current(); | 22 Thread* thread = Thread::Current(); |
| 23 Zone* zone = thread->zone(); | 23 Zone* zone = thread->zone(); |
| 24 | 24 |
| 25 // Setup a dart class and function. | 25 // Setup a dart class and function. |
| 26 char script_chars[1024]; | 26 char script_chars[1024]; |
| 27 OS::SNPrint(script_chars, | 27 OS::SNPrint(script_chars, sizeof(script_chars), |
| 28 sizeof(script_chars), | |
| 29 "class Base {\n" | 28 "class Base {\n" |
| 30 " dynCall() { return 3; }\n" | 29 " dynCall() { return 3; }\n" |
| 31 " static statCall() { return 4; }\n" | 30 " static statCall() { return 4; }\n" |
| 32 "\n" | 31 "\n" |
| 33 "}\n" | 32 "}\n" |
| 34 "class %s extends Base {\n" | 33 "class %s extends Base {\n" |
| 35 " %s %s(String s, int i) { return i; }\n" | 34 " %s %s(String s, int i) { return i; }\n" |
| 36 "}\n", | 35 "}\n", |
| 37 test_class_name, | 36 test_class_name, is_static ? "static" : "", |
| 38 is_static ? "static" : "", | |
| 39 test_static_function_name); | 37 test_static_function_name); |
| 40 | 38 |
| 41 String& url = String::Handle(zone, | 39 String& url = String::Handle( |
| 42 is_static ? | 40 zone, is_static ? String::New("dart-test:DartStaticResolve") |
| 43 String::New("dart-test:DartStaticResolve") : | 41 : String::New("dart-test:DartDynamicResolve")); |
| 44 String::New("dart-test:DartDynamicResolve")); | |
| 45 String& source = String::Handle(zone, String::New(script_chars)); | 42 String& source = String::Handle(zone, String::New(script_chars)); |
| 46 Script& script = Script::Handle(zone, | 43 Script& script = |
| 47 Script::New(url, source, RawScript::kScriptTag)); | 44 Script::Handle(zone, Script::New(url, source, RawScript::kScriptTag)); |
| 48 const String& lib_name = String::Handle(zone, String::New(test_library_name)); | 45 const String& lib_name = String::Handle(zone, String::New(test_library_name)); |
| 49 Library& lib = Library::Handle(zone, Library::New(lib_name)); | 46 Library& lib = Library::Handle(zone, Library::New(lib_name)); |
| 50 lib.Register(thread); | 47 lib.Register(thread); |
| 51 EXPECT(CompilerTest::TestCompileScript(lib, script)); | 48 EXPECT(CompilerTest::TestCompileScript(lib, script)); |
| 52 EXPECT(ClassFinalizer::ProcessPendingClasses()); | 49 EXPECT(ClassFinalizer::ProcessPendingClasses()); |
| 53 } | 50 } |
| 54 | 51 |
| 55 | 52 |
| 56 // Setup a static function for invocation. | 53 // Setup a static function for invocation. |
| 57 static void SetupStaticFunction(const char* test_library_name, | 54 static void SetupStaticFunction(const char* test_library_name, |
| 58 const char* test_class_name, | 55 const char* test_class_name, |
| 59 const char* test_static_function_name) { | 56 const char* test_static_function_name) { |
| 60 // Setup a static dart class and function. | 57 // Setup a static dart class and function. |
| 61 SetupFunction(test_library_name, | 58 SetupFunction(test_library_name, test_class_name, test_static_function_name, |
| 62 test_class_name, | |
| 63 test_static_function_name, | |
| 64 true); | 59 true); |
| 65 } | 60 } |
| 66 | 61 |
| 67 | 62 |
| 68 // Setup an instance function for invocation. | 63 // Setup an instance function for invocation. |
| 69 static void SetupInstanceFunction(const char* test_library_name, | 64 static void SetupInstanceFunction(const char* test_library_name, |
| 70 const char* test_class_name, | 65 const char* test_class_name, |
| 71 const char* test_function_name) { | 66 const char* test_function_name) { |
| 72 // Setup a static dart class and function. | 67 // Setup a static dart class and function. |
| 73 SetupFunction(test_library_name, | 68 SetupFunction(test_library_name, test_class_name, test_function_name, false); |
| 74 test_class_name, | |
| 75 test_function_name, | |
| 76 false); | |
| 77 } | 69 } |
| 78 | 70 |
| 79 | 71 |
| 80 TEST_CASE(DartStaticResolve) { | 72 TEST_CASE(DartStaticResolve) { |
| 81 const char* test_library_name = "ResolverApp"; | 73 const char* test_library_name = "ResolverApp"; |
| 82 const char* test_class_name = "A"; | 74 const char* test_class_name = "A"; |
| 83 const char* test_static_function_name = "static_foo"; | 75 const char* test_static_function_name = "static_foo"; |
| 84 const int kTestValue = 42; | 76 const int kTestValue = 42; |
| 85 | 77 |
| 86 // Setup a static function which can be invoked. | 78 // Setup a static function which can be invoked. |
| 87 SetupStaticFunction(test_library_name, | 79 SetupStaticFunction(test_library_name, test_class_name, |
| 88 test_class_name, | |
| 89 test_static_function_name); | 80 test_static_function_name); |
| 90 | 81 |
| 91 const String& library_name = String::Handle(String::New(test_library_name)); | 82 const String& library_name = String::Handle(String::New(test_library_name)); |
| 92 const Library& library = | 83 const Library& library = |
| 93 Library::Handle(Library::LookupLibrary(thread, library_name)); | 84 Library::Handle(Library::LookupLibrary(thread, library_name)); |
| 94 const String& class_name = String::Handle(String::New(test_class_name)); | 85 const String& class_name = String::Handle(String::New(test_class_name)); |
| 95 const String& static_function_name = | 86 const String& static_function_name = |
| 96 String::Handle(String::New(test_static_function_name)); | 87 String::Handle(String::New(test_static_function_name)); |
| 97 | 88 |
| 98 // Now try to resolve and invoke the static function in this class. | 89 // Now try to resolve and invoke the static function in this class. |
| 99 { | 90 { |
| 100 const int kNumArguments = 2; | 91 const int kNumArguments = 2; |
| 101 const Function& function = Function::Handle( | 92 const Function& function = Function::Handle( |
| 102 Resolver::ResolveStatic(library, | 93 Resolver::ResolveStatic(library, class_name, static_function_name, |
| 103 class_name, | 94 kNumArguments, Object::empty_array())); |
| 104 static_function_name, | |
| 105 kNumArguments, | |
| 106 Object::empty_array())); | |
| 107 EXPECT(!function.IsNull()); // No ambiguity error expected. | 95 EXPECT(!function.IsNull()); // No ambiguity error expected. |
| 108 const Array& args = Array::Handle(Array::New(kNumArguments)); | 96 const Array& args = Array::Handle(Array::New(kNumArguments)); |
| 109 const String& arg0 = String::Handle(String::New("junk")); | 97 const String& arg0 = String::Handle(String::New("junk")); |
| 110 args.SetAt(0, arg0); | 98 args.SetAt(0, arg0); |
| 111 const Smi& arg1 = Smi::Handle(Smi::New(kTestValue)); | 99 const Smi& arg1 = Smi::Handle(Smi::New(kTestValue)); |
| 112 args.SetAt(1, arg1); | 100 args.SetAt(1, arg1); |
| 113 const Smi& retval = Smi::Handle( | 101 const Smi& retval = Smi::Handle( |
| 114 reinterpret_cast<RawSmi*>(DartEntry::InvokeFunction(function, args))); | 102 reinterpret_cast<RawSmi*>(DartEntry::InvokeFunction(function, args))); |
| 115 EXPECT_EQ(kTestValue, retval.Value()); | 103 EXPECT_EQ(kTestValue, retval.Value()); |
| 116 } | 104 } |
| 117 | 105 |
| 118 // Now try to resolve a static function with invalid argument count. | 106 // Now try to resolve a static function with invalid argument count. |
| 119 { | 107 { |
| 120 const int kNumArguments = 1; | 108 const int kNumArguments = 1; |
| 121 const Function& bad_function = Function::Handle( | 109 const Function& bad_function = Function::Handle( |
| 122 Resolver::ResolveStatic(library, | 110 Resolver::ResolveStatic(library, class_name, static_function_name, |
| 123 class_name, | 111 kNumArguments, Object::empty_array())); |
| 124 static_function_name, | |
| 125 kNumArguments, | |
| 126 Object::empty_array())); | |
| 127 EXPECT(bad_function.IsNull()); // No ambiguity error expected. | 112 EXPECT(bad_function.IsNull()); // No ambiguity error expected. |
| 128 } | 113 } |
| 129 | 114 |
| 130 // Hierarchy walking. | 115 // Hierarchy walking. |
| 131 { | 116 { |
| 132 const String& super_static_function_name = | 117 const String& super_static_function_name = |
| 133 String::Handle(String::New("statCall")); | 118 String::Handle(String::New("statCall")); |
| 134 const String& super_class_name = String::Handle(String::New("Base")); | 119 const String& super_class_name = String::Handle(String::New("Base")); |
| 135 const int kNumArguments = 0; | 120 const int kNumArguments = 0; |
| 136 const Function& super_function = Function::Handle( | 121 const Function& super_function = Function::Handle(Resolver::ResolveStatic( |
| 137 Resolver::ResolveStatic(library, | 122 library, super_class_name, super_static_function_name, kNumArguments, |
| 138 super_class_name, | 123 Object::empty_array())); |
| 139 super_static_function_name, | |
| 140 kNumArguments, | |
| 141 Object::empty_array())); | |
| 142 EXPECT(!super_function.IsNull()); // No ambiguity error expected. | 124 EXPECT(!super_function.IsNull()); // No ambiguity error expected. |
| 143 } | 125 } |
| 144 } | 126 } |
| 145 | 127 |
| 146 | 128 |
| 147 TEST_CASE(DartDynamicResolve) { | 129 TEST_CASE(DartDynamicResolve) { |
| 148 const char* test_library_name = "ResolverApp"; | 130 const char* test_library_name = "ResolverApp"; |
| 149 const char* test_class_name = "A"; | 131 const char* test_class_name = "A"; |
| 150 const char* test_function_name = "foo"; | 132 const char* test_function_name = "foo"; |
| 151 const int kTestValue = 42; | 133 const int kTestValue = 42; |
| 152 | 134 |
| 153 // Setup a function which can be invoked. | 135 // Setup a function which can be invoked. |
| 154 SetupInstanceFunction(test_library_name, | 136 SetupInstanceFunction(test_library_name, test_class_name, test_function_name); |
| 155 test_class_name, | |
| 156 test_function_name); | |
| 157 | 137 |
| 158 // Now create an instance object of the class and try to | 138 // Now create an instance object of the class and try to |
| 159 // resolve a function in it. | 139 // resolve a function in it. |
| 160 const String& lib_name = String::Handle(String::New(test_library_name)); | 140 const String& lib_name = String::Handle(String::New(test_library_name)); |
| 161 const Library& lib = Library::Handle(Library::LookupLibrary(thread, | 141 const Library& lib = |
| 162 lib_name)); | 142 Library::Handle(Library::LookupLibrary(thread, lib_name)); |
| 163 ASSERT(!lib.IsNull()); | 143 ASSERT(!lib.IsNull()); |
| 164 const Class& cls = Class::Handle(lib.LookupClass( | 144 const Class& cls = Class::Handle( |
| 165 String::Handle(Symbols::New(thread, test_class_name)))); | 145 lib.LookupClass(String::Handle(Symbols::New(thread, test_class_name)))); |
| 166 EXPECT(!cls.IsNull()); // No ambiguity error expected. | 146 EXPECT(!cls.IsNull()); // No ambiguity error expected. |
| 167 | 147 |
| 168 Instance& receiver = Instance::Handle(Instance::New(cls)); | 148 Instance& receiver = Instance::Handle(Instance::New(cls)); |
| 169 const String& function_name = String::Handle(String::New(test_function_name)); | 149 const String& function_name = String::Handle(String::New(test_function_name)); |
| 170 | 150 |
| 171 // Now try to resolve and invoke the instance function in this class. | 151 // Now try to resolve and invoke the instance function in this class. |
| 172 { | 152 { |
| 173 const int kNumArguments = 3; | 153 const int kNumArguments = 3; |
| 174 ArgumentsDescriptor args_desc( | 154 ArgumentsDescriptor args_desc( |
| 175 Array::Handle(ArgumentsDescriptor::New(kNumArguments))); | 155 Array::Handle(ArgumentsDescriptor::New(kNumArguments))); |
| 176 const Function& function = Function::Handle( | 156 const Function& function = Function::Handle( |
| 177 Resolver::ResolveDynamic(receiver, | 157 Resolver::ResolveDynamic(receiver, function_name, args_desc)); |
| 178 function_name, | |
| 179 args_desc)); | |
| 180 EXPECT(!function.IsNull()); | 158 EXPECT(!function.IsNull()); |
| 181 const Array& args = Array::Handle(Array::New(kNumArguments)); | 159 const Array& args = Array::Handle(Array::New(kNumArguments)); |
| 182 args.SetAt(0, receiver); | 160 args.SetAt(0, receiver); |
| 183 const String& arg0 = String::Handle(String::New("junk")); | 161 const String& arg0 = String::Handle(String::New("junk")); |
| 184 args.SetAt(1, arg0); | 162 args.SetAt(1, arg0); |
| 185 const Smi& arg1 = Smi::Handle(Smi::New(kTestValue)); | 163 const Smi& arg1 = Smi::Handle(Smi::New(kTestValue)); |
| 186 args.SetAt(2, arg1); | 164 args.SetAt(2, arg1); |
| 187 const Smi& retval = Smi::Handle( | 165 const Smi& retval = Smi::Handle( |
| 188 reinterpret_cast<RawSmi*>(DartEntry::InvokeFunction(function, args))); | 166 reinterpret_cast<RawSmi*>(DartEntry::InvokeFunction(function, args))); |
| 189 EXPECT_EQ(kTestValue, retval.Value()); | 167 EXPECT_EQ(kTestValue, retval.Value()); |
| 190 } | 168 } |
| 191 | 169 |
| 192 // Now try to resolve an instance function with invalid argument count. | 170 // Now try to resolve an instance function with invalid argument count. |
| 193 { | 171 { |
| 194 const int kNumArguments = 1; | 172 const int kNumArguments = 1; |
| 195 ArgumentsDescriptor args_desc( | 173 ArgumentsDescriptor args_desc( |
| 196 Array::Handle(ArgumentsDescriptor::New(kNumArguments))); | 174 Array::Handle(ArgumentsDescriptor::New(kNumArguments))); |
| 197 const Function& bad_function = Function::Handle( | 175 const Function& bad_function = Function::Handle( |
| 198 Resolver::ResolveDynamic(receiver, | 176 Resolver::ResolveDynamic(receiver, function_name, args_desc)); |
| 199 function_name, | |
| 200 args_desc)); | |
| 201 EXPECT(bad_function.IsNull()); | 177 EXPECT(bad_function.IsNull()); |
| 202 } | 178 } |
| 203 | 179 |
| 204 // Hierarchy walking. | 180 // Hierarchy walking. |
| 205 { | 181 { |
| 206 const int kNumArguments = 1; | 182 const int kNumArguments = 1; |
| 207 ArgumentsDescriptor args_desc( | 183 ArgumentsDescriptor args_desc( |
| 208 Array::Handle(ArgumentsDescriptor::New(kNumArguments))); | 184 Array::Handle(ArgumentsDescriptor::New(kNumArguments))); |
| 209 const String& super_function_name = | 185 const String& super_function_name = String::Handle(String::New("dynCall")); |
| 210 String::Handle(String::New("dynCall")); | |
| 211 const Function& super_function = Function::Handle( | 186 const Function& super_function = Function::Handle( |
| 212 Resolver::ResolveDynamic(receiver, | 187 Resolver::ResolveDynamic(receiver, super_function_name, args_desc)); |
| 213 super_function_name, | |
| 214 args_desc)); | |
| 215 EXPECT(!super_function.IsNull()); | 188 EXPECT(!super_function.IsNull()); |
| 216 } | 189 } |
| 217 } | 190 } |
| 218 | 191 |
| 219 } // namespace dart | 192 } // namespace dart |
| OLD | NEW |