Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(207)

Unified Diff: runtime/vm/flow_graph_builder.cc

Issue 11231074: Change signature of noSuchMethod to take an InvocationMirror. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: One more test expectation Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/code_generator.cc ('k') | runtime/vm/parser.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/flow_graph_builder.cc
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index ac1b47f0d1d4df6430059f500ad59b534d64539d..568450335f21e6a4ba1fce68c7353cd30ccea2c5 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -2707,31 +2707,61 @@ StaticCallInstr* EffectGraphVisitor::BuildStaticNoSuchMethodCall(
AstNode* receiver,
const String& method_name,
ArgumentListNode* method_arguments) {
- const String& no_such_method_name =
- String::ZoneHandle(Symbols::NoSuchMethod());
- const Function& no_such_method_func = Function::ZoneHandle(
- Resolver::ResolveDynamicAnyArgs(target_class, no_such_method_name));
- // We are guaranteed to find noSuchMethod of class Object.
- ASSERT(!no_such_method_func.IsNull());
+ // Build the graph to allocate an InvocationMirror object by calling
+ // the static allocation method.
+ const String& mirror_name = String::Handle(Symbols::InvocationMirror());
+ const Library& corelib = Library::Handle(Library::CoreLibrary());
+ const Class& mirror_class = Class::Handle(
+ corelib.LookupClassAllowPrivate(mirror_name));
+ ASSERT(!mirror_class.IsNull());
+ const String& function_name = String::Handle(
+ Symbols::AllocateInvocationMirror());
+ const Function& allocation_function = Function::ZoneHandle(
+ Resolver::ResolveStaticByName(mirror_class,
+ function_name,
+ Resolver::kIsQualified));
+ ASSERT(!allocation_function.IsNull());
+
+ // Evaluate the receiver before the arguments. This will be used
+ // as an argument to the noSuchMethod call.
+ ValueGraphVisitor for_receiver(owner(), temp_index());
+ receiver->Visit(&for_receiver);
+ Append(for_receiver);
+ PushArgumentInstr* push_receiver = PushArgument(for_receiver.value());
+ // Allocate the arguments and pass them into the construction
+ // of the InvocationMirror.
const intptr_t args_pos = method_arguments->token_pos();
ArgumentListNode* arguments = new ArgumentListNode(args_pos);
- // The first argument is the receiver.
- arguments->Add(receiver);
- // The second argument is the original method name.
- // TODO(regis): This will change once mirrors are supported.
+ // The first argument is the original method name.
arguments->Add(new LiteralNode(args_pos, method_name));
- // The third argument is an array containing the original method arguments.
+ // The second argument is an array containing the original method arguments.
ArrayNode* args_array =
new ArrayNode(args_pos, Type::ZoneHandle(Type::ListInterface()));
for (intptr_t i = 0; i < method_arguments->length(); i++) {
args_array->AddElement(method_arguments->NodeAt(i));
}
arguments->Add(args_array);
-
- ZoneGrowableArray<PushArgumentInstr*>* args =
+ ZoneGrowableArray<PushArgumentInstr*>* allocation_args =
new ZoneGrowableArray<PushArgumentInstr*>(arguments->length());
- BuildPushArguments(*arguments, args);
+ BuildPushArguments(*arguments, allocation_args);
+ StaticCallInstr* allocation = new StaticCallInstr(args_pos,
+ allocation_function,
+ Array::ZoneHandle(),
+ allocation_args);
+ Value* invocation_mirror = Bind(allocation);
+ PushArgumentInstr* push_invocation_mirror = PushArgument(invocation_mirror);
+ // Lookup noSuchMethod and call it with the receiver and the InvocationMirror.
+ const String& no_such_method_name =
+ String::ZoneHandle(Symbols::NoSuchMethod());
+ const Function& no_such_method_func = Function::ZoneHandle(
+ Resolver::ResolveDynamicAnyArgs(target_class, no_such_method_name));
+ // We are guaranteed to find noSuchMethod of class Object.
+ ASSERT(!no_such_method_func.IsNull());
+ ZoneGrowableArray<PushArgumentInstr*>* args =
+ new ZoneGrowableArray<PushArgumentInstr*>(2);
+ args->Add(push_receiver);
+ args->Add(push_invocation_mirror);
return new StaticCallInstr(args_pos,
no_such_method_func,
Array::ZoneHandle(),
« no previous file with comments | « runtime/vm/code_generator.cc ('k') | runtime/vm/parser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698