| Index: runtime/vm/code_generator.cc
|
| ===================================================================
|
| --- runtime/vm/code_generator.cc (revision 24510)
|
| +++ runtime/vm/code_generator.cc (working copy)
|
| @@ -1158,9 +1158,7 @@
|
| getter_name,
|
| kNumArguments,
|
| kNumNamedArguments));
|
| - if (getter.IsNull() ||
|
| - getter.IsMethodExtractor() ||
|
| - getter.IsNoSuchMethodDispatcher()) {
|
| + if (getter.IsNull() || getter.IsMethodExtractor()) {
|
| return false;
|
| }
|
|
|
| @@ -1182,41 +1180,6 @@
|
| }
|
|
|
|
|
| -// Create a method for noSuchMethod invocation and attach it to the receiver
|
| -// class.
|
| -static RawFunction* CreateNoSuchMethodDispatcher(
|
| - const String& target_name,
|
| - const Class& receiver_class,
|
| - const Array& arguments_descriptor) {
|
| - Function& invocation = Function::Handle(
|
| - Function::New(String::Handle(Symbols::New(target_name)),
|
| - RawFunction::kNoSuchMethodDispatcher,
|
| - false, // Not static.
|
| - false, // Not const.
|
| - false, // Not abstract.
|
| - false, // Not external.
|
| - receiver_class,
|
| - 0)); // No token position.
|
| -
|
| - // Initialize signature: receiver is a single fixed parameter.
|
| - const intptr_t kNumParameters = 1;
|
| - invocation.set_num_fixed_parameters(kNumParameters);
|
| - invocation.SetNumOptionalParameters(0, 0);
|
| - invocation.set_parameter_types(Array::Handle(Array::New(kNumParameters,
|
| - Heap::kOld)));
|
| - invocation.set_parameter_names(Array::Handle(Array::New(kNumParameters,
|
| - Heap::kOld)));
|
| - invocation.SetParameterTypeAt(0, Type::Handle(Type::DynamicType()));
|
| - invocation.SetParameterNameAt(0, Symbols::This());
|
| - invocation.set_result_type(Type::Handle(Type::DynamicType()));
|
| - invocation.set_is_visible(false); // Not visible in stack trace.
|
| -
|
| - receiver_class.AddFunction(invocation);
|
| -
|
| - return invocation.raw();
|
| -}
|
| -
|
| -
|
| // The IC miss handler has failed to find a (cacheable) instance function to
|
| // invoke. Handle three possibilities:
|
| //
|
| @@ -1252,35 +1215,29 @@
|
| args,
|
| &result)) {
|
| ArgumentsDescriptor desc(args_descriptor);
|
| - Function& target_function = Function::Handle(
|
| - Resolver::ResolveDynamicAnyArgs(receiver_class, target_name));
|
| - // Check number of arguments and check that there is not already a method
|
| - // with the same name present.
|
| - // TODO(fschneider): Handle multiple arguments.
|
| - if (target_function.IsNull() &&
|
| - (desc.Count() == 1) && (desc.PositionalCount() == 1)) {
|
| - // Create Function for noSuchMethodInvocation and add it to the class.
|
| - target_function ^= CreateNoSuchMethodDispatcher(target_name,
|
| - receiver_class,
|
| - args_descriptor);
|
| -
|
| - // Update IC data.
|
| - ASSERT(!target_function.IsNull());
|
| + const Function& target_function = Function::Handle(
|
| + receiver_class.GetNoSuchMethodDispatcher(target_name, args_descriptor));
|
| + // Update IC data.
|
| + ASSERT(!target_function.IsNull());
|
| + if (ic_data.num_args_tested() == 1) {
|
| ic_data.AddReceiverCheck(receiver.GetClassId(), target_function);
|
| - if (FLAG_trace_ic) {
|
| - OS::PrintErr("NoSuchMethod IC miss: adding <%s> id:%"Pd" -> <%s>\n",
|
| - Class::Handle(receiver.clazz()).ToCString(),
|
| - receiver.GetClassId(),
|
| - target_function.ToCString());
|
| - }
|
| - result =
|
| - DartEntry::InvokeFunction(target_function, args, args_descriptor);
|
| } else {
|
| - result = DartEntry::InvokeNoSuchMethod(receiver,
|
| - target_name,
|
| - args,
|
| - args_descriptor);
|
| + // Operators calls have two or three arguments tested ([], []=, etc.)
|
| + ASSERT(ic_data.num_args_tested() > 1);
|
| + GrowableArray<intptr_t> class_ids(ic_data.num_args_tested());
|
| + class_ids.Add(receiver.GetClassId());
|
| + for (intptr_t i = 1; i < ic_data.num_args_tested(); ++i) {
|
| + class_ids.Add(Object::Handle(args.At(i)).GetClassId());
|
| + }
|
| + ic_data.AddCheck(class_ids, target_function);
|
| }
|
| + if (FLAG_trace_ic) {
|
| + OS::PrintErr("NoSuchMethod IC miss: adding <%s> id:%"Pd" -> <%s>\n",
|
| + Class::Handle(receiver.clazz()).ToCString(),
|
| + receiver.GetClassId(),
|
| + target_function.ToCString());
|
| + }
|
| + result = DartEntry::InvokeFunction(target_function, args, args_descriptor);
|
| }
|
| CheckResultError(result);
|
| arguments.SetReturn(result);
|
|
|