[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:
parent
e874d6a3d0
commit
d46467c0d2
@ -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()) {
|
||||
|
@ -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.
|
||||
|
@ -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) \
|
||||
|
@ -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")
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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.
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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() {
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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_;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user