| Index: src/ast/scopes.cc
|
| diff --git a/src/ast/scopes.cc b/src/ast/scopes.cc
|
| index 2443063e2a7a00869287fcfa044faa929660eaa4..cb07ba901e9770668d2f2c2ec0a69d76128b5ad9 100644
|
| --- a/src/ast/scopes.cc
|
| +++ b/src/ast/scopes.cc
|
| @@ -333,7 +333,9 @@ Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
|
| // info of this script context onto the existing script scope to avoid
|
| // nesting script scopes.
|
| Handle<ScopeInfo> scope_info(context->scope_info(), isolate);
|
| - script_scope->SetScriptScopeInfo(scope_info);
|
| + if (deserialization_mode == DeserializationMode::kIncludingVariables) {
|
| + script_scope->SetScriptScopeInfo(scope_info);
|
| + }
|
| DCHECK(context->previous()->IsNativeContext());
|
| break;
|
| } else if (context->IsFunctionContext()) {
|
| @@ -370,20 +372,20 @@ Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
|
| Scope(zone, ast_value_factory->GetString(handle(name, isolate)),
|
| Handle<ScopeInfo>(context->scope_info()));
|
| }
|
| + if (deserialization_mode == DeserializationMode::kScopesOnly) {
|
| + outer_scope->scope_info_ = Handle<ScopeInfo>::null();
|
| + }
|
| if (current_scope != nullptr) {
|
| outer_scope->AddInnerScope(current_scope);
|
| DCHECK_IMPLIES(
|
| - deserialization_mode == DeserializationMode::kKeepScopeInfo,
|
| + deserialization_mode == DeserializationMode::kIncludingVariables,
|
| current_scope->scope_info_->HasOuterScopeInfo());
|
| DCHECK_IMPLIES(
|
| - deserialization_mode == DeserializationMode::kKeepScopeInfo,
|
| + deserialization_mode == DeserializationMode::kIncludingVariables,
|
| 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,7 +393,7 @@ 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 (deserialization_mode == DeserializationMode::kIncludingVariables) {
|
| if (script_scope->scope_info_.is_null()) {
|
| DCHECK(!current_scope->scope_info_->HasOuterScopeInfo());
|
| } else {
|
| @@ -404,46 +406,6 @@ Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
|
| 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);
|
| @@ -468,8 +430,7 @@ int Scope::num_parameters() const {
|
| return is_declaration_scope() ? AsDeclarationScope()->num_parameters() : 0;
|
| }
|
|
|
| -void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory,
|
| - bool* ok) {
|
| +void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) {
|
| DCHECK(is_sloppy(language_mode()));
|
| DCHECK(is_function_scope() || is_eval_scope() || is_script_scope() ||
|
| (is_block_scope() && outer_scope()->is_function_scope()));
|
| @@ -545,18 +506,19 @@ void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory,
|
| // Based on the preceding check, it doesn't matter what we pass as
|
| // allow_harmony_restrictive_generators and
|
| // sloppy_mode_block_scope_function_redefinition.
|
| + bool ok = true;
|
| DeclareVariable(declaration, VAR,
|
| Variable::DefaultInitializationFlag(VAR), false,
|
| - nullptr, ok);
|
| - DCHECK(*ok); // Based on the preceding check, this should not fail
|
| - if (!*ok) return;
|
| + nullptr, &ok);
|
| + CHECK(ok); // Based on the preceding check, this should not fail
|
| }
|
|
|
| - // 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 +527,28 @@ void DeclarationScope::Analyze(ParseInfo* info, AnalyzeMode mode) {
|
| DCHECK(info->literal() != NULL);
|
| DeclarationScope* scope = info->literal()->scope();
|
|
|
| + if (!info->context().is_null() && !info->context()->IsNativeContext()) {
|
| + if (scope->outer_scope()) {
|
| + DeclarationScope* script_scope = new (info->zone())
|
| + DeclarationScope(info->zone(), info->ast_value_factory());
|
| + info->set_script_scope(script_scope);
|
| + scope->ReplaceOuterScope(Scope::DeserializeScopeChain(
|
| + info->isolate(), info->zone(), *info->context(), script_scope,
|
| + info->ast_value_factory(),
|
| + Scope::DeserializationMode::kIncludingVariables));
|
| + } else {
|
| + DCHECK(info->context()->IsScriptContext());
|
| + Handle<ScopeInfo> scope_info(info->context()->scope_info(),
|
| + info->isolate());
|
| + scope->SetScriptScopeInfo(scope_info);
|
| + }
|
| + }
|
| +
|
| + if (scope->is_eval_scope() && is_sloppy(scope->language_mode())) {
|
| + AstNodeFactory factory(info->ast_value_factory());
|
| + scope->HoistSloppyBlockFunctions(&factory);
|
| + }
|
| +
|
| // We are compiling one of three cases:
|
| // 1) top-level code,
|
| // 2) a function/eval/module on the top-level
|
| @@ -747,8 +731,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);
|
| outer_scope_ = outer;
|
|
|