OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 "vm/resolver.h" | 5 #include "vm/resolver.h" |
6 | 6 |
7 #include "vm/dart_entry.h" | 7 #include "vm/dart_entry.h" |
8 #include "vm/flags.h" | 8 #include "vm/flags.h" |
9 #include "vm/isolate.h" | 9 #include "vm/isolate.h" |
10 #include "vm/object.h" | 10 #include "vm/object.h" |
11 #include "vm/object_store.h" | 11 #include "vm/object_store.h" |
12 #include "vm/symbols.h" | 12 #include "vm/symbols.h" |
13 | 13 |
14 namespace dart { | 14 namespace dart { |
15 | 15 |
16 DEFINE_FLAG(bool, trace_resolving, false, "Trace resolving."); | 16 DEFINE_FLAG(bool, trace_resolving, false, "Trace resolving."); |
17 | 17 DECLARE_FLAG(bool, lazy_dispatchers); |
18 | 18 |
19 // The actual names of named arguments are not checked by the dynamic resolver, | 19 // The actual names of named arguments are not checked by the dynamic resolver, |
20 // but by the method entry code. It is important that the dynamic resolver | 20 // but by the method entry code. It is important that the dynamic resolver |
21 // checks that no named arguments are passed to a method that does not accept | 21 // checks that no named arguments are passed to a method that does not accept |
22 // them, since the entry code of such a method does not check for named | 22 // them, since the entry code of such a method does not check for named |
23 // arguments. The dynamic resolver actually checks that a valid number of named | 23 // arguments. The dynamic resolver actually checks that a valid number of named |
24 // arguments is passed in. | 24 // arguments is passed in. |
25 RawFunction* Resolver::ResolveDynamic(const Instance& receiver, | 25 RawFunction* Resolver::ResolveDynamic(const Instance& receiver, |
26 const String& function_name, | 26 const String& function_name, |
27 const ArgumentsDescriptor& args_desc) { | 27 const ArgumentsDescriptor& args_desc) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 } | 59 } |
60 | 60 |
61 | 61 |
62 // Method extractors are used to create implicit closures from methods. | 62 // Method extractors are used to create implicit closures from methods. |
63 // When an expression obj.M is evaluated for the first time and receiver obj | 63 // When an expression obj.M is evaluated for the first time and receiver obj |
64 // does not have a getter called M but has a method called M then an extractor | 64 // does not have a getter called M but has a method called M then an extractor |
65 // is created and injected as a getter (under the name get:M) into the class | 65 // is created and injected as a getter (under the name get:M) into the class |
66 // owning method M. | 66 // owning method M. |
67 static RawFunction* CreateMethodExtractor(const String& getter_name, | 67 static RawFunction* CreateMethodExtractor(const String& getter_name, |
68 const Function& method) { | 68 const Function& method) { |
| 69 ASSERT(FLAG_lazy_dispatchers); |
69 const Function& closure_function = | 70 const Function& closure_function = |
70 Function::Handle(method.ImplicitClosureFunction()); | 71 Function::Handle(method.ImplicitClosureFunction()); |
71 | 72 |
72 const Class& owner = Class::Handle(closure_function.Owner()); | 73 const Class& owner = Class::Handle(closure_function.Owner()); |
73 Function& extractor = Function::Handle( | 74 Function& extractor = Function::Handle( |
74 Function::New(String::Handle(Symbols::New(getter_name)), | 75 Function::New(String::Handle(Symbols::New(getter_name)), |
75 RawFunction::kMethodExtractor, | 76 RawFunction::kMethodExtractor, |
76 false, // Not static. | 77 false, // Not static. |
77 false, // Not const. | 78 false, // Not const. |
78 false, // Not abstract. | 79 false, // Not abstract. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 | 118 |
118 // Now look for an instance function whose name matches function_name | 119 // Now look for an instance function whose name matches function_name |
119 // in the class. | 120 // in the class. |
120 Function& function = Function::Handle(); | 121 Function& function = Function::Handle(); |
121 while (!cls.IsNull()) { | 122 while (!cls.IsNull()) { |
122 function ^= cls.LookupDynamicFunction(function_name); | 123 function ^= cls.LookupDynamicFunction(function_name); |
123 if (!function.IsNull()) { | 124 if (!function.IsNull()) { |
124 return function.raw(); | 125 return function.raw(); |
125 } | 126 } |
126 // Getter invocation might actually be a method extraction. | 127 // Getter invocation might actually be a method extraction. |
127 if (is_getter && function.IsNull()) { | 128 if (FLAG_lazy_dispatchers) { |
128 function ^= cls.LookupDynamicFunction(field_name); | 129 if (is_getter && function.IsNull()) { |
129 if (!function.IsNull()) { | 130 function ^= cls.LookupDynamicFunction(field_name); |
130 // We were looking for the getter but found a method with the same name. | 131 if (!function.IsNull()) { |
131 // Create a method extractor and return it. | 132 // We were looking for the getter but found a method with the same |
132 function ^= CreateMethodExtractor(function_name, function); | 133 // name. Create a method extractor and return it. |
133 return function.raw(); | 134 function ^= CreateMethodExtractor(function_name, function); |
| 135 return function.raw(); |
| 136 } |
134 } | 137 } |
135 } | 138 } |
136 cls = cls.SuperClass(); | 139 cls = cls.SuperClass(); |
137 } | 140 } |
138 return function.raw(); | 141 return function.raw(); |
139 } | 142 } |
140 | 143 |
141 | 144 |
142 RawFunction* Resolver::ResolveStatic(const Library& library, | 145 RawFunction* Resolver::ResolveStatic(const Library& library, |
143 const String& class_name, | 146 const String& class_name, |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 OS::Print("ResolveStaticAllowPrivate error '%s': %s.\n", | 251 OS::Print("ResolveStaticAllowPrivate error '%s': %s.\n", |
249 function_name.ToCString(), | 252 function_name.ToCString(), |
250 error_message.ToCString()); | 253 error_message.ToCString()); |
251 } | 254 } |
252 return Function::null(); | 255 return Function::null(); |
253 } | 256 } |
254 return function.raw(); | 257 return function.raw(); |
255 } | 258 } |
256 | 259 |
257 } // namespace dart | 260 } // namespace dart |
OLD | NEW |