| 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/log.h" | 10 #include "vm/log.h" |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 const Class& cls = Class::Handle(receiver.clazz()); | 29 const Class& cls = Class::Handle(receiver.clazz()); |
| 30 return ResolveDynamicForReceiverClass(cls, function_name, args_desc); | 30 return ResolveDynamicForReceiverClass(cls, function_name, args_desc); |
| 31 } | 31 } |
| 32 | 32 |
| 33 | 33 |
| 34 RawFunction* Resolver::ResolveDynamicForReceiverClass( | 34 RawFunction* Resolver::ResolveDynamicForReceiverClass( |
| 35 const Class& receiver_class, | 35 const Class& receiver_class, |
| 36 const String& function_name, | 36 const String& function_name, |
| 37 const ArgumentsDescriptor& args_desc, | 37 const ArgumentsDescriptor& args_desc, |
| 38 bool allow_add) { | 38 bool allow_add) { |
| 39 Thread* thread = Thread::Current(); |
| 40 Zone* zone = thread->zone(); |
| 39 | 41 |
| 40 Function& function = Function::Handle( | 42 Function& function = Function::Handle(zone, |
| 41 ResolveDynamicAnyArgs(receiver_class, function_name, allow_add)); | 43 ResolveDynamicAnyArgs(zone, receiver_class, function_name, allow_add)); |
| 42 | 44 |
| 43 if (function.IsNull() || | 45 if (function.IsNull() || |
| 44 !function.AreValidArguments(args_desc, NULL)) { | 46 !function.AreValidArguments(args_desc, NULL)) { |
| 45 // Return a null function to signal to the upper levels to dispatch to | 47 // Return a null function to signal to the upper levels to dispatch to |
| 46 // "noSuchMethod" function. | 48 // "noSuchMethod" function. |
| 47 if (FLAG_trace_resolving) { | 49 if (FLAG_trace_resolving) { |
| 48 String& error_message = | 50 String& error_message = |
| 49 String::Handle(Symbols::New("function not found")); | 51 String::Handle(zone, Symbols::New(thread, "function not found")); |
| 50 if (!function.IsNull()) { | 52 if (!function.IsNull()) { |
| 51 // Obtain more detailed error message. | 53 // Obtain more detailed error message. |
| 52 function.AreValidArguments(args_desc, &error_message); | 54 function.AreValidArguments(args_desc, &error_message); |
| 53 } | 55 } |
| 54 THR_Print("ResolveDynamic error '%s': %s.\n", | 56 THR_Print("ResolveDynamic error '%s': %s.\n", |
| 55 function_name.ToCString(), | 57 function_name.ToCString(), |
| 56 error_message.ToCString()); | 58 error_message.ToCString()); |
| 57 } | 59 } |
| 58 return Function::null(); | 60 return Function::null(); |
| 59 } | 61 } |
| 60 return function.raw(); | 62 return function.raw(); |
| 61 } | 63 } |
| 62 | 64 |
| 63 | 65 |
| 64 RawFunction* Resolver::ResolveDynamicAnyArgs( | 66 RawFunction* Resolver::ResolveDynamicAnyArgs( |
| 67 Zone* zone, |
| 65 const Class& receiver_class, | 68 const Class& receiver_class, |
| 66 const String& function_name, | 69 const String& function_name, |
| 67 bool allow_add) { | 70 bool allow_add) { |
| 68 Class& cls = Class::Handle(receiver_class.raw()); | 71 Class& cls = Class::Handle(zone, receiver_class.raw()); |
| 69 if (FLAG_trace_resolving) { | 72 if (FLAG_trace_resolving) { |
| 70 THR_Print("ResolveDynamic '%s' for class %s\n", | 73 THR_Print("ResolveDynamic '%s' for class %s\n", |
| 71 function_name.ToCString(), | 74 function_name.ToCString(), |
| 72 String::Handle(cls.Name()).ToCString()); | 75 String::Handle(zone, cls.Name()).ToCString()); |
| 73 } | 76 } |
| 74 | 77 |
| 75 const bool is_getter = Field::IsGetterName(function_name); | 78 const bool is_getter = Field::IsGetterName(function_name); |
| 76 String& field_name = String::Handle(); | 79 String& field_name = String::Handle(zone); |
| 77 if (is_getter) { | 80 if (is_getter) { |
| 78 field_name ^= Field::NameFromGetter(function_name); | 81 field_name ^= Field::NameFromGetter(function_name); |
| 79 | 82 |
| 80 if (field_name.CharAt(0) == '#') { | 83 if (field_name.CharAt(0) == '#') { |
| 81 // Resolving a getter "get:#..." is a request to closurize an instance | 84 // Resolving a getter "get:#..." is a request to closurize an instance |
| 82 // property of the receiver object. It can be of the form: | 85 // property of the receiver object. It can be of the form: |
| 83 // - get:#id, which closurizes a method or getter id | 86 // - get:#id, which closurizes a method or getter id |
| 84 // - get:#set:id, which closurizes a setter id | 87 // - get:#set:id, which closurizes a setter id |
| 85 // - get:#operator, eg. get:#<<, which closurizes an operator method. | 88 // - get:#operator, eg. get:#<<, which closurizes an operator method. |
| 86 // If the property can be resolved, a method extractor function | 89 // If the property can be resolved, a method extractor function |
| 87 // "get:#..." is created and injected into the receiver's class. | 90 // "get:#..." is created and injected into the receiver's class. |
| 88 field_name = String::SubString(field_name, 1); | 91 field_name = String::SubString(field_name, 1); |
| 89 ASSERT(!Field::IsGetterName(field_name)); | 92 ASSERT(!Field::IsGetterName(field_name)); |
| 90 | 93 |
| 91 String& property_getter_name = String::Handle(); | 94 String& property_getter_name = String::Handle(zone); |
| 92 if (!Field::IsSetterName(field_name)) { | 95 if (!Field::IsSetterName(field_name)) { |
| 93 // If this is not a setter, we need to look for both the regular | 96 // If this is not a setter, we need to look for both the regular |
| 94 // name and the getter name. (In the case of an operator, this | 97 // name and the getter name. (In the case of an operator, this |
| 95 // code will also try to resolve for example get:<< and will fail, | 98 // code will also try to resolve for example get:<< and will fail, |
| 96 // but that's harmless.) | 99 // but that's harmless.) |
| 97 property_getter_name = Field::GetterName(field_name); | 100 property_getter_name = Field::GetterName(field_name); |
| 98 } | 101 } |
| 99 | 102 |
| 100 Function& function = Function::Handle(); | 103 Function& function = Function::Handle(zone); |
| 101 while (!cls.IsNull()) { | 104 while (!cls.IsNull()) { |
| 102 function = cls.LookupDynamicFunction(field_name); | 105 function = cls.LookupDynamicFunction(field_name); |
| 103 if (!function.IsNull()) { | 106 if (!function.IsNull()) { |
| 104 return function.GetMethodExtractor(function_name); | 107 return function.GetMethodExtractor(function_name); |
| 105 } | 108 } |
| 106 if (!property_getter_name.IsNull()) { | 109 if (!property_getter_name.IsNull()) { |
| 107 function = cls.LookupDynamicFunction(property_getter_name); | 110 function = cls.LookupDynamicFunction(property_getter_name); |
| 108 if (!function.IsNull()) { | 111 if (!function.IsNull()) { |
| 109 return function.GetMethodExtractor(function_name); | 112 return function.GetMethodExtractor(function_name); |
| 110 } | 113 } |
| 111 } | 114 } |
| 112 cls = cls.SuperClass(); | 115 cls = cls.SuperClass(); |
| 113 } | 116 } |
| 114 return Function::null(); | 117 return Function::null(); |
| 115 } | 118 } |
| 116 } | 119 } |
| 117 | 120 |
| 118 // Now look for an instance function whose name matches function_name | 121 // Now look for an instance function whose name matches function_name |
| 119 // in the class. | 122 // in the class. |
| 120 Function& function = Function::Handle(); | 123 Function& function = Function::Handle(zone); |
| 121 while (!cls.IsNull()) { | 124 while (!cls.IsNull()) { |
| 122 function ^= cls.LookupDynamicFunction(function_name); | 125 function ^= cls.LookupDynamicFunction(function_name); |
| 123 if (!function.IsNull()) { | 126 if (!function.IsNull()) { |
| 124 return function.raw(); | 127 return function.raw(); |
| 125 } | 128 } |
| 126 // Getter invocation might actually be a method extraction. | 129 // Getter invocation might actually be a method extraction. |
| 127 if (FLAG_lazy_dispatchers) { | 130 if (FLAG_lazy_dispatchers) { |
| 128 if (is_getter && function.IsNull()) { | 131 if (is_getter && function.IsNull()) { |
| 129 function ^= cls.LookupDynamicFunction(field_name); | 132 function ^= cls.LookupDynamicFunction(field_name); |
| 130 if (!function.IsNull() && allow_add) { | 133 if (!function.IsNull() && allow_add) { |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 THR_Print("ResolveStaticAllowPrivate error '%s': %s.\n", | 255 THR_Print("ResolveStaticAllowPrivate error '%s': %s.\n", |
| 253 function_name.ToCString(), | 256 function_name.ToCString(), |
| 254 error_message.ToCString()); | 257 error_message.ToCString()); |
| 255 } | 258 } |
| 256 return Function::null(); | 259 return Function::null(); |
| 257 } | 260 } |
| 258 return function.raw(); | 261 return function.raw(); |
| 259 } | 262 } |
| 260 | 263 |
| 261 } // namespace dart | 264 } // namespace dart |
| OLD | NEW |