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

Unified Diff: src/ast/scopes.cc

Issue 2352593002: Preparse inner functions (new try) (Closed)
Patch Set: add comment Created 4 years, 3 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 | « src/ast/scopes.h ('k') | src/flag-definitions.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ast/scopes.cc
diff --git a/src/ast/scopes.cc b/src/ast/scopes.cc
index b6ae337877ca8368a03a90364f6b205d0775b771..8d23875ab6bca368251b9dd13d2172e8291a571d 100644
--- a/src/ast/scopes.cc
+++ b/src/ast/scopes.cc
@@ -1073,12 +1073,14 @@ void DeclarationScope::AllocateVariables(ParseInfo* info, AnalyzeMode mode) {
}
}
-bool Scope::AllowsLazyParsing() const {
- // If we are inside a block scope, we must parse eagerly to find out how
- // to allocate variables on the block scope. At this point, declarations may
- // not have yet been parsed.
+bool Scope::AllowsLazyParsingWithoutUnresolvedVariables() const {
+ // If we are inside a block scope, we must find unresolved variables in the
+ // inner scopes to find out how to allocate variables on the block scope. At
+ // this point, declarations may not have yet been parsed.
for (const Scope* s = this; s != nullptr; s = s->outer_scope_) {
if (s->is_block_scope()) return false;
+ // TODO(marja): Refactor parsing modes: also add s->is_function_scope()
+ // here.
}
return true;
}
@@ -1178,7 +1180,7 @@ Scope* Scope::GetOuterScopeWithContext() {
Handle<StringSet> DeclarationScope::CollectNonLocals(
ParseInfo* info, Handle<StringSet> non_locals) {
- VariableProxy* free_variables = FetchFreeVariables(this, info);
+ VariableProxy* free_variables = FetchFreeVariables(this, true, info);
for (VariableProxy* proxy = free_variables; proxy != nullptr;
proxy = proxy->next_unresolved()) {
non_locals = StringSet::Add(non_locals, proxy->name());
@@ -1191,8 +1193,9 @@ void DeclarationScope::AnalyzePartially(DeclarationScope* migrate_to,
// Try to resolve unresolved variables for this Scope and migrate those which
// cannot be resolved inside. It doesn't make sense to try to resolve them in
// the outer Scopes here, because they are incomplete.
- for (VariableProxy* proxy = FetchFreeVariables(this); proxy != nullptr;
- proxy = proxy->next_unresolved()) {
+ for (VariableProxy* proxy =
+ FetchFreeVariables(this, !FLAG_lazy_inner_functions);
+ proxy != nullptr; proxy = proxy->next_unresolved()) {
DCHECK(!proxy->is_resolved());
VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy);
migrate_to->AddUnresolved(copy);
@@ -1515,6 +1518,29 @@ void Scope::ResolveVariable(ParseInfo* info, VariableProxy* proxy) {
DCHECK(!proxy->is_resolved());
Variable* var = LookupRecursive(proxy, nullptr);
ResolveTo(info, proxy, var);
+
+ if (FLAG_lazy_inner_functions) {
+ if (info != nullptr && info->is_native()) return;
+ // Pessimistically force context allocation for all variables to which inner
+ // scope variables could potentially resolve to.
+ Scope* scope = GetClosureScope()->outer_scope_;
+ while (scope != nullptr && scope->scope_info_.is_null()) {
+ var = scope->LookupLocal(proxy->raw_name());
+ if (var != nullptr) {
+ // Since we don't lazy parse inner arrow functions, inner functions
+ // cannot refer to the outer "this".
+ if (!var->is_dynamic() && !var->is_this() &&
+ !var->has_forced_context_allocation()) {
+ var->ForceContextAllocation();
+ var->set_is_used();
+ // We don't know what the (potentially lazy parsed) inner function
+ // does with the variable; pessimistically assume that it's assigned.
+ var->set_maybe_assigned();
+ }
+ }
+ scope = scope->outer_scope_;
+ }
+ }
}
void Scope::ResolveTo(ParseInfo* info, VariableProxy* proxy, Variable* var) {
@@ -1560,13 +1586,16 @@ void Scope::ResolveVariablesRecursively(ParseInfo* info) {
}
VariableProxy* Scope::FetchFreeVariables(DeclarationScope* max_outer_scope,
- ParseInfo* info,
+ bool try_to_resolve, ParseInfo* info,
VariableProxy* stack) {
for (VariableProxy *proxy = unresolved_, *next = nullptr; proxy != nullptr;
proxy = next) {
next = proxy->next_unresolved();
DCHECK(!proxy->is_resolved());
- Variable* var = LookupRecursive(proxy, max_outer_scope->outer_scope());
+ Variable* var = nullptr;
+ if (try_to_resolve) {
+ var = LookupRecursive(proxy, max_outer_scope->outer_scope());
+ }
if (var == nullptr) {
proxy->set_next_unresolved(stack);
stack = proxy;
@@ -1579,7 +1608,8 @@ VariableProxy* Scope::FetchFreeVariables(DeclarationScope* max_outer_scope,
unresolved_ = nullptr;
for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
- stack = scope->FetchFreeVariables(max_outer_scope, info, stack);
+ stack =
+ scope->FetchFreeVariables(max_outer_scope, try_to_resolve, info, stack);
}
return stack;
« no previous file with comments | « src/ast/scopes.h ('k') | src/flag-definitions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698