| 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 |