OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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_macros.h" | 7 #include "vm/assembler_macros.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 1079 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1090 ic_data.AddCheck(class_ids, target_function); | 1090 ic_data.AddCheck(class_ids, target_function); |
1091 } | 1091 } |
1092 | 1092 |
1093 | 1093 |
1094 // An instance call could not be resolved by an IC miss handler. Check if | 1094 // An instance call could not be resolved by an IC miss handler. Check if |
1095 // it was a getter call and if there is an instance function with the same | 1095 // it was a getter call and if there is an instance function with the same |
1096 // name. If so, create and return an implicit closure from the function. | 1096 // name. If so, create and return an implicit closure from the function. |
1097 // Otherwise return null. | 1097 // Otherwise return null. |
1098 static RawInstance* ResolveImplicitClosure(const Instance& receiver, | 1098 static RawInstance* ResolveImplicitClosure(const Instance& receiver, |
1099 const Class& receiver_class, | 1099 const Class& receiver_class, |
1100 const String& target_name) { | 1100 const String& target_name, |
| 1101 const ICData& ic_data) { |
1101 // 1. Check if was a getter call. | 1102 // 1. Check if was a getter call. |
1102 if (!Field::IsGetterName(target_name)) return Instance::null(); | 1103 if (!Field::IsGetterName(target_name)) return Instance::null(); |
1103 | 1104 |
1104 // 2. Check if there is an instance function with the same name. | 1105 // 2. Check if there is an instance function with the same name. |
1105 String& function_name = String::Handle(Field::NameFromGetter(target_name)); | 1106 String& function_name = String::Handle(Field::NameFromGetter(target_name)); |
1106 function_name = Symbols::New(function_name); | 1107 function_name = Symbols::New(function_name); |
1107 const Function& function = Function::Handle( | 1108 const Function& function = Function::Handle( |
1108 Resolver::ResolveDynamicAnyArgs(receiver_class, function_name)); | 1109 Resolver::ResolveDynamicAnyArgs(receiver_class, function_name)); |
1109 if (function.IsNull()) return Instance::null(); | 1110 if (function.IsNull()) return Instance::null(); |
1110 | 1111 |
1111 // Create a closure object for the implicit closure function. | 1112 // Create a closure object for the implicit closure function. |
1112 const Function& closure_function = | 1113 const Function& closure_function = |
1113 Function::Handle(function.ImplicitClosureFunction()); | 1114 Function::Handle(function.ImplicitClosureFunction()); |
1114 const Context& context = Context::Handle(Context::New(1)); | 1115 const Context& context = Context::Handle(Context::New(1)); |
1115 context.SetAt(0, receiver); | 1116 context.SetAt(0, receiver); |
1116 const Instance& closure = | 1117 const Instance& closure = |
1117 Instance::Handle(Closure::New(closure_function, context)); | 1118 Instance::Handle(Closure::New(closure_function, context)); |
1118 if (receiver_class.HasTypeArguments()) { | 1119 if (receiver_class.HasTypeArguments()) { |
1119 const AbstractTypeArguments& type_arguments = | 1120 const AbstractTypeArguments& type_arguments = |
1120 AbstractTypeArguments::Handle(receiver.GetTypeArguments()); | 1121 AbstractTypeArguments::Handle(receiver.GetTypeArguments()); |
1121 closure.SetTypeArguments(type_arguments); | 1122 closure.SetTypeArguments(type_arguments); |
1122 } | 1123 } |
| 1124 |
| 1125 ASSERT(ic_data.num_args_tested() == 1); |
| 1126 ic_data.AddReceiverCheck( |
| 1127 receiver_class.id(), |
| 1128 Function::Handle(StubCode::GetMethodExtractor(closure_function))); |
1123 return closure.raw(); | 1129 return closure.raw(); |
1124 } | 1130 } |
1125 | 1131 |
1126 | 1132 |
1127 static RawInstructions* EnsureCompiled(const Function& function) { | 1133 static RawInstructions* EnsureCompiled(const Function& function) { |
1128 if (!function.HasCode()) { | 1134 if (!function.HasCode()) { |
1129 const Error& error = Error::Handle(Compiler::CompileFunction(function)); | 1135 const Error& error = Error::Handle(Compiler::CompileFunction(function)); |
1130 if (!error.IsNull()) { | 1136 if (!error.IsNull()) { |
1131 Exceptions::PropagateError(error); | 1137 Exceptions::PropagateError(error); |
1132 } | 1138 } |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1397 | 1403 |
1398 Class& receiver_class = Class::Handle(receiver.clazz()); | 1404 Class& receiver_class = Class::Handle(receiver.clazz()); |
1399 // For lookups treat null as an instance of class Object. | 1405 // For lookups treat null as an instance of class Object. |
1400 if (receiver_class.IsNullClass()) { | 1406 if (receiver_class.IsNullClass()) { |
1401 receiver_class = isolate->object_store()->object_class(); | 1407 receiver_class = isolate->object_store()->object_class(); |
1402 } | 1408 } |
1403 const String& target_name = String::Handle(ic_data.target_name()); | 1409 const String& target_name = String::Handle(ic_data.target_name()); |
1404 | 1410 |
1405 Instance& closure = Instance::Handle(ResolveImplicitClosure(receiver, | 1411 Instance& closure = Instance::Handle(ResolveImplicitClosure(receiver, |
1406 receiver_class, | 1412 receiver_class, |
1407 target_name)); | 1413 target_name, |
| 1414 ic_data)); |
1408 if (!closure.IsNull()) { | 1415 if (!closure.IsNull()) { |
1409 arguments.SetReturn(closure); | 1416 arguments.SetReturn(closure); |
1410 return; | 1417 return; |
1411 } | 1418 } |
1412 | 1419 |
1413 Object& result = Object::Handle(); | 1420 Object& result = Object::Handle(); |
1414 if (!ResolveCallThroughGetter(receiver, | 1421 if (!ResolveCallThroughGetter(receiver, |
1415 receiver_class, | 1422 receiver_class, |
1416 target_name, | 1423 target_name, |
1417 args_descriptor, | 1424 args_descriptor, |
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1955 return; | 1962 return; |
1956 } | 1963 } |
1957 HeapTrace* heap_trace = Isolate::Current()->heap()->trace(); | 1964 HeapTrace* heap_trace = Isolate::Current()->heap()->trace(); |
1958 heap_trace->TraceStoreIntoObject(RawObject::ToAddr(object), | 1965 heap_trace->TraceStoreIntoObject(RawObject::ToAddr(object), |
1959 field_addr, | 1966 field_addr, |
1960 RawObject::ToAddr(value)); | 1967 RawObject::ToAddr(value)); |
1961 } | 1968 } |
1962 END_LEAF_RUNTIME_ENTRY | 1969 END_LEAF_RUNTIME_ENTRY |
1963 | 1970 |
1964 } // namespace dart | 1971 } // namespace dart |
OLD | NEW |