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

Unified Diff: runtime/vm/flow_graph_builder.cc

Issue 11267027: More fixes for super[] (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: 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/flow_graph_builder.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/flow_graph_builder.cc
===================================================================
--- runtime/vm/flow_graph_builder.cc (revision 14156)
+++ runtime/vm/flow_graph_builder.cc (working copy)
@@ -2002,7 +2002,7 @@
if (node->is_super_getter()) {
// Statically resolved instance getter, i.e. "super getter".
getter_function =
- Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name);
+ Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name);
ASSERT(!getter_function.IsNull());
ASSERT(node->receiver() != NULL);
ValueGraphVisitor receiver_value(owner(), temp_index());
@@ -2265,6 +2265,26 @@
void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) {
+ Function* super_function = NULL;
+ if (node->IsSuperLoad()) {
+ // Resolve the load indexed operator in the super class.
+ const String& index_operator_name =
+ String::ZoneHandle(Symbols::IndexToken());
+ super_function = &Function::ZoneHandle(
+ Resolver::ResolveDynamicAnyArgs(node->super_class(),
+ index_operator_name));
+ if (super_function->IsNull()) {
+ // Could not resolve super operator. Generate call noSuchMethod() of the
+ // super class instead.
+ ArgumentListNode* arguments = new ArgumentListNode(node->token_pos());
+ arguments->Add(node->index_expr());
+ BuildStaticNoSuchMethodCall(node->super_class(),
+ node->array(),
+ index_operator_name,
+ arguments);
+ return;
+ }
+ }
ZoneGrowableArray<PushArgumentInstr*>* arguments =
new ZoneGrowableArray<PushArgumentInstr*>(2);
ValueGraphVisitor for_array(owner(), temp_index());
@@ -2277,22 +2297,67 @@
Append(for_index);
arguments->Add(PushArgument(for_index.value()));
- const intptr_t checked_argument_count = 1;
- const String& name =
- String::ZoneHandle(Symbols::New(Token::Str(Token::kINDEX)));
- InstanceCallInstr* load = new InstanceCallInstr(node->token_pos(),
- name,
- Token::kINDEX,
- arguments,
- Array::ZoneHandle(),
- checked_argument_count);
- ReturnDefinition(load);
+ if (super_function != NULL) {
+ // Generate static call to super operator.
+ StaticCallInstr* load = new StaticCallInstr(node->token_pos(),
+ *super_function,
+ Array::ZoneHandle(),
+ arguments);
+ ReturnDefinition(load);
+ } else {
+ // Generate dynamic call to index operator.
+ const intptr_t checked_argument_count = 1;
+ const String& name = String::ZoneHandle(Symbols::IndexToken());
+ InstanceCallInstr* load = new InstanceCallInstr(node->token_pos(),
+ name,
+ Token::kINDEX,
+ arguments,
+ Array::ZoneHandle(),
+ checked_argument_count);
+ ReturnDefinition(load);
+ }
}
Definition* EffectGraphVisitor::BuildStoreIndexedValues(
StoreIndexedNode* node,
bool result_is_needed) {
+ Function* super_function = NULL;
+ if (node->IsSuperStore()) {
+ // Resolve the store indexed operator in the super class.
+ const String& store_index_op_name =
+ String::ZoneHandle(Symbols::AssignIndexToken());
+ super_function = &Function::ZoneHandle(
+ Resolver::ResolveDynamicAnyArgs(node->super_class(),
+ store_index_op_name));
+ if (super_function->IsNull()) {
+ // Could not resolve super operator. Generate call noSuchMethod() of the
+ // super class instead.
+ if (result_is_needed) {
+ // Even though noSuchMethod most likely does not return,
+ // we save the stored value if the result is needed.
+ ValueGraphVisitor for_value(owner(), temp_index());
+ node->value()->Visit(&for_value);
+ Append(for_value);
+ Bind(BuildStoreExprTemp(for_value.value()));
+ }
+ ArgumentListNode* arguments = new ArgumentListNode(node->token_pos());
+ arguments->Add(node->index_expr());
+ arguments->Add(node->value());
+ StaticCallInstr* call =
+ BuildStaticNoSuchMethodCall(node->super_class(),
+ node->array(),
+ store_index_op_name,
+ arguments);
+ if (result_is_needed) {
+ Do(call);
+ return BuildLoadExprTemp();
+ } else {
+ return call;
+ }
+ }
+ }
+
ZoneGrowableArray<PushArgumentInstr*>* arguments =
new ZoneGrowableArray<PushArgumentInstr*>(3);
ValueGraphVisitor for_array(owner(), temp_index());
@@ -2316,20 +2381,38 @@
}
arguments->Add(PushArgument(value));
- const intptr_t checked_argument_count = 3;
- const String& name =
- String::ZoneHandle(Symbols::New(Token::Str(Token::kASSIGN_INDEX)));
- InstanceCallInstr* store = new InstanceCallInstr(node->token_pos(),
- name,
- Token::kASSIGN_INDEX,
- arguments,
- Array::ZoneHandle(),
- checked_argument_count);
- if (result_is_needed) {
- Do(store);
- return BuildLoadExprTemp();
+ if (super_function != NULL) {
+ // Generate static call to super operator []=.
+
+ StaticCallInstr* store =
+ new StaticCallInstr(node->token_pos(),
+ *super_function,
+ Array::ZoneHandle(),
+ arguments);
+ if (result_is_needed) {
+ Do(store);
+ return BuildLoadExprTemp();
+ } else {
+ return store;
+ }
} else {
- return store;
+ // Generate dynamic call to operator []=.
+ const intptr_t checked_argument_count = 3;
+ const String& name =
+ String::ZoneHandle(Symbols::New(Token::Str(Token::kASSIGN_INDEX)));
+ InstanceCallInstr* store =
+ new InstanceCallInstr(node->token_pos(),
+ name,
+ Token::kASSIGN_INDEX,
+ arguments,
+ Array::ZoneHandle(),
+ checked_argument_count);
+ if (result_is_needed) {
+ Do(store);
+ return BuildLoadExprTemp();
+ } else {
+ return store;
+ }
}
}
@@ -2583,6 +2666,45 @@
}
+// Looks up dynamic method noSuchMethod in target_class
+// (including its super class chain) and builds a static call to it.
+StaticCallInstr* EffectGraphVisitor::BuildStaticNoSuchMethodCall(
+ const Class& target_class,
+ 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());
+
+ 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.
+ arguments->Add(new LiteralNode(args_pos, method_name));
+ // The third 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 =
+ new ZoneGrowableArray<PushArgumentInstr*>(arguments->length());
+ BuildPushArguments(*arguments, args);
+ return new StaticCallInstr(args_pos,
+ no_such_method_func,
+ Array::ZoneHandle(),
+ args);
+}
+
+
void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) {
// TODO(kmillikin) non-local control flow is not handled correctly
// by the inliner.
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698