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 |