OLD | NEW |
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 3419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3430 intptr_t kernel_offset, | 3430 intptr_t kernel_offset, |
3431 intptr_t parameter_index) { | 3431 intptr_t parameter_index) { |
3432 LocalVariable* var = LookupVariable(kernel_offset); | 3432 LocalVariable* var = LookupVariable(kernel_offset); |
3433 LocalVariable* parameter = | 3433 LocalVariable* parameter = |
3434 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 3434 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
3435 Symbols::TempParam(), var->type()); | 3435 Symbols::TempParam(), var->type()); |
3436 parameter->set_index(parameter_index); | 3436 parameter->set_index(parameter_index); |
3437 if (var->is_captured()) parameter->set_is_captured_parameter(true); | 3437 if (var->is_captured()) parameter->set_is_captured_parameter(true); |
3438 return parameter; | 3438 return parameter; |
3439 } | 3439 } |
3440 // This method follows the logic of | |
3441 // StreamingFlowGraphBuilder::BuildGraphOfImplicitClosureFunction. For | |
3442 // additional details on converted closure functions, please, see the comment on | |
3443 // the method Function::ConvertedClosureFunction. | |
3444 FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfConvertedClosureFunction( | |
3445 const Function& function) { | |
3446 const Function& target = Function::ZoneHandle(Z, function.parent_function()); | |
3447 | |
3448 TargetEntryInstr* normal_entry = flow_graph_builder_->BuildTargetEntry(); | |
3449 flow_graph_builder_->graph_entry_ = new (Z) GraphEntryInstr( | |
3450 *parsed_function(), normal_entry, Compiler::kNoOSRDeoptId); | |
3451 SetupDefaultParameterValues(); | |
3452 | |
3453 Fragment body(normal_entry); | |
3454 body += flow_graph_builder_->CheckStackOverflowInPrologue(); | |
3455 body += NullConstant(); | |
3456 LocalVariable* result = MakeTemporary(); | |
3457 | |
3458 // Load all the arguments. | |
3459 ASSERT(target.is_static()); | |
3460 | |
3461 // TODO(30455): Kernel generic methods undone. Since the frontend can't yet | |
3462 // emit generic methods into kernel, all type parameters to the target must | |
3463 // come from the context. When generic methods are fully supported, we will | |
3464 // need to get the type arguments provided by the caller and append them to | |
3465 // the captured type arguments via 'prependTypeArguments'. | |
3466 | |
3467 FunctionNodeHelper function_node_helper(this); | |
3468 function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kTypeParameters); | |
3469 intptr_t type_param_count = PeekUInt(); | |
3470 function_node_helper.ReadUntilExcluding( | |
3471 FunctionNodeHelper::kPositionalParameters); | |
3472 | |
3473 // Positional. | |
3474 const intptr_t positional_argument_count = ReadListLength(); | |
3475 | |
3476 // The first argument is the instance of the closure class. For converted | |
3477 // closures its context field contains the context vector that is used by the | |
3478 // converted top-level function (target) explicitly and that should be passed | |
3479 // to that function as the first parameter. | |
3480 intptr_t parameter_index = parsed_function()->first_parameter_index(); | |
3481 LocalVariable* parameter = LookupParameterDirect( | |
3482 ReaderOffset() + relative_kernel_offset_, parameter_index--); | |
3483 body += LoadLocal(parameter); // 0th variable offset. | |
3484 body += flow_graph_builder_->LoadField(Closure::context_offset()); | |
3485 LocalVariable* context = MakeTemporary(); | |
3486 | |
3487 if (type_param_count > 0) { | |
3488 body += LoadLocal(context); | |
3489 body += flow_graph_builder_->LoadField(Context::variable_offset(0)); | |
3490 body += PushArgument(); | |
3491 } | |
3492 | |
3493 body += LoadLocal(context); | |
3494 body += PushArgument(); | |
3495 SkipVariableDeclaration(); // read 0th variable. | |
3496 | |
3497 // The rest of the parameters are the same for the method of the Closure class | |
3498 // being invoked and the top-level function (target). | |
3499 for (intptr_t i = 1; i < positional_argument_count; i++) { | |
3500 LocalVariable* parameter = LookupParameterDirect( | |
3501 ReaderOffset() + relative_kernel_offset_, parameter_index--); | |
3502 body += LoadLocal(parameter); // ith variable offset. | |
3503 body += PushArgument(); | |
3504 SkipVariableDeclaration(); // read ith variable. | |
3505 } | |
3506 | |
3507 // Named. | |
3508 const intptr_t named_argument_count = ReadListLength(); | |
3509 Array& argument_names = Array::ZoneHandle(Z); | |
3510 if (named_argument_count > 0) { | |
3511 argument_names = Array::New(named_argument_count); | |
3512 for (intptr_t i = 0; i < named_argument_count; i++) { | |
3513 // ith variable offset. | |
3514 body += | |
3515 LoadLocal(LookupVariable(ReaderOffset() + relative_kernel_offset_)); | |
3516 body += PushArgument(); | |
3517 | |
3518 // read ith variable. | |
3519 VariableDeclarationHelper helper(this); | |
3520 helper.ReadUntilExcluding(VariableDeclarationHelper::kEnd); | |
3521 | |
3522 argument_names.SetAt(i, H.DartSymbol(helper.name_index_)); | |
3523 } | |
3524 } | |
3525 | |
3526 // Forward them to the target. | |
3527 intptr_t argument_count = positional_argument_count + named_argument_count; | |
3528 if (type_param_count) ++argument_count; | |
3529 body += StaticCall(TokenPosition::kNoSource, target, argument_count, | |
3530 argument_names, type_param_count); | |
3531 | |
3532 // Return the result. | |
3533 body += StoreLocal(TokenPosition::kNoSource, result); | |
3534 body += Drop(); | |
3535 body += Drop(); | |
3536 body += Return(function_node_helper.end_position_); | |
3537 | |
3538 return new (Z) | |
3539 FlowGraph(*parsed_function(), flow_graph_builder_->graph_entry_, | |
3540 flow_graph_builder_->next_block_id_ - 1); | |
3541 } | |
3542 | 3440 |
3543 FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfFunction(bool constructor) { | 3441 FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfFunction(bool constructor) { |
3544 const Function& dart_function = parsed_function()->function(); | 3442 const Function& dart_function = parsed_function()->function(); |
3545 TargetEntryInstr* normal_entry = flow_graph_builder_->BuildTargetEntry(); | 3443 TargetEntryInstr* normal_entry = flow_graph_builder_->BuildTargetEntry(); |
3546 flow_graph_builder_->graph_entry_ = new (Z) GraphEntryInstr( | 3444 flow_graph_builder_->graph_entry_ = new (Z) GraphEntryInstr( |
3547 *parsed_function(), normal_entry, flow_graph_builder_->osr_id_); | 3445 *parsed_function(), normal_entry, flow_graph_builder_->osr_id_); |
3548 | 3446 |
3549 SetupDefaultParameterValues(); | 3447 SetupDefaultParameterValues(); |
3550 | 3448 |
3551 Fragment body; | 3449 Fragment body; |
| 3450 |
| 3451 if (dart_function.IsConvertedClosureFunction()) { |
| 3452 LocalVariable* closure = new (Z) LocalVariable( |
| 3453 TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 3454 Symbols::TempParam(), AbstractType::ZoneHandle(Z, Type::DynamicType())); |
| 3455 closure->set_index(parsed_function()->first_parameter_index()); |
| 3456 closure->set_is_captured_parameter(true); |
| 3457 body += LoadLocal(closure); |
| 3458 body += LoadField(Closure::context_offset()); |
| 3459 LocalVariable* context = closure; |
| 3460 body += StoreLocal(TokenPosition::kNoSource, context); |
| 3461 |
| 3462 // TODO(30455): Kernel generic methods undone. When generic closures are |
| 3463 // supported, the type arguments passed by the caller will actually need to |
| 3464 // be used here. |
| 3465 if (dart_function.IsGeneric() && FLAG_reify_generic_functions) { |
| 3466 LocalVariable* type_args_slot = |
| 3467 parsed_function()->function_type_arguments(); |
| 3468 ASSERT(type_args_slot != NULL); |
| 3469 body += LoadField(Context::variable_offset(0)); |
| 3470 body += StoreLocal(TokenPosition::kNoSource, type_args_slot); |
| 3471 } |
| 3472 body += Drop(); |
| 3473 } |
| 3474 |
3552 if (!dart_function.is_native()) | 3475 if (!dart_function.is_native()) |
3553 body += flow_graph_builder_->CheckStackOverflowInPrologue(); | 3476 body += flow_graph_builder_->CheckStackOverflowInPrologue(); |
3554 intptr_t context_size = | 3477 intptr_t context_size = |
3555 parsed_function()->node_sequence()->scope()->num_context_variables(); | 3478 parsed_function()->node_sequence()->scope()->num_context_variables(); |
3556 if (context_size > 0) { | 3479 if (context_size > 0) { |
3557 body += flow_graph_builder_->PushContext(context_size); | 3480 body += flow_graph_builder_->PushContext(context_size); |
3558 LocalVariable* context = MakeTemporary(); | 3481 LocalVariable* context = MakeTemporary(); |
3559 | 3482 |
3560 // Copy captured parameters from the stack into the context. | 3483 // Copy captured parameters from the stack into the context. |
3561 LocalScope* scope = parsed_function()->node_sequence()->scope(); | 3484 LocalScope* scope = parsed_function()->node_sequence()->scope(); |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3860 switch (function.kind()) { | 3783 switch (function.kind()) { |
3861 case RawFunction::kClosureFunction: | 3784 case RawFunction::kClosureFunction: |
3862 case RawFunction::kImplicitClosureFunction: | 3785 case RawFunction::kImplicitClosureFunction: |
3863 case RawFunction::kConvertedClosureFunction: | 3786 case RawFunction::kConvertedClosureFunction: |
3864 case RawFunction::kRegularFunction: | 3787 case RawFunction::kRegularFunction: |
3865 case RawFunction::kGetterFunction: | 3788 case RawFunction::kGetterFunction: |
3866 case RawFunction::kSetterFunction: { | 3789 case RawFunction::kSetterFunction: { |
3867 ReadUntilFunctionNode(); // read until function node. | 3790 ReadUntilFunctionNode(); // read until function node. |
3868 if (function.IsImplicitClosureFunction()) { | 3791 if (function.IsImplicitClosureFunction()) { |
3869 return BuildGraphOfImplicitClosureFunction(function); | 3792 return BuildGraphOfImplicitClosureFunction(function); |
3870 } else if (function.IsConvertedClosureFunction()) { | |
3871 return BuildGraphOfConvertedClosureFunction(function); | |
3872 } | 3793 } |
3873 return BuildGraphOfFunction(false); | 3794 return BuildGraphOfFunction(false); |
3874 } | 3795 } |
3875 case RawFunction::kConstructor: { | 3796 case RawFunction::kConstructor: { |
3876 ReadUntilFunctionNode(); // read until function node. | 3797 ReadUntilFunctionNode(); // read until function node. |
3877 return BuildGraphOfFunction(!function.IsFactory()); | 3798 return BuildGraphOfFunction(!function.IsFactory()); |
3878 } | 3799 } |
3879 case RawFunction::kImplicitGetter: | 3800 case RawFunction::kImplicitGetter: |
3880 case RawFunction::kImplicitStaticFinalGetter: | 3801 case RawFunction::kImplicitStaticFinalGetter: |
3881 case RawFunction::kImplicitSetter: { | 3802 case RawFunction::kImplicitSetter: { |
(...skipping 3946 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7828 } | 7749 } |
7829 } | 7750 } |
7830 | 7751 |
7831 return Array::Handle(Array::null()); | 7752 return Array::Handle(Array::null()); |
7832 } | 7753 } |
7833 | 7754 |
7834 } // namespace kernel | 7755 } // namespace kernel |
7835 } // namespace dart | 7756 } // namespace dart |
7836 | 7757 |
7837 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 7758 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
OLD | NEW |