Index: src/ast/scopes.cc |
diff --git a/src/ast/scopes.cc b/src/ast/scopes.cc |
index b74d7ab824f7c2c1e6f83d342fe71beaca43e820..9acd36bc4842dc1947c70ed0e1e2c739255b7cb6 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()) { |
+ ReplaceOuterScope(Scope::DeserializeScopeChain( |
+ 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,12 @@ int Scope::num_parameters() const { |
void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory, |
bool* ok) { |
+ if (is_eval_scope() && !outer_scope()->outer_scope()) return; |
marja
2016/09/12 07:50:32
Add a comment which explains that hoisting for eva
marja
2016/09/12 07:50:32
Style nit: outer_scope()->outer_scope() == nullptr
jochen (gone - plz use gerrit)
2016/09/12 08:18:18
done
|
+ 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())); |
@@ -557,6 +528,12 @@ void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory, |
// scope. |
delegate->set_to(NewUnresolved(factory, name)); |
delegate->set_from(delegate->scope()->NewUnresolved(factory, name)); |
+ |
+ Expression* assignment = factory->NewAssignment( |
marja
2016/09/12 07:50:32
Hmm, I wrote the exact same code and people had ob
jochen (gone - plz use gerrit)
2016/09/12 08:18:18
AST rewriting happens around the same time. The ma
|
+ Token::ASSIGN, delegate->to(), delegate->from(), kNoSourcePosition); |
+ Statement* statement = |
+ factory->NewExpressionStatement(assignment, kNoSourcePosition); |
+ delegate->set_statement(statement); |
} |
} |
} |
@@ -565,6 +542,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 +562,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 +738,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); |