| 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/flags.h" | 7 #include "vm/flags.h" |
| 8 #include "vm/isolate.h" | 8 #include "vm/isolate.h" |
| 9 #include "vm/object.h" | 9 #include "vm/object.h" |
| 10 #include "vm/object_store.h" | 10 #include "vm/object_store.h" |
| 11 #include "vm/symbols.h" |
| 11 | 12 |
| 12 namespace dart { | 13 namespace dart { |
| 13 | 14 |
| 14 DEFINE_FLAG(bool, trace_resolving, false, "Trace resolving."); | 15 DEFINE_FLAG(bool, trace_resolving, false, "Trace resolving."); |
| 15 | 16 |
| 16 | 17 |
| 17 // The actual names of named arguments are not checked by the dynamic resolver, | 18 // The actual names of named arguments are not checked by the dynamic resolver, |
| 18 // but by the method entry code. It is important that the dynamic resolver | 19 // but by the method entry code. It is important that the dynamic resolver |
| 19 // checks that no named arguments are passed to a method that does not accept | 20 // checks that no named arguments are passed to a method that does not accept |
| 20 // them, since the entry code of such a method does not check for named | 21 // them, since the entry code of such a method does not check for named |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 OS::Print("ResolveDynamic error '%s': %s.\n", | 65 OS::Print("ResolveDynamic error '%s': %s.\n", |
| 65 function_name.ToCString(), | 66 function_name.ToCString(), |
| 66 error_message.ToCString()); | 67 error_message.ToCString()); |
| 67 } | 68 } |
| 68 return Function::null(); | 69 return Function::null(); |
| 69 } | 70 } |
| 70 return function.raw(); | 71 return function.raw(); |
| 71 } | 72 } |
| 72 | 73 |
| 73 | 74 |
| 75 // Method extractors are used to create implicit closures from methods. |
| 76 // When an expression obj.M is evaluated for the first time and receiver obj |
| 77 // does not have a getter called M but has a method called M then an extractor |
| 78 // is created and injected as a getter (under the name get:M) into the class |
| 79 // ownining method M. |
| 80 static RawFunction* CreateMethodExtractor(const String& getter_name, |
| 81 const Function& method) { |
| 82 const Function& closure_function = |
| 83 Function::Handle(method.ImplicitClosureFunction()); |
| 84 |
| 85 const Class& owner = Class::Handle(closure_function.Owner()); |
| 86 Function& extractor = Function::Handle( |
| 87 Function::New(String::Handle(Symbols::New(getter_name)), |
| 88 RawFunction::kMethodExtractor, |
| 89 false, // Not static. |
| 90 false, // Not const. |
| 91 false, // Not abstract. |
| 92 false, // Not external. |
| 93 owner, |
| 94 0)); // No token position. |
| 95 |
| 96 // Initialize signature: receiver is a single fixed parameter. |
| 97 const intptr_t kNumParameters = 1; |
| 98 extractor.set_num_fixed_parameters(kNumParameters); |
| 99 extractor.SetNumOptionalParameters(0, 0); |
| 100 extractor.set_parameter_types(Array::Handle(Array::New(kNumParameters, |
| 101 Heap::kOld))); |
| 102 extractor.set_parameter_names(Array::Handle(Array::New(kNumParameters, |
| 103 Heap::kOld))); |
| 104 extractor.SetParameterTypeAt(0, Type::Handle(Type::DynamicType())); |
| 105 extractor.SetParameterNameAt(0, Symbols::This()); |
| 106 extractor.set_result_type(Type::Handle(Type::DynamicType())); |
| 107 |
| 108 extractor.set_extracted_method_closure(closure_function); |
| 109 |
| 110 owner.AddFunction(extractor); |
| 111 |
| 112 return extractor.raw(); |
| 113 } |
| 114 |
| 115 |
| 74 RawFunction* Resolver::ResolveDynamicAnyArgs( | 116 RawFunction* Resolver::ResolveDynamicAnyArgs( |
| 75 const Class& receiver_class, | 117 const Class& receiver_class, |
| 76 const String& function_name) { | 118 const String& function_name) { |
| 77 Class& cls = Class::Handle(receiver_class.raw()); | 119 Class& cls = Class::Handle(receiver_class.raw()); |
| 78 if (FLAG_trace_resolving) { | 120 if (FLAG_trace_resolving) { |
| 79 OS::Print("ResolveDynamic '%s' for class %s\n", | 121 OS::Print("ResolveDynamic '%s' for class %s\n", |
| 80 function_name.ToCString(), | 122 function_name.ToCString(), |
| 81 String::Handle(cls.Name()).ToCString()); | 123 String::Handle(cls.Name()).ToCString()); |
| 82 } | 124 } |
| 125 |
| 126 const bool is_getter = Field::IsGetterName(function_name); |
| 127 String& field_name = String::Handle(); |
| 128 if (is_getter) { |
| 129 field_name ^= Field::NameFromGetter(function_name); |
| 130 } |
| 131 |
| 83 // Now look for an instance function whose name matches function_name | 132 // Now look for an instance function whose name matches function_name |
| 84 // in the class. | 133 // in the class. |
| 85 Function& function = | 134 Function& function = Function::Handle(); |
| 86 Function::Handle(cls.LookupDynamicFunction(function_name)); | 135 while (function.IsNull() && !cls.IsNull()) { |
| 87 while (function.IsNull()) { | 136 function ^= cls.LookupDynamicFunction(function_name); |
| 137 |
| 138 // Getter invocation might actually be a method extraction. |
| 139 if (is_getter && function.IsNull()) { |
| 140 function ^= cls.LookupDynamicFunction(field_name); |
| 141 if (!function.IsNull()) { |
| 142 // We were looking for the getter but found a method with the same name. |
| 143 // Create a method extractor and return it. |
| 144 function ^= CreateMethodExtractor(function_name, function); |
| 145 } |
| 146 } |
| 147 |
| 88 cls = cls.SuperClass(); | 148 cls = cls.SuperClass(); |
| 89 if (cls.IsNull()) break; | |
| 90 function = cls.LookupDynamicFunction(function_name); | |
| 91 } | 149 } |
| 92 return function.raw(); | 150 return function.raw(); |
| 93 } | 151 } |
| 94 | 152 |
| 95 | 153 |
| 96 RawFunction* Resolver::ResolveStatic(const Library& library, | 154 RawFunction* Resolver::ResolveStatic(const Library& library, |
| 97 const String& class_name, | 155 const String& class_name, |
| 98 const String& function_name, | 156 const String& function_name, |
| 99 int num_arguments, | 157 int num_arguments, |
| 100 const Array& argument_names, | 158 const Array& argument_names, |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 OS::Print("ResolveStatic error '%s': %s.\n", | 250 OS::Print("ResolveStatic error '%s': %s.\n", |
| 193 function_name.ToCString(), | 251 function_name.ToCString(), |
| 194 error_message.ToCString()); | 252 error_message.ToCString()); |
| 195 } | 253 } |
| 196 return Function::null(); | 254 return Function::null(); |
| 197 } | 255 } |
| 198 return function.raw(); | 256 return function.raw(); |
| 199 } | 257 } |
| 200 | 258 |
| 201 } // namespace dart | 259 } // namespace dart |
| OLD | NEW |