Index: runtime/vm/parser.cc |
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc |
index 2958e4798f00198a7041db0f02d686c0963e5ca0..4a89597fb515c3a2e7a86d31348f8670d5ed5464 100644 |
--- a/runtime/vm/parser.cc |
+++ b/runtime/vm/parser.cc |
@@ -782,6 +782,12 @@ void Parser::ParseFunction(ParsedFunction* parsed_function) { |
} |
node_sequence = parser.ParseFunc(func, default_parameter_values); |
break; |
+ case RawFunction::kGetFieldClosure: |
+ node_sequence = parser.ParseGetFieldClosure(func); |
+ break; |
+ case RawFunction::kSetFieldClosure: |
+ node_sequence = parser.ParseSetFieldClosure(func); |
+ break; |
case RawFunction::kImplicitGetter: |
ASSERT(!func.is_static()); |
node_sequence = parser.ParseInstanceGetter(func); |
@@ -1230,6 +1236,72 @@ SequenceNode* Parser::ParseInstanceSetter(const Function& func) { |
} |
+SequenceNode* Parser::ParseGetFieldClosure(const Function& func) { |
+ TRACE_PARSER("ParseGetFieldClosure"); |
+ ParamList params; |
+ |
+ const intptr_t ident_pos = func.token_pos(); |
+ ASSERT(func.token_pos() == 0); |
+ ASSERT(current_class().raw() == func.Owner()); |
+ params.AddReceiver(ReceiverType(current_class()), ident_pos); |
+ params.AddFinalParameter(0, // token pos |
+ &Symbols::PhaseParameter(), |
+ &Type::ZoneHandle(Type::DynamicType())); |
+ ASSERT(func.num_fixed_parameters() == 2); |
+ ASSERT(!func.HasOptionalParameters()); |
+ |
+ OpenFunctionBlock(func); |
+ AddFormalParamsToScope(¶ms, current_block_->scope); |
+ |
+ LoadLocalNode* victim = |
+ new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(1)); |
+ |
+ const String& selector = String::ZoneHandle(func.name()); |
+ AstNode* get_field = CallGetter(ident_pos, victim, selector); |
+ |
+ ReturnNode* return_node = new ReturnNode(ident_pos, get_field); |
+ current_block_->statements->Add(return_node); |
+ return CloseBlock(); |
+} |
+ |
+ |
+SequenceNode* Parser::ParseSetFieldClosure(const Function& func) { |
+ TRACE_PARSER("ParseSetFieldClosure"); |
+ ParamList params; |
+ |
+ const intptr_t ident_pos = func.token_pos(); |
+ ASSERT(func.token_pos() == 0); |
+ ASSERT(current_class().raw() == func.Owner()); |
+ params.AddReceiver(ReceiverType(current_class()), ident_pos); |
+ params.AddFinalParameter(0, // token pos |
+ &Symbols::PhaseParameter(), |
+ &Type::ZoneHandle(Type::DynamicType())); |
+ params.AddFinalParameter(0, // token pos |
+ &Symbols::Value(), |
+ &Type::ZoneHandle(Type::DynamicType())); |
+ ASSERT(func.num_fixed_parameters() == 3); |
+ ASSERT(!func.HasOptionalParameters()); |
+ |
+ OpenFunctionBlock(func); |
+ AddFormalParamsToScope(¶ms, current_block_->scope); |
+ |
+ LoadLocalNode* victim = |
+ new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(1)); |
+ LoadLocalNode* value = |
+ new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(2)); |
+ |
+ const String& selector = String::ZoneHandle(func.name()); |
+ AstNode* get_field = CallGetter(ident_pos, victim, selector); |
+ AstNode* set_field = |
+ Parser::CreateAssignmentNode(get_field, value, &selector, ident_pos); |
+ ASSERT(set_field->IsInstanceSetterNode()); |
+ |
+ ReturnNode* return_node = new ReturnNode(ident_pos, set_field); |
+ current_block_->statements->Add(return_node); |
+ return CloseBlock(); |
+} |
+ |
+ |
SequenceNode* Parser::ParseMethodExtractor(const Function& func) { |
TRACE_PARSER("ParseMethodExtractor"); |
ParamList params; |