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