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

Side by Side Diff: runtime/vm/kernel_binary_flowgraph.cc

Issue 3000333002: Fix several bugs in closure conversion. (Closed)
Patch Set: Comments. Created 3 years, 3 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 unified diff | Download patch
« no previous file with comments | « runtime/vm/kernel_binary_flowgraph.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/kernel_binary_flowgraph.h" 5 #include "vm/kernel_binary_flowgraph.h"
6 #include "vm/compiler.h" 6 #include "vm/compiler.h"
7 #include "vm/longjump.h" 7 #include "vm/longjump.h"
8 #include "vm/object_store.h" 8 #include "vm/object_store.h"
9 9
10 #if !defined(DART_PRECOMPILED_RUNTIME) 10 #if !defined(DART_PRECOMPILED_RUNTIME)
(...skipping 1179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1190 case kLabeledStatement: 1190 case kLabeledStatement:
1191 VisitStatement(); // read body. 1191 VisitStatement(); // read body.
1192 return; 1192 return;
1193 case kBreakStatement: 1193 case kBreakStatement:
1194 builder_->ReadPosition(); // read position. 1194 builder_->ReadPosition(); // read position.
1195 builder_->ReadUInt(); // read target_index. 1195 builder_->ReadUInt(); // read target_index.
1196 return; 1196 return;
1197 case kWhileStatement: 1197 case kWhileStatement:
1198 ++depth_.loop_; 1198 ++depth_.loop_;
1199 builder_->ReadPosition(); // read position. 1199 builder_->ReadPosition(); // read position.
1200 VisitExpression(); // read condition. 1200 VisitExpression(); // read condition.
1201 VisitStatement(); // read body. 1201 VisitStatement(); // read body.
1202 --depth_.loop_; 1202 --depth_.loop_;
1203 return; 1203 return;
1204 case kDoStatement: 1204 case kDoStatement:
1205 ++depth_.loop_; 1205 ++depth_.loop_;
1206 builder_->ReadPosition(); // read position. 1206 builder_->ReadPosition(); // read position.
1207 VisitStatement(); // read body. 1207 VisitStatement(); // read body.
1208 VisitExpression(); // read condition. 1208 VisitExpression(); // read condition.
1209 --depth_.loop_; 1209 --depth_.loop_;
1210 return; 1210 return;
1211 case kForStatement: { 1211 case kForStatement: {
1212 PositionScope scope(builder_->reader_); 1212 PositionScope scope(builder_->reader_);
1213 1213
1214 intptr_t offset = 1214 intptr_t offset =
1215 builder_->ReaderOffset() - 1; // -1 to include tag byte. 1215 builder_->ReaderOffset() - 1; // -1 to include tag byte.
1216 1216
1217 EnterScope(relative_kernel_offset_ + offset); 1217 EnterScope(relative_kernel_offset_ + offset);
1218 1218
(...skipping 2198 matching lines...) Expand 10 before | Expand all | Expand 10 after
3417 argument_names); 3417 argument_names);
3418 3418
3419 // Return the result. 3419 // Return the result.
3420 body += Return(function_node_helper.end_position_); 3420 body += Return(function_node_helper.end_position_);
3421 3421
3422 return new (Z) 3422 return new (Z)
3423 FlowGraph(*parsed_function(), flow_graph_builder_->graph_entry_, 3423 FlowGraph(*parsed_function(), flow_graph_builder_->graph_entry_,
3424 flow_graph_builder_->next_block_id_ - 1); 3424 flow_graph_builder_->next_block_id_ - 1);
3425 } 3425 }
3426 3426
3427 LocalVariable* StreamingFlowGraphBuilder::LookupParameterDirect(
3428 intptr_t kernel_offset,
3429 intptr_t parameter_index) {
3430 LocalVariable* var = LookupVariable(kernel_offset);
3431 LocalVariable* parameter =
3432 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
3433 Symbols::TempParam(), var->type());
3434 parameter->set_index(parameter_index);
3435 if (var->is_captured()) parameter->set_is_captured_parameter(true);
3436 return parameter;
3437 }
3427 // This method follows the logic of 3438 // This method follows the logic of
3428 // StreamingFlowGraphBuilder::BuildGraphOfImplicitClosureFunction. For 3439 // StreamingFlowGraphBuilder::BuildGraphOfImplicitClosureFunction. For
3429 // additional details on converted closure functions, please, see the comment on 3440 // additional details on converted closure functions, please, see the comment on
3430 // the method Function::ConvertedClosureFunction. 3441 // the method Function::ConvertedClosureFunction.
3431 FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfConvertedClosureFunction( 3442 FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfConvertedClosureFunction(
3432 const Function& function) { 3443 const Function& function) {
3433 const Function& target = Function::ZoneHandle(Z, function.parent_function()); 3444 const Function& target = Function::ZoneHandle(Z, function.parent_function());
3434 3445
3435 TargetEntryInstr* normal_entry = flow_graph_builder_->BuildTargetEntry(); 3446 TargetEntryInstr* normal_entry = flow_graph_builder_->BuildTargetEntry();
3436 flow_graph_builder_->graph_entry_ = new (Z) GraphEntryInstr( 3447 flow_graph_builder_->graph_entry_ = new (Z) GraphEntryInstr(
(...skipping 20 matching lines...) Expand all
3457 function_node_helper.ReadUntilExcluding( 3468 function_node_helper.ReadUntilExcluding(
3458 FunctionNodeHelper::kPositionalParameters); 3469 FunctionNodeHelper::kPositionalParameters);
3459 3470
3460 // Positional. 3471 // Positional.
3461 const intptr_t positional_argument_count = ReadListLength(); 3472 const intptr_t positional_argument_count = ReadListLength();
3462 3473
3463 // The first argument is the instance of the closure class. For converted 3474 // The first argument is the instance of the closure class. For converted
3464 // closures its context field contains the context vector that is used by the 3475 // closures its context field contains the context vector that is used by the
3465 // converted top-level function (target) explicitly and that should be passed 3476 // converted top-level function (target) explicitly and that should be passed
3466 // to that function as the first parameter. 3477 // to that function as the first parameter.
3467 body += LoadLocal(LookupVariable( 3478 intptr_t parameter_index = parsed_function()->first_parameter_index();
3468 ReaderOffset() + relative_kernel_offset_)); // 0th variable offset. 3479 LocalVariable* parameter = LookupParameterDirect(
3480 ReaderOffset() + relative_kernel_offset_, parameter_index--);
3481 body += LoadLocal(parameter); // 0th variable offset.
3469 body += flow_graph_builder_->LoadField(Closure::context_offset()); 3482 body += flow_graph_builder_->LoadField(Closure::context_offset());
3470 LocalVariable* context = MakeTemporary(); 3483 LocalVariable* context = MakeTemporary();
3471 3484
3472 if (type_param_count > 0) { 3485 if (type_param_count > 0) {
3473 body += LoadLocal(context); 3486 body += LoadLocal(context);
3474 body += flow_graph_builder_->LoadField(Context::variable_offset(0)); 3487 body += flow_graph_builder_->LoadField(Context::variable_offset(0));
3475 body += PushArgument(); 3488 body += PushArgument();
3476 } 3489 }
3477 3490
3478 body += LoadLocal(context); 3491 body += LoadLocal(context);
3479 body += PushArgument(); 3492 body += PushArgument();
3480 SkipVariableDeclaration(); // read 0th variable. 3493 SkipVariableDeclaration(); // read 0th variable.
3481 3494
3482 // The rest of the parameters are the same for the method of the Closure class 3495 // The rest of the parameters are the same for the method of the Closure class
3483 // being invoked and the top-level function (target). 3496 // being invoked and the top-level function (target).
3484 for (intptr_t i = 1; i < positional_argument_count; i++) { 3497 for (intptr_t i = 1; i < positional_argument_count; i++) {
3485 body += LoadLocal(LookupVariable( 3498 LocalVariable* parameter = LookupParameterDirect(
3486 ReaderOffset() + relative_kernel_offset_)); // ith variable offset. 3499 ReaderOffset() + relative_kernel_offset_, parameter_index--);
3500 body += LoadLocal(parameter); // ith variable offset.
3487 body += PushArgument(); 3501 body += PushArgument();
3488 SkipVariableDeclaration(); // read ith variable. 3502 SkipVariableDeclaration(); // read ith variable.
3489 } 3503 }
3490 3504
3491 // Named. 3505 // Named.
3492 const intptr_t named_argument_count = ReadListLength(); 3506 const intptr_t named_argument_count = ReadListLength();
3493 Array& argument_names = Array::ZoneHandle(Z); 3507 Array& argument_names = Array::ZoneHandle(Z);
3494 if (named_argument_count > 0) { 3508 if (named_argument_count > 0) {
3495 argument_names = Array::New(named_argument_count); 3509 argument_names = Array::New(named_argument_count);
3496 for (intptr_t i = 0; i < named_argument_count; i++) { 3510 for (intptr_t i = 0; i < named_argument_count; i++) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
3538 intptr_t context_size = 3552 intptr_t context_size =
3539 parsed_function()->node_sequence()->scope()->num_context_variables(); 3553 parsed_function()->node_sequence()->scope()->num_context_variables();
3540 if (context_size > 0) { 3554 if (context_size > 0) {
3541 body += flow_graph_builder_->PushContext(context_size); 3555 body += flow_graph_builder_->PushContext(context_size);
3542 LocalVariable* context = MakeTemporary(); 3556 LocalVariable* context = MakeTemporary();
3543 3557
3544 // Copy captured parameters from the stack into the context. 3558 // Copy captured parameters from the stack into the context.
3545 LocalScope* scope = parsed_function()->node_sequence()->scope(); 3559 LocalScope* scope = parsed_function()->node_sequence()->scope();
3546 intptr_t parameter_count = dart_function.NumParameters(); 3560 intptr_t parameter_count = dart_function.NumParameters();
3547 intptr_t parameter_index = parsed_function()->first_parameter_index(); 3561 intptr_t parameter_index = parsed_function()->first_parameter_index();
3562
3548 for (intptr_t i = 0; i < parameter_count; ++i, --parameter_index) { 3563 for (intptr_t i = 0; i < parameter_count; ++i, --parameter_index) {
3549 LocalVariable* variable = scope->VariableAt(i); 3564 LocalVariable* variable = scope->VariableAt(i);
3550 if (variable->is_captured()) { 3565 if (variable->is_captured()) {
3551 // There is no LocalVariable describing the on-stack parameter so 3566 // There is no LocalVariable describing the on-stack parameter so
3552 // create one directly and use the same type. 3567 // create one directly and use the same type.
3553 LocalVariable* parameter = new (Z) 3568 LocalVariable* parameter = new (Z)
3554 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, 3569 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
3555 Symbols::TempParam(), variable->type()); 3570 Symbols::TempParam(), variable->type());
3556 parameter->set_index(parameter_index); 3571 parameter->set_index(parameter_index);
3557 // Mark the stack variable so it will be ignored by the code for 3572 // Mark the stack variable so it will be ignored by the code for
(...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after
4303 ReadUInt(); // read kernel position. 4318 ReadUInt(); // read kernel position.
4304 ReadUInt(); // read relative variable index. 4319 ReadUInt(); // read relative variable index.
4305 SkipExpression(); // read expression. 4320 SkipExpression(); // read expression.
4306 return; 4321 return;
4307 case kSpecializedVariableSet: 4322 case kSpecializedVariableSet:
4308 ReadPosition(); // read position. 4323 ReadPosition(); // read position.
4309 ReadUInt(); // read kernel position. 4324 ReadUInt(); // read kernel position.
4310 SkipExpression(); // read expression. 4325 SkipExpression(); // read expression.
4311 return; 4326 return;
4312 case kPropertyGet: 4327 case kPropertyGet:
4313 ReadPosition(); // read position. 4328 ReadPosition(); // read position.
4314 SkipExpression(); // read receiver. 4329 SkipExpression(); // read receiver.
4315 SkipName(); // read name. 4330 SkipName(); // read name.
4316 SkipCanonicalNameReference(); // read interface_target_reference. 4331 SkipCanonicalNameReference(); // read interface_target_reference.
4317 return; 4332 return;
4318 case kPropertySet: 4333 case kPropertySet:
4319 ReadPosition(); // read position. 4334 ReadPosition(); // read position.
4320 SkipExpression(); // read receiver. 4335 SkipExpression(); // read receiver.
4321 SkipName(); // read name. 4336 SkipName(); // read name.
4322 SkipExpression(); // read value. 4337 SkipExpression(); // read value.
4323 SkipCanonicalNameReference(); // read interface_target_reference. 4338 SkipCanonicalNameReference(); // read interface_target_reference.
4324 return; 4339 return;
4325 case kDirectPropertyGet: 4340 case kDirectPropertyGet:
4326 ReadPosition(); // read position. 4341 ReadPosition(); // read position.
4327 SkipExpression(); // read receiver. 4342 SkipExpression(); // read receiver.
4328 SkipCanonicalNameReference(); // read target_reference. 4343 SkipCanonicalNameReference(); // read target_reference.
4329 return; 4344 return;
4330 case kDirectPropertySet: 4345 case kDirectPropertySet:
4331 ReadPosition(); // read position. 4346 ReadPosition(); // read position.
4332 SkipExpression(); // read receiver. 4347 SkipExpression(); // read receiver.
4333 SkipCanonicalNameReference(); // read target_reference. 4348 SkipCanonicalNameReference(); // read target_reference.
4334 SkipExpression(); // read value· 4349 SkipExpression(); // read value·
4335 return; 4350 return;
4336 case kStaticGet: 4351 case kStaticGet:
4337 ReadPosition(); // read position. 4352 ReadPosition(); // read position.
4338 SkipCanonicalNameReference(); // read target_reference. 4353 SkipCanonicalNameReference(); // read target_reference.
4339 return; 4354 return;
4340 case kStaticSet: 4355 case kStaticSet:
4341 ReadPosition(); // read position. 4356 ReadPosition(); // read position.
4342 SkipCanonicalNameReference(); // read target_reference. 4357 SkipCanonicalNameReference(); // read target_reference.
4343 SkipExpression(); // read expression. 4358 SkipExpression(); // read expression.
4344 return; 4359 return;
4345 case kMethodInvocation: 4360 case kMethodInvocation:
4346 ReadPosition(); // read position. 4361 ReadPosition(); // read position.
4347 SkipExpression(); // read receiver. 4362 SkipExpression(); // read receiver.
4348 SkipName(); // read name. 4363 SkipName(); // read name.
4349 SkipArguments(); // read arguments. 4364 SkipArguments(); // read arguments.
4350 SkipCanonicalNameReference(); // read interface_target_reference. 4365 SkipCanonicalNameReference(); // read interface_target_reference.
4351 return; 4366 return;
4352 case kDirectMethodInvocation: 4367 case kDirectMethodInvocation:
4353 SkipExpression(); // read receiver. 4368 SkipExpression(); // read receiver.
4354 SkipCanonicalNameReference(); // read target_reference. 4369 SkipCanonicalNameReference(); // read target_reference.
4355 SkipArguments(); // read arguments. 4370 SkipArguments(); // read arguments.
4356 return; 4371 return;
4357 case kStaticInvocation: 4372 case kStaticInvocation:
4358 case kConstStaticInvocation: 4373 case kConstStaticInvocation:
4359 ReadPosition(); // read position. 4374 ReadPosition(); // read position.
(...skipping 813 matching lines...) Expand 10 before | Expand all | Expand 10 after
5173 *negate = PeekTag() == kNot; 5188 *negate = PeekTag() == kNot;
5174 if (*negate) { 5189 if (*negate) {
5175 SkipBytes(1); // Skip Not tag, thus go directly to the inner expression. 5190 SkipBytes(1); // Skip Not tag, thus go directly to the inner expression.
5176 } 5191 }
5177 Fragment instructions = BuildExpression(); // read expression. 5192 Fragment instructions = BuildExpression(); // read expression.
5178 instructions += CheckBooleanInCheckedMode(); 5193 instructions += CheckBooleanInCheckedMode();
5179 return instructions; 5194 return instructions;
5180 } 5195 }
5181 5196
5182 const TypeArguments& StreamingFlowGraphBuilder::BuildTypeArguments() { 5197 const TypeArguments& StreamingFlowGraphBuilder::BuildTypeArguments() {
5183 ReadUInt(); // read arguments count. 5198 ReadUInt(); // read arguments count.
5184 intptr_t type_count = ReadListLength(); // read type count. 5199 intptr_t type_count = ReadListLength(); // read type count.
5185 return T.BuildTypeArguments(type_count); // read types. 5200 return T.BuildTypeArguments(type_count); // read types.
5186 } 5201 }
5187 5202
5188 Fragment StreamingFlowGraphBuilder::BuildArguments(Array* argument_names, 5203 Fragment StreamingFlowGraphBuilder::BuildArguments(Array* argument_names,
5189 intptr_t* argument_count, 5204 intptr_t* argument_count,
5190 bool skip_push_arguments, 5205 bool skip_push_arguments,
5191 bool do_drop) { 5206 bool do_drop) {
5192 intptr_t dummy; 5207 intptr_t dummy;
5193 if (argument_count == NULL) argument_count = &dummy; 5208 if (argument_count == NULL) argument_count = &dummy;
5194 *argument_count = ReadUInt(); // read arguments count. 5209 *argument_count = ReadUInt(); // read arguments count.
5195 5210
(...skipping 18 matching lines...) Expand all
5214 if (do_drop) instructions += Drop(); 5229 if (do_drop) instructions += Drop();
5215 } 5230 }
5216 5231
5217 // List of named. 5232 // List of named.
5218 list_length = ReadListLength(); // read list length. 5233 list_length = ReadListLength(); // read list length.
5219 if (argument_names != NULL && list_length > 0) { 5234 if (argument_names != NULL && list_length > 0) {
5220 *argument_names ^= Array::New(list_length, Heap::kOld); 5235 *argument_names ^= Array::New(list_length, Heap::kOld);
5221 } 5236 }
5222 for (intptr_t i = 0; i < list_length; ++i) { 5237 for (intptr_t i = 0; i < list_length; ++i) {
5223 String& name = H.DartSymbol(ReadStringReference()); // read ith name index. 5238 String& name = H.DartSymbol(ReadStringReference()); // read ith name index.
5224 instructions += BuildExpression(); // read ith expression. 5239 instructions += BuildExpression(); // read ith expression.
5225 if (!skip_push_arguments) instructions += PushArgument(); 5240 if (!skip_push_arguments) instructions += PushArgument();
5226 if (do_drop) instructions += Drop(); 5241 if (do_drop) instructions += Drop();
5227 if (argument_names != NULL) { 5242 if (argument_names != NULL) {
5228 argument_names->SetAt(i, name); 5243 argument_names->SetAt(i, name);
5229 } 5244 }
5230 } 5245 }
5231 5246
5232 return instructions; 5247 return instructions;
5233 } 5248 }
5234 5249
(...skipping 2558 matching lines...) Expand 10 before | Expand all | Expand 10 after
7793 } 7808 }
7794 } 7809 }
7795 7810
7796 return Array::Handle(Array::null()); 7811 return Array::Handle(Array::null());
7797 } 7812 }
7798 7813
7799 } // namespace kernel 7814 } // namespace kernel
7800 } // namespace dart 7815 } // namespace dart
7801 7816
7802 #endif // !defined(DART_PRECOMPILED_RUNTIME) 7817 #endif // !defined(DART_PRECOMPILED_RUNTIME)
OLDNEW
« no previous file with comments | « runtime/vm/kernel_binary_flowgraph.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698