| 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 | 6 |
| 7 #include "vm/compiler.h" | 7 #include "vm/compiler.h" |
| 8 #include "vm/longjump.h" | 8 #include "vm/longjump.h" |
| 9 #include "vm/object_store.h" | 9 #include "vm/object_store.h" |
| 10 | 10 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 ASSERT(scope_ == NULL && depth_.loop_ == 0 && depth_.function_ == 0); | 60 ASSERT(scope_ == NULL && depth_.loop_ == 0 && depth_.function_ == 0); |
| 61 result_ = new (Z) ScopeBuildingResult(); | 61 result_ = new (Z) ScopeBuildingResult(); |
| 62 | 62 |
| 63 ParsedFunction* parsed_function = parsed_function_; | 63 ParsedFunction* parsed_function = parsed_function_; |
| 64 const Function& function = parsed_function->function(); | 64 const Function& function = parsed_function->function(); |
| 65 | 65 |
| 66 // Setup a [ActiveClassScope] and a [ActiveMemberScope] which will be used | 66 // Setup a [ActiveClassScope] and a [ActiveMemberScope] which will be used |
| 67 // e.g. for type translation. | 67 // e.g. for type translation. |
| 68 const dart::Class& klass = | 68 const dart::Class& klass = |
| 69 dart::Class::Handle(zone_, parsed_function_->function().Owner()); | 69 dart::Class::Handle(zone_, parsed_function_->function().Owner()); |
| 70 |
| 70 Function& outermost_function = Function::Handle(Z); | 71 Function& outermost_function = Function::Handle(Z); |
| 71 intptr_t outermost_kernel_offset = -1; | 72 builder_->DiscoverEnclosingElements(Z, function, &outermost_function); |
| 72 intptr_t parent_class_offset = -1; | |
| 73 builder_->DiscoverEnclosingElements(Z, function, &outermost_function, | |
| 74 &outermost_kernel_offset, | |
| 75 &parent_class_offset); | |
| 76 // Use [klass]/[kernel_class] as active class. Type parameters will get | |
| 77 // resolved via [kernel_class] unless we are nested inside a static factory | |
| 78 // in which case we will use [member]. | |
| 79 intptr_t class_type_parameters = 0; | |
| 80 intptr_t class_type_parameters_offset_start = -1; | |
| 81 if (parent_class_offset > 0) { | |
| 82 builder_->GetTypeParameterInfoForClass(parent_class_offset, | |
| 83 &class_type_parameters, | |
| 84 &class_type_parameters_offset_start); | |
| 85 } | |
| 86 ActiveClassScope active_class_scope(&active_class_, class_type_parameters, | |
| 87 class_type_parameters_offset_start, | |
| 88 &klass); | |
| 89 | 73 |
| 90 bool member_is_procedure = false; | 74 ActiveClassScope active_class_scope(&active_class_, &klass); |
| 91 bool is_factory_procedure = false; | 75 ActiveMemberScope active_member(&active_class_, &outermost_function); |
| 92 intptr_t member_type_parameters = 0; | |
| 93 intptr_t member_type_parameters_offset_start = -1; | |
| 94 builder_->GetTypeParameterInfoForPossibleProcedure( | |
| 95 outermost_kernel_offset, &member_is_procedure, &is_factory_procedure, | |
| 96 &member_type_parameters, &member_type_parameters_offset_start); | |
| 97 | |
| 98 ActiveMemberScope active_member(&active_class_, member_is_procedure, | |
| 99 is_factory_procedure, member_type_parameters, | |
| 100 member_type_parameters_offset_start); | |
| 101 | 76 |
| 102 LocalScope* enclosing_scope = NULL; | 77 LocalScope* enclosing_scope = NULL; |
| 103 if (function.IsLocalFunction()) { | 78 if (function.IsLocalFunction()) { |
| 104 enclosing_scope = LocalScope::RestoreOuterScope( | 79 enclosing_scope = LocalScope::RestoreOuterScope( |
| 105 ContextScope::Handle(Z, function.context_scope())); | 80 ContextScope::Handle(Z, function.context_scope())); |
| 106 } | 81 } |
| 107 current_function_scope_ = scope_ = new (Z) LocalScope(enclosing_scope, 0, 0); | 82 current_function_scope_ = scope_ = new (Z) LocalScope(enclosing_scope, 0, 0); |
| 108 scope_->set_begin_token_pos(function.token_pos()); | 83 scope_->set_begin_token_pos(function.token_pos()); |
| 109 scope_->set_end_token_pos(function.end_token_pos()); | 84 scope_->set_end_token_pos(function.end_token_pos()); |
| 110 | 85 |
| 111 // Add function type arguments variable before current context variable. | 86 // Add function type arguments variable before current context variable. |
| 112 if (FLAG_reify_generic_functions && function.IsGeneric()) { | 87 if (FLAG_reify_generic_functions && function.IsGeneric()) { |
| 113 LocalVariable* type_args_var = MakeVariable( | 88 LocalVariable* type_args_var = MakeVariable( |
| 114 TokenPosition::kNoSource, TokenPosition::kNoSource, | 89 TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 115 Symbols::FunctionTypeArgumentsVar(), AbstractType::dynamic_type()); | 90 Symbols::FunctionTypeArgumentsVar(), AbstractType::dynamic_type()); |
| 116 scope_->AddVariable(type_args_var); | 91 scope_->AddVariable(type_args_var); |
| 117 parsed_function_->set_function_type_arguments(type_args_var); | 92 parsed_function_->set_function_type_arguments(type_args_var); |
| 118 } | 93 } |
| 119 | 94 |
| 120 LocalVariable* context_var = parsed_function->current_context_var(); | 95 LocalVariable* context_var = parsed_function->current_context_var(); |
| 121 context_var->set_is_forced_stack(); | 96 context_var->set_is_forced_stack(); |
| 122 scope_->AddVariable(context_var); | 97 scope_->AddVariable(context_var); |
| 123 | 98 |
| 124 parsed_function->SetNodeSequence( | 99 parsed_function->SetNodeSequence( |
| 125 new SequenceNode(TokenPosition::kNoSource, scope_)); | 100 new SequenceNode(TokenPosition::kNoSource, scope_)); |
| 126 | 101 |
| 127 intptr_t parent_offset = -1; | |
| 128 builder_->SetOffset(kernel_offset_); | 102 builder_->SetOffset(kernel_offset_); |
| 129 | 103 |
| 130 FunctionNodeHelper function_node_helper(builder_); | 104 FunctionNodeHelper function_node_helper(builder_); |
| 131 | 105 |
| 132 switch (function.kind()) { | 106 switch (function.kind()) { |
| 133 case RawFunction::kClosureFunction: | 107 case RawFunction::kClosureFunction: |
| 134 case RawFunction::kImplicitClosureFunction: | 108 case RawFunction::kImplicitClosureFunction: |
| 135 case RawFunction::kConvertedClosureFunction: | 109 case RawFunction::kConvertedClosureFunction: |
| 136 case RawFunction::kRegularFunction: | 110 case RawFunction::kRegularFunction: |
| 137 case RawFunction::kGetterFunction: | 111 case RawFunction::kGetterFunction: |
| 138 case RawFunction::kSetterFunction: | 112 case RawFunction::kSetterFunction: |
| 139 case RawFunction::kConstructor: { | 113 case RawFunction::kConstructor: { |
| 140 const Tag tag = builder_->PeekTag(); | 114 const Tag tag = builder_->PeekTag(); |
| 141 parent_offset = builder_->ReadUntilFunctionNode(); | 115 intptr_t parent_offset = builder_->ReadUntilFunctionNode(); |
| 142 function_node_helper.ReadUntilExcluding( | 116 function_node_helper.ReadUntilExcluding( |
| 143 FunctionNodeHelper::kPositionalParameters); | 117 FunctionNodeHelper::kPositionalParameters); |
| 144 current_function_async_marker_ = function_node_helper.async_marker_; | 118 current_function_async_marker_ = function_node_helper.async_marker_; |
| 145 // NOTE: FunctionNode is read further below the if. | 119 // NOTE: FunctionNode is read further below the if. |
| 146 | 120 |
| 147 intptr_t pos = 0; | 121 intptr_t pos = 0; |
| 148 if (function.IsClosureFunction()) { | 122 if (function.IsClosureFunction()) { |
| 149 LocalVariable* variable = MakeVariable( | 123 LocalVariable* variable = MakeVariable( |
| 150 TokenPosition::kNoSource, TokenPosition::kNoSource, | 124 TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 151 Symbols::ClosureParameter(), AbstractType::dynamic_type()); | 125 Symbols::ClosureParameter(), AbstractType::dynamic_type()); |
| (...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 631 intptr_t list_length = builder_->ReadListLength(); // read list length. | 605 intptr_t list_length = builder_->ReadListLength(); // read list length. |
| 632 for (intptr_t i = 0; i < list_length; ++i) { | 606 for (intptr_t i = 0; i < list_length; ++i) { |
| 633 VisitExpression(); // read ith key. | 607 VisitExpression(); // read ith key. |
| 634 VisitExpression(); // read ith value. | 608 VisitExpression(); // read ith value. |
| 635 } | 609 } |
| 636 return; | 610 return; |
| 637 } | 611 } |
| 638 case kFunctionExpression: { | 612 case kFunctionExpression: { |
| 639 intptr_t offset = | 613 intptr_t offset = |
| 640 builder_->ReaderOffset() - 1; // -1 to include tag byte. | 614 builder_->ReaderOffset() - 1; // -1 to include tag byte. |
| 641 HandleLocalFunction(offset); | 615 HandleLocalFunction(offset); // read function node. |
| 642 return; | 616 return; |
| 643 } | 617 } |
| 644 case kLet: { | 618 case kLet: { |
| 645 PositionScope scope(builder_->reader_); | 619 PositionScope scope(builder_->reader_); |
| 646 intptr_t offset = | 620 intptr_t offset = |
| 647 builder_->ReaderOffset() - 1; // -1 to include tag byte. | 621 builder_->ReaderOffset() - 1; // -1 to include tag byte. |
| 648 | 622 |
| 649 EnterScope(offset); | 623 EnterScope(offset); |
| 650 | 624 |
| 651 VisitVariableDeclaration(); // read variable declaration. | 625 VisitVariableDeclaration(); // read variable declaration. |
| (...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1120 // factory constructor function. | 1094 // factory constructor function. |
| 1121 HandleSpecialLoad(&result_->type_arguments_variable, | 1095 HandleSpecialLoad(&result_->type_arguments_variable, |
| 1122 Symbols::TypeArgumentsParameter()); | 1096 Symbols::TypeArgumentsParameter()); |
| 1123 } else { | 1097 } else { |
| 1124 // The type argument vector is stored on the instance object. We therefore | 1098 // The type argument vector is stored on the instance object. We therefore |
| 1125 // need to capture `this`. | 1099 // need to capture `this`. |
| 1126 HandleSpecialLoad(&result_->this_variable, Symbols::This()); | 1100 HandleSpecialLoad(&result_->this_variable, Symbols::This()); |
| 1127 } | 1101 } |
| 1128 | 1102 |
| 1129 builder_->ReadUInt(); // read index for parameter. | 1103 builder_->ReadUInt(); // read index for parameter. |
| 1130 builder_->ReadUInt(); // read list binary offset. | |
| 1131 builder_->ReadUInt(); // read index in list. | |
| 1132 builder_->SkipOptionalDartType(); // read bound bound. | 1104 builder_->SkipOptionalDartType(); // read bound bound. |
| 1133 } | 1105 } |
| 1134 | 1106 |
| 1135 void StreamingScopeBuilder::HandleLocalFunction(intptr_t parent_kernel_offset) { | 1107 void StreamingScopeBuilder::HandleLocalFunction(intptr_t parent_kernel_offset) { |
| 1136 // "Peek" ahead into the function node | 1108 // "Peek" ahead into the function node |
| 1137 intptr_t offset = builder_->ReaderOffset(); | 1109 intptr_t offset = builder_->ReaderOffset(); |
| 1138 | 1110 |
| 1139 FunctionNodeHelper function_node_helper(builder_); | 1111 FunctionNodeHelper function_node_helper(builder_); |
| 1140 function_node_helper.ReadUntilExcluding( | 1112 function_node_helper.ReadUntilExcluding( |
| 1141 FunctionNodeHelper::kPositionalParameters); | 1113 FunctionNodeHelper::kPositionalParameters); |
| (...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1601 ClassFinalizer::FinalizeType(*active_class_->klass, signature_type); | 1573 ClassFinalizer::FinalizeType(*active_class_->klass, signature_type); |
| 1602 // Do not refer to signature_function anymore, since it may have been | 1574 // Do not refer to signature_function anymore, since it may have been |
| 1603 // replaced during canonicalization. | 1575 // replaced during canonicalization. |
| 1604 signature_function = Function::null(); | 1576 signature_function = Function::null(); |
| 1605 } | 1577 } |
| 1606 | 1578 |
| 1607 result_ = signature_type.raw(); | 1579 result_ = signature_type.raw(); |
| 1608 } | 1580 } |
| 1609 | 1581 |
| 1610 void StreamingDartTypeTranslator::BuildTypeParameterType() { | 1582 void StreamingDartTypeTranslator::BuildTypeParameterType() { |
| 1611 builder_->ReadUInt(); // read parameter index. | 1583 intptr_t parameter_index = builder_->ReadUInt(); // read parameter index. |
| 1612 intptr_t binary_offset = builder_->ReadUInt(); // read lists binary offset. | 1584 builder_->SkipOptionalDartType(); // read bound. |
| 1613 intptr_t list_index = builder_->ReadUInt(); // read index in list. | |
| 1614 builder_->SkipOptionalDartType(); // read bound. | |
| 1615 | 1585 |
| 1616 ASSERT(binary_offset > 0); | 1586 const TypeArguments& class_types = |
| 1587 dart::TypeArguments::Handle(Z, active_class_->klass->type_parameters()); |
| 1588 if (parameter_index < class_types.Length()) { |
| 1589 // The index of the type parameter in [parameters] is |
| 1590 // the same index into the `klass->type_parameters()` array. |
| 1591 result_ ^= class_types.TypeAt(parameter_index); |
| 1592 return; |
| 1593 } |
| 1594 parameter_index -= class_types.Length(); |
| 1617 | 1595 |
| 1618 for (TypeParameterScope* scope = type_parameter_scope_; scope != NULL; | 1596 if (active_class_->HasMember()) { |
| 1619 scope = scope->outer()) { | 1597 if (active_class_->MemberIsFactoryProcedure()) { |
| 1620 if (scope->parameters_offset() == binary_offset) { | |
| 1621 result_ ^= dart::Type::DynamicType(); | |
| 1622 return; | |
| 1623 } | |
| 1624 } | |
| 1625 | |
| 1626 if (active_class_->member_is_procedure) { | |
| 1627 if (active_class_->member_type_parameters > 0) { | |
| 1628 // | 1598 // |
| 1629 // WARNING: This is a little hackish: | 1599 // WARNING: This is a little hackish: |
| 1630 // | 1600 // |
| 1631 // We have a static factory constructor. The kernel IR gives the factory | 1601 // We have a static factory constructor. The kernel IR gives the factory |
| 1632 // constructor function it's own type parameters (which are equal in name | 1602 // constructor function it's own type parameters (which are equal in name |
| 1633 // and number to the ones of the enclosing class). | 1603 // and number to the ones of the enclosing class). |
| 1634 // I.e., | 1604 // I.e., |
| 1635 // | 1605 // |
| 1636 // class A<T> { | 1606 // class A<T> { |
| 1637 // factory A.x() { return new B<T>(); } | 1607 // factory A.x() { return new B<T>(); } |
| 1638 // } | 1608 // } |
| 1639 // | 1609 // |
| 1640 // is basically translated to this: | 1610 // is basically translated to this: |
| 1641 // | 1611 // |
| 1642 // class A<T> { | 1612 // class A<T> { |
| 1643 // static A.x<T'>() { return new B<T'>(); } | 1613 // static A.x<T'>() { return new B<T'>(); } |
| 1644 // } | 1614 // } |
| 1645 // | 1615 // |
| 1646 if (active_class_->member_type_parameters_offset_start == binary_offset) { | 1616 if (class_types.Length() > parameter_index) { |
| 1647 if (active_class_->member_is_factory_procedure) { | 1617 result_ ^= class_types.TypeAt(parameter_index); |
| 1648 // The index of the type parameter in [parameters] is | |
| 1649 // the same index into the `klass->type_parameters()` array. | |
| 1650 result_ ^= dart::TypeArguments::Handle( | |
| 1651 Z, active_class_->klass->type_parameters()) | |
| 1652 .TypeAt(list_index); | |
| 1653 } else { | |
| 1654 result_ ^= dart::Type::DynamicType(); | |
| 1655 } | |
| 1656 return; | 1618 return; |
| 1657 } | 1619 } |
| 1620 parameter_index -= class_types.Length(); |
| 1621 } |
| 1622 |
| 1623 intptr_t procedure_type_parameter_count = |
| 1624 active_class_->MemberIsProcedure() |
| 1625 ? active_class_->MemberTypeParameterCount(Z) |
| 1626 : 0; |
| 1627 if (procedure_type_parameter_count > 0) { |
| 1628 if (procedure_type_parameter_count > parameter_index) { |
| 1629 // Here we technically could load the correct one via something like |
| 1630 // result_ ^= dart::TypeArguments::Handle( |
| 1631 // Z, active_class_->member->type_parameters()) |
| 1632 // .TypeAt(parameter_index); |
| 1633 // but that isn't currently supported elsewhere |
| 1634 // (FlowGraphBuilder::LoadFunctionTypeArguments()). |
| 1635 result_ ^= dart::Type::DynamicType(); |
| 1636 return; |
| 1637 } |
| 1638 parameter_index -= procedure_type_parameter_count; |
| 1658 } | 1639 } |
| 1659 } | 1640 } |
| 1660 | 1641 |
| 1661 if (active_class_->class_type_parameters_offset_start == binary_offset) { | 1642 if (type_parameter_scope_ != NULL && parameter_index >= 0 && |
| 1662 // The index of the type parameter in [parameters] is | 1643 parameter_index < type_parameter_scope_->outer_parameter_count() + |
| 1663 // the same index into the `klass->type_parameters()` array. | 1644 type_parameter_scope_->parameters_count()) { |
| 1664 result_ ^= | 1645 result_ ^= dart::Type::DynamicType(); |
| 1665 dart::TypeArguments::Handle(Z, active_class_->klass->type_parameters()) | |
| 1666 .TypeAt(list_index); | |
| 1667 return; | 1646 return; |
| 1668 } | 1647 } |
| 1669 | 1648 |
| 1670 UNREACHABLE(); | 1649 H.ReportError("Unexpected input. Please report this at dartbug.com."); |
| 1671 } | 1650 } |
| 1672 | 1651 |
| 1673 const TypeArguments& StreamingDartTypeTranslator::BuildTypeArguments( | 1652 const TypeArguments& StreamingDartTypeTranslator::BuildTypeArguments( |
| 1674 intptr_t length) { | 1653 intptr_t length) { |
| 1675 bool only_dynamic = true; | 1654 bool only_dynamic = true; |
| 1676 intptr_t offset = builder_->ReaderOffset(); | 1655 intptr_t offset = builder_->ReaderOffset(); |
| 1677 for (intptr_t i = 0; i < length; ++i) { | 1656 for (intptr_t i = 0; i < length; ++i) { |
| 1678 if (builder_->ReadTag() != kDynamicType) { // Read the ith types tag. | 1657 if (builder_->ReadTag() != kDynamicType) { // Read the ith types tag. |
| 1679 only_dynamic = false; | 1658 only_dynamic = false; |
| 1680 builder_->SetOffset(offset); | 1659 builder_->SetOffset(offset); |
| (...skipping 818 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2499 script_.set_compile_time_constants(array); | 2478 script_.set_compile_time_constants(array); |
| 2500 } | 2479 } |
| 2501 KernelConstantsMap constants(script_.compile_time_constants()); | 2480 KernelConstantsMap constants(script_.compile_time_constants()); |
| 2502 constants.InsertNewOrGetValue(kernel_offset, value); | 2481 constants.InsertNewOrGetValue(kernel_offset, value); |
| 2503 script_.set_compile_time_constants(constants.Release()); | 2482 script_.set_compile_time_constants(constants.Release()); |
| 2504 } | 2483 } |
| 2505 | 2484 |
| 2506 void StreamingFlowGraphBuilder::DiscoverEnclosingElements( | 2485 void StreamingFlowGraphBuilder::DiscoverEnclosingElements( |
| 2507 Zone* zone, | 2486 Zone* zone, |
| 2508 const Function& function, | 2487 const Function& function, |
| 2509 Function* outermost_function, | 2488 Function* outermost_function) { |
| 2510 intptr_t* outermost_kernel_offset, | |
| 2511 intptr_t* parent_class_offset) { | |
| 2512 // Find out if there is an enclosing kernel class (which will be used to | 2489 // Find out if there is an enclosing kernel class (which will be used to |
| 2513 // resolve type parameters). | 2490 // resolve type parameters). |
| 2514 *outermost_function = function.raw(); | 2491 *outermost_function = function.raw(); |
| 2515 while (outermost_function->parent_function() != Object::null()) { | 2492 while (outermost_function->parent_function() != Object::null()) { |
| 2516 *outermost_function = outermost_function->parent_function(); | 2493 *outermost_function = outermost_function->parent_function(); |
| 2517 } | 2494 } |
| 2518 | |
| 2519 if (outermost_function->kernel_offset() > 0) { | |
| 2520 *outermost_kernel_offset = outermost_function->kernel_offset(); | |
| 2521 *parent_class_offset = GetParentOffset(*outermost_kernel_offset); | |
| 2522 } | |
| 2523 } | |
| 2524 | |
| 2525 intptr_t StreamingFlowGraphBuilder::GetParentOffset(intptr_t offset) { | |
| 2526 AlternativeReadingScope alt(reader_, offset); | |
| 2527 | |
| 2528 Tag tag = PeekTag(); | |
| 2529 switch (tag) { | |
| 2530 case kConstructor: { | |
| 2531 ConstructorHelper constructor_helper(this); | |
| 2532 constructor_helper.ReadUntilIncluding( | |
| 2533 ConstructorHelper::kParentClassBinaryOffset); | |
| 2534 return constructor_helper.parent_class_binary_offset_; | |
| 2535 } | |
| 2536 case kProcedure: { | |
| 2537 ProcedureHelper procedure_helper(this); | |
| 2538 procedure_helper.ReadUntilIncluding( | |
| 2539 ProcedureHelper::kParentClassBinaryOffset); | |
| 2540 return procedure_helper.parent_class_binary_offset_; | |
| 2541 } | |
| 2542 case kField: { | |
| 2543 FieldHelper field_helper(this); | |
| 2544 field_helper.ReadUntilIncluding(FieldHelper::kParentClassBinaryOffset); | |
| 2545 return field_helper.parent_class_binary_offset_; | |
| 2546 } | |
| 2547 default: | |
| 2548 UNIMPLEMENTED(); | |
| 2549 return -1; | |
| 2550 } | |
| 2551 } | |
| 2552 | |
| 2553 void StreamingFlowGraphBuilder::GetTypeParameterInfoForClass( | |
| 2554 intptr_t class_offset, | |
| 2555 intptr_t* type_paremeter_counts, | |
| 2556 intptr_t* type_paremeter_offset) { | |
| 2557 AlternativeReadingScope alt(reader_, class_offset); | |
| 2558 | |
| 2559 ClassHelper class_helper(this); | |
| 2560 class_helper.ReadUntilExcluding(ClassHelper::kTypeParameters); | |
| 2561 *type_paremeter_counts = | |
| 2562 ReadListLength(); // read type_parameters list length. | |
| 2563 *type_paremeter_offset = ReaderOffset(); | |
| 2564 } | |
| 2565 | |
| 2566 void StreamingFlowGraphBuilder::GetTypeParameterInfoForPossibleProcedure( | |
| 2567 intptr_t outermost_kernel_offset, | |
| 2568 bool* member_is_procedure, | |
| 2569 bool* is_factory_procedure, | |
| 2570 intptr_t* member_type_parameters, | |
| 2571 intptr_t* member_type_parameters_offset_start) { | |
| 2572 if (outermost_kernel_offset >= 0) { | |
| 2573 AlternativeReadingScope alt(reader_, outermost_kernel_offset); | |
| 2574 Tag tag = PeekTag(); | |
| 2575 if (tag == kProcedure) { | |
| 2576 *member_is_procedure = true; | |
| 2577 | |
| 2578 ProcedureHelper procedure_helper(this); | |
| 2579 procedure_helper.ReadUntilExcluding(ProcedureHelper::kFunction); | |
| 2580 *is_factory_procedure = procedure_helper.kind_ == Procedure::kFactory; | |
| 2581 if (ReadTag() == kSomething) { | |
| 2582 FunctionNodeHelper function_node_helper(this); | |
| 2583 function_node_helper.ReadUntilExcluding( | |
| 2584 FunctionNodeHelper::kTypeParameters); | |
| 2585 | |
| 2586 // read type_parameters list length. | |
| 2587 intptr_t list_length = ReadListLength(); | |
| 2588 if (list_length > 0) { | |
| 2589 *member_type_parameters = list_length; | |
| 2590 *member_type_parameters_offset_start = ReaderOffset(); | |
| 2591 } | |
| 2592 } | |
| 2593 } | |
| 2594 } | |
| 2595 } | 2495 } |
| 2596 | 2496 |
| 2597 intptr_t StreamingFlowGraphBuilder::ReadUntilFunctionNode() { | 2497 intptr_t StreamingFlowGraphBuilder::ReadUntilFunctionNode() { |
| 2598 const Tag tag = PeekTag(); | 2498 const Tag tag = PeekTag(); |
| 2599 if (tag == kProcedure) { | 2499 if (tag == kProcedure) { |
| 2600 ProcedureHelper procedure_helper(this); | 2500 ProcedureHelper procedure_helper(this); |
| 2601 procedure_helper.ReadUntilExcluding(ProcedureHelper::kFunction); | 2501 procedure_helper.ReadUntilExcluding(ProcedureHelper::kFunction); |
| 2602 if (ReadTag() == kNothing) { // read function node tag. | 2502 if (ReadTag() == kNothing) { // read function node tag. |
| 2603 // Running a procedure without a function node doesn't make sense. | 2503 // Running a procedure without a function node doesn't make sense. |
| 2604 UNREACHABLE(); | 2504 UNREACHABLE(); |
| (...skipping 793 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3398 | 3298 |
| 3399 FlowGraph* StreamingFlowGraphBuilder::BuildGraph(intptr_t kernel_offset) { | 3299 FlowGraph* StreamingFlowGraphBuilder::BuildGraph(intptr_t kernel_offset) { |
| 3400 const Function& function = parsed_function()->function(); | 3300 const Function& function = parsed_function()->function(); |
| 3401 | 3301 |
| 3402 // Setup a [ActiveClassScope] and a [ActiveMemberScope] which will be used | 3302 // Setup a [ActiveClassScope] and a [ActiveMemberScope] which will be used |
| 3403 // e.g. for type translation. | 3303 // e.g. for type translation. |
| 3404 const dart::Class& klass = | 3304 const dart::Class& klass = |
| 3405 dart::Class::Handle(zone_, parsed_function()->function().Owner()); | 3305 dart::Class::Handle(zone_, parsed_function()->function().Owner()); |
| 3406 | 3306 |
| 3407 Function& outermost_function = Function::Handle(Z); | 3307 Function& outermost_function = Function::Handle(Z); |
| 3408 intptr_t outermost_kernel_offset = -1; | 3308 DiscoverEnclosingElements(Z, function, &outermost_function); |
| 3409 intptr_t parent_class_offset = -1; | |
| 3410 DiscoverEnclosingElements(Z, function, &outermost_function, | |
| 3411 &outermost_kernel_offset, &parent_class_offset); | |
| 3412 // Use [klass]/[kernel_class] as active class. Type parameters will get | |
| 3413 // resolved via [kernel_class] unless we are nested inside a static factory | |
| 3414 // in which case we will use [member]. | |
| 3415 intptr_t class_type_parameters = 0; | |
| 3416 intptr_t class_type_parameters_offset_start = -1; | |
| 3417 if (parent_class_offset > 0) { | |
| 3418 GetTypeParameterInfoForClass(parent_class_offset, &class_type_parameters, | |
| 3419 &class_type_parameters_offset_start); | |
| 3420 } | |
| 3421 | 3309 |
| 3422 ActiveClassScope active_class_scope(active_class(), class_type_parameters, | 3310 ActiveClassScope active_class_scope(active_class(), &klass); |
| 3423 class_type_parameters_offset_start, | 3311 ActiveMemberScope active_member(active_class(), &outermost_function); |
| 3424 &klass); | |
| 3425 | |
| 3426 bool member_is_procedure = false; | |
| 3427 bool is_factory_procedure = false; | |
| 3428 intptr_t member_type_parameters = 0; | |
| 3429 intptr_t member_type_parameters_offset_start = -1; | |
| 3430 GetTypeParameterInfoForPossibleProcedure( | |
| 3431 outermost_kernel_offset, &member_is_procedure, &is_factory_procedure, | |
| 3432 &member_type_parameters, &member_type_parameters_offset_start); | |
| 3433 | |
| 3434 ActiveMemberScope active_member(active_class(), member_is_procedure, | |
| 3435 is_factory_procedure, member_type_parameters, | |
| 3436 member_type_parameters_offset_start); | |
| 3437 | 3312 |
| 3438 // The IR builder will create its own local variables and scopes, and it | 3313 // The IR builder will create its own local variables and scopes, and it |
| 3439 // will not need an AST. The code generator will assume that there is a | 3314 // will not need an AST. The code generator will assume that there is a |
| 3440 // local variable stack slot allocated for the current context and (I | 3315 // local variable stack slot allocated for the current context and (I |
| 3441 // think) that the runtime will expect it to be at a fixed offset which | 3316 // think) that the runtime will expect it to be at a fixed offset which |
| 3442 // requires allocating an unused expression temporary variable. | 3317 // requires allocating an unused expression temporary variable. |
| 3443 set_scopes(parsed_function()->EnsureKernelScopes()); | 3318 set_scopes(parsed_function()->EnsureKernelScopes()); |
| 3444 | 3319 |
| 3445 SetOffset(kernel_offset); | 3320 SetOffset(kernel_offset); |
| 3446 | 3321 |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3772 SkipInterfaceType(true); | 3647 SkipInterfaceType(true); |
| 3773 return; | 3648 return; |
| 3774 case kFunctionType: | 3649 case kFunctionType: |
| 3775 SkipFunctionType(false); | 3650 SkipFunctionType(false); |
| 3776 return; | 3651 return; |
| 3777 case kSimpleFunctionType: | 3652 case kSimpleFunctionType: |
| 3778 SkipFunctionType(true); | 3653 SkipFunctionType(true); |
| 3779 return; | 3654 return; |
| 3780 case kTypeParameterType: | 3655 case kTypeParameterType: |
| 3781 ReadUInt(); // read index for parameter. | 3656 ReadUInt(); // read index for parameter. |
| 3782 ReadUInt(); // read list binary offset. | |
| 3783 ReadUInt(); // read index in list. | |
| 3784 SkipOptionalDartType(); // read bound bound. | 3657 SkipOptionalDartType(); // read bound bound. |
| 3785 return; | 3658 return; |
| 3786 default: | 3659 default: |
| 3787 UNREACHABLE(); | 3660 UNREACHABLE(); |
| 3788 } | 3661 } |
| 3789 } | 3662 } |
| 3790 | 3663 |
| 3791 void StreamingFlowGraphBuilder::SkipOptionalDartType() { | 3664 void StreamingFlowGraphBuilder::SkipOptionalDartType() { |
| 3792 Tag tag = ReadTag(); // read tag. | 3665 Tag tag = ReadTag(); // read tag. |
| 3793 if (tag == kNothing) { | 3666 if (tag == kNothing) { |
| (...skipping 3534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7328 } | 7201 } |
| 7329 } | 7202 } |
| 7330 | 7203 |
| 7331 return Array::Handle(Array::null()); | 7204 return Array::Handle(Array::null()); |
| 7332 } | 7205 } |
| 7333 | 7206 |
| 7334 } // namespace kernel | 7207 } // namespace kernel |
| 7335 } // namespace dart | 7208 } // namespace dart |
| 7336 | 7209 |
| 7337 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 7210 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
| OLD | NEW |