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 |