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

Unified Diff: runtime/vm/flow_graph_builder.cc

Issue 9570015: Support instance getters and setters, indexed loads and stores. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 10 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
Index: runtime/vm/flow_graph_builder.cc
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index 4fe69647020c2baa94af0f83b25581f242d3d1b2..5c7ef5def99bbc76a36a3faf2e6732e281e838f9 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -129,6 +129,15 @@ void TestGraphVisitor::BranchOnValue(Value* value) {
}
+void ArgumentGraphVisitor::ReturnValue(Value* value) {
+ value_ = value;
+ if (value->IsConstant()) {
+ AddInstruction(new BindInstr(temp_index(), value));
+ value_ = new TempVal(AllocateTempIndex());
+ }
+}
+
+
void EffectGraphVisitor::Bailout(const char* reason) {
owner()->Bailout(reason);
}
@@ -222,18 +231,18 @@ void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) {
Bailout("EffectGraphVisitor::VisitBinaryOpNode AND/OR");
}
- ValueGraphVisitor for_left_value(owner(), temp_index());
+ ArgumentGraphVisitor for_left_value(owner(), temp_index());
node->left()->Visit(&for_left_value);
Append(for_left_value);
- CHECK_ALIVE(return);
- ValueGraphVisitor for_right_value(owner(), for_left_value.temp_index());
+ ArgumentGraphVisitor for_right_value(owner(), for_left_value.temp_index());
node->right()->Visit(&for_right_value);
Append(for_right_value);
- CHECK_ALIVE(return);
ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2);
arguments->Add(for_left_value.value());
arguments->Add(for_right_value.value());
- InstanceCallComp* call = new InstanceCallComp(node->Name(), arguments);
+ const String& name = String::ZoneHandle(String::NewSymbol(node->Name()));
+ InstanceCallComp* call =
+ new InstanceCallComp(node, name, arguments, Array::ZoneHandle(), 2);
ReturnComputation(call);
}
@@ -252,25 +261,33 @@ void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) {
} else if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) {
Bailout("'==' or '!=' comparison not yet implemented");
}
- ValueGraphVisitor for_left_value(owner(), temp_index());
- node->left()->Visit(&for_left_value);
- Append(for_left_value);
- CHECK_ALIVE(return);
- ValueGraphVisitor for_right_value(owner(), for_left_value.temp_index());
- node->right()->Visit(&for_right_value);
- Append(for_right_value);
- CHECK_ALIVE(return);
+
if ((node->kind() == Token::kEQ_STRICT) ||
(node->kind() == Token::kNE_STRICT)) {
+ ValueGraphVisitor for_left_value(owner(), temp_index());
+ node->left()->Visit(&for_left_value);
+ Append(for_left_value);
+ ValueGraphVisitor for_right_value(owner(), for_left_value.temp_index());
+ node->right()->Visit(&for_right_value);
+ Append(for_right_value);
StrictCompareComp* comp = new StrictCompareComp(
node->kind(), for_left_value.value(), for_right_value.value());
ReturnComputation(comp);
return;
}
+
+ ArgumentGraphVisitor for_left_value(owner(), temp_index());
+ node->left()->Visit(&for_left_value);
+ Append(for_left_value);
+ ArgumentGraphVisitor for_right_value(owner(), for_left_value.temp_index());
+ node->right()->Visit(&for_right_value);
+ Append(for_right_value);
ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2);
arguments->Add(for_left_value.value());
arguments->Add(for_right_value.value());
- InstanceCallComp* call = new InstanceCallComp(node->Name(), arguments);
+ const String& name = String::ZoneHandle(String::NewSymbol(node->Name()));
+ InstanceCallComp* call =
+ new InstanceCallComp(node, name, arguments, Array::ZoneHandle(), 2);
ReturnComputation(call);
}
@@ -280,12 +297,17 @@ void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) {
if (node->kind() == Token::kNOT) {
Bailout("EffectGraphVisitor::VisitUnaryOpNode NOT");
}
- ValueGraphVisitor for_value(owner(), temp_index());
+ ArgumentGraphVisitor for_value(owner(), temp_index());
node->operand()->Visit(&for_value);
Append(for_value);
- ZoneGrowableArray<Value*>* argument = new ZoneGrowableArray<Value*>(1);
- argument->Add(for_value.value());
- InstanceCallComp* call = new InstanceCallComp(node->Name(), argument);
+ ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1);
+ arguments->Add(for_value.value());
+ const String& name =
+ String::ZoneHandle(String::NewSymbol((node->kind() == Token::kSUB)
+ ? Token::Str(Token::kNEGATE)
+ : node->Name()));
+ InstanceCallComp* call =
+ new InstanceCallComp(node, name, arguments, Array::ZoneHandle(), 1);
ReturnComputation(call);
}
@@ -390,57 +412,44 @@ void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) {
}
+void EffectGraphVisitor::TranslateArgumentList(
+ const ArgumentListNode& node,
+ intptr_t next_temp_index,
+ ZoneGrowableArray<Value*>* values) {
+ for (intptr_t i = 0; i < node.length(); ++i) {
+ ArgumentGraphVisitor for_argument(owner(), next_temp_index);
+ node.NodeAt(i)->Visit(&for_argument);
+ Append(for_argument);
+ next_temp_index = for_argument.temp_index();
+ values->Add(for_argument.value());
+ }
+}
+
void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) {
ArgumentListNode* arguments = node->arguments();
int length = arguments->length();
ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(length + 1);
- ValueGraphVisitor for_receiver(owner(), temp_index());
+ ArgumentGraphVisitor for_receiver(owner(), temp_index());
node->receiver()->Visit(&for_receiver);
Append(for_receiver);
- CHECK_ALIVE(return);
- Value* receiver_value = for_receiver.value();
- temp_index_ = for_receiver.temp_index();
- if (receiver_value->IsConstant()) {
- AddInstruction(new BindInstr(temp_index(), receiver_value));
- receiver_value = new TempVal(AllocateTempIndex());
- }
- values->Add(receiver_value);
+ values->Add(for_receiver.value());
- TranslateArgumentList(*arguments, values);
- CHECK_ALIVE(return);
+ TranslateArgumentList(*arguments, for_receiver.temp_index(), values);
InstanceCallComp* call =
- new InstanceCallComp(node->function_name().ToCString(), values);
+ new InstanceCallComp(node, node->function_name(), values,
+ arguments->names(), 1);
ReturnComputation(call);
}
-void EffectGraphVisitor::TranslateArgumentList(
- const ArgumentListNode& node, ZoneGrowableArray<Value*>* values) {
- int index = temp_index();
- for (intptr_t i = 0; i < node.length(); ++i) {
- ValueGraphVisitor for_value(owner(), index);
- node.NodeAt(i)->Visit(&for_value);
- Append(for_value);
- CHECK_ALIVE(return);
- Value* argument_value = for_value.value();
- index = for_value.temp_index();
- if (argument_value->IsConstant()) {
- AddInstruction(new BindInstr(index, argument_value));
- argument_value = new TempVal(index++);
- }
- values->Add(argument_value);
- }
-}
-
// <Expression> ::= StaticCall { function: Function
// arguments: <ArgumentList> }
void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) {
int length = node->arguments()->length();
ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(length);
- TranslateArgumentList(*node->arguments(), values);
- CHECK_ALIVE(return);
- StaticCallComp* call = new StaticCallComp(node->function(), values);
+ TranslateArgumentList(*node->arguments(), temp_index(), values);
+ StaticCallComp* call = new StaticCallComp(node, values);
ReturnComputation(call);
}
@@ -461,12 +470,35 @@ void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) {
- Bailout("EffectGraphVisitor::VisitInstanceGetterNode");
+ ArgumentGraphVisitor for_receiver(owner(), temp_index());
+ node->receiver()->Visit(&for_receiver);
+ Append(for_receiver);
+ ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1);
+ arguments->Add(for_receiver.value());
+ const String& name =
+ String::ZoneHandle(Field::GetterSymbol(node->field_name()));
+ InstanceCallComp* call =
+ new InstanceCallComp(node, name, arguments, Array::ZoneHandle(), 1);
+ ReturnComputation(call);
}
void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
- Bailout("EffectGraphVisitor::VisitInstanceSetterNode");
+ // We preallocate a temporary to overlap with the value of the assignment.
+ const Smi& zero = Smi::ZoneHandle(Smi::New(0));
+ AddInstruction(new BindInstr(temp_index(), new ConstantVal(zero)));
+ TempVal* placeholder = new TempVal(temp_index());
+ ArgumentGraphVisitor for_receiver(owner(), temp_index() + 1);
+ node->receiver()->Visit(&for_receiver);
+ Append(for_receiver);
+ ArgumentGraphVisitor for_value(owner(), for_receiver.temp_index());
+ node->value()->Visit(&for_value);
+ Append(for_value);
+ InstanceSetterComp* setter = new InstanceSetterComp(node,
+ placeholder,
+ for_receiver.value(),
+ for_value.value());
+ ReturnComputation(setter);
}
@@ -512,8 +544,16 @@ void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) {
ValueGraphVisitor for_value(owner(), temp_index());
node->value()->Visit(&for_value);
Append(for_value);
- CHECK_ALIVE(return);
- StoreLocalComp* store = new StoreLocalComp(node->local(), for_value.value());
+
+ Value* value = for_value.value();
+ if (FLAG_enable_type_checks) {
+ AssertAssignableComp* assert =
+ new AssertAssignableComp(value, node->local().type());
+ AddInstruction(new BindInstr(temp_index(), assert));
+ value = new TempVal(temp_index());
+ }
+
+ StoreLocalComp* store = new StoreLocalComp(node->local(), value);
ReturnComputation(store);
}
@@ -541,12 +581,49 @@ void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) {
void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) {
- Bailout("EffectGraphVisitor::VisitLoadIndexedNode");
+ ArgumentGraphVisitor for_array(owner(), temp_index());
+ node->array()->Visit(&for_array);
+ Append(for_array);
+ ArgumentGraphVisitor for_index(owner(), for_array.temp_index());
+ node->index_expr()->Visit(&for_index);
+ Append(for_index);
+ ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2);
+ arguments->Add(for_array.value());
+ arguments->Add(for_index.value());
+ const String& name =
+ String::ZoneHandle(String::NewSymbol(Token::Str(Token::kINDEX)));
+ InstanceCallComp* call =
+ new InstanceCallComp(node, name, arguments, Array::ZoneHandle(), 1);
+ ReturnComputation(call);
}
void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) {
- Bailout("EffectGraphVisitor::VisitStoreIndexedNode");
+ // This is not a straight instance call to e0.[]=(e1, e2), it is a
+ // call to
+ //
+ // (a, i, v) { a.[]=(i, v); return v; }(e0, e1, e2)
+ //
+ // Without constructing that function, we simulate it at the IL
+ // level by preallocating a slot for the return value.
+ const Smi& zero = Smi::ZoneHandle(Smi::New(0));
+ AddInstruction(new BindInstr(temp_index(), new ConstantVal(zero)));
+ TempVal* placeholder = new TempVal(temp_index());
+ ArgumentGraphVisitor for_array(owner(), temp_index() + 1);
+ node->array()->Visit(&for_array);
+ Append(for_array);
+ ArgumentGraphVisitor for_index(owner(), for_array.temp_index());
+ node->index_expr()->Visit(&for_index);
+ Append(for_index);
+ ArgumentGraphVisitor for_value(owner(), for_index.temp_index());
+ node->value()->Visit(&for_value);
+ Append(for_value);
+ StoreIndexedComp* store = new StoreIndexedComp(node,
+ placeholder,
+ for_array.value(),
+ for_index.value(),
+ for_value.value());
+ ReturnComputation(store);
}
@@ -660,7 +737,7 @@ void FlowGraphPrinter::VisitAssertAssignable(AssertAssignableComp* comp) {
void FlowGraphPrinter::VisitInstanceCall(InstanceCallComp* comp) {
- OS::Print("InstanceCall(%s", comp->name());
+ OS::Print("InstanceCall(%s", comp->function_name().ToCString());
for (int i = 0; i < comp->ArgumentCount(); ++i) {
OS::Print(", ");
comp->ArgumentAt(i)->Accept(this);
@@ -702,6 +779,30 @@ void FlowGraphPrinter::VisitStoreLocal(StoreLocalComp* comp) {
}
+void FlowGraphPrinter::VisitStoreIndexed(StoreIndexedComp* comp) {
+ OS::Print("StoreIndexed(");
+ comp->placeholder()->Accept(this);
+ OS::Print(", ");
+ comp->array()->Accept(this);
+ OS::Print(", ");
+ comp->index()->Accept(this);
+ OS::Print(", ");
+ comp->value()->Accept(this);
+ OS::Print(")");
+}
+
+
+void FlowGraphPrinter::VisitInstanceSetter(InstanceSetterComp* comp) {
+ OS::Print("InstanceSetter(");
+ comp->placeholder()->Accept(this);
+ OS::Print(", ");
+ comp->receiver()->Accept(this);
+ OS::Print(", ");
+ comp->value()->Accept(this);
+ OS::Print(")");
+}
+
+
void FlowGraphPrinter::VisitJoinEntry(JoinEntryInstr* instr) {
OS::Print("%2d: [join]", instr->block_number());
}

Powered by Google App Engine
This is Rietveld 408576698