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 |