[parser] Remove FLAG_preparser_scope_analysis and friends

This flag has been on by default for some time. Once
https://chromium-review.googlesource.com/c/v8/v8/+/1270578 lands we need it to
be able to find duplicate parameters (to be spec-compliant).

Change-Id: I222023d7cd955127d3ecca42283b37063e962c58
Reviewed-on: https://chromium-review.googlesource.com/c/1270581
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56468}
This commit is contained in:
Toon Verwaest 2018-10-09 10:38:26 +02:00 committed by Commit Bot
parent e874d6a3d0
commit d46467c0d2
14 changed files with 175 additions and 306 deletions

View File

@ -624,7 +624,6 @@ void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) {
Variable* var = DeclareVariableName(name, VariableMode::kVar);
if (var != kDummyPreParserVariable &&
var != kDummyPreParserLexicalVariable) {
DCHECK(FLAG_preparser_scope_analysis);
var->set_maybe_assigned();
}
}
@ -686,7 +685,6 @@ bool DeclarationScope::Analyze(ParseInfo* info) {
scope->set_should_eager_compile();
if (scope->must_use_preparsed_scope_data_) {
DCHECK(FLAG_preparser_scope_analysis);
DCHECK_EQ(scope->scope_type_, ScopeType::FUNCTION_SCOPE);
allow_deref.emplace();
info->consumed_preparsed_scope_data()->RestoreScopeAllocationData(scope);
@ -1058,21 +1056,17 @@ Variable* DeclarationScope::DeclareParameterName(
if (name == ast_value_factory->arguments_string()) {
has_arguments_parameter_ = true;
}
if (FLAG_preparser_scope_analysis) {
Variable* var;
if (declare_as_local) {
var = Declare(zone(), name, VariableMode::kVar);
} else {
var = new (zone()) Variable(this, name, VariableMode::kTemporary,
NORMAL_VARIABLE, kCreatedInitialized);
}
if (add_parameter) {
params_.Add(var, zone());
}
return var;
Variable* var;
if (declare_as_local) {
var = Declare(zone(), name, VariableMode::kVar);
} else {
var = new (zone()) Variable(this, name, VariableMode::kTemporary,
NORMAL_VARIABLE, kCreatedInitialized);
}
DeclareVariableName(name, VariableMode::kVar);
return nullptr;
if (add_parameter) {
params_.Add(var, zone());
}
return var;
}
Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode,
@ -1223,26 +1217,22 @@ Variable* Scope::DeclareVariableName(const AstRawString* name,
DCHECK(scope_info_.is_null());
// Declare the variable in the declaration scope.
if (FLAG_preparser_scope_analysis) {
Variable* var = LookupLocal(name);
DCHECK_NE(var, kDummyPreParserLexicalVariable);
DCHECK_NE(var, kDummyPreParserVariable);
if (var == nullptr) {
var = DeclareLocal(name, mode);
} else if (IsLexicalVariableMode(mode) ||
IsLexicalVariableMode(var->mode())) {
// Duplicate functions are allowed in the sloppy mode, but if this is not
// a function declaration, it's an error. This is an error PreParser
// hasn't previously detected. TODO(marja): Investigate whether we can now
// start returning this error.
} else if (mode == VariableMode::kVar) {
var->set_maybe_assigned();
}
var->set_is_used();
return var;
} else {
return variables_.DeclareName(zone(), name, mode);
Variable* var = LookupLocal(name);
DCHECK_NE(var, kDummyPreParserLexicalVariable);
DCHECK_NE(var, kDummyPreParserVariable);
if (var == nullptr) {
var = DeclareLocal(name, mode);
} else if (IsLexicalVariableMode(mode) ||
IsLexicalVariableMode(var->mode())) {
// Duplicate functions are allowed in the sloppy mode, but if this is not
// a function declaration, it's an error. This is an error PreParser
// hasn't previously detected. TODO(marja): Investigate whether we can now
// start returning this error.
} else if (mode == VariableMode::kVar) {
var->set_maybe_assigned();
}
var->set_is_used();
return var;
}
void Scope::DeclareCatchVariableName(const AstRawString* name) {
@ -1251,11 +1241,7 @@ void Scope::DeclareCatchVariableName(const AstRawString* name) {
DCHECK(is_catch_scope());
DCHECK(scope_info_.is_null());
if (FLAG_preparser_scope_analysis) {
Declare(zone(), name, VariableMode::kVar);
} else {
variables_.DeclareName(zone(), name, VariableMode::kVar);
}
Declare(zone(), name, VariableMode::kVar);
}
void Scope::AddUnresolved(VariableProxy* proxy) {
@ -1521,7 +1507,6 @@ void DeclarationScope::ResetAfterPreparsing(AstValueFactory* ast_value_factory,
}
void Scope::SavePreParsedScopeData() {
DCHECK(FLAG_preparser_scope_analysis);
if (PreParsedScopeDataBuilder::ScopeIsSkippableFunctionScope(this)) {
AsDeclarationScope()->SavePreParsedScopeDataForDeclarationScope();
}
@ -1533,7 +1518,6 @@ void Scope::SavePreParsedScopeData() {
void DeclarationScope::SavePreParsedScopeDataForDeclarationScope() {
if (preparsed_scope_data_builder_ != nullptr) {
DCHECK(FLAG_preparser_scope_analysis);
preparsed_scope_data_builder_->SaveScopeAllocationData(this);
}
}
@ -1543,8 +1527,7 @@ void DeclarationScope::AnalyzePartially(AstNodeFactory* ast_node_factory) {
base::ThreadedList<VariableProxy> new_unresolved_list;
if (!IsArrowFunction(function_kind_) &&
(!outer_scope_->is_script_scope() ||
(FLAG_preparser_scope_analysis &&
preparsed_scope_data_builder_ != nullptr &&
(preparsed_scope_data_builder_ != nullptr &&
preparsed_scope_data_builder_->ContainsInnerFunctions()))) {
// Try to resolve unresolved variables for this Scope and migrate those
// which cannot be resolved inside. It doesn't make sense to try to resolve
@ -1565,9 +1548,7 @@ void DeclarationScope::AnalyzePartially(AstNodeFactory* ast_node_factory) {
function_ = ast_node_factory->CopyVariable(function_);
}
if (FLAG_preparser_scope_analysis) {
SavePreParsedScopeData();
}
SavePreParsedScopeData();
}
#ifdef DEBUG
@ -1876,7 +1857,6 @@ Variable* Scope::LookupRecursive(ParseInfo* info, VariableProxy* proxy,
// TODO(marja): Separate LookupRecursive for preparsed scopes better.
if (var == kDummyPreParserVariable || var == kDummyPreParserLexicalVariable) {
DCHECK(GetDeclarationScope()->is_being_lazily_parsed());
DCHECK(FLAG_lazy_inner_functions);
return var;
}
@ -2255,7 +2235,6 @@ void ModuleScope::AllocateModuleVariables() {
void Scope::AllocateVariablesRecursively() {
DCHECK(!already_resolved_);
DCHECK_IMPLIES(!FLAG_preparser_scope_analysis, num_stack_slots_ == 0);
// Don't allocate variables of preparsed scopes.
if (is_declaration_scope() && AsDeclarationScope()->was_lazily_parsed()) {

View File

@ -937,7 +937,6 @@ BackgroundCompileTask::BackgroundCompileTask(
// Get preparsed scope data from the function literal.
if (function_literal->produced_preparsed_scope_data()) {
DCHECK(FLAG_preparser_scope_analysis);
ZonePreParsedScopeData* serialized_data =
function_literal->produced_preparsed_scope_data()->Serialize(
info_->zone());
@ -1069,15 +1068,12 @@ bool Compiler::Compile(Handle<SharedFunctionInfo> shared_info,
return true;
}
if (FLAG_preparser_scope_analysis) {
if (shared_info->HasUncompiledDataWithPreParsedScope()) {
parse_info.set_consumed_preparsed_scope_data(
ConsumedPreParsedScopeData::For(
isolate,
handle(shared_info->uncompiled_data_with_pre_parsed_scope()
->pre_parsed_scope_data(),
isolate)));
}
if (shared_info->HasUncompiledDataWithPreParsedScope()) {
parse_info.set_consumed_preparsed_scope_data(
ConsumedPreParsedScopeData::For(
isolate, handle(shared_info->uncompiled_data_with_pre_parsed_scope()
->pre_parsed_scope_data(),
isolate)));
}
// Parse and update ParseInfo with the results.

View File

@ -935,9 +935,7 @@ class RuntimeCallTimer final {
V(ParseProgram) \
V(PreParseArrowFunctionLiteral) \
V(PreParseBackgroundArrowFunctionLiteral) \
V(PreParseBackgroundNoVariableResolution) \
V(PreParseBackgroundWithVariableResolution) \
V(PreParseNoVariableResolution) \
V(PreParseWithVariableResolution) \
V(PropertyCallback) \
V(PrototypeMap_TransitionToAccessorProperty) \

View File

@ -1006,13 +1006,6 @@ DEFINE_IMPLICATION(trace_maps, log_code)
// parser.cc
DEFINE_BOOL(allow_natives_syntax, false, "allow natives syntax")
DEFINE_BOOL(lazy_inner_functions, true, "enable lazy parsing inner functions")
DEFINE_BOOL(aggressive_lazy_inner_functions, false,
"even lazier inner function parsing")
DEFINE_IMPLICATION(aggressive_lazy_inner_functions, lazy_inner_functions)
DEFINE_BOOL(preparser_scope_analysis, true,
"perform scope analysis for preparsed inner functions")
DEFINE_IMPLICATION(preparser_scope_analysis, aggressive_lazy_inner_functions)
// simulator-arm.cc, simulator-arm64.cc and simulator-mips.cc
DEFINE_BOOL(trace_sim, false, "Trace simulator execution")

View File

@ -14070,21 +14070,19 @@ void SharedFunctionInfo::InitFromFunctionLiteral(
// value after compiling, but avoid overwriting values set manually by the
// bootstrapper.
shared_info->set_length(SharedFunctionInfo::kInvalidLength);
if (FLAG_preparser_scope_analysis) {
ProducedPreParsedScopeData* scope_data =
lit->produced_preparsed_scope_data();
if (scope_data != nullptr) {
Handle<PreParsedScopeData> pre_parsed_scope_data;
if (scope_data->Serialize(shared_info->GetIsolate())
.ToHandle(&pre_parsed_scope_data)) {
Handle<UncompiledData> data =
isolate->factory()->NewUncompiledDataWithPreParsedScope(
lit->inferred_name(), lit->start_position(),
lit->end_position(), lit->function_literal_id(),
pre_parsed_scope_data);
shared_info->set_uncompiled_data(*data);
needs_position_info = false;
}
ProducedPreParsedScopeData* scope_data =
lit->produced_preparsed_scope_data();
if (scope_data != nullptr) {
Handle<PreParsedScopeData> pre_parsed_scope_data;
if (scope_data->Serialize(shared_info->GetIsolate())
.ToHandle(&pre_parsed_scope_data)) {
Handle<UncompiledData> data =
isolate->factory()->NewUncompiledDataWithPreParsedScope(
lit->inferred_name(), lit->start_position(),
lit->end_position(), lit->function_literal_id(),
pre_parsed_scope_data);
shared_info->set_uncompiled_data(*data);
needs_position_info = false;
}
}
}

View File

@ -76,7 +76,7 @@ ParseInfo::ParseInfo(Isolate* isolate, Handle<SharedFunctionInfo> shared)
// wrapped script at all.
DCHECK_IMPLIES(is_toplevel(), !Script::cast(shared->script())->is_wrapped());
set_allow_lazy_parsing(FLAG_lazy_inner_functions);
set_allow_lazy_parsing(true);
set_asm_wasm_broken(shared->is_asm_wasm_broken());
set_start_position(shared->StartPosition());

View File

@ -4425,7 +4425,7 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
bool did_preparse_successfully = impl()->SkipFunction(
nullptr, kind, FunctionLiteral::kAnonymousExpression,
formal_parameters.scope, &dummy_num_parameters,
&produced_preparsed_scope_data, false, false, &hint, CHECK_OK);
&produced_preparsed_scope_data, false, &hint, CHECK_OK);
// Validate parameter names. We can do this only after preparsing the
// function, since the function can declare itself strict.

View File

@ -2480,9 +2480,6 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
const bool is_top_level = AllowsLazyParsingWithoutUnresolvedVariables();
const bool is_lazy_top_level_function = is_lazy && is_top_level;
const bool is_lazy_inner_function = is_lazy && !is_top_level;
const bool is_expression =
function_type == FunctionLiteral::kAnonymousExpression ||
function_type == FunctionLiteral::kNamedExpression;
RuntimeCallTimerScope runtime_timer(
runtime_call_stats_,
@ -2509,9 +2506,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
// Inner functions will be parsed using a temporary Zone. After parsing, we
// will migrate unresolved variable into a Scope in the main Zone.
const bool should_preparse_inner =
parse_lazily() && FLAG_lazy_inner_functions && is_lazy_inner_function &&
(!is_expression || FLAG_aggressive_lazy_inner_functions);
const bool should_preparse_inner = parse_lazily() && is_lazy_inner_function;
// This may be modified later to reflect preparsing decision taken
bool should_preparse =
@ -2545,8 +2540,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
bool did_preparse_successfully =
should_preparse &&
SkipFunction(function_name, kind, function_type, scope, &num_parameters,
&produced_preparsed_scope_data, is_lazy_inner_function,
is_lazy_top_level_function, &eager_compile_hint, CHECK_OK);
&produced_preparsed_scope_data, is_lazy_top_level_function,
&eager_compile_hint, CHECK_OK);
if (!did_preparse_successfully) {
body = ParseFunction(
function_name, pos, kind, function_type, scope, &num_parameters,
@ -2567,16 +2562,12 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
function_name->byte_length());
}
if (V8_UNLIKELY(FLAG_runtime_stats) && did_preparse_successfully) {
const RuntimeCallCounterId counters[2][2] = {
{RuntimeCallCounterId::kPreParseBackgroundNoVariableResolution,
RuntimeCallCounterId::kPreParseNoVariableResolution},
{RuntimeCallCounterId::kPreParseBackgroundWithVariableResolution,
RuntimeCallCounterId::kPreParseWithVariableResolution}};
const RuntimeCallCounterId counters[2] = {
RuntimeCallCounterId::kPreParseBackgroundWithVariableResolution,
RuntimeCallCounterId::kPreParseWithVariableResolution};
if (runtime_call_stats_) {
bool tracked_variables =
PreParser::ShouldTrackUnresolvedVariables(is_lazy_top_level_function);
runtime_call_stats_->CorrectCurrentCounterId(
counters[tracked_variables][parsing_on_main_thread_]);
counters[parsing_on_main_thread_]);
}
}
@ -2614,8 +2605,7 @@ bool Parser::SkipFunction(
const AstRawString* function_name, FunctionKind kind,
FunctionLiteral::FunctionType function_type,
DeclarationScope* function_scope, int* num_parameters,
ProducedPreParsedScopeData** produced_preparsed_scope_data,
bool is_inner_function, bool may_abort,
ProducedPreParsedScopeData** produced_preparsed_scope_data, bool may_abort,
FunctionLiteral::EagerCompileHint* hint, bool* ok) {
FunctionState function_state(&function_state_, &scope_, function_scope);
function_scope->set_zone(&preparser_zone_);
@ -2628,7 +2618,6 @@ bool Parser::SkipFunction(
// FIXME(marja): There are 2 ways to skip functions now. Unify them.
if (consumed_preparsed_scope_data_) {
DCHECK(FLAG_preparser_scope_analysis);
int end_position;
LanguageMode language_mode;
int num_inner_functions;
@ -2660,13 +2649,9 @@ bool Parser::SkipFunction(
// AST. This gathers the data needed to build a lazy function.
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse");
// Aborting inner function preparsing would leave scopes in an inconsistent
// state; we don't parse inner functions in the abortable mode anyway.
DCHECK(!is_inner_function || !may_abort);
PreParser::PreParseResult result = reusable_preparser()->PreParseFunction(
function_name, kind, function_type, function_scope, is_inner_function,
may_abort, use_counts_, produced_preparsed_scope_data, this->script_id());
function_name, kind, function_type, function_scope, may_abort,
use_counts_, produced_preparsed_scope_data, this->script_id());
// Return immediately if pre-parser decided to abort parsing.
if (result == PreParser::kPreParseAbort) {

View File

@ -461,8 +461,8 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
FunctionLiteral::FunctionType function_type,
DeclarationScope* function_scope, int* num_parameters,
ProducedPreParsedScopeData** produced_preparsed_scope_data,
bool is_inner_function, bool may_abort,
FunctionLiteral::EagerCompileHint* hint, bool* ok);
bool may_abort, FunctionLiteral::EagerCompileHint* hint,
bool* ok);
Block* BuildParameterInitializationBlock(
const ParserFormalParameters& parameters, bool* ok);

View File

@ -152,7 +152,6 @@ PreParsedScopeDataBuilder::PreParsedScopeDataBuilder(
byte_data_(new (zone) ByteData(zone)),
data_for_inner_functions_(zone),
bailed_out_(false) {
DCHECK(FLAG_preparser_scope_analysis);
if (parent != nullptr) {
parent->data_for_inner_functions_.push_back(this);
}
@ -167,14 +166,11 @@ PreParsedScopeDataBuilder::DataGatheringScope::DataGatheringScope(
: function_scope_(function_scope),
preparser_(preparser),
builder_(nullptr) {
if (FLAG_preparser_scope_analysis) {
PreParsedScopeDataBuilder* parent =
preparser->preparsed_scope_data_builder();
Zone* main_zone = preparser->main_zone();
builder_ = new (main_zone) PreParsedScopeDataBuilder(main_zone, parent);
preparser->set_preparsed_scope_data_builder(builder_);
function_scope->set_preparsed_scope_data_builder(builder_);
}
PreParsedScopeDataBuilder* parent = preparser->preparsed_scope_data_builder();
Zone* main_zone = preparser->main_zone();
builder_ = new (main_zone) PreParsedScopeDataBuilder(main_zone, parent);
preparser->set_preparsed_scope_data_builder(builder_);
function_scope->set_preparsed_scope_data_builder(builder_);
}
PreParsedScopeDataBuilder::DataGatheringScope::~DataGatheringScope() {

View File

@ -78,11 +78,9 @@ PreParserIdentifier GetSymbolHelper(Scanner* scanner) {
PreParserIdentifier PreParser::GetSymbol() const {
PreParserIdentifier symbol = GetSymbolHelper(scanner());
if (track_unresolved_variables_) {
const AstRawString* result = scanner()->CurrentSymbol(ast_value_factory());
DCHECK_NOT_NULL(result);
symbol.string_ = result;
}
const AstRawString* result = scanner()->CurrentSymbol(ast_value_factory());
DCHECK_NOT_NULL(result);
symbol.string_ = result;
return symbol;
}
@ -117,9 +115,8 @@ PreParser::PreParseResult PreParser::PreParseProgram() {
PreParser::PreParseResult PreParser::PreParseFunction(
const AstRawString* function_name, FunctionKind kind,
FunctionLiteral::FunctionType function_type,
DeclarationScope* function_scope, bool is_inner_function, bool may_abort,
int* use_counts, ProducedPreParsedScopeData** produced_preparsed_scope_data,
int script_id) {
DeclarationScope* function_scope, bool may_abort, int* use_counts,
ProducedPreParsedScopeData** produced_preparsed_scope_data, int script_id) {
DCHECK_EQ(FUNCTION_SCOPE, function_scope->scope_type());
use_counts_ = use_counts;
set_script_id(script_id);
@ -127,15 +124,11 @@ PreParser::PreParseResult PreParser::PreParseFunction(
function_scope->set_is_being_lazily_parsed(true);
#endif
track_unresolved_variables_ =
ShouldTrackUnresolvedVariables(is_inner_function);
// Start collecting data for a new function which might contain skippable
// functions.
std::unique_ptr<PreParsedScopeDataBuilder::DataGatheringScope>
preparsed_scope_data_builder_scope;
if (FLAG_preparser_scope_analysis && !IsArrowFunction(kind)) {
DCHECK(track_unresolved_variables_);
if (!IsArrowFunction(kind)) {
preparsed_scope_data_builder_scope.reset(
new PreParsedScopeDataBuilder::DataGatheringScope(function_scope,
this));
@ -243,15 +236,13 @@ PreParser::PreParseResult PreParser::PreParseFunction(
}
}
if (track_unresolved_variables_) {
// Declare arguments after parsing the function since lexical
// 'arguments' masks the arguments object. Declare arguments before
// declaring the function var since the arguments object masks 'function
// arguments'.
function_scope->DeclareArguments(ast_value_factory());
// Declare arguments after parsing the function since lexical
// 'arguments' masks the arguments object. Declare arguments before
// declaring the function var since the arguments object masks 'function
// arguments'.
function_scope->DeclareArguments(ast_value_factory());
DeclareFunctionNameVar(function_name, function_type, function_scope);
}
DeclareFunctionNameVar(function_name, function_type, function_scope);
*produced_preparsed_scope_data = ProducedPreParsedScopeData::For(
preparsed_scope_data_builder_, main_zone());
@ -293,14 +284,11 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
DCHECK_NE(FunctionLiteral::kWrapped, function_type);
// Function ::
// '(' FormalParameterList? ')' '{' FunctionBody '}'
const RuntimeCallCounterId counters[2][2] = {
{RuntimeCallCounterId::kPreParseBackgroundNoVariableResolution,
RuntimeCallCounterId::kPreParseNoVariableResolution},
{RuntimeCallCounterId::kPreParseBackgroundWithVariableResolution,
RuntimeCallCounterId::kPreParseWithVariableResolution}};
RuntimeCallTimerScope runtime_timer(
runtime_call_stats_,
counters[track_unresolved_variables_][parsing_on_main_thread_]);
const RuntimeCallCounterId counters[2] = {
RuntimeCallCounterId::kPreParseBackgroundWithVariableResolution,
RuntimeCallCounterId::kPreParseWithVariableResolution};
RuntimeCallTimerScope runtime_timer(runtime_call_stats_,
counters[parsing_on_main_thread_]);
base::ElapsedTimer timer;
if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
@ -314,8 +302,6 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
preparsed_scope_data_builder_scope;
if (!function_state_->next_function_is_likely_called() &&
preparsed_scope_data_builder_ != nullptr) {
DCHECK(FLAG_preparser_scope_analysis);
DCHECK(track_unresolved_variables_);
preparsed_scope_data_builder_scope.reset(
new PreParsedScopeDataBuilder::DataGatheringScope(function_scope,
this));
@ -368,9 +354,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
}
if (V8_UNLIKELY(FLAG_log_function_events)) {
double ms = timer.Elapsed().InMillisecondsF();
const char* event_name = track_unresolved_variables_
? "preparse-resolution"
: "preparse-no-resolution";
const char* event_name = "preparse-resolution";
// We might not always get a function name here. However, it can be easily
// reconstructed from the script id and the byte range in the log processor.
const char* name = "";
@ -408,8 +392,7 @@ PreParserStatement PreParser::BuildParameterInitializationBlock(
const PreParserFormalParameters& parameters, bool* ok) {
DCHECK(!parameters.is_simple);
DCHECK(scope()->is_function_scope());
if (FLAG_preparser_scope_analysis &&
scope()->AsDeclarationScope()->calls_sloppy_eval() &&
if (scope()->AsDeclarationScope()->calls_sloppy_eval() &&
preparsed_scope_data_builder_ != nullptr) {
// We cannot replicate the Scope structure constructed by the Parser,
// because we've lost information whether each individual parameter was
@ -432,11 +415,9 @@ PreParserStatement PreParser::BuildParameterInitializationBlock(
PreParserExpression PreParser::ExpressionFromIdentifier(
const PreParserIdentifier& name, int start_position, InferName infer) {
VariableProxy* proxy = nullptr;
if (track_unresolved_variables_) {
DCHECK_NOT_NULL(name.string_);
proxy = scope()->NewUnresolved(factory()->ast_node_factory(), name.string_,
start_position, NORMAL_VARIABLE);
}
DCHECK_NOT_NULL(name.string_);
proxy = scope()->NewUnresolved(factory()->ast_node_factory(), name.string_,
start_position, NORMAL_VARIABLE);
return PreParserExpression::FromIdentifier(name, proxy, zone());
}
@ -446,19 +427,15 @@ void PreParser::DeclareAndInitializeVariables(
const DeclarationParsingResult::Declaration* declaration,
ZonePtrList<const AstRawString>* names, bool* ok) {
if (declaration->pattern.variables_ != nullptr) {
DCHECK(FLAG_lazy_inner_functions);
DCHECK(track_unresolved_variables_);
for (auto variable : *(declaration->pattern.variables_)) {
declaration_descriptor->scope->RemoveUnresolved(variable);
Variable* var = scope()->DeclareVariableName(
variable->raw_name(), declaration_descriptor->mode);
if (FLAG_preparser_scope_analysis) {
MarkLoopVariableAsAssigned(declaration_descriptor->scope, var,
declaration_descriptor->declaration_kind);
// This is only necessary if there is an initializer, but we don't have
// that information here. Consequently, the preparser sometimes says
// maybe-assigned where the parser (correctly) says never-assigned.
}
MarkLoopVariableAsAssigned(declaration_descriptor->scope, var,
declaration_descriptor->declaration_kind);
// This is only necessary if there is an initializer, but we don't have
// that information here. Consequently, the preparser sometimes says
// maybe-assigned where the parser (correctly) says never-assigned.
if (names) {
names->Add(variable->raw_name(), zone());
}

View File

@ -77,7 +77,6 @@ class PreParserIdentifier {
};
explicit PreParserIdentifier(Type type) : string_(nullptr), type_(type) {}
// Only non-nullptr when PreParser.track_unresolved_variables_ is true.
const AstRawString* string_;
Type type_;
@ -431,7 +430,6 @@ class PreParserExpressionList {
PreParserExpressionList* operator->() { return this; }
void Add(const PreParserExpression& expression, Zone* zone) {
if (expression.variables_ != nullptr) {
DCHECK(FLAG_lazy_inner_functions);
DCHECK_NOT_NULL(zone);
if (variables_ == nullptr) {
variables_ = new (zone) VariableZoneThreadedListType();
@ -570,7 +568,6 @@ class PreParserFactory {
// normalized to string literals during object literal parsing.
PreParserExpression expression = PreParserExpression::Default();
if (identifier.string_ != nullptr) {
DCHECK(FLAG_lazy_inner_functions);
VariableProxy* variable = ast_node_factory_.NewVariableProxy(
identifier.string_, NORMAL_VARIABLE);
expression.AddVariable(variable, zone_);
@ -837,8 +834,7 @@ class PreParserFactory {
}
private:
// For creating VariableProxy objects (if
// PreParser::track_unresolved_variables_ is used).
// For creating VariableProxy objects to track unresolved variables.
AstNodeFactory ast_node_factory_;
Zone* zone_;
};
@ -995,7 +991,6 @@ class PreParser : public ParserBase<PreParser> {
runtime_call_stats, logger, script_id,
parsing_module, parsing_on_main_thread),
use_counts_(nullptr),
track_unresolved_variables_(true),
preparsed_scope_data_builder_(nullptr) {}
static bool IsPreParser() { return true; }
@ -1019,15 +1014,10 @@ class PreParser : public ParserBase<PreParser> {
PreParseResult PreParseFunction(
const AstRawString* function_name, FunctionKind kind,
FunctionLiteral::FunctionType function_type,
DeclarationScope* function_scope, bool track_unresolved_variables,
bool may_abort, int* use_counts,
DeclarationScope* function_scope, bool may_abort, int* use_counts,
ProducedPreParsedScopeData** produced_preparser_scope_data,
int script_id);
V8_INLINE static bool ShouldTrackUnresolvedVariables(bool is_inner_function) {
return FLAG_preparser_scope_analysis || is_inner_function;
}
PreParsedScopeDataBuilder* preparsed_scope_data_builder() const {
return preparsed_scope_data_builder_;
}
@ -1062,8 +1052,7 @@ class PreParser : public ParserBase<PreParser> {
FunctionLiteral::FunctionType function_type,
DeclarationScope* function_scope, int* num_parameters,
ProducedPreParsedScopeData** produced_preparsed_scope_data,
bool is_inner_function, bool may_abort,
FunctionLiteral::EagerCompileHint* hint, bool* ok) {
bool may_abort, FunctionLiteral::EagerCompileHint* hint, bool* ok) {
UNREACHABLE();
}
@ -1150,18 +1139,15 @@ class PreParser : public ParserBase<PreParser> {
}
V8_INLINE void RewriteCatchPattern(CatchInfo* catch_info, bool* ok) {
if (track_unresolved_variables_) {
const AstRawString* catch_name = catch_info->name.string_;
if (catch_name == nullptr) {
catch_name = ast_value_factory()->dot_catch_string();
}
catch_info->scope->DeclareCatchVariableName(catch_name);
const AstRawString* catch_name = catch_info->name.string_;
if (catch_name == nullptr) {
catch_name = ast_value_factory()->dot_catch_string();
}
catch_info->scope->DeclareCatchVariableName(catch_name);
if (catch_info->pattern.variables_ != nullptr) {
for (auto variable : *catch_info->pattern.variables_) {
scope()->DeclareVariableName(variable->raw_name(),
VariableMode::kLet);
}
if (catch_info->pattern.variables_ != nullptr) {
for (auto variable : *catch_info->pattern.variables_) {
scope()->DeclareVariableName(variable->raw_name(), VariableMode::kLet);
}
}
}
@ -1186,8 +1172,7 @@ class PreParser : public ParserBase<PreParser> {
const AstRawString* function_name,
FunctionLiteral::FunctionType function_type,
DeclarationScope* function_scope) {
if (track_unresolved_variables_ &&
function_type == FunctionLiteral::kNamedExpression &&
if (function_type == FunctionLiteral::kNamedExpression &&
function_scope->LookupLocal(function_name) == nullptr) {
DCHECK_EQ(function_scope, scope());
function_scope->DeclareFunctionVar(function_name);
@ -1225,7 +1210,6 @@ class PreParser : public ParserBase<PreParser> {
ZonePtrList<const AstRawString>* names, bool* ok) {
DCHECK_NULL(names);
if (variable_name.string_ != nullptr) {
DCHECK(track_unresolved_variables_);
scope()->DeclareVariableName(variable_name.string_, mode);
if (is_sloppy_block_function) {
GetDeclarationScope()->DeclareSloppyBlockFunction(variable_name.string_,
@ -1242,7 +1226,6 @@ class PreParser : public ParserBase<PreParser> {
// Preparser shouldn't be used in contexts where we need to track the names.
DCHECK_NULL(names);
if (variable_name.string_ != nullptr) {
DCHECK(track_unresolved_variables_);
scope()->DeclareVariableName(variable_name.string_, VariableMode::kLet);
}
return PreParserStatement::Default();
@ -1251,7 +1234,6 @@ class PreParser : public ParserBase<PreParser> {
ClassInfo* class_info,
int class_token_pos, bool* ok) {
if (name.string_ != nullptr) {
DCHECK(track_unresolved_variables_);
scope()->DeclareVariableName(name.string_, VariableMode::kConst);
}
}
@ -1271,7 +1253,6 @@ class PreParser : public ParserBase<PreParser> {
if (kind == ClassLiteralProperty::PRIVATE_FIELD &&
property_name.string_ != nullptr) {
DCHECK(track_unresolved_variables_);
scope()->DeclareVariableName(property_name.string_, VariableMode::kConst);
}
}
@ -1412,8 +1393,6 @@ class PreParser : public ParserBase<PreParser> {
// TODO(marja): To be able to produce the same errors, the preparser needs
// to start tracking which expressions are variables and which are assigned.
if (expression.variables_ != nullptr) {
DCHECK(FLAG_lazy_inner_functions);
DCHECK(track_unresolved_variables_);
for (auto variable : *expression.variables_) {
variable->set_is_assigned();
}
@ -1472,31 +1451,27 @@ class PreParser : public ParserBase<PreParser> {
V8_INLINE void DesugarBindingInForEachStatement(
ForInfo* for_info, PreParserStatement* body_block,
PreParserExpression* each_variable, bool* ok) {
if (track_unresolved_variables_) {
DCHECK_EQ(1, for_info->parsing_result.declarations.size());
bool is_for_var_of =
for_info->mode == ForEachStatement::ITERATE &&
for_info->parsing_result.descriptor.mode == VariableMode::kVar;
bool collect_names =
IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) ||
is_for_var_of;
DCHECK_EQ(1, for_info->parsing_result.declarations.size());
bool is_for_var_of =
for_info->mode == ForEachStatement::ITERATE &&
for_info->parsing_result.descriptor.mode == VariableMode::kVar;
bool collect_names =
IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) ||
is_for_var_of;
DeclareAndInitializeVariables(
PreParserStatement::Default(), &for_info->parsing_result.descriptor,
&for_info->parsing_result.declarations[0],
collect_names ? &for_info->bound_names : nullptr, ok);
}
DeclareAndInitializeVariables(
PreParserStatement::Default(), &for_info->parsing_result.descriptor,
&for_info->parsing_result.declarations[0],
collect_names ? &for_info->bound_names : nullptr, ok);
}
V8_INLINE PreParserStatement CreateForEachStatementTDZ(
PreParserStatement init_block, const ForInfo& for_info, bool* ok) {
if (track_unresolved_variables_) {
if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) {
for (auto name : for_info.bound_names) {
scope()->DeclareVariableName(name, VariableMode::kLet);
}
return PreParserStatement::Default();
if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) {
for (auto name : for_info.bound_names) {
scope()->DeclareVariableName(name, VariableMode::kLet);
}
return PreParserStatement::Default();
}
return init_block;
}
@ -1507,11 +1482,9 @@ class PreParser : public ParserBase<PreParser> {
PreParserStatement body, Scope* inner_scope, const ForInfo& for_info,
bool* ok) {
// See Parser::DesugarLexicalBindingsInForStatement.
if (track_unresolved_variables_) {
for (auto name : for_info.bound_names) {
inner_scope->DeclareVariableName(
name, for_info.parsing_result.descriptor.mode);
}
for (auto name : for_info.bound_names) {
inner_scope->DeclareVariableName(name,
for_info.parsing_result.descriptor.mode);
}
return loop;
}
@ -1611,38 +1584,32 @@ class PreParser : public ParserBase<PreParser> {
}
V8_INLINE PreParserExpression ThisExpression(int pos = kNoSourcePosition) {
if (track_unresolved_variables_) {
scope()->NewUnresolved(factory()->ast_node_factory(),
ast_value_factory()->this_string(), pos,
THIS_VARIABLE);
}
scope()->NewUnresolved(factory()->ast_node_factory(),
ast_value_factory()->this_string(), pos,
THIS_VARIABLE);
return PreParserExpression::This();
}
V8_INLINE PreParserExpression NewSuperPropertyReference(int pos) {
if (track_unresolved_variables_) {
scope()->NewUnresolved(factory()->ast_node_factory(),
ast_value_factory()->this_function_string(), pos,
NORMAL_VARIABLE);
scope()->NewUnresolved(factory()->ast_node_factory(),
ast_value_factory()->this_string(), pos,
THIS_VARIABLE);
}
scope()->NewUnresolved(factory()->ast_node_factory(),
ast_value_factory()->this_function_string(), pos,
NORMAL_VARIABLE);
scope()->NewUnresolved(factory()->ast_node_factory(),
ast_value_factory()->this_string(), pos,
THIS_VARIABLE);
return PreParserExpression::Default();
}
V8_INLINE PreParserExpression NewSuperCallReference(int pos) {
if (track_unresolved_variables_) {
scope()->NewUnresolved(factory()->ast_node_factory(),
ast_value_factory()->this_function_string(), pos,
NORMAL_VARIABLE);
scope()->NewUnresolved(factory()->ast_node_factory(),
ast_value_factory()->new_target_string(), pos,
NORMAL_VARIABLE);
scope()->NewUnresolved(factory()->ast_node_factory(),
ast_value_factory()->this_string(), pos,
THIS_VARIABLE);
}
scope()->NewUnresolved(factory()->ast_node_factory(),
ast_value_factory()->this_function_string(), pos,
NORMAL_VARIABLE);
scope()->NewUnresolved(factory()->ast_node_factory(),
ast_value_factory()->new_target_string(), pos,
NORMAL_VARIABLE);
scope()->NewUnresolved(factory()->ast_node_factory(),
ast_value_factory()->this_string(), pos,
THIS_VARIABLE);
return PreParserExpression::SuperCallReference();
}
@ -1702,11 +1669,8 @@ class PreParser : public ParserBase<PreParser> {
const PreParserExpression& initializer,
int initializer_end_position,
bool is_rest) {
if (track_unresolved_variables_) {
DCHECK(FLAG_lazy_inner_functions);
parameters->params.Add(new (zone()) PreParserFormalParameters::Parameter(
pattern.variables_, is_rest));
}
parameters->params.Add(new (zone()) PreParserFormalParameters::Parameter(
pattern.variables_, is_rest));
parameters->UpdateArityAndFunctionLength(!initializer.IsNull(), is_rest);
}
@ -1716,34 +1680,30 @@ class PreParser : public ParserBase<PreParser> {
parameters,
bool is_simple) {
if (!is_simple) scope->SetHasNonSimpleParameters();
if (track_unresolved_variables_) {
DCHECK(FLAG_lazy_inner_functions);
for (auto parameter : parameters) {
DCHECK_IMPLIES(is_simple, parameter->variables_ != nullptr);
DCHECK_IMPLIES(is_simple, parameter->variables_->LengthForTest() == 1);
if (parameter->variables_ == nullptr) {
// No names were declared; declare a dummy one here to up the
// parameter count.
scope->DeclareParameterName(ast_value_factory()->empty_string(),
parameter->is_rest, ast_value_factory(),
false, true);
} else {
// Make sure each parameter is added only once even if it's a
// destructuring parameter which contains multiple names.
bool add_parameter = true;
for (auto variable : (*parameter->variables_)) {
// Find duplicates in simple and complex parameter lists.
if (scope->LookupLocal(variable->raw_name())) {
classifier()->RecordDuplicateFormalParameterError(
Scanner::Location::invalid());
}
// We declare the parameter name for all names, but only create a
// parameter entry for the first one.
scope->DeclareParameterName(variable->raw_name(),
parameter->is_rest, ast_value_factory(),
true, add_parameter);
add_parameter = false;
for (auto parameter : parameters) {
DCHECK_IMPLIES(is_simple, parameter->variables_ != nullptr);
DCHECK_IMPLIES(is_simple, parameter->variables_->LengthForTest() == 1);
if (parameter->variables_ == nullptr) {
// No names were declared; declare a dummy one here to up the
// parameter count.
scope->DeclareParameterName(ast_value_factory()->empty_string(),
parameter->is_rest, ast_value_factory(),
false, true);
} else {
// Make sure each parameter is added only once even if it's a
// destructuring parameter which contains multiple names.
bool add_parameter = true;
for (auto variable : (*parameter->variables_)) {
// Find duplicates in simple and complex parameter lists.
if (scope->LookupLocal(variable->raw_name())) {
classifier()->RecordDuplicateFormalParameterError(
Scanner::Location::invalid());
}
// We declare the parameter name for all names, but only create a
// parameter entry for the first one.
scope->DeclareParameterName(variable->raw_name(), parameter->is_rest,
ast_value_factory(), true, add_parameter);
add_parameter = false;
}
}
}
@ -1752,17 +1712,14 @@ class PreParser : public ParserBase<PreParser> {
V8_INLINE void DeclareArrowFunctionFormalParameters(
PreParserFormalParameters* parameters, const PreParserExpression& params,
const Scanner::Location& params_loc, bool* ok) {
if (track_unresolved_variables_) {
DCHECK(FLAG_lazy_inner_functions);
if (params.variables_ != nullptr) {
Scope* scope = parameters->scope;
for (auto variable : *params.variables_) {
if (scope->LookupLocal(variable->raw_name())) {
classifier()->RecordDuplicateFormalParameterError(
Scanner::Location::invalid());
}
scope->DeclareVariableName(variable->raw_name(), VariableMode::kVar);
if (params.variables_ != nullptr) {
Scope* scope = parameters->scope;
for (auto variable : *params.variables_) {
if (scope->LookupLocal(variable->raw_name())) {
classifier()->RecordDuplicateFormalParameterError(
Scanner::Location::invalid());
}
scope->DeclareVariableName(variable->raw_name(), VariableMode::kVar);
}
}
}
@ -1801,7 +1758,6 @@ class PreParser : public ParserBase<PreParser> {
// Preparser's private field members.
int* use_counts_;
bool track_unresolved_variables_;
PreParserLogger log_;
PreParsedScopeDataBuilder* preparsed_scope_data_builder_;

View File

@ -34,9 +34,6 @@ enum class Bailout { BAILOUT_IF_OUTER_SLOPPY, NO };
} // namespace
TEST(PreParserScopeAnalysis) {
i::FLAG_lazy_inner_functions = true;
i::FLAG_preparser_scope_analysis = true;
i::FLAG_aggressive_lazy_inner_functions = true;
i::Isolate* isolate = CcTest::i_isolate();
i::Factory* factory = isolate->factory();
LocalContext env;
@ -793,7 +790,6 @@ TEST(PreParserScopeAnalysis) {
// https://bugs.chromium.org/p/chromium/issues/detail?id=753896. Should not
// crash.
TEST(Regress753896) {
i::FLAG_preparser_scope_analysis = true;
i::Isolate* isolate = CcTest::i_isolate();
i::Factory* factory = isolate->factory();
i::HandleScope scope(isolate);

View File

@ -3394,12 +3394,8 @@ TEST(InnerAssignment) {
CHECK_NOT_NULL(var);
CHECK(var->is_used() || !expected);
bool is_maybe_assigned = var->maybe_assigned() == i::kMaybeAssigned;
if (i::FLAG_lazy_inner_functions) {
CHECK(is_maybe_assigned == expected ||
(is_maybe_assigned && inners[j].allow_error_in_inner_function));
} else {
CHECK_EQ(is_maybe_assigned, expected);
}
CHECK(is_maybe_assigned == expected ||
(is_maybe_assigned && inners[j].allow_error_in_inner_function));
}
}
}
@ -9664,7 +9660,6 @@ TEST(ArgumentsRedeclaration) {
// Test that lazily parsed inner functions don't result in overly pessimistic
// context allocations.
TEST(NoPessimisticContextAllocation) {
i::FLAG_lazy_inner_functions = true;
i::Isolate* isolate = CcTest::i_isolate();
i::Factory* factory = isolate->factory();
i::HandleScope scope(isolate);