| Index: src/parsing/parser.cc
|
| diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc
|
| index 572e2351e2d5975507fc795d2cffd1bb31fa2c76..596572a0f5c7b229932c22c0e5916e9c474f7e5f 100644
|
| --- a/src/parsing/parser.cc
|
| +++ b/src/parsing/parser.cc
|
| @@ -563,7 +563,6 @@ Parser::Parser(ParseInfo* info)
|
| info->extension(), info->ast_value_factory(), NULL),
|
| scanner_(info->unicode_cache()),
|
| reusable_preparser_(NULL),
|
| - original_scope_(NULL),
|
| target_stack_(NULL),
|
| compile_options_(info->compile_options()),
|
| cached_parse_data_(NULL),
|
| @@ -600,33 +599,33 @@ Parser::Parser(ParseInfo* info)
|
| }
|
| }
|
|
|
| -void Parser::DeserializeScopeChain(
|
| - ParseInfo* info, Handle<Context> context,
|
| - Scope::DeserializationMode deserialization_mode) {
|
| +void Parser::InspectScopeChain(ParseInfo* info,
|
| + MaybeHandle<ScopeInfo> maybe_outer_scope) {
|
| DCHECK(ThreadId::Current().Equals(info->isolate()->thread_id()));
|
| // TODO(wingo): Add an outer SCRIPT_SCOPE corresponding to the native
|
| // context, which will have the "this" binding for script scopes.
|
| DeclarationScope* script_scope = NewScriptScope();
|
| info->set_script_scope(script_scope);
|
| - Scope* scope = script_scope;
|
| - if (!context.is_null() && !context->IsNativeContext()) {
|
| - scope = Scope::DeserializeScopeChain(info->isolate(), zone(), *context,
|
| - script_scope, ast_value_factory(),
|
| - deserialization_mode);
|
| - DCHECK(!info->is_module() || scope->is_module_scope());
|
| - if (info->context().is_null()) {
|
| - DCHECK(deserialization_mode ==
|
| - Scope::DeserializationMode::kDeserializeOffHeap);
|
| - } else {
|
| - // The Scope is backed up by ScopeInfo (which is in the V8 heap); this
|
| - // means the Parser cannot operate independent of the V8 heap. Tell the
|
| - // string table to internalize strings and values right after they're
|
| - // created. This kind of parsing can only be done in the main thread.
|
| - DCHECK(parsing_on_main_thread_);
|
| - ast_value_factory()->Internalize(info->isolate());
|
| + Handle<ScopeInfo> outer_scope;
|
| + if (maybe_outer_scope.ToHandle(&outer_scope)) {
|
| + if (outer_scope->scope_type() != SCRIPT_SCOPE) {
|
| + info->set_allow_lazy_parsing(false);
|
| + }
|
| + Handle<ScopeInfo> receiver_scope = outer_scope;
|
| + while (receiver_scope->scope_type() != SCRIPT_SCOPE &&
|
| + (receiver_scope->scope_type() != FUNCTION_SCOPE ||
|
| + IsArrowFunction(receiver_scope->function_kind()))) {
|
| + if (!receiver_scope->HasOuterScopeInfo()) {
|
| + receiver_scope = Handle<ScopeInfo>::null();
|
| + break;
|
| + }
|
| + receiver_scope = Handle<ScopeInfo>(receiver_scope->OuterScopeInfo());
|
| + }
|
| + if (!receiver_scope.is_null()) {
|
| + outermost_receiver_function_kind_ = receiver_scope->function_kind();
|
| + outermost_receiver_scope_type_ = receiver_scope->scope_type();
|
| }
|
| }
|
| - original_scope_ = scope;
|
| }
|
|
|
| FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
|
| @@ -657,8 +656,11 @@ FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
|
| cached_parse_data_->Initialize();
|
| }
|
|
|
| - DeserializeScopeChain(info, info->context(),
|
| - Scope::DeserializationMode::kKeepScopeInfo);
|
| + InspectScopeChain(
|
| + info,
|
| + info->context().is_null() || info->context()->IsNativeContext()
|
| + ? MaybeHandle<ScopeInfo>()
|
| + : MaybeHandle<ScopeInfo>(info->context()->scope_info(), isolate));
|
|
|
| source = String::Flatten(source);
|
| FunctionLiteral* result;
|
| @@ -716,10 +718,10 @@ FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
|
|
|
| FunctionLiteral* result = NULL;
|
| {
|
| - Scope* outer = original_scope_;
|
| + Scope* outer = info->script_scope();
|
| DCHECK_NOT_NULL(outer);
|
| if (info->is_eval()) {
|
| - if (!outer->is_script_scope() || is_strict(info->language_mode())) {
|
| + if (is_strict(info->language_mode())) {
|
| parsing_mode = PARSE_EAGERLY;
|
| }
|
| outer = NewEvalScope(outer);
|
| @@ -767,7 +769,7 @@ FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
|
| // pre-existing bindings should be made writable, enumerable and
|
| // nonconfigurable if possible, whereas this code will leave attributes
|
| // unchanged if the property already exists.
|
| - InsertSloppyBlockFunctionVarBindings(scope, &ok);
|
| + scope->HoistSloppyBlockFunctions(factory(), &ok);
|
| }
|
| if (ok) {
|
| CheckConflictingVarDeclarations(scope, &ok);
|
| @@ -812,8 +814,11 @@ FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info) {
|
| timer.Start();
|
| }
|
| Handle<SharedFunctionInfo> shared_info = info->shared_info();
|
| - DeserializeScopeChain(info, info->context(),
|
| - Scope::DeserializationMode::kKeepScopeInfo);
|
| + InspectScopeChain(
|
| + info,
|
| + info->context().is_null() || info->context()->IsNativeContext()
|
| + ? MaybeHandle<ScopeInfo>()
|
| + : MaybeHandle<ScopeInfo>(info->context()->scope_info(), isolate));
|
|
|
| // Initialize parser state.
|
| source = String::Flatten(source);
|
| @@ -879,12 +884,10 @@ FunctionLiteral* Parser::DoParseLazy(ParseInfo* info,
|
|
|
| {
|
| // Parse the function literal.
|
| - Scope* outer = original_scope_;
|
| + Scope* outer = info->script_scope();
|
| DCHECK(outer);
|
| FunctionState function_state(&function_state_, &scope_state_, outer,
|
| info->function_kind());
|
| - DCHECK(is_sloppy(outer->language_mode()) ||
|
| - is_strict(info->language_mode()));
|
| FunctionLiteral::FunctionType function_type = ComputeFunctionType(info);
|
| bool ok = true;
|
|
|
| @@ -4018,7 +4021,7 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
|
| Block* init_block = BuildParameterInitializationBlock(parameters, CHECK_OK);
|
|
|
| if (is_sloppy(inner_scope->language_mode())) {
|
| - InsertSloppyBlockFunctionVarBindings(inner_scope, CHECK_OK);
|
| + inner_scope->HoistSloppyBlockFunctions(factory(), CHECK_OK);
|
| }
|
|
|
| // TODO(littledan): Merge the two rejection blocks into one
|
| @@ -4040,7 +4043,7 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
|
| } else {
|
| DCHECK_EQ(inner_scope, function_scope);
|
| if (is_sloppy(function_scope->language_mode())) {
|
| - InsertSloppyBlockFunctionVarBindings(function_scope, CHECK_OK);
|
| + function_scope->HoistSloppyBlockFunctions(factory(), CHECK_OK);
|
| }
|
| }
|
|
|
| @@ -4258,29 +4261,6 @@ void Parser::InsertShadowingVarBindingInitializers(Block* inner_block) {
|
| }
|
| }
|
|
|
| -void Parser::InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope,
|
| - bool* ok) {
|
| - scope->HoistSloppyBlockFunctions(factory(), CHECK_OK_VOID);
|
| -
|
| - SloppyBlockFunctionMap* map = scope->sloppy_block_function_map();
|
| - for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
|
| - // Write in assignments to var for each block-scoped function declaration
|
| - auto delegates = static_cast<SloppyBlockFunctionStatement*>(p->value);
|
| - for (SloppyBlockFunctionStatement* delegate = delegates;
|
| - delegate != nullptr; delegate = delegate->next()) {
|
| - if (delegate->to() == nullptr) {
|
| - continue;
|
| - }
|
| - Expression* assignment = factory()->NewAssignment(
|
| - Token::ASSIGN, delegate->to(), delegate->from(), kNoSourcePosition);
|
| - Statement* statement =
|
| - factory()->NewExpressionStatement(assignment, kNoSourcePosition);
|
| - delegate->set_statement(statement);
|
| - }
|
| - }
|
| -}
|
| -
|
| -
|
| // ----------------------------------------------------------------------------
|
| // Parser support
|
|
|
| @@ -4435,8 +4415,6 @@ void Parser::ParseOnBackground(ParseInfo* info) {
|
| }
|
| DCHECK(info->context().is_null() || info->context()->IsNativeContext());
|
|
|
| - DCHECK(original_scope_);
|
| -
|
| // When streaming, we don't know the length of the source until we have parsed
|
| // it. The raw data can be UTF-8, so we wouldn't know the source length until
|
| // we have decoded it anyway even if we knew the raw data length (which we
|
|
|