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

Unified Diff: src/parsing/parser.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/parsing/parser.cc
diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc
index 572e2351e2d5975507fc795d2cffd1bb31fa2c76..70d270e1202712bb69e1a7f6a3f195e9e1a6394a 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,31 @@ Parser::Parser(ParseInfo* info)
}
}
-void Parser::DeserializeScopeChain(
- ParseInfo* info, Handle<Context> context,
- Scope::DeserializationMode deserialization_mode) {
+void Parser::InspectScopeChain(ParseInfo* info, Handle<ScopeInfo> 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());
+ if (!outer_scope.is_null()) {
+ if (outer_scope->scope_type() != SCRIPT_SCOPE) {
+ info->set_allow_lazy_parsing(false);
marja 2016/09/12 07:50:33 ... here I was wondering why we do this... there's
jochen (gone - plz use gerrit) 2016/09/12 08:18:18 I moved this from line 722 in the old code
+ }
+ 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()) {
+ outer_most_receivers_function_kind_ = receiver_scope->function_kind();
+ outer_most_receivers_scope_type_ = receiver_scope->scope_type();
}
}
- original_scope_ = scope;
}
FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
@@ -657,8 +654,10 @@ 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()
+ ? Handle<ScopeInfo>()
+ : Handle<ScopeInfo>(info->context()->scope_info()));
source = String::Flatten(source);
FunctionLiteral* result;
@@ -716,10 +715,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 +766,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 +811,10 @@ 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()
+ ? Handle<ScopeInfo>()
+ : Handle<ScopeInfo>(info->context()->scope_info()));
// Initialize parser state.
source = String::Flatten(source);
@@ -879,12 +880,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 +4017,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 +4039,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 +4257,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 +4411,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

Powered by Google App Engine
This is Rietveld 408576698