OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/code_generator.h" | 5 #include "vm/code_generator.h" |
6 | 6 |
7 #include "vm/assembler.h" | 7 #include "vm/assembler.h" |
8 #include "vm/ast.h" | 8 #include "vm/ast.h" |
9 #include "vm/bigint_operations.h" | 9 #include "vm/bigint_operations.h" |
10 #include "vm/code_patcher.h" | 10 #include "vm/code_patcher.h" |
(...skipping 1166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1177 | 1177 |
1178 // An instance call of the form o.f(...) could not be resolved. Check if | 1178 // An instance call of the form o.f(...) could not be resolved. Check if |
1179 // there is a getter with the same name. If so, invoke it. If the value is | 1179 // there is a getter with the same name. If so, invoke it. If the value is |
1180 // a closure, invoke it with the given arguments. If the value is a | 1180 // a closure, invoke it with the given arguments. If the value is a |
1181 // non-closure, attempt to invoke "call" on it. | 1181 // non-closure, attempt to invoke "call" on it. |
1182 static bool ResolveCallThroughGetter(const Instance& receiver, | 1182 static bool ResolveCallThroughGetter(const Instance& receiver, |
1183 const Class& receiver_class, | 1183 const Class& receiver_class, |
1184 const String& target_name, | 1184 const String& target_name, |
1185 const Array& arguments_descriptor, | 1185 const Array& arguments_descriptor, |
1186 const Array& arguments, | 1186 const Array& arguments, |
| 1187 const ICData& ic_data, |
1187 Object* result) { | 1188 Object* result) { |
1188 // 1. Check if there is a getter with the same name. | 1189 // 1. Check if there is a getter with the same name. |
1189 const String& getter_name = String::Handle(Field::GetterName(target_name)); | 1190 const String& getter_name = String::Handle(Field::GetterName(target_name)); |
1190 const int kNumArguments = 1; | 1191 const int kNumArguments = 1; |
1191 const int kNumNamedArguments = 0; | 1192 const int kNumNamedArguments = 0; |
1192 const Function& getter = Function::Handle( | 1193 const Function& getter = Function::Handle( |
1193 Resolver::ResolveDynamicForReceiverClass(receiver_class, | 1194 Resolver::ResolveDynamicForReceiverClass(receiver_class, |
1194 getter_name, | 1195 getter_name, |
1195 kNumArguments, | 1196 kNumArguments, |
1196 kNumNamedArguments)); | 1197 kNumNamedArguments)); |
1197 if (getter.IsNull() || getter.IsMethodExtractor()) { | 1198 if (getter.IsNull() || getter.IsMethodExtractor()) { |
1198 return false; | 1199 return false; |
1199 } | 1200 } |
1200 | 1201 |
1201 // 2. Invoke the getter. | 1202 const Function& target_function = |
1202 const Array& args = Array::Handle(Array::New(kNumArguments)); | 1203 Function::Handle(receiver_class.GetInvocationDispatcher( |
1203 args.SetAt(0, receiver); | 1204 target_name, |
1204 const Object& value = Object::Handle(DartEntry::InvokeFunction(getter, args)); | 1205 arguments_descriptor, |
1205 | 1206 RawFunction::kInvokeFieldDispatcher)); |
1206 // 3. If there was some error, propagate it. | 1207 // Update IC data. |
1207 CheckResultError(value); | 1208 ASSERT(!target_function.IsNull()); |
1208 | 1209 ic_data.AddReceiverCheck(receiver.GetClassId(), target_function); |
1209 // 4. Invoke the value as a closure. | 1210 if (FLAG_trace_ic) { |
1210 Instance& instance = Instance::Handle(); | 1211 OS::PrintErr("InvokeField IC miss: adding <%s> id:%"Pd" -> <%s>\n", |
1211 instance ^= value.raw(); | 1212 Class::Handle(receiver.clazz()).ToCString(), |
1212 arguments.SetAt(0, instance); | 1213 receiver.GetClassId(), |
1213 *result = DartEntry::InvokeClosure(arguments, arguments_descriptor); | 1214 target_function.ToCString()); |
| 1215 } |
| 1216 *result = DartEntry::InvokeFunction(target_function, |
| 1217 arguments, |
| 1218 arguments_descriptor); |
1214 CheckResultError(*result); | 1219 CheckResultError(*result); |
1215 return true; | 1220 return true; |
1216 } | 1221 } |
1217 | 1222 |
1218 | 1223 |
1219 // The IC miss handler has failed to find a (cacheable) instance function to | 1224 // The IC miss handler has failed to find a (cacheable) instance function to |
1220 // invoke. Handle three possibilities: | 1225 // invoke. Handle three possibilities: |
1221 // | 1226 // |
1222 // 1. If the call was a getter o.f, there may be an instance function with | 1227 // 1. If the call was a getter o.f, there may be an instance function with |
1223 // the same name. If so, create an implicit closure and return it. | 1228 // the same name. If so, create an implicit closure and return it. |
(...skipping 18 matching lines...) Expand all Loading... |
1242 receiver_class = isolate->object_store()->object_class(); | 1247 receiver_class = isolate->object_store()->object_class(); |
1243 } | 1248 } |
1244 const String& target_name = String::Handle(ic_data.target_name()); | 1249 const String& target_name = String::Handle(ic_data.target_name()); |
1245 | 1250 |
1246 Object& result = Object::Handle(); | 1251 Object& result = Object::Handle(); |
1247 if (!ResolveCallThroughGetter(receiver, | 1252 if (!ResolveCallThroughGetter(receiver, |
1248 receiver_class, | 1253 receiver_class, |
1249 target_name, | 1254 target_name, |
1250 args_descriptor, | 1255 args_descriptor, |
1251 args, | 1256 args, |
| 1257 ic_data, |
1252 &result)) { | 1258 &result)) { |
1253 ArgumentsDescriptor desc(args_descriptor); | 1259 ArgumentsDescriptor desc(args_descriptor); |
1254 const Function& target_function = Function::Handle( | 1260 const Function& target_function = |
1255 receiver_class.GetNoSuchMethodDispatcher(target_name, args_descriptor)); | 1261 Function::Handle(receiver_class.GetInvocationDispatcher( |
| 1262 target_name, |
| 1263 args_descriptor, |
| 1264 RawFunction::kNoSuchMethodDispatcher)); |
1256 // Update IC data. | 1265 // Update IC data. |
1257 ASSERT(!target_function.IsNull()); | 1266 ASSERT(!target_function.IsNull()); |
1258 intptr_t receiver_cid = receiver.GetClassId(); | 1267 intptr_t receiver_cid = receiver.GetClassId(); |
1259 if (ic_data.num_args_tested() == 1) { | 1268 if (ic_data.num_args_tested() == 1) { |
1260 // In optimized code we may enter into here via the | 1269 // In optimized code we may enter into here via the |
1261 // MegamorphicCacheMissHandler since noSuchMethod dispatchers are not | 1270 // MegamorphicCacheMissHandler since noSuchMethod dispatchers are not |
1262 // inserted into the megamorphic cache. Therefore, we need to guard | 1271 // inserted into the megamorphic cache. Therefore, we need to guard |
1263 // against entering the same check twice into the ICData. | 1272 // against entering the same check twice into the ICData. |
1264 // Note that num_args_tested == 1 in optimized code. | 1273 // Note that num_args_tested == 1 in optimized code. |
1265 // TODO(fschneider): Handle extraordinary cases like noSuchMethod and | 1274 // TODO(fschneider): Handle extraordinary cases like noSuchMethod and |
(...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1882 // Arg1: Value that is being stored. | 1891 // Arg1: Value that is being stored. |
1883 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { | 1892 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { |
1884 ASSERT(arguments.ArgCount() == kUpdateFieldCidRuntimeEntry.argument_count()); | 1893 ASSERT(arguments.ArgCount() == kUpdateFieldCidRuntimeEntry.argument_count()); |
1885 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); | 1894 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); |
1886 const Object& value = Object::Handle(arguments.ArgAt(1)); | 1895 const Object& value = Object::Handle(arguments.ArgAt(1)); |
1887 | 1896 |
1888 field.UpdateCid(value.GetClassId()); | 1897 field.UpdateCid(value.GetClassId()); |
1889 } | 1898 } |
1890 | 1899 |
1891 } // namespace dart | 1900 } // namespace dart |
OLD | NEW |