Chromium Code Reviews| 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 1109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1120 | 1120 |
| 1121 const Object& result = Object::Handle( | 1121 const Object& result = Object::Handle( |
| 1122 DartEntry::InvokeClosure(instance, | 1122 DartEntry::InvokeClosure(instance, |
| 1123 function_args, | 1123 function_args, |
| 1124 args_descriptor)); | 1124 args_descriptor)); |
| 1125 CheckResultError(result); | 1125 CheckResultError(result); |
| 1126 arguments.SetReturn(result); | 1126 arguments.SetReturn(result); |
| 1127 } | 1127 } |
| 1128 | 1128 |
| 1129 | 1129 |
| 1130 static const char* CreateMethodExtractorName(const Function& closure_function) { | |
|
srdjan
2013/01/16 22:08:56
ASSERT(closure_function.IsClosureFunction()) ... a
Vyacheslav Egorov (Google)
2013/01/17 12:46:38
This method died.
| |
| 1131 const char* kFormat = "[MethodExtractor:%s]"; | |
| 1132 const char* function_name = | |
| 1133 String::Handle(closure_function.name()).ToCString(); | |
| 1134 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name) + 1; | |
| 1135 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | |
| 1136 OS::SNPrint(chars, len, kFormat, function_name); | |
| 1137 return chars; | |
| 1138 } | |
| 1139 | |
| 1140 | |
| 1141 static RawFunction* GetMethodExtractor(const Function& closure_function) { | |
|
srdjan
2013/01/16 22:08:56
Please add a brief comment what a method extractor
Vyacheslav Egorov (Google)
2013/01/17 12:46:38
Done.
| |
| 1142 Function& extractor = Function::Handle(closure_function.method_extractor()); | |
| 1143 if (extractor.IsNull()) { | |
| 1144 const char* name = CreateMethodExtractorName(closure_function); | |
| 1145 | |
| 1146 const Class& owner = Class::Handle(closure_function.Owner()); | |
| 1147 extractor ^= Function::New(String::Handle(Symbols::New(name)), | |
| 1148 RawFunction::kMethodExtractor, | |
| 1149 false, // Not static. | |
| 1150 false, // Not const. | |
| 1151 false, // Not abstract. | |
| 1152 false, // Not external. | |
| 1153 owner, | |
| 1154 0); // No token position. | |
| 1155 // Initialize function's signature. | |
| 1156 const intptr_t kNumParameters = 1; | |
| 1157 extractor.set_num_fixed_parameters(kNumParameters); | |
| 1158 extractor.SetNumOptionalParameters(0, 0); | |
| 1159 extractor.set_parameter_types(Array::Handle(Array::New(kNumParameters, | |
| 1160 Heap::kOld))); | |
| 1161 extractor.set_parameter_names(Array::Handle(Array::New(kNumParameters, | |
| 1162 Heap::kOld))); | |
| 1163 extractor.SetParameterTypeAt(0, Type::Handle(Type::DynamicType())); | |
| 1164 extractor.SetParameterNameAt(0, Symbols::This()); | |
| 1165 extractor.set_result_type(Type::Handle(Type::DynamicType())); | |
| 1166 | |
| 1167 extractor.set_extracted_method_closure(closure_function); | |
| 1168 | |
| 1169 Compiler::CompileFunction(extractor); | |
| 1170 } | |
| 1171 return extractor.raw(); | |
| 1172 } | |
| 1173 | |
| 1174 | |
| 1130 // An instance call could not be resolved by an IC miss handler. Check if | 1175 // An instance call could not be resolved by an IC miss handler. Check if |
| 1131 // it was a getter call and if there is an instance function with the same | 1176 // it was a getter call and if there is an instance function with the same |
| 1132 // name. If so, create and return an implicit closure from the function. | 1177 // name. If so, create and return an implicit closure from the function. |
| 1133 // Otherwise return null. | 1178 // Otherwise return null. |
| 1134 static RawInstance* ResolveImplicitClosure(const Instance& receiver, | 1179 static RawInstance* ResolveImplicitClosure(const Instance& receiver, |
| 1135 const Class& receiver_class, | 1180 const Class& receiver_class, |
| 1136 const String& target_name) { | 1181 const String& target_name, |
| 1182 const ICData& ic_data) { | |
| 1137 // 1. Check if was a getter call. | 1183 // 1. Check if was a getter call. |
| 1138 if (!Field::IsGetterName(target_name)) return Instance::null(); | 1184 if (!Field::IsGetterName(target_name)) return Instance::null(); |
| 1139 | 1185 |
| 1140 // 2. Check if there is an instance function with the same name. | 1186 // 2. Check if there is an instance function with the same name. |
| 1141 String& function_name = String::Handle(Field::NameFromGetter(target_name)); | 1187 String& function_name = String::Handle(Field::NameFromGetter(target_name)); |
| 1142 function_name = Symbols::New(function_name); | 1188 function_name = Symbols::New(function_name); |
| 1143 const Function& function = Function::Handle( | 1189 const Function& function = Function::Handle( |
| 1144 Resolver::ResolveDynamicAnyArgs(receiver_class, function_name)); | 1190 Resolver::ResolveDynamicAnyArgs(receiver_class, function_name)); |
| 1145 if (function.IsNull()) return Instance::null(); | 1191 if (function.IsNull()) return Instance::null(); |
| 1146 | 1192 |
| 1147 // Create a closure object for the implicit closure function. | 1193 // Create a closure object for the implicit closure function. |
| 1148 const Function& closure_function = | 1194 const Function& closure_function = |
| 1149 Function::Handle(function.ImplicitClosureFunction()); | 1195 Function::Handle(function.ImplicitClosureFunction()); |
| 1150 const Context& context = Context::Handle(Context::New(1)); | 1196 const Context& context = Context::Handle(Context::New(1)); |
| 1151 context.SetAt(0, receiver); | 1197 context.SetAt(0, receiver); |
| 1152 const Instance& closure = | 1198 const Instance& closure = |
| 1153 Instance::Handle(Closure::New(closure_function, context)); | 1199 Instance::Handle(Closure::New(closure_function, context)); |
| 1154 if (receiver_class.HasTypeArguments()) { | 1200 if (receiver_class.HasTypeArguments()) { |
| 1155 const AbstractTypeArguments& type_arguments = | 1201 const AbstractTypeArguments& type_arguments = |
| 1156 AbstractTypeArguments::Handle(receiver.GetTypeArguments()); | 1202 AbstractTypeArguments::Handle(receiver.GetTypeArguments()); |
| 1157 closure.SetTypeArguments(type_arguments); | 1203 closure.SetTypeArguments(type_arguments); |
| 1158 } | 1204 } |
| 1205 | |
| 1206 ASSERT(ic_data.num_args_tested() == 1); | |
| 1207 ic_data.AddReceiverCheck( | |
| 1208 receiver_class.id(), | |
| 1209 Function::Handle(GetMethodExtractor(closure_function))); | |
| 1159 return closure.raw(); | 1210 return closure.raw(); |
| 1160 } | 1211 } |
| 1161 | 1212 |
| 1162 | 1213 |
| 1163 // An instance call of the form o.f(...) could not be resolved. Check if | 1214 // An instance call of the form o.f(...) could not be resolved. Check if |
| 1164 // there is a getter with the same name. If so, invoke it. If the value is | 1215 // there is a getter with the same name. If so, invoke it. If the value is |
| 1165 // a closure, invoke it with the given arguments. If the value is a | 1216 // a closure, invoke it with the given arguments. If the value is a |
| 1166 // non-closure, attempt to invoke "call" on it. | 1217 // non-closure, attempt to invoke "call" on it. |
| 1167 static bool ResolveCallThroughGetter(const Instance& receiver, | 1218 static bool ResolveCallThroughGetter(const Instance& receiver, |
| 1168 const Class& receiver_class, | 1219 const Class& receiver_class, |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1226 | 1277 |
| 1227 Class& receiver_class = Class::Handle(receiver.clazz()); | 1278 Class& receiver_class = Class::Handle(receiver.clazz()); |
| 1228 // For lookups treat null as an instance of class Object. | 1279 // For lookups treat null as an instance of class Object. |
| 1229 if (receiver_class.IsNullClass()) { | 1280 if (receiver_class.IsNullClass()) { |
| 1230 receiver_class = isolate->object_store()->object_class(); | 1281 receiver_class = isolate->object_store()->object_class(); |
| 1231 } | 1282 } |
| 1232 const String& target_name = String::Handle(ic_data.target_name()); | 1283 const String& target_name = String::Handle(ic_data.target_name()); |
| 1233 | 1284 |
| 1234 Instance& closure = Instance::Handle(ResolveImplicitClosure(receiver, | 1285 Instance& closure = Instance::Handle(ResolveImplicitClosure(receiver, |
| 1235 receiver_class, | 1286 receiver_class, |
| 1236 target_name)); | 1287 target_name, |
| 1288 ic_data)); | |
| 1237 if (!closure.IsNull()) { | 1289 if (!closure.IsNull()) { |
| 1238 arguments.SetReturn(closure); | 1290 arguments.SetReturn(closure); |
| 1239 return; | 1291 return; |
| 1240 } | 1292 } |
| 1241 | 1293 |
| 1242 Object& result = Object::Handle(); | 1294 Object& result = Object::Handle(); |
| 1243 if (!ResolveCallThroughGetter(receiver, | 1295 if (!ResolveCallThroughGetter(receiver, |
| 1244 receiver_class, | 1296 receiver_class, |
| 1245 target_name, | 1297 target_name, |
| 1246 args_descriptor, | 1298 args_descriptor, |
| (...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1750 return; | 1802 return; |
| 1751 } | 1803 } |
| 1752 HeapTrace* heap_trace = Isolate::Current()->heap()->trace(); | 1804 HeapTrace* heap_trace = Isolate::Current()->heap()->trace(); |
| 1753 heap_trace->TraceStoreIntoObject(RawObject::ToAddr(object), | 1805 heap_trace->TraceStoreIntoObject(RawObject::ToAddr(object), |
| 1754 field_addr, | 1806 field_addr, |
| 1755 RawObject::ToAddr(value)); | 1807 RawObject::ToAddr(value)); |
| 1756 } | 1808 } |
| 1757 END_LEAF_RUNTIME_ENTRY | 1809 END_LEAF_RUNTIME_ENTRY |
| 1758 | 1810 |
| 1759 } // namespace dart | 1811 } // namespace dart |
| OLD | NEW |