Chromium Code Reviews| Index: runtime/vm/kernel_binary_flowgraph.cc |
| diff --git a/runtime/vm/kernel_binary_flowgraph.cc b/runtime/vm/kernel_binary_flowgraph.cc |
| index b862e439e1aa037c97ac4258be2fd3dc236743e0..65edcd840c5bdb33bb2eb64d09065c0c77d43a91 100644 |
| --- a/runtime/vm/kernel_binary_flowgraph.cc |
| +++ b/runtime/vm/kernel_binary_flowgraph.cc |
| @@ -68,37 +68,12 @@ ScopeBuildingResult* StreamingScopeBuilder::BuildScopes() { |
| // e.g. for type translation. |
| const dart::Class& klass = |
| dart::Class::Handle(zone_, parsed_function_->function().Owner()); |
| + |
| Function& outermost_function = Function::Handle(Z); |
| - intptr_t outermost_kernel_offset = -1; |
| - intptr_t parent_class_offset = -1; |
| - builder_->DiscoverEnclosingElements(Z, function, &outermost_function, |
| - &outermost_kernel_offset, |
| - &parent_class_offset); |
| - // Use [klass]/[kernel_class] as active class. Type parameters will get |
| - // resolved via [kernel_class] unless we are nested inside a static factory |
| - // in which case we will use [member]. |
| - intptr_t class_type_parameters = 0; |
| - intptr_t class_type_parameters_offset_start = -1; |
| - if (parent_class_offset > 0) { |
| - builder_->GetTypeParameterInfoForClass(parent_class_offset, |
| - &class_type_parameters, |
| - &class_type_parameters_offset_start); |
| - } |
| - ActiveClassScope active_class_scope(&active_class_, class_type_parameters, |
| - class_type_parameters_offset_start, |
| - &klass); |
| - |
| - bool member_is_procedure = false; |
| - bool is_factory_procedure = false; |
| - intptr_t member_type_parameters = 0; |
| - intptr_t member_type_parameters_offset_start = -1; |
| - builder_->GetTypeParameterInfoForPossibleProcedure( |
| - outermost_kernel_offset, &member_is_procedure, &is_factory_procedure, |
| - &member_type_parameters, &member_type_parameters_offset_start); |
| - |
| - ActiveMemberScope active_member(&active_class_, member_is_procedure, |
| - is_factory_procedure, member_type_parameters, |
| - member_type_parameters_offset_start); |
| + builder_->DiscoverEnclosingElements(Z, function, &outermost_function); |
| + |
| + ActiveClassScope active_class_scope(&active_class_, &klass); |
| + ActiveMemberScope active_member(&active_class_, &outermost_function); |
| LocalScope* enclosing_scope = NULL; |
| if (function.IsLocalFunction()) { |
| @@ -125,7 +100,6 @@ ScopeBuildingResult* StreamingScopeBuilder::BuildScopes() { |
| parsed_function->SetNodeSequence( |
| new SequenceNode(TokenPosition::kNoSource, scope_)); |
| - intptr_t parent_offset = -1; |
| builder_->SetOffset(kernel_offset_); |
| FunctionNodeHelper function_node_helper(builder_); |
| @@ -137,7 +111,7 @@ ScopeBuildingResult* StreamingScopeBuilder::BuildScopes() { |
| case RawFunction::kSetterFunction: |
| case RawFunction::kConstructor: { |
| const Tag tag = builder_->PeekTag(); |
| - parent_offset = builder_->ReadUntilFunctionNode(); |
| + intptr_t parent_offset = builder_->ReadUntilFunctionNode(); |
| function_node_helper.ReadUntilExcluding( |
| FunctionNodeHelper::kPositionalParameters); |
| current_function_async_marker_ = function_node_helper.async_marker_; |
| @@ -636,7 +610,7 @@ void StreamingScopeBuilder::VisitExpression() { |
| case kFunctionExpression: { |
| intptr_t offset = |
| builder_->ReaderOffset() - 1; // -1 to include tag byte. |
| - HandleLocalFunction(offset); |
| + HandleLocalFunction(offset); // read function node. |
| return; |
| } |
| case kLet: { |
| @@ -1093,8 +1067,6 @@ void StreamingScopeBuilder::VisitTypeParameterType() { |
| } |
| builder_->ReadUInt(); // read index for parameter. |
| - builder_->ReadUInt(); // read list binary offset. |
| - builder_->ReadUInt(); // read index in list. |
| builder_->SkipOptionalDartType(); // read bound bound. |
| } |
| @@ -1569,63 +1541,73 @@ void StreamingDartTypeTranslator::BuildFunctionType(bool simple) { |
| } |
| void StreamingDartTypeTranslator::BuildTypeParameterType() { |
| - builder_->ReadUInt(); // read parameter index. |
| - intptr_t binary_offset = builder_->ReadUInt(); // read lists binary offset. |
| - intptr_t list_index = builder_->ReadUInt(); // read index in list. |
| - builder_->SkipOptionalDartType(); // read bound. |
| + intptr_t parameter_index = builder_->ReadUInt(); // read parameter index. |
| + builder_->SkipOptionalDartType(); // read bound. |
| - ASSERT(binary_offset > 0); |
| + TypeArguments& class_types = |
|
Dmitry Stefantsov
2017/07/07 09:23:53
It looks like [class_types] is not changed anywher
|
| + dart::TypeArguments::Handle(Z, active_class_->klass->type_parameters()); |
| + if (class_types.Length() > parameter_index) { |
| + // The index of the type parameter in [parameters] is |
| + // the same index into the `klass->type_parameters()` array. |
| + result_ ^= class_types.TypeAt(parameter_index); |
| + return; |
| + } |
| + parameter_index -= class_types.Length(); |
| - for (TypeParameterScope* scope = type_parameter_scope_; scope != NULL; |
| - scope = scope->outer()) { |
| - if (scope->parameters_offset() == binary_offset) { |
| - result_ ^= dart::Type::DynamicType(); |
| + if (active_class_->MemberIsFactoryProcedure()) { |
| + // |
| + // WARNING: This is a little hackish: |
| + // |
| + // We have a static factory constructor. The kernel IR gives the factory |
| + // constructor function it's own type parameters (which are equal in name |
| + // and number to the ones of the enclosing class). |
| + // I.e., |
| + // |
| + // class A<T> { |
| + // factory A.x() { return new B<T>(); } |
| + // } |
| + // |
| + // is basically translated to this: |
| + // |
| + // class A<T> { |
| + // static A.x<T'>() { return new B<T'>(); } |
| + // } |
| + // |
| + if (class_types.Length() > parameter_index) { |
| + result_ ^= class_types.TypeAt(parameter_index); |
| return; |
| } |
| + parameter_index -= class_types.Length(); |
| } |
| - if (active_class_->member_is_procedure) { |
| - if (active_class_->member_type_parameters > 0) { |
| - // |
| - // WARNING: This is a little hackish: |
| - // |
| - // We have a static factory constructor. The kernel IR gives the factory |
| - // constructor function it's own type parameters (which are equal in name |
| - // and number to the ones of the enclosing class). |
| - // I.e., |
| - // |
| - // class A<T> { |
| - // factory A.x() { return new B<T>(); } |
| - // } |
| - // |
| - // is basically translated to this: |
| - // |
| - // class A<T> { |
| - // static A.x<T'>() { return new B<T'>(); } |
| - // } |
| - // |
| - if (active_class_->member_type_parameters_offset_start == binary_offset) { |
| - if (active_class_->member_is_factory_procedure) { |
| - // The index of the type parameter in [parameters] is |
| - // the same index into the `klass->type_parameters()` array. |
| - result_ ^= dart::TypeArguments::Handle( |
| - Z, active_class_->klass->type_parameters()) |
| - .TypeAt(list_index); |
| - } else { |
| - result_ ^= dart::Type::DynamicType(); |
| - } |
| - return; |
| - } |
| + bool member_is_procedure = active_class_->MemberIsProcedure(); |
| + intptr_t procedure_type_parameter_count = |
| + member_is_procedure ? active_class_->MemberTypeParameterCount(Z) : 0; |
| + if (procedure_type_parameter_count > 0) { |
| + if (procedure_type_parameter_count > parameter_index) { |
| + // Here we technically could load the correct one via something like |
| + // result_ ^= dart::TypeArguments::Handle( |
| + // Z, active_class_->member->type_parameters()) |
| + // .TypeAt(parameter_index); |
| + // but that isn't currently supported elsewhere |
| + // (FlowGraphBuilder::LoadFunctionTypeArguments()). |
| + result_ ^= dart::Type::DynamicType(); |
| + return; |
| } |
| + parameter_index -= procedure_type_parameter_count; |
| } |
| - if (active_class_->class_type_parameters_offset_start == binary_offset) { |
| - // The index of the type parameter in [parameters] is |
| - // the same index into the `klass->type_parameters()` array. |
| - result_ ^= |
| - dart::TypeArguments::Handle(Z, active_class_->klass->type_parameters()) |
| - .TypeAt(list_index); |
| - return; |
| + for (TypeParameterScope* scope = type_parameter_scope_; scope != NULL; |
| + scope = scope->outer()) { |
| + if (parameter_index - scope->summed_outer_parameters_count() >= 0) { |
| + if (parameter_index - scope->summed_outer_parameters_count() >= |
| + scope->parameters_count()) { |
| + UNREACHABLE(); |
| + } |
| + parameter_index -= scope->summed_outer_parameters_count(); |
| + result_ ^= dart::Type::DynamicType(); |
| + return; |
| + } |
| } |
| UNREACHABLE(); |
| @@ -2467,92 +2449,13 @@ void StreamingConstantEvaluator::CacheConstantValue(intptr_t kernel_offset, |
| void StreamingFlowGraphBuilder::DiscoverEnclosingElements( |
| Zone* zone, |
| const Function& function, |
| - Function* outermost_function, |
| - intptr_t* outermost_kernel_offset, |
| - intptr_t* parent_class_offset) { |
| + Function* outermost_function) { |
| // Find out if there is an enclosing kernel class (which will be used to |
| // resolve type parameters). |
| *outermost_function = function.raw(); |
| while (outermost_function->parent_function() != Object::null()) { |
| *outermost_function = outermost_function->parent_function(); |
| } |
| - |
| - if (outermost_function->kernel_offset() > 0) { |
| - *outermost_kernel_offset = outermost_function->kernel_offset(); |
| - *parent_class_offset = GetParentOffset(*outermost_kernel_offset); |
| - } |
| -} |
| - |
| -intptr_t StreamingFlowGraphBuilder::GetParentOffset(intptr_t offset) { |
| - AlternativeReadingScope alt(reader_, offset); |
| - |
| - Tag tag = PeekTag(); |
| - switch (tag) { |
| - case kConstructor: { |
| - ConstructorHelper constructor_helper(this); |
| - constructor_helper.ReadUntilIncluding( |
| - ConstructorHelper::kParentClassBinaryOffset); |
| - return constructor_helper.parent_class_binary_offset_; |
| - } |
| - case kProcedure: { |
| - ProcedureHelper procedure_helper(this); |
| - procedure_helper.ReadUntilIncluding( |
| - ProcedureHelper::kParentClassBinaryOffset); |
| - return procedure_helper.parent_class_binary_offset_; |
| - } |
| - case kField: { |
| - FieldHelper field_helper(this); |
| - field_helper.ReadUntilIncluding(FieldHelper::kParentClassBinaryOffset); |
| - return field_helper.parent_class_binary_offset_; |
| - } |
| - default: |
| - UNIMPLEMENTED(); |
| - return -1; |
| - } |
| -} |
| - |
| -void StreamingFlowGraphBuilder::GetTypeParameterInfoForClass( |
| - intptr_t class_offset, |
| - intptr_t* type_paremeter_counts, |
| - intptr_t* type_paremeter_offset) { |
| - AlternativeReadingScope alt(reader_, class_offset); |
| - |
| - ClassHelper class_helper(this); |
| - class_helper.ReadUntilExcluding(ClassHelper::kTypeParameters); |
| - *type_paremeter_counts = |
| - ReadListLength(); // read type_parameters list length. |
| - *type_paremeter_offset = ReaderOffset(); |
| -} |
| - |
| -void StreamingFlowGraphBuilder::GetTypeParameterInfoForPossibleProcedure( |
| - intptr_t outermost_kernel_offset, |
| - bool* member_is_procedure, |
| - bool* is_factory_procedure, |
| - intptr_t* member_type_parameters, |
| - intptr_t* member_type_parameters_offset_start) { |
| - if (outermost_kernel_offset >= 0) { |
| - AlternativeReadingScope alt(reader_, outermost_kernel_offset); |
| - Tag tag = PeekTag(); |
| - if (tag == kProcedure) { |
| - *member_is_procedure = true; |
| - |
| - ProcedureHelper procedure_helper(this); |
| - procedure_helper.ReadUntilExcluding(ProcedureHelper::kFunction); |
| - *is_factory_procedure = procedure_helper.kind_ == Procedure::kFactory; |
| - if (ReadTag() == kSomething) { |
| - FunctionNodeHelper function_node_helper(this); |
| - function_node_helper.ReadUntilExcluding( |
| - FunctionNodeHelper::kTypeParameters); |
| - |
| - // read type_parameters list length. |
| - intptr_t list_length = ReadListLength(); |
| - if (list_length > 0) { |
| - *member_type_parameters = list_length; |
| - *member_type_parameters_offset_start = ReaderOffset(); |
| - } |
| - } |
| - } |
| - } |
| } |
| intptr_t StreamingFlowGraphBuilder::ReadUntilFunctionNode() { |
| @@ -3319,35 +3222,10 @@ FlowGraph* StreamingFlowGraphBuilder::BuildGraph(intptr_t kernel_offset) { |
| dart::Class::Handle(zone_, parsed_function()->function().Owner()); |
| Function& outermost_function = Function::Handle(Z); |
| - intptr_t outermost_kernel_offset = -1; |
| - intptr_t parent_class_offset = -1; |
| - DiscoverEnclosingElements(Z, function, &outermost_function, |
| - &outermost_kernel_offset, &parent_class_offset); |
| - // Use [klass]/[kernel_class] as active class. Type parameters will get |
| - // resolved via [kernel_class] unless we are nested inside a static factory |
| - // in which case we will use [member]. |
| - intptr_t class_type_parameters = 0; |
| - intptr_t class_type_parameters_offset_start = -1; |
| - if (parent_class_offset > 0) { |
| - GetTypeParameterInfoForClass(parent_class_offset, &class_type_parameters, |
| - &class_type_parameters_offset_start); |
| - } |
| - |
| - ActiveClassScope active_class_scope(active_class(), class_type_parameters, |
| - class_type_parameters_offset_start, |
| - &klass); |
| - |
| - bool member_is_procedure = false; |
| - bool is_factory_procedure = false; |
| - intptr_t member_type_parameters = 0; |
| - intptr_t member_type_parameters_offset_start = -1; |
| - GetTypeParameterInfoForPossibleProcedure( |
| - outermost_kernel_offset, &member_is_procedure, &is_factory_procedure, |
| - &member_type_parameters, &member_type_parameters_offset_start); |
| - |
| - ActiveMemberScope active_member(active_class(), member_is_procedure, |
| - is_factory_procedure, member_type_parameters, |
| - member_type_parameters_offset_start); |
| + DiscoverEnclosingElements(Z, function, &outermost_function); |
| + |
| + ActiveClassScope active_class_scope(active_class(), &klass); |
| + ActiveMemberScope active_member(active_class(), &outermost_function); |
| // The IR builder will create its own local variables and scopes, and it |
| // will not need an AST. The code generator will assume that there is a |
| @@ -3678,8 +3556,6 @@ void StreamingFlowGraphBuilder::SkipDartType() { |
| return; |
| case kTypeParameterType: |
| ReadUInt(); // read index for parameter. |
| - ReadUInt(); // read list binary offset. |
| - ReadUInt(); // read index in list. |
| SkipOptionalDartType(); // read bound bound. |
| return; |
| default: |