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

Unified Diff: src/ast/scopes.cc

Issue 2306413002: Fully deserialize the scope chain after parsing, not before (Closed)
Patch Set: updates 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
Index: src/ast/scopes.cc
diff --git a/src/ast/scopes.cc b/src/ast/scopes.cc
index b74d7ab824f7c2c1e6f83d342fe71beaca43e820..b1c7d2edcb007160c27696f3c9225dabd6b782d3 100644
--- a/src/ast/scopes.cc
+++ b/src/ast/scopes.cc
@@ -307,11 +307,25 @@ bool Scope::IsAsmFunction() const {
return is_function_scope() && AsDeclarationScope()->asm_function();
}
+Scope* Scope::DeserializeScopeChainForTesting(
+ Isolate* isolate, Zone* zone, Context* context,
+ DeclarationScope* script_scope, AstValueFactory* ast_value_factory) {
+ return DeserializeScopeChain(isolate, zone, context, script_scope,
+ ast_value_factory);
+}
+
+void DeclarationScope::DeserializeScopeChain(ParseInfo* info) {
+ if (!info->context().is_null() && !info->context()->IsNativeContext()) {
adamk 2016/09/12 16:57:47 Can you make this an early return instead? I'd fin
jochen (gone - plz use gerrit) 2016/09/12 19:00:43 done
+ ReplaceOuterScope(Scope::DeserializeScopeChain(
adamk 2016/09/12 16:57:47 Nit: You shouldn't need to qualify DeserializeScop
jochen (gone - plz use gerrit) 2016/09/12 19:00:43 done
jochen (gone - plz use gerrit) 2016/09/12 19:02:08 Actually, the compiler disagrees so I reverted thi
+ info->isolate(), zone(), *info->context(), info->script_scope(),
+ info->ast_value_factory()));
+ }
+}
+
Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
Context* context,
DeclarationScope* script_scope,
- AstValueFactory* ast_value_factory,
- DeserializationMode deserialization_mode) {
+ AstValueFactory* ast_value_factory) {
// Reconstruct the outer scope chain from a closure's context chain.
Scope* current_scope = nullptr;
Scope* innermost_scope = nullptr;
@@ -372,18 +386,11 @@ Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
}
if (current_scope != nullptr) {
outer_scope->AddInnerScope(current_scope);
- DCHECK_IMPLIES(
- deserialization_mode == DeserializationMode::kKeepScopeInfo,
- current_scope->scope_info_->HasOuterScopeInfo());
- DCHECK_IMPLIES(
- deserialization_mode == DeserializationMode::kKeepScopeInfo,
- outer_scope->scope_info_->Equals(
- current_scope->scope_info_->OuterScopeInfo()));
+ DCHECK(current_scope->scope_info_->HasOuterScopeInfo());
+ DCHECK(outer_scope->scope_info_->Equals(
+ current_scope->scope_info_->OuterScopeInfo()));
}
current_scope = outer_scope;
- if (deserialization_mode == DeserializationMode::kDeserializeOffHeap) {
- current_scope->DeserializeScopeInfo(isolate, ast_value_factory);
- }
if (innermost_scope == nullptr) innermost_scope = current_scope;
context = context->previous();
}
@@ -391,59 +398,17 @@ Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
if (innermost_scope == nullptr) return script_scope;
script_scope->AddInnerScope(current_scope);
#if DEBUG
- if (deserialization_mode == DeserializationMode::kKeepScopeInfo) {
- if (script_scope->scope_info_.is_null()) {
- DCHECK(!current_scope->scope_info_->HasOuterScopeInfo());
- } else {
- DCHECK(!script_scope->scope_info_->HasOuterScopeInfo());
- DCHECK(script_scope->scope_info_->Equals(
- current_scope->scope_info_->OuterScopeInfo()));
- }
+ if (script_scope->scope_info_.is_null()) {
+ DCHECK(!current_scope->scope_info_->HasOuterScopeInfo());
+ } else {
+ DCHECK(!script_scope->scope_info_->HasOuterScopeInfo());
+ DCHECK(script_scope->scope_info_->Equals(
+ current_scope->scope_info_->OuterScopeInfo()));
}
#endif
return innermost_scope;
}
-void Scope::DeserializeScopeInfo(Isolate* isolate,
- AstValueFactory* ast_value_factory) {
- if (scope_info_.is_null()) return;
-
- DCHECK(ThreadId::Current().Equals(isolate->thread_id()));
-
- // Internalize context local variables.
- for (int var = 0; var < scope_info_->ContextLocalCount(); ++var) {
- Handle<String> name_handle(scope_info_->ContextLocalName(var), isolate);
- const AstRawString* name = ast_value_factory->GetString(name_handle);
- int index = Context::MIN_CONTEXT_SLOTS + var;
- VariableMode mode = scope_info_->ContextLocalMode(var);
- InitializationFlag init_flag = scope_info_->ContextLocalInitFlag(var);
- MaybeAssignedFlag maybe_assigned_flag =
- scope_info_->ContextLocalMaybeAssignedFlag(var);
- VariableLocation location = VariableLocation::CONTEXT;
- VariableKind kind = NORMAL_VARIABLE;
- if (index == scope_info_->ReceiverContextSlotIndex()) {
- kind = THIS_VARIABLE;
- }
-
- Variable* result = variables_.Declare(zone(), this, name, mode, kind,
- init_flag, maybe_assigned_flag);
- result->AllocateTo(location, index);
- }
-
- // Internalize function proxy for this scope.
- if (scope_info_->HasFunctionName()) {
- Handle<String> name_handle(scope_info_->FunctionName(), isolate);
- const AstRawString* name = ast_value_factory->GetString(name_handle);
- int index = scope_info_->FunctionContextSlotIndex(*name_handle);
- if (index >= 0) {
- Variable* result = AsDeclarationScope()->DeclareFunctionVar(name);
- result->AllocateTo(VariableLocation::CONTEXT, index);
- }
- }
-
- scope_info_ = Handle<ScopeInfo>::null();
-}
-
DeclarationScope* Scope::AsDeclarationScope() {
DCHECK(is_declaration_scope());
return static_cast<DeclarationScope*>(this);
@@ -470,6 +435,15 @@ int Scope::num_parameters() const {
void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory,
bool* ok) {
adamk 2016/09/12 16:57:47 It doesn't look like this out parameter should eve
jochen (gone - plz use gerrit) 2016/09/12 19:00:43 done
+ // For the outer most eval scope (which is inside a script scope), don't
+ // hoist during parsing, but later during DeclarationScope::Analyze when the
+ // actual scope chain is available.
+ if (is_eval_scope() && !outer_scope()->outer_scope()) return;
+ HoistSloppyBlockFunctionsInternal(factory, ok);
+}
+
+void DeclarationScope::HoistSloppyBlockFunctionsInternal(
+ AstNodeFactory* factory, bool* ok) {
DCHECK(is_sloppy(language_mode()));
DCHECK(is_function_scope() || is_eval_scope() || is_script_scope() ||
(is_block_scope() && outer_scope()->is_function_scope()));
@@ -552,11 +526,12 @@ void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory,
if (!*ok) return;
}
- // Create VariableProxies for creating an assignment statement
- // (later). Read from the local lexical scope and write to the function
- // scope.
- delegate->set_to(NewUnresolved(factory, name));
- delegate->set_from(delegate->scope()->NewUnresolved(factory, name));
+ Expression* assignment = factory->NewAssignment(
+ Token::ASSIGN, NewUnresolved(factory, name),
+ delegate->scope()->NewUnresolved(factory, name), kNoSourcePosition);
+ Statement* statement =
+ factory->NewExpressionStatement(assignment, kNoSourcePosition);
+ delegate->set_statement(statement);
}
}
}
@@ -565,6 +540,15 @@ void DeclarationScope::Analyze(ParseInfo* info, AnalyzeMode mode) {
DCHECK(info->literal() != NULL);
DeclarationScope* scope = info->literal()->scope();
+ scope->DeserializeScopeChain(info);
+
+ if (scope->is_eval_scope() && is_sloppy(scope->language_mode())) {
+ AstNodeFactory factory(info->ast_value_factory());
+ bool ok = true;
+ scope->HoistSloppyBlockFunctionsInternal(&factory, &ok);
+ CHECK(ok);
+ }
+
// We are compiling one of three cases:
// 1) top-level code,
// 2) a function/eval/module on the top-level
@@ -576,6 +560,11 @@ void DeclarationScope::Analyze(ParseInfo* info, AnalyzeMode mode) {
scope->AllocateVariables(info, mode);
#ifdef DEBUG
+ if (scope->outer_scope()) {
+ DCHECK(is_sloppy(scope->outer_scope()->language_mode()) ||
+ is_strict(info->language_mode()));
+ }
+
if (info->script_is_native() ? FLAG_print_builtin_scopes
: FLAG_print_scopes) {
scope->Print();
@@ -747,7 +736,6 @@ void Scope::ReplaceOuterScope(Scope* outer) {
DCHECK_NOT_NULL(outer);
DCHECK_NOT_NULL(outer_scope_);
DCHECK(!already_resolved_);
- DCHECK(!outer->already_resolved_);
DCHECK(!outer_scope_->already_resolved_);
outer_scope_->RemoveInnerScope(this);
outer->AddInnerScope(this);
« no previous file with comments | « src/ast/scopes.h ('k') | src/background-parsing-task.cc » ('j') | src/parsing/parser.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698