Chromium Code Reviews| Index: runtime/vm/code_generator.cc |
| diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc |
| index 0dd758140a55a5fbf8bf0f3b22e95517a5076111..58da738d483ba5dea7464ba281e45fb27bd658f9 100644 |
| --- a/runtime/vm/code_generator.cc |
| +++ b/runtime/vm/code_generator.cc |
| @@ -1127,13 +1127,59 @@ DEFINE_RUNTIME_ENTRY(InvokeNonClosure, 3) { |
| } |
| +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.
|
| + const char* kFormat = "[MethodExtractor:%s]"; |
| + const char* function_name = |
| + String::Handle(closure_function.name()).ToCString(); |
| + intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name) + 1; |
| + char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| + OS::SNPrint(chars, len, kFormat, function_name); |
| + return chars; |
| +} |
| + |
| + |
| +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.
|
| + Function& extractor = Function::Handle(closure_function.method_extractor()); |
| + if (extractor.IsNull()) { |
| + const char* name = CreateMethodExtractorName(closure_function); |
| + |
| + const Class& owner = Class::Handle(closure_function.Owner()); |
| + extractor ^= Function::New(String::Handle(Symbols::New(name)), |
| + RawFunction::kMethodExtractor, |
| + false, // Not static. |
| + false, // Not const. |
| + false, // Not abstract. |
| + false, // Not external. |
| + owner, |
| + 0); // No token position. |
| + // Initialize function's signature. |
| + const intptr_t kNumParameters = 1; |
| + extractor.set_num_fixed_parameters(kNumParameters); |
| + extractor.SetNumOptionalParameters(0, 0); |
| + extractor.set_parameter_types(Array::Handle(Array::New(kNumParameters, |
| + Heap::kOld))); |
| + extractor.set_parameter_names(Array::Handle(Array::New(kNumParameters, |
| + Heap::kOld))); |
| + extractor.SetParameterTypeAt(0, Type::Handle(Type::DynamicType())); |
| + extractor.SetParameterNameAt(0, Symbols::This()); |
| + extractor.set_result_type(Type::Handle(Type::DynamicType())); |
| + |
| + extractor.set_extracted_method_closure(closure_function); |
| + |
| + Compiler::CompileFunction(extractor); |
| + } |
| + return extractor.raw(); |
| +} |
| + |
| + |
| // An instance call could not be resolved by an IC miss handler. Check if |
| // it was a getter call and if there is an instance function with the same |
| // name. If so, create and return an implicit closure from the function. |
| // Otherwise return null. |
| static RawInstance* ResolveImplicitClosure(const Instance& receiver, |
| const Class& receiver_class, |
| - const String& target_name) { |
| + const String& target_name, |
| + const ICData& ic_data) { |
| // 1. Check if was a getter call. |
| if (!Field::IsGetterName(target_name)) return Instance::null(); |
| @@ -1156,6 +1202,11 @@ static RawInstance* ResolveImplicitClosure(const Instance& receiver, |
| AbstractTypeArguments::Handle(receiver.GetTypeArguments()); |
| closure.SetTypeArguments(type_arguments); |
| } |
| + |
| + ASSERT(ic_data.num_args_tested() == 1); |
| + ic_data.AddReceiverCheck( |
| + receiver_class.id(), |
| + Function::Handle(GetMethodExtractor(closure_function))); |
| return closure.raw(); |
| } |
| @@ -1233,7 +1284,8 @@ DEFINE_RUNTIME_ENTRY(InstanceFunctionLookup, 4) { |
| Instance& closure = Instance::Handle(ResolveImplicitClosure(receiver, |
| receiver_class, |
| - target_name)); |
| + target_name, |
| + ic_data)); |
| if (!closure.IsNull()) { |
| arguments.SetReturn(closure); |
| return; |