Index: runtime/vm/kernel_binary_flowgraph.cc |
diff --git a/runtime/vm/kernel_binary_flowgraph.cc b/runtime/vm/kernel_binary_flowgraph.cc |
index 54d6d2e480e4d1162fd29edc2088944cd9a1efde..3f0d127a76aee16c8a0f227c19cfcb577102f01c 100644 |
--- a/runtime/vm/kernel_binary_flowgraph.cc |
+++ b/runtime/vm/kernel_binary_flowgraph.cc |
@@ -67,37 +67,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()) { |
@@ -124,7 +99,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_); |
@@ -138,7 +112,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_; |
@@ -638,7 +612,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: { |
@@ -1127,8 +1101,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. |
} |
@@ -1608,23 +1580,21 @@ 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); |
- |
- for (TypeParameterScope* scope = type_parameter_scope_; scope != NULL; |
- scope = scope->outer()) { |
- if (scope->parameters_offset() == binary_offset) { |
- result_ ^= dart::Type::DynamicType(); |
- return; |
- } |
+ const TypeArguments& class_types = |
+ dart::TypeArguments::Handle(Z, active_class_->klass->type_parameters()); |
+ if (parameter_index < class_types.Length()) { |
+ // 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(); |
- if (active_class_->member_is_procedure) { |
- if (active_class_->member_type_parameters > 0) { |
+ if (active_class_->HasMember()) { |
+ if (active_class_->MemberIsFactoryProcedure()) { |
// |
// WARNING: This is a little hackish: |
// |
@@ -1643,31 +1613,40 @@ void StreamingDartTypeTranslator::BuildTypeParameterType() { |
// 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(); |
- } |
+ if (class_types.Length() > parameter_index) { |
+ result_ ^= class_types.TypeAt(parameter_index); |
+ return; |
+ } |
+ parameter_index -= class_types.Length(); |
+ } |
+ |
+ intptr_t procedure_type_parameter_count = |
+ active_class_->MemberIsProcedure() |
+ ? 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); |
+ if (type_parameter_scope_ != NULL && parameter_index >= 0 && |
+ parameter_index < type_parameter_scope_->outer_parameter_count() + |
+ type_parameter_scope_->parameters_count()) { |
+ result_ ^= dart::Type::DynamicType(); |
return; |
} |
- UNREACHABLE(); |
+ H.ReportError("Unexpected input. Please report this at dartbug.com."); |
} |
const TypeArguments& StreamingDartTypeTranslator::BuildTypeArguments( |
@@ -2506,92 +2485,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() { |
@@ -3405,35 +3305,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 |
@@ -3779,8 +3654,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: |