Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(628)

Unified Diff: runtime/vm/parser.cc

Issue 2818273002: Remove parent_level field of function type parameters. (Closed)
Patch Set: address comments Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/precompiler.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/parser.cc
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 72f078e230c2e0d2ebd48d395761846368e917e4..5a00eed55abd78bcab906aab20fb82157e5c0c77 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -1181,16 +1181,10 @@ void Parser::ParseFunction(ParsedFunction* parsed_function) {
parsed_function->set_instantiator(instantiator);
}
}
- if (FLAG_generic_method_semantics && parser.current_function().IsGeneric()) {
- const String* variable_name = &Symbols::FunctionInstantiatorVar();
- const bool kTestOnly = true;
- LocalVariable* instantiator =
- node_sequence->scope()->LookupVariable(*variable_name, kTestOnly);
- ASSERT(instantiator != NULL);
- parsed_function->set_function_instantiator(instantiator);
- // Function instantiator variables of parent generic functions, if any, are
- // captured and accessible via the context.
- }
+ // ParseFunc has recorded the generic function type arguments variable.
+ ASSERT(!FLAG_generic_method_semantics ||
+ !parser.current_function().IsGeneric() ||
+ (parsed_function->function_type_arguments() != NULL));
}
@@ -3471,11 +3465,23 @@ SequenceNode* Parser::ParseFunc(const Function& func, bool check_semicolon) {
OpenFunctionBlock(func); // Build local scope for function.
if (FLAG_generic_method_semantics && func.IsGeneric()) {
- // Insert function instantiator variable to scope.
- LocalVariable* function_instantiator = new (Z) LocalVariable(
+ // Lookup function type arguments variable in parent function scope, if any.
+ if (func.HasGenericParent()) {
+ const String* variable_name = &Symbols::FunctionTypeArgumentsVar();
+ LocalVariable* parent_type_arguments =
+ current_block_->scope->LookupVariable(*variable_name, true);
+ ASSERT(parent_type_arguments != NULL);
+ // TODO(regis): It may be too early to capture parent_type_arguments here.
+ // In case it is never used, we could save capturing and concatenating.
+ current_block_->scope->CaptureVariable(parent_type_arguments);
+ parsed_function_->set_parent_type_arguments(parent_type_arguments);
+ }
+ // Insert function type arguments variable to scope.
+ LocalVariable* function_type_arguments = new (Z) LocalVariable(
TokenPosition::kNoSource, TokenPosition::kNoSource,
- Symbols::FunctionInstantiatorVar(), Object::dynamic_type());
- current_block_->scope->AddVariable(function_instantiator);
+ Symbols::FunctionTypeArgumentsVar(), Object::dynamic_type());
+ current_block_->scope->AddVariable(function_type_arguments);
+ parsed_function_->set_function_type_arguments(function_type_arguments);
}
ParamList params;
@@ -3638,7 +3644,7 @@ SequenceNode* Parser::ParseFunc(const Function& func, bool check_semicolon) {
// captured if type checks are enabled, because they may access it to
// instantiate types.
// If any enclosing parent of the function being parsed is generic, capture
- // their function instantiators.
+ // their function type arguments.
CaptureAllInstantiators();
}
@@ -5534,13 +5540,12 @@ void Parser::ParseTypeParameters(bool parameterizing_class) {
} else {
type_parameter_bound = I->object_store()->object_type();
}
+ // Note that we cannot yet calculate the final index of a function type
+ // parameter, because we may not have parsed the parent function yet.
type_parameter = TypeParameter::New(
parameterizing_class ? current_class() : Class::Handle(Z),
parameterizing_class ? Function::Handle(Z) : innermost_function(),
- index, 0, type_parameter_name, type_parameter_bound, declaration_pos);
- if (!parameterizing_class) {
- type_parameter.SetIsFinalized();
- }
+ index, type_parameter_name, type_parameter_bound, declaration_pos);
type_parameters_array.Add(
&AbstractType::ZoneHandle(Z, type_parameter.raw()));
if (FLAG_enable_mirrors && metadata_pos.IsReal()) {
@@ -7734,35 +7739,15 @@ void Parser::CaptureInstantiator() {
}
-void Parser::CaptureFunctionInstantiators() {
+void Parser::CaptureFunctionTypeArguments() {
ASSERT(InGenericFunctionScope());
ASSERT(FunctionLevel() > 0);
if (!FLAG_generic_method_semantics) {
return;
}
- // Capture function instantiators starting at parent of innermost function.
- intptr_t variable_function_level = FunctionLevel() - 1;
- const String* variable_name = &Symbols::FunctionInstantiatorVar();
- LocalScope* scope = current_block_->scope;
- do {
- while (scope->function_level() > variable_function_level) {
- scope = scope->parent();
- }
- // Function instantiator is in top scope at that function level.
- LocalScope* parent_scope = scope->parent();
- while ((parent_scope != NULL) &&
- (parent_scope->function_level() == scope->function_level())) {
- scope = parent_scope;
- parent_scope = scope->parent();
- }
- LocalVariable* function_instantiator_var =
- scope->LookupVariable(*variable_name, true);
- if (function_instantiator_var != NULL) {
- current_block_->scope->CaptureVariable(function_instantiator_var);
- }
- scope = scope->parent();
- variable_function_level--;
- } while (variable_function_level >= 0);
+ const String* variable_name = &Symbols::FunctionTypeArgumentsVar();
+ current_block_->scope->CaptureVariable(
+ current_block_->scope->LookupVariable(*variable_name, true));
}
@@ -7770,8 +7755,8 @@ void Parser::CaptureAllInstantiators() {
if (IsInstantiatorRequired()) {
CaptureInstantiator();
}
- if (AreFunctionInstantiatorsRequired()) {
- CaptureFunctionInstantiators();
+ if (innermost_function().HasGenericParent()) {
+ CaptureFunctionTypeArguments();
}
}
@@ -8028,14 +8013,6 @@ AstNode* Parser::ParseFunctionStatement(bool is_literal) {
}
}
- if (!found_func && !result_type.IsFinalized()) {
- // Now that type parameters are declared, the result type can be resolved
- // and finalized.
- ResolveType(&result_type);
- result_type = CanonicalizeType(result_type);
- function.set_result_type(result_type);
- }
-
CheckToken(Token::kLPAREN);
// The function type needs to be finalized at compile time, since the closure
@@ -8082,11 +8059,12 @@ AstNode* Parser::ParseFunctionStatement(bool is_literal) {
// variables of this function's scope that are referenced by the local
// function (and its inner nested functions) will be marked as captured.
- ASSERT(AbstractType::Handle(Z, function.result_type()).IsResolved());
+ ResolveType(&result_type); // Parameter types are resolved in ParseFunc.
+ function.set_result_type(result_type);
statements = Parser::ParseFunc(function, !is_literal);
INC_STAT(thread(), num_functions_parsed, 1);
- // Now that the local function has formal parameters, lookup the signature
+ // Now that the local function has formal parameters, finalize its signature
signature_type = function.SignatureType();
signature_type ^= CanonicalizeType(signature_type);
function.SetSignatureType(signature_type);
@@ -11923,9 +11901,9 @@ AstNode* Parser::LoadTypeParameter(PrimaryNode* primary) {
Type& type = Type::ZoneHandle(Z, Type::DynamicType());
return new (Z) TypeNode(primary_pos, type);
}
- if (type_parameter.parent_level() > 0) {
- // Make sure that the function instantiators are captured.
- CaptureFunctionInstantiators();
+ if (FunctionLevel() > 0) {
+ // Make sure that the parent function type arguments are captured.
+ CaptureFunctionTypeArguments();
}
}
ASSERT(type_parameter.IsFinalized());
@@ -12429,7 +12407,6 @@ void Parser::ResolveType(AbstractType* type) {
return;
}
if (FLAG_generic_method_semantics) {
- ASSERT(type_parameter.IsFinalized());
ASSERT(!type_parameter.IsMalformed());
*type = type_parameter.raw();
} else {
@@ -12567,19 +12544,6 @@ bool Parser::IsInstantiatorRequired() const {
}
-bool Parser::AreFunctionInstantiatorsRequired() const {
- ASSERT(!innermost_function().IsNull());
- Function& parent = Function::Handle(innermost_function().parent_function());
- while (!parent.IsNull()) {
- if (parent.IsGeneric()) {
- return true;
- }
- parent = parent.parent_function();
- }
- return false;
-}
-
-
bool Parser::InGenericFunctionScope() const {
if (!innermost_function().IsNull()) {
// With one more free tag bit in Function, we could cache this information.
@@ -13750,7 +13714,7 @@ AstNode* Parser::ParseMapLiteral(TokenPosition type_pos,
ASSERT(!factory_method.IsNull());
if (!map_type_arguments.IsNull() && !map_type_arguments.IsInstantiated() &&
(FunctionLevel() > 0)) {
- // Make sure that the instantiator is captured.
+ // Make sure that the instantiators are captured.
CaptureAllInstantiators();
}
TypeArguments& factory_type_args =
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/precompiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698