Chromium Code Reviews| 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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 61 ASSERT(scope_ == NULL && depth_.loop_ == 0 && depth_.function_ == 0); | 61 ASSERT(scope_ == NULL && depth_.loop_ == 0 && depth_.function_ == 0); |
| 62 result_ = new (Z) ScopeBuildingResult(); | 62 result_ = new (Z) ScopeBuildingResult(); |
| 63 | 63 |
| 64 ParsedFunction* parsed_function = parsed_function_; | 64 ParsedFunction* parsed_function = parsed_function_; |
| 65 const Function& function = parsed_function->function(); | 65 const Function& function = parsed_function->function(); |
| 66 | 66 |
| 67 // Setup a [ActiveClassScope] and a [ActiveMemberScope] which will be used | 67 // Setup a [ActiveClassScope] and a [ActiveMemberScope] which will be used |
| 68 // e.g. for type translation. | 68 // e.g. for type translation. |
| 69 const dart::Class& klass = | 69 const dart::Class& klass = |
| 70 dart::Class::Handle(zone_, parsed_function_->function().Owner()); | 70 dart::Class::Handle(zone_, parsed_function_->function().Owner()); |
| 71 | |
| 71 Function& outermost_function = Function::Handle(Z); | 72 Function& outermost_function = Function::Handle(Z); |
| 72 intptr_t outermost_kernel_offset = -1; | 73 builder_->DiscoverEnclosingElements(Z, function, &outermost_function); |
| 73 intptr_t parent_class_offset = -1; | |
| 74 builder_->DiscoverEnclosingElements(Z, function, &outermost_function, | |
| 75 &outermost_kernel_offset, | |
| 76 &parent_class_offset); | |
| 77 // Use [klass]/[kernel_class] as active class. Type parameters will get | |
| 78 // resolved via [kernel_class] unless we are nested inside a static factory | |
| 79 // in which case we will use [member]. | |
| 80 intptr_t class_type_parameters = 0; | |
| 81 intptr_t class_type_parameters_offset_start = -1; | |
| 82 if (parent_class_offset > 0) { | |
| 83 builder_->GetTypeParameterInfoForClass(parent_class_offset, | |
| 84 &class_type_parameters, | |
| 85 &class_type_parameters_offset_start); | |
| 86 } | |
| 87 ActiveClassScope active_class_scope(&active_class_, class_type_parameters, | |
| 88 class_type_parameters_offset_start, | |
| 89 &klass); | |
| 90 | 74 |
| 91 bool member_is_procedure = false; | 75 ActiveClassScope active_class_scope(&active_class_, &klass); |
| 92 bool is_factory_procedure = false; | 76 ActiveMemberScope active_member(&active_class_, &outermost_function); |
| 93 intptr_t member_type_parameters = 0; | |
| 94 intptr_t member_type_parameters_offset_start = -1; | |
| 95 builder_->GetTypeParameterInfoForPossibleProcedure( | |
| 96 outermost_kernel_offset, &member_is_procedure, &is_factory_procedure, | |
| 97 &member_type_parameters, &member_type_parameters_offset_start); | |
| 98 | |
| 99 ActiveMemberScope active_member(&active_class_, member_is_procedure, | |
| 100 is_factory_procedure, member_type_parameters, | |
| 101 member_type_parameters_offset_start); | |
| 102 | 77 |
| 103 LocalScope* enclosing_scope = NULL; | 78 LocalScope* enclosing_scope = NULL; |
| 104 if (function.IsLocalFunction()) { | 79 if (function.IsLocalFunction()) { |
| 105 enclosing_scope = LocalScope::RestoreOuterScope( | 80 enclosing_scope = LocalScope::RestoreOuterScope( |
| 106 ContextScope::Handle(Z, function.context_scope())); | 81 ContextScope::Handle(Z, function.context_scope())); |
| 107 } | 82 } |
| 108 current_function_scope_ = scope_ = new (Z) LocalScope(enclosing_scope, 0, 0); | 83 current_function_scope_ = scope_ = new (Z) LocalScope(enclosing_scope, 0, 0); |
| 109 scope_->set_begin_token_pos(function.token_pos()); | 84 scope_->set_begin_token_pos(function.token_pos()); |
| 110 scope_->set_end_token_pos(function.end_token_pos()); | 85 scope_->set_end_token_pos(function.end_token_pos()); |
| 111 | 86 |
| 112 // Add function type arguments variable before current context variable. | 87 // Add function type arguments variable before current context variable. |
| 113 if (FLAG_reify_generic_functions && function.IsGeneric()) { | 88 if (FLAG_reify_generic_functions && function.IsGeneric()) { |
| 114 LocalVariable* type_args_var = MakeVariable( | 89 LocalVariable* type_args_var = MakeVariable( |
| 115 TokenPosition::kNoSource, TokenPosition::kNoSource, | 90 TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 116 Symbols::FunctionTypeArgumentsVar(), AbstractType::dynamic_type()); | 91 Symbols::FunctionTypeArgumentsVar(), AbstractType::dynamic_type()); |
| 117 scope_->AddVariable(type_args_var); | 92 scope_->AddVariable(type_args_var); |
| 118 parsed_function_->set_function_type_arguments(type_args_var); | 93 parsed_function_->set_function_type_arguments(type_args_var); |
| 119 } | 94 } |
| 120 | 95 |
| 121 LocalVariable* context_var = parsed_function->current_context_var(); | 96 LocalVariable* context_var = parsed_function->current_context_var(); |
| 122 context_var->set_is_forced_stack(); | 97 context_var->set_is_forced_stack(); |
| 123 scope_->AddVariable(context_var); | 98 scope_->AddVariable(context_var); |
| 124 | 99 |
| 125 parsed_function->SetNodeSequence( | 100 parsed_function->SetNodeSequence( |
| 126 new SequenceNode(TokenPosition::kNoSource, scope_)); | 101 new SequenceNode(TokenPosition::kNoSource, scope_)); |
| 127 | 102 |
| 128 intptr_t parent_offset = -1; | |
| 129 builder_->SetOffset(kernel_offset_); | 103 builder_->SetOffset(kernel_offset_); |
| 130 | 104 |
| 131 FunctionNodeHelper function_node_helper(builder_); | 105 FunctionNodeHelper function_node_helper(builder_); |
| 132 | 106 |
| 133 switch (function.kind()) { | 107 switch (function.kind()) { |
| 134 case RawFunction::kClosureFunction: | 108 case RawFunction::kClosureFunction: |
| 135 case RawFunction::kRegularFunction: | 109 case RawFunction::kRegularFunction: |
| 136 case RawFunction::kGetterFunction: | 110 case RawFunction::kGetterFunction: |
| 137 case RawFunction::kSetterFunction: | 111 case RawFunction::kSetterFunction: |
| 138 case RawFunction::kConstructor: { | 112 case RawFunction::kConstructor: { |
| 139 const Tag tag = builder_->PeekTag(); | 113 const Tag tag = builder_->PeekTag(); |
| 140 parent_offset = builder_->ReadUntilFunctionNode(); | 114 intptr_t parent_offset = builder_->ReadUntilFunctionNode(); |
| 141 function_node_helper.ReadUntilExcluding( | 115 function_node_helper.ReadUntilExcluding( |
| 142 FunctionNodeHelper::kPositionalParameters); | 116 FunctionNodeHelper::kPositionalParameters); |
| 143 current_function_async_marker_ = function_node_helper.async_marker_; | 117 current_function_async_marker_ = function_node_helper.async_marker_; |
| 144 // NOTE: FunctionNode is read further below the if. | 118 // NOTE: FunctionNode is read further below the if. |
| 145 | 119 |
| 146 intptr_t pos = 0; | 120 intptr_t pos = 0; |
| 147 if (function.IsClosureFunction()) { | 121 if (function.IsClosureFunction()) { |
| 148 LocalVariable* variable = MakeVariable( | 122 LocalVariable* variable = MakeVariable( |
| 149 TokenPosition::kNoSource, TokenPosition::kNoSource, | 123 TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 150 Symbols::ClosureParameter(), AbstractType::dynamic_type()); | 124 Symbols::ClosureParameter(), AbstractType::dynamic_type()); |
| (...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 629 intptr_t list_length = builder_->ReadListLength(); // read list length. | 603 intptr_t list_length = builder_->ReadListLength(); // read list length. |
| 630 for (intptr_t i = 0; i < list_length; ++i) { | 604 for (intptr_t i = 0; i < list_length; ++i) { |
| 631 VisitExpression(); // read ith key. | 605 VisitExpression(); // read ith key. |
| 632 VisitExpression(); // read ith value. | 606 VisitExpression(); // read ith value. |
| 633 } | 607 } |
| 634 return; | 608 return; |
| 635 } | 609 } |
| 636 case kFunctionExpression: { | 610 case kFunctionExpression: { |
| 637 intptr_t offset = | 611 intptr_t offset = |
| 638 builder_->ReaderOffset() - 1; // -1 to include tag byte. | 612 builder_->ReaderOffset() - 1; // -1 to include tag byte. |
| 639 HandleLocalFunction(offset); | 613 HandleLocalFunction(offset); // read function node. |
| 640 return; | 614 return; |
| 641 } | 615 } |
| 642 case kLet: { | 616 case kLet: { |
| 643 PositionScope scope(builder_->reader_); | 617 PositionScope scope(builder_->reader_); |
| 644 intptr_t offset = | 618 intptr_t offset = |
| 645 builder_->ReaderOffset() - 1; // -1 to include tag byte. | 619 builder_->ReaderOffset() - 1; // -1 to include tag byte. |
| 646 | 620 |
| 647 EnterScope(offset); | 621 EnterScope(offset); |
| 648 | 622 |
| 649 VisitVariableDeclaration(); // read variable declaration. | 623 VisitVariableDeclaration(); // read variable declaration. |
| (...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1086 // factory constructor function. | 1060 // factory constructor function. |
| 1087 HandleSpecialLoad(&result_->type_arguments_variable, | 1061 HandleSpecialLoad(&result_->type_arguments_variable, |
| 1088 Symbols::TypeArgumentsParameter()); | 1062 Symbols::TypeArgumentsParameter()); |
| 1089 } else { | 1063 } else { |
| 1090 // The type argument vector is stored on the instance object. We therefore | 1064 // The type argument vector is stored on the instance object. We therefore |
| 1091 // need to capture `this`. | 1065 // need to capture `this`. |
| 1092 HandleSpecialLoad(&result_->this_variable, Symbols::This()); | 1066 HandleSpecialLoad(&result_->this_variable, Symbols::This()); |
| 1093 } | 1067 } |
| 1094 | 1068 |
| 1095 builder_->ReadUInt(); // read index for parameter. | 1069 builder_->ReadUInt(); // read index for parameter. |
| 1096 builder_->ReadUInt(); // read list binary offset. | |
| 1097 builder_->ReadUInt(); // read index in list. | |
| 1098 builder_->SkipOptionalDartType(); // read bound bound. | 1070 builder_->SkipOptionalDartType(); // read bound bound. |
| 1099 } | 1071 } |
| 1100 | 1072 |
| 1101 void StreamingScopeBuilder::HandleLocalFunction(intptr_t parent_kernel_offset) { | 1073 void StreamingScopeBuilder::HandleLocalFunction(intptr_t parent_kernel_offset) { |
| 1102 // "Peek" ahead into the function node | 1074 // "Peek" ahead into the function node |
| 1103 intptr_t offset = builder_->ReaderOffset(); | 1075 intptr_t offset = builder_->ReaderOffset(); |
| 1104 | 1076 |
| 1105 FunctionNodeHelper function_node_helper(builder_); | 1077 FunctionNodeHelper function_node_helper(builder_); |
| 1106 function_node_helper.ReadUntilExcluding( | 1078 function_node_helper.ReadUntilExcluding( |
| 1107 FunctionNodeHelper::kPositionalParameters); | 1079 FunctionNodeHelper::kPositionalParameters); |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1562 ClassFinalizer::FinalizeType(*active_class_->klass, signature_type); | 1534 ClassFinalizer::FinalizeType(*active_class_->klass, signature_type); |
| 1563 // Do not refer to signature_function anymore, since it may have been | 1535 // Do not refer to signature_function anymore, since it may have been |
| 1564 // replaced during canonicalization. | 1536 // replaced during canonicalization. |
| 1565 signature_function = Function::null(); | 1537 signature_function = Function::null(); |
| 1566 } | 1538 } |
| 1567 | 1539 |
| 1568 result_ = signature_type.raw(); | 1540 result_ = signature_type.raw(); |
| 1569 } | 1541 } |
| 1570 | 1542 |
| 1571 void StreamingDartTypeTranslator::BuildTypeParameterType() { | 1543 void StreamingDartTypeTranslator::BuildTypeParameterType() { |
| 1572 builder_->ReadUInt(); // read parameter index. | 1544 intptr_t parameter_index = builder_->ReadUInt(); // read parameter index. |
| 1573 intptr_t binary_offset = builder_->ReadUInt(); // read lists binary offset. | 1545 builder_->SkipOptionalDartType(); // read bound. |
| 1574 intptr_t list_index = builder_->ReadUInt(); // read index in list. | |
| 1575 builder_->SkipOptionalDartType(); // read bound. | |
| 1576 | 1546 |
| 1577 ASSERT(binary_offset > 0); | 1547 TypeArguments& class_types = |
|
Dmitry Stefantsov
2017/07/07 09:23:53
It looks like [class_types] is not changed anywher
| |
| 1548 dart::TypeArguments::Handle(Z, active_class_->klass->type_parameters()); | |
| 1549 if (class_types.Length() > parameter_index) { | |
| 1550 // The index of the type parameter in [parameters] is | |
| 1551 // the same index into the `klass->type_parameters()` array. | |
| 1552 result_ ^= class_types.TypeAt(parameter_index); | |
| 1553 return; | |
| 1554 } | |
| 1555 parameter_index -= class_types.Length(); | |
| 1556 | |
| 1557 if (active_class_->MemberIsFactoryProcedure()) { | |
| 1558 // | |
| 1559 // WARNING: This is a little hackish: | |
| 1560 // | |
| 1561 // We have a static factory constructor. The kernel IR gives the factory | |
| 1562 // constructor function it's own type parameters (which are equal in name | |
| 1563 // and number to the ones of the enclosing class). | |
| 1564 // I.e., | |
| 1565 // | |
| 1566 // class A<T> { | |
| 1567 // factory A.x() { return new B<T>(); } | |
| 1568 // } | |
| 1569 // | |
| 1570 // is basically translated to this: | |
| 1571 // | |
| 1572 // class A<T> { | |
| 1573 // static A.x<T'>() { return new B<T'>(); } | |
| 1574 // } | |
| 1575 // | |
| 1576 if (class_types.Length() > parameter_index) { | |
| 1577 result_ ^= class_types.TypeAt(parameter_index); | |
| 1578 return; | |
| 1579 } | |
| 1580 parameter_index -= class_types.Length(); | |
| 1581 } | |
| 1582 | |
| 1583 bool member_is_procedure = active_class_->MemberIsProcedure(); | |
| 1584 intptr_t procedure_type_parameter_count = | |
| 1585 member_is_procedure ? active_class_->MemberTypeParameterCount(Z) : 0; | |
| 1586 if (procedure_type_parameter_count > 0) { | |
| 1587 if (procedure_type_parameter_count > parameter_index) { | |
| 1588 // Here we technically could load the correct one via something like | |
| 1589 // result_ ^= dart::TypeArguments::Handle( | |
| 1590 // Z, active_class_->member->type_parameters()) | |
| 1591 // .TypeAt(parameter_index); | |
| 1592 // but that isn't currently supported elsewhere | |
| 1593 // (FlowGraphBuilder::LoadFunctionTypeArguments()). | |
| 1594 result_ ^= dart::Type::DynamicType(); | |
| 1595 return; | |
| 1596 } | |
| 1597 parameter_index -= procedure_type_parameter_count; | |
| 1598 } | |
| 1578 | 1599 |
| 1579 for (TypeParameterScope* scope = type_parameter_scope_; scope != NULL; | 1600 for (TypeParameterScope* scope = type_parameter_scope_; scope != NULL; |
| 1580 scope = scope->outer()) { | 1601 scope = scope->outer()) { |
| 1581 if (scope->parameters_offset() == binary_offset) { | 1602 if (parameter_index - scope->summed_outer_parameters_count() >= 0) { |
| 1603 if (parameter_index - scope->summed_outer_parameters_count() >= | |
| 1604 scope->parameters_count()) { | |
| 1605 UNREACHABLE(); | |
| 1606 } | |
| 1607 parameter_index -= scope->summed_outer_parameters_count(); | |
| 1582 result_ ^= dart::Type::DynamicType(); | 1608 result_ ^= dart::Type::DynamicType(); |
| 1583 return; | 1609 return; |
| 1584 } | 1610 } |
| 1585 } | 1611 } |
| 1586 | 1612 |
| 1587 if (active_class_->member_is_procedure) { | |
| 1588 if (active_class_->member_type_parameters > 0) { | |
| 1589 // | |
| 1590 // WARNING: This is a little hackish: | |
| 1591 // | |
| 1592 // We have a static factory constructor. The kernel IR gives the factory | |
| 1593 // constructor function it's own type parameters (which are equal in name | |
| 1594 // and number to the ones of the enclosing class). | |
| 1595 // I.e., | |
| 1596 // | |
| 1597 // class A<T> { | |
| 1598 // factory A.x() { return new B<T>(); } | |
| 1599 // } | |
| 1600 // | |
| 1601 // is basically translated to this: | |
| 1602 // | |
| 1603 // class A<T> { | |
| 1604 // static A.x<T'>() { return new B<T'>(); } | |
| 1605 // } | |
| 1606 // | |
| 1607 if (active_class_->member_type_parameters_offset_start == binary_offset) { | |
| 1608 if (active_class_->member_is_factory_procedure) { | |
| 1609 // The index of the type parameter in [parameters] is | |
| 1610 // the same index into the `klass->type_parameters()` array. | |
| 1611 result_ ^= dart::TypeArguments::Handle( | |
| 1612 Z, active_class_->klass->type_parameters()) | |
| 1613 .TypeAt(list_index); | |
| 1614 } else { | |
| 1615 result_ ^= dart::Type::DynamicType(); | |
| 1616 } | |
| 1617 return; | |
| 1618 } | |
| 1619 } | |
| 1620 } | |
| 1621 | |
| 1622 if (active_class_->class_type_parameters_offset_start == binary_offset) { | |
| 1623 // The index of the type parameter in [parameters] is | |
| 1624 // the same index into the `klass->type_parameters()` array. | |
| 1625 result_ ^= | |
| 1626 dart::TypeArguments::Handle(Z, active_class_->klass->type_parameters()) | |
| 1627 .TypeAt(list_index); | |
| 1628 return; | |
| 1629 } | |
| 1630 | |
| 1631 UNREACHABLE(); | 1613 UNREACHABLE(); |
| 1632 } | 1614 } |
| 1633 | 1615 |
| 1634 const TypeArguments& StreamingDartTypeTranslator::BuildTypeArguments( | 1616 const TypeArguments& StreamingDartTypeTranslator::BuildTypeArguments( |
| 1635 intptr_t length) { | 1617 intptr_t length) { |
| 1636 bool only_dynamic = true; | 1618 bool only_dynamic = true; |
| 1637 intptr_t offset = builder_->ReaderOffset(); | 1619 intptr_t offset = builder_->ReaderOffset(); |
| 1638 for (intptr_t i = 0; i < length; ++i) { | 1620 for (intptr_t i = 0; i < length; ++i) { |
| 1639 if (builder_->ReadTag() != kDynamicType) { // Read the ith types tag. | 1621 if (builder_->ReadTag() != kDynamicType) { // Read the ith types tag. |
| 1640 only_dynamic = false; | 1622 only_dynamic = false; |
| (...skipping 819 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2460 script_.set_compile_time_constants(array); | 2442 script_.set_compile_time_constants(array); |
| 2461 } | 2443 } |
| 2462 KernelConstantsMap constants(script_.compile_time_constants()); | 2444 KernelConstantsMap constants(script_.compile_time_constants()); |
| 2463 constants.InsertNewOrGetValue(kernel_offset, value); | 2445 constants.InsertNewOrGetValue(kernel_offset, value); |
| 2464 script_.set_compile_time_constants(constants.Release()); | 2446 script_.set_compile_time_constants(constants.Release()); |
| 2465 } | 2447 } |
| 2466 | 2448 |
| 2467 void StreamingFlowGraphBuilder::DiscoverEnclosingElements( | 2449 void StreamingFlowGraphBuilder::DiscoverEnclosingElements( |
| 2468 Zone* zone, | 2450 Zone* zone, |
| 2469 const Function& function, | 2451 const Function& function, |
| 2470 Function* outermost_function, | 2452 Function* outermost_function) { |
| 2471 intptr_t* outermost_kernel_offset, | |
| 2472 intptr_t* parent_class_offset) { | |
| 2473 // Find out if there is an enclosing kernel class (which will be used to | 2453 // Find out if there is an enclosing kernel class (which will be used to |
| 2474 // resolve type parameters). | 2454 // resolve type parameters). |
| 2475 *outermost_function = function.raw(); | 2455 *outermost_function = function.raw(); |
| 2476 while (outermost_function->parent_function() != Object::null()) { | 2456 while (outermost_function->parent_function() != Object::null()) { |
| 2477 *outermost_function = outermost_function->parent_function(); | 2457 *outermost_function = outermost_function->parent_function(); |
| 2478 } | 2458 } |
| 2479 | |
| 2480 if (outermost_function->kernel_offset() > 0) { | |
| 2481 *outermost_kernel_offset = outermost_function->kernel_offset(); | |
| 2482 *parent_class_offset = GetParentOffset(*outermost_kernel_offset); | |
| 2483 } | |
| 2484 } | |
| 2485 | |
| 2486 intptr_t StreamingFlowGraphBuilder::GetParentOffset(intptr_t offset) { | |
| 2487 AlternativeReadingScope alt(reader_, offset); | |
| 2488 | |
| 2489 Tag tag = PeekTag(); | |
| 2490 switch (tag) { | |
| 2491 case kConstructor: { | |
| 2492 ConstructorHelper constructor_helper(this); | |
| 2493 constructor_helper.ReadUntilIncluding( | |
| 2494 ConstructorHelper::kParentClassBinaryOffset); | |
| 2495 return constructor_helper.parent_class_binary_offset_; | |
| 2496 } | |
| 2497 case kProcedure: { | |
| 2498 ProcedureHelper procedure_helper(this); | |
| 2499 procedure_helper.ReadUntilIncluding( | |
| 2500 ProcedureHelper::kParentClassBinaryOffset); | |
| 2501 return procedure_helper.parent_class_binary_offset_; | |
| 2502 } | |
| 2503 case kField: { | |
| 2504 FieldHelper field_helper(this); | |
| 2505 field_helper.ReadUntilIncluding(FieldHelper::kParentClassBinaryOffset); | |
| 2506 return field_helper.parent_class_binary_offset_; | |
| 2507 } | |
| 2508 default: | |
| 2509 UNIMPLEMENTED(); | |
| 2510 return -1; | |
| 2511 } | |
| 2512 } | |
| 2513 | |
| 2514 void StreamingFlowGraphBuilder::GetTypeParameterInfoForClass( | |
| 2515 intptr_t class_offset, | |
| 2516 intptr_t* type_paremeter_counts, | |
| 2517 intptr_t* type_paremeter_offset) { | |
| 2518 AlternativeReadingScope alt(reader_, class_offset); | |
| 2519 | |
| 2520 ClassHelper class_helper(this); | |
| 2521 class_helper.ReadUntilExcluding(ClassHelper::kTypeParameters); | |
| 2522 *type_paremeter_counts = | |
| 2523 ReadListLength(); // read type_parameters list length. | |
| 2524 *type_paremeter_offset = ReaderOffset(); | |
| 2525 } | |
| 2526 | |
| 2527 void StreamingFlowGraphBuilder::GetTypeParameterInfoForPossibleProcedure( | |
| 2528 intptr_t outermost_kernel_offset, | |
| 2529 bool* member_is_procedure, | |
| 2530 bool* is_factory_procedure, | |
| 2531 intptr_t* member_type_parameters, | |
| 2532 intptr_t* member_type_parameters_offset_start) { | |
| 2533 if (outermost_kernel_offset >= 0) { | |
| 2534 AlternativeReadingScope alt(reader_, outermost_kernel_offset); | |
| 2535 Tag tag = PeekTag(); | |
| 2536 if (tag == kProcedure) { | |
| 2537 *member_is_procedure = true; | |
| 2538 | |
| 2539 ProcedureHelper procedure_helper(this); | |
| 2540 procedure_helper.ReadUntilExcluding(ProcedureHelper::kFunction); | |
| 2541 *is_factory_procedure = procedure_helper.kind_ == Procedure::kFactory; | |
| 2542 if (ReadTag() == kSomething) { | |
| 2543 FunctionNodeHelper function_node_helper(this); | |
| 2544 function_node_helper.ReadUntilExcluding( | |
| 2545 FunctionNodeHelper::kTypeParameters); | |
| 2546 | |
| 2547 // read type_parameters list length. | |
| 2548 intptr_t list_length = ReadListLength(); | |
| 2549 if (list_length > 0) { | |
| 2550 *member_type_parameters = list_length; | |
| 2551 *member_type_parameters_offset_start = ReaderOffset(); | |
| 2552 } | |
| 2553 } | |
| 2554 } | |
| 2555 } | |
| 2556 } | 2459 } |
| 2557 | 2460 |
| 2558 intptr_t StreamingFlowGraphBuilder::ReadUntilFunctionNode() { | 2461 intptr_t StreamingFlowGraphBuilder::ReadUntilFunctionNode() { |
| 2559 const Tag tag = PeekTag(); | 2462 const Tag tag = PeekTag(); |
| 2560 if (tag == kProcedure) { | 2463 if (tag == kProcedure) { |
| 2561 ProcedureHelper procedure_helper(this); | 2464 ProcedureHelper procedure_helper(this); |
| 2562 procedure_helper.ReadUntilExcluding(ProcedureHelper::kFunction); | 2465 procedure_helper.ReadUntilExcluding(ProcedureHelper::kFunction); |
| 2563 if (ReadTag() == kNothing) { // read function node tag. | 2466 if (ReadTag() == kNothing) { // read function node tag. |
| 2564 // Running a procedure without a function node doesn't make sense. | 2467 // Running a procedure without a function node doesn't make sense. |
| 2565 UNREACHABLE(); | 2468 UNREACHABLE(); |
| (...skipping 746 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3312 | 3215 |
| 3313 FlowGraph* StreamingFlowGraphBuilder::BuildGraph(intptr_t kernel_offset) { | 3216 FlowGraph* StreamingFlowGraphBuilder::BuildGraph(intptr_t kernel_offset) { |
| 3314 const Function& function = parsed_function()->function(); | 3217 const Function& function = parsed_function()->function(); |
| 3315 | 3218 |
| 3316 // Setup a [ActiveClassScope] and a [ActiveMemberScope] which will be used | 3219 // Setup a [ActiveClassScope] and a [ActiveMemberScope] which will be used |
| 3317 // e.g. for type translation. | 3220 // e.g. for type translation. |
| 3318 const dart::Class& klass = | 3221 const dart::Class& klass = |
| 3319 dart::Class::Handle(zone_, parsed_function()->function().Owner()); | 3222 dart::Class::Handle(zone_, parsed_function()->function().Owner()); |
| 3320 | 3223 |
| 3321 Function& outermost_function = Function::Handle(Z); | 3224 Function& outermost_function = Function::Handle(Z); |
| 3322 intptr_t outermost_kernel_offset = -1; | 3225 DiscoverEnclosingElements(Z, function, &outermost_function); |
| 3323 intptr_t parent_class_offset = -1; | |
| 3324 DiscoverEnclosingElements(Z, function, &outermost_function, | |
| 3325 &outermost_kernel_offset, &parent_class_offset); | |
| 3326 // Use [klass]/[kernel_class] as active class. Type parameters will get | |
| 3327 // resolved via [kernel_class] unless we are nested inside a static factory | |
| 3328 // in which case we will use [member]. | |
| 3329 intptr_t class_type_parameters = 0; | |
| 3330 intptr_t class_type_parameters_offset_start = -1; | |
| 3331 if (parent_class_offset > 0) { | |
| 3332 GetTypeParameterInfoForClass(parent_class_offset, &class_type_parameters, | |
| 3333 &class_type_parameters_offset_start); | |
| 3334 } | |
| 3335 | 3226 |
| 3336 ActiveClassScope active_class_scope(active_class(), class_type_parameters, | 3227 ActiveClassScope active_class_scope(active_class(), &klass); |
| 3337 class_type_parameters_offset_start, | 3228 ActiveMemberScope active_member(active_class(), &outermost_function); |
| 3338 &klass); | |
| 3339 | |
| 3340 bool member_is_procedure = false; | |
| 3341 bool is_factory_procedure = false; | |
| 3342 intptr_t member_type_parameters = 0; | |
| 3343 intptr_t member_type_parameters_offset_start = -1; | |
| 3344 GetTypeParameterInfoForPossibleProcedure( | |
| 3345 outermost_kernel_offset, &member_is_procedure, &is_factory_procedure, | |
| 3346 &member_type_parameters, &member_type_parameters_offset_start); | |
| 3347 | |
| 3348 ActiveMemberScope active_member(active_class(), member_is_procedure, | |
| 3349 is_factory_procedure, member_type_parameters, | |
| 3350 member_type_parameters_offset_start); | |
| 3351 | 3229 |
| 3352 // The IR builder will create its own local variables and scopes, and it | 3230 // The IR builder will create its own local variables and scopes, and it |
| 3353 // will not need an AST. The code generator will assume that there is a | 3231 // will not need an AST. The code generator will assume that there is a |
| 3354 // local variable stack slot allocated for the current context and (I | 3232 // local variable stack slot allocated for the current context and (I |
| 3355 // think) that the runtime will expect it to be at a fixed offset which | 3233 // think) that the runtime will expect it to be at a fixed offset which |
| 3356 // requires allocating an unused expression temporary variable. | 3234 // requires allocating an unused expression temporary variable. |
| 3357 set_scopes(parsed_function()->EnsureKernelScopes()); | 3235 set_scopes(parsed_function()->EnsureKernelScopes()); |
| 3358 | 3236 |
| 3359 SetOffset(kernel_offset); | 3237 SetOffset(kernel_offset); |
| 3360 | 3238 |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3671 SkipInterfaceType(true); | 3549 SkipInterfaceType(true); |
| 3672 return; | 3550 return; |
| 3673 case kFunctionType: | 3551 case kFunctionType: |
| 3674 SkipFunctionType(false); | 3552 SkipFunctionType(false); |
| 3675 return; | 3553 return; |
| 3676 case kSimpleFunctionType: | 3554 case kSimpleFunctionType: |
| 3677 SkipFunctionType(true); | 3555 SkipFunctionType(true); |
| 3678 return; | 3556 return; |
| 3679 case kTypeParameterType: | 3557 case kTypeParameterType: |
| 3680 ReadUInt(); // read index for parameter. | 3558 ReadUInt(); // read index for parameter. |
| 3681 ReadUInt(); // read list binary offset. | |
| 3682 ReadUInt(); // read index in list. | |
| 3683 SkipOptionalDartType(); // read bound bound. | 3559 SkipOptionalDartType(); // read bound bound. |
| 3684 return; | 3560 return; |
| 3685 default: | 3561 default: |
| 3686 UNREACHABLE(); | 3562 UNREACHABLE(); |
| 3687 } | 3563 } |
| 3688 } | 3564 } |
| 3689 | 3565 |
| 3690 void StreamingFlowGraphBuilder::SkipOptionalDartType() { | 3566 void StreamingFlowGraphBuilder::SkipOptionalDartType() { |
| 3691 Tag tag = ReadTag(); // read tag. | 3567 Tag tag = ReadTag(); // read tag. |
| 3692 if (tag == kNothing) { | 3568 if (tag == kNothing) { |
| (...skipping 3376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7069 } | 6945 } |
| 7070 } | 6946 } |
| 7071 | 6947 |
| 7072 return Array::Handle(Array::null()); | 6948 return Array::Handle(Array::null()); |
| 7073 } | 6949 } |
| 7074 | 6950 |
| 7075 } // namespace kernel | 6951 } // namespace kernel |
| 7076 } // namespace dart | 6952 } // namespace dart |
| 7077 | 6953 |
| 7078 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 6954 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
| OLD | NEW |