summaryrefslogtreecommitdiff
path: root/deps/v8/src/parsing
diff options
context:
space:
mode:
authorMichaël Zasso <targos@protonmail.com>2020-07-13 10:39:42 +0200
committerMichaël Zasso <targos@protonmail.com>2020-07-13 14:41:41 +0200
commit12478684aab233942e0d5dc24f195930c8a5e59d (patch)
tree97dbee955ab91d4df480bcb82274d710a2195e64 /deps/v8/src/parsing
parent913d36d97da187a3804f6cfa96b4d24a8b7be78a (diff)
downloadnode-new-12478684aab233942e0d5dc24f195930c8a5e59d.tar.gz
deps: update V8 to 8.4.371.19
PR-URL: https://github.com/nodejs/node/pull/33579 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Shelley Vohr <codebytere@gmail.com>
Diffstat (limited to 'deps/v8/src/parsing')
-rw-r--r--deps/v8/src/parsing/expression-scope.h37
-rw-r--r--deps/v8/src/parsing/parse-info.cc360
-rw-r--r--deps/v8/src/parsing/parse-info.h434
-rw-r--r--deps/v8/src/parsing/parser-base.h127
-rw-r--r--deps/v8/src/parsing/parser.cc192
-rw-r--r--deps/v8/src/parsing/parser.h35
-rw-r--r--deps/v8/src/parsing/parsing.cc72
-rw-r--r--deps/v8/src/parsing/pending-compilation-error-handler.cc111
-rw-r--r--deps/v8/src/parsing/pending-compilation-error-handler.h54
-rw-r--r--deps/v8/src/parsing/preparse-data-impl.h9
-rw-r--r--deps/v8/src/parsing/preparse-data.cc14
-rw-r--r--deps/v8/src/parsing/preparse-data.h7
-rw-r--r--deps/v8/src/parsing/preparser.cc9
-rw-r--r--deps/v8/src/parsing/preparser.h11
-rw-r--r--deps/v8/src/parsing/rewriter.cc19
-rw-r--r--deps/v8/src/parsing/scanner-inl.h16
-rw-r--r--deps/v8/src/parsing/scanner.cc15
-rw-r--r--deps/v8/src/parsing/scanner.h23
-rw-r--r--deps/v8/src/parsing/token.h10
19 files changed, 824 insertions, 731 deletions
diff --git a/deps/v8/src/parsing/expression-scope.h b/deps/v8/src/parsing/expression-scope.h
index 6dd55a25c2..9cb04003ab 100644
--- a/deps/v8/src/parsing/expression-scope.h
+++ b/deps/v8/src/parsing/expression-scope.h
@@ -53,15 +53,36 @@ class ExpressionScope {
AsExpressionParsingScope()->TrackVariable(result);
} else {
Variable* var = Declare(name, pos);
- if (IsVarDeclaration() && !parser()->scope()->is_declaration_scope()) {
- // Make sure we'll properly resolve the variable since we might be in a
- // with or catch scope. In those cases the proxy isn't guaranteed to
- // refer to the declared variable, so consider it unresolved.
- parser()->scope()->AddUnresolved(result);
- } else {
- DCHECK_NOT_NULL(var);
- result->BindTo(var);
+ if (IsVarDeclaration()) {
+ bool passed_through_with = false;
+ for (Scope* scope = parser()->scope(); !scope->is_declaration_scope();
+ scope = scope->outer_scope()) {
+ if (scope->is_with_scope()) {
+ passed_through_with = true;
+ } else if (scope->is_catch_scope()) {
+ Variable* var = scope->LookupLocal(name);
+ // If a variable is declared in a catch scope with a masking
+ // catch-declared variable, the initializing assignment is an
+ // assignment to the catch-declared variable instead.
+ // https://tc39.es/ecma262/#sec-variablestatements-in-catch-blocks
+ if (var != nullptr) {
+ result->set_is_assigned();
+ if (passed_through_with) break;
+ result->BindTo(var);
+ var->SetMaybeAssigned();
+ return result;
+ }
+ }
+ }
+ if (passed_through_with) {
+ // If a variable is declared in a with scope, the initializing
+ // assignment might target a with-declared variable instead.
+ parser()->scope()->AddUnresolved(result);
+ return result;
+ }
}
+ DCHECK_NOT_NULL(var);
+ result->BindTo(var);
}
return result;
}
diff --git a/deps/v8/src/parsing/parse-info.cc b/deps/v8/src/parsing/parse-info.cc
index 3723636804..37432e05b7 100644
--- a/deps/v8/src/parsing/parse-info.cc
+++ b/deps/v8/src/parsing/parse-info.cc
@@ -20,64 +20,108 @@
namespace v8 {
namespace internal {
-ParseInfo::ParseInfo(AccountingAllocator* zone_allocator, int script_id)
- : zone_(std::make_unique<Zone>(zone_allocator, ZONE_NAME)),
- flags_(0),
- extension_(nullptr),
- script_scope_(nullptr),
- stack_limit_(0),
- hash_seed_(0),
- function_kind_(FunctionKind::kNormalFunction),
- function_syntax_kind_(FunctionSyntaxKind::kDeclaration),
+UnoptimizedCompileFlags::UnoptimizedCompileFlags(Isolate* isolate,
+ int script_id)
+ : flags_(0),
script_id_(script_id),
- start_position_(0),
- end_position_(0),
- parameters_end_pos_(kNoSourcePosition),
- function_literal_id_(kFunctionLiteralIdInvalid),
- max_function_literal_id_(kFunctionLiteralIdInvalid),
- character_stream_(nullptr),
- ast_value_factory_(nullptr),
- ast_string_constants_(nullptr),
- function_name_(nullptr),
- runtime_call_stats_(nullptr),
- source_range_map_(nullptr),
- literal_(nullptr) {}
-
-ParseInfo::ParseInfo(Isolate* isolate, AccountingAllocator* zone_allocator,
- int script_id)
- : ParseInfo(zone_allocator, script_id) {
- set_hash_seed(HashSeed(isolate));
- set_stack_limit(isolate->stack_guard()->real_climit());
- set_runtime_call_stats(isolate->counters()->runtime_call_stats());
- set_logger(isolate->logger());
- set_ast_string_constants(isolate->ast_string_constants());
- set_collect_source_positions(!FLAG_enable_lazy_source_positions ||
- isolate->NeedsDetailedOptimizedCodeLineInfo());
- if (!isolate->is_best_effort_code_coverage()) set_coverage_enabled();
- if (isolate->is_block_code_coverage()) set_block_coverage_enabled();
- if (isolate->is_collecting_type_profile()) set_collect_type_profile();
- if (isolate->compiler_dispatcher()->IsEnabled()) {
- parallel_tasks_.reset(new ParallelTasks(isolate->compiler_dispatcher()));
- }
+ function_kind_(FunctionKind::kNormalFunction),
+ function_syntax_kind_(FunctionSyntaxKind::kDeclaration) {
+ set_collect_type_profile(isolate->is_collecting_type_profile());
+ set_coverage_enabled(!isolate->is_best_effort_code_coverage());
+ set_block_coverage_enabled(isolate->is_block_code_coverage());
set_might_always_opt(FLAG_always_opt || FLAG_prepare_always_opt);
- set_allow_lazy_compile(FLAG_lazy);
set_allow_natives_syntax(FLAG_allow_natives_syntax);
+ set_allow_lazy_compile(FLAG_lazy);
set_allow_harmony_dynamic_import(FLAG_harmony_dynamic_import);
set_allow_harmony_import_meta(FLAG_harmony_import_meta);
- set_allow_harmony_optional_chaining(FLAG_harmony_optional_chaining);
- set_allow_harmony_nullish(FLAG_harmony_nullish);
set_allow_harmony_private_methods(FLAG_harmony_private_methods);
+ set_collect_source_positions(!FLAG_enable_lazy_source_positions ||
+ isolate->NeedsDetailedOptimizedCodeLineInfo());
set_allow_harmony_top_level_await(FLAG_harmony_top_level_await);
+ set_allow_harmony_logical_assignment(FLAG_harmony_logical_assignment);
+}
+
+// static
+UnoptimizedCompileFlags UnoptimizedCompileFlags::ForFunctionCompile(
+ Isolate* isolate, SharedFunctionInfo shared) {
+ Script script = Script::cast(shared.script());
+
+ UnoptimizedCompileFlags flags(isolate, script.id());
+
+ flags.SetFlagsFromFunction(&shared);
+ flags.SetFlagsForFunctionFromScript(script);
+
+ flags.set_allow_lazy_parsing(true);
+ flags.set_is_asm_wasm_broken(shared.is_asm_wasm_broken());
+ flags.set_is_repl_mode(shared.is_repl_mode());
+
+ // CollectTypeProfile uses its own feedback slots. If we have existing
+ // FeedbackMetadata, we can only collect type profile if the feedback vector
+ // has the appropriate slots.
+ flags.set_collect_type_profile(
+ isolate->is_collecting_type_profile() &&
+ (shared.HasFeedbackMetadata()
+ ? shared.feedback_metadata().HasTypeProfileSlot()
+ : script.IsUserJavaScript()));
+
+ // Do not support re-parsing top-level function of a wrapped script.
+ DCHECK_IMPLIES(flags.is_toplevel(), !script.is_wrapped());
+
+ return flags;
+}
+
+// static
+UnoptimizedCompileFlags UnoptimizedCompileFlags::ForScriptCompile(
+ Isolate* isolate, Script script) {
+ UnoptimizedCompileFlags flags(isolate, script.id());
+
+ flags.SetFlagsForFunctionFromScript(script);
+ flags.SetFlagsForToplevelCompile(
+ isolate->is_collecting_type_profile(), script.IsUserJavaScript(),
+ flags.outer_language_mode(), construct_repl_mode(script.is_repl_mode()));
+ if (script.is_wrapped()) {
+ flags.set_function_syntax_kind(FunctionSyntaxKind::kWrapped);
+ }
+
+ return flags;
}
-ParseInfo::ParseInfo(Isolate* isolate)
- : ParseInfo(isolate, isolate->allocator(), isolate->GetNextScriptId()) {
- LOG(isolate, ScriptEvent(Logger::ScriptEventType::kReserveId, script_id()));
+// static
+UnoptimizedCompileFlags UnoptimizedCompileFlags::ForToplevelCompile(
+ Isolate* isolate, bool is_user_javascript, LanguageMode language_mode,
+ REPLMode repl_mode) {
+ UnoptimizedCompileFlags flags(isolate, isolate->GetNextScriptId());
+ flags.SetFlagsForToplevelCompile(isolate->is_collecting_type_profile(),
+ is_user_javascript, language_mode,
+ repl_mode);
+
+ LOG(isolate,
+ ScriptEvent(Logger::ScriptEventType::kReserveId, flags.script_id()));
+ return flags;
+}
+
+// static
+UnoptimizedCompileFlags UnoptimizedCompileFlags::ForToplevelFunction(
+ const UnoptimizedCompileFlags toplevel_flags,
+ const FunctionLiteral* literal) {
+ DCHECK(toplevel_flags.is_toplevel());
+ DCHECK(!literal->is_toplevel());
+
+ // Replicate the toplevel flags, then setup the function-specific flags.
+ UnoptimizedCompileFlags flags = toplevel_flags;
+ flags.SetFlagsFromFunction(literal);
+
+ return flags;
+}
+
+// static
+UnoptimizedCompileFlags UnoptimizedCompileFlags::ForTest(Isolate* isolate) {
+ return UnoptimizedCompileFlags(isolate, Script::kTemporaryScriptId);
}
template <typename T>
-void ParseInfo::SetFunctionInfo(T function) {
- set_language_mode(function->language_mode());
+void UnoptimizedCompileFlags::SetFlagsFromFunction(T function) {
+ set_outer_language_mode(function->language_mode());
set_function_kind(function->kind());
set_function_syntax_kind(function->syntax_kind());
set_requires_instance_members_initializer(
@@ -85,63 +129,88 @@ void ParseInfo::SetFunctionInfo(T function) {
set_class_scope_has_private_brand(function->class_scope_has_private_brand());
set_has_static_private_methods_or_accessors(
function->has_static_private_methods_or_accessors());
- set_toplevel(function->is_toplevel());
+ set_is_toplevel(function->is_toplevel());
set_is_oneshot_iife(function->is_oneshot_iife());
}
-ParseInfo::ParseInfo(Isolate* isolate, SharedFunctionInfo shared)
- : ParseInfo(isolate, isolate->allocator(),
- Script::cast(shared.script()).id()) {
- // Do not support re-parsing top-level function of a wrapped script.
- // TODO(yangguo): consider whether we need a top-level function in a
- // wrapped script at all.
- DCHECK_IMPLIES(is_toplevel(), !Script::cast(shared.script()).is_wrapped());
-
+void UnoptimizedCompileFlags::SetFlagsForToplevelCompile(
+ bool is_collecting_type_profile, bool is_user_javascript,
+ LanguageMode language_mode, REPLMode repl_mode) {
set_allow_lazy_parsing(true);
- set_asm_wasm_broken(shared.is_asm_wasm_broken());
+ set_is_toplevel(true);
+ set_collect_type_profile(is_user_javascript && is_collecting_type_profile);
+ set_outer_language_mode(
+ stricter_language_mode(outer_language_mode(), language_mode));
+ set_is_repl_mode((repl_mode == REPLMode::kYes));
- set_start_position(shared.StartPosition());
- set_end_position(shared.EndPosition());
- function_literal_id_ = shared.function_literal_id();
- SetFunctionInfo(&shared);
+ set_block_coverage_enabled(block_coverage_enabled() && is_user_javascript);
+}
- Script script = Script::cast(shared.script());
- SetFlagsForFunctionFromScript(script);
+void UnoptimizedCompileFlags::SetFlagsForFunctionFromScript(Script script) {
+ DCHECK_EQ(script_id(), script.id());
- set_repl_mode(shared.is_repl_mode());
+ set_is_eval(script.compilation_type() == Script::COMPILATION_TYPE_EVAL);
+ set_is_module(script.origin_options().IsModule());
+ DCHECK(!(is_eval() && is_module()));
- // CollectTypeProfile uses its own feedback slots. If we have existing
- // FeedbackMetadata, we can only collect type profile if the feedback vector
- // has the appropriate slots.
- set_collect_type_profile(
- isolate->is_collecting_type_profile() &&
- (shared.HasFeedbackMetadata()
- ? shared.feedback_metadata().HasTypeProfileSlot()
- : script.IsUserJavaScript()));
+ set_block_coverage_enabled(block_coverage_enabled() &&
+ script.IsUserJavaScript());
}
-ParseInfo::ParseInfo(Isolate* isolate, Script script)
- : ParseInfo(isolate, isolate->allocator(), script.id()) {
- SetFlagsForToplevelCompileFromScript(isolate, script,
- isolate->is_collecting_type_profile());
+UnoptimizedCompileState::UnoptimizedCompileState(Isolate* isolate)
+ : hash_seed_(HashSeed(isolate)),
+ allocator_(isolate->allocator()),
+ ast_string_constants_(isolate->ast_string_constants()),
+ logger_(isolate->logger()),
+ parallel_tasks_(isolate->compiler_dispatcher()->IsEnabled()
+ ? new ParallelTasks(isolate->compiler_dispatcher())
+ : nullptr) {}
+
+UnoptimizedCompileState::UnoptimizedCompileState(
+ const UnoptimizedCompileState& other) V8_NOEXCEPT
+ : hash_seed_(other.hash_seed()),
+ allocator_(other.allocator()),
+ ast_string_constants_(other.ast_string_constants()),
+ logger_(other.logger()),
+ // TODO(leszeks): Should this create a new ParallelTasks instance?
+ parallel_tasks_(nullptr) {}
+
+ParseInfo::ParseInfo(const UnoptimizedCompileFlags flags,
+ UnoptimizedCompileState* state)
+ : flags_(flags),
+ state_(state),
+ zone_(std::make_unique<Zone>(state->allocator(), ZONE_NAME)),
+ extension_(nullptr),
+ script_scope_(nullptr),
+ stack_limit_(0),
+ parameters_end_pos_(kNoSourcePosition),
+ max_function_literal_id_(kFunctionLiteralIdInvalid),
+ character_stream_(nullptr),
+ ast_value_factory_(nullptr),
+ function_name_(nullptr),
+ runtime_call_stats_(nullptr),
+ source_range_map_(nullptr),
+ literal_(nullptr),
+ allow_eval_cache_(false),
+ contains_asm_module_(false),
+ language_mode_(flags.outer_language_mode()) {
+ if (flags.block_coverage_enabled()) {
+ AllocateSourceRangeMap();
+ }
+}
+
+ParseInfo::ParseInfo(Isolate* isolate, const UnoptimizedCompileFlags flags,
+ UnoptimizedCompileState* state)
+ : ParseInfo(flags, state) {
+ SetPerThreadState(isolate->stack_guard()->real_climit(),
+ isolate->counters()->runtime_call_stats());
}
// static
-std::unique_ptr<ParseInfo> ParseInfo::FromParent(
- const ParseInfo* outer_parse_info, AccountingAllocator* zone_allocator,
+std::unique_ptr<ParseInfo> ParseInfo::ForToplevelFunction(
+ const UnoptimizedCompileFlags flags, UnoptimizedCompileState* compile_state,
const FunctionLiteral* literal, const AstRawString* function_name) {
- // Can't use make_unique because the constructor is private.
- std::unique_ptr<ParseInfo> result(
- new ParseInfo(zone_allocator, outer_parse_info->script_id_));
-
- // Replicate shared state of the outer_parse_info.
- result->flags_ = outer_parse_info->flags_;
- result->set_logger(outer_parse_info->logger());
- result->set_ast_string_constants(outer_parse_info->ast_string_constants());
- result->set_hash_seed(outer_parse_info->hash_seed());
-
- DCHECK_EQ(outer_parse_info->parameters_end_pos(), kNoSourcePosition);
- DCHECK_NULL(outer_parse_info->extension());
+ std::unique_ptr<ParseInfo> result(new ParseInfo(flags, compile_state));
// Clone the function_name AstRawString into the ParseInfo's own
// AstValueFactory.
@@ -152,10 +221,6 @@ std::unique_ptr<ParseInfo> ParseInfo::FromParent(
// Setup function specific details.
DCHECK(!literal->is_toplevel());
result->set_function_name(cloned_function_name);
- result->set_start_position(literal->start_position());
- result->set_end_position(literal->end_position());
- result->set_function_literal_id(literal->function_literal_id());
- result->SetFunctionInfo(literal);
return result;
}
@@ -165,17 +230,15 @@ ParseInfo::~ParseInfo() = default;
DeclarationScope* ParseInfo::scope() const { return literal()->scope(); }
template <typename LocalIsolate>
-Handle<Script> ParseInfo::CreateScript(LocalIsolate* isolate,
- Handle<String> source,
- ScriptOriginOptions origin_options,
- NativesFlag natives) {
+Handle<Script> ParseInfo::CreateScript(
+ LocalIsolate* isolate, Handle<String> source,
+ MaybeHandle<FixedArray> maybe_wrapped_arguments,
+ ScriptOriginOptions origin_options, NativesFlag natives) {
// Create a script object describing the script to be compiled.
- DCHECK_GE(script_id_, 0);
+ DCHECK(flags().script_id() >= 0 ||
+ flags().script_id() == Script::kTemporaryScriptId);
Handle<Script> script =
- isolate->factory()->NewScriptWithId(source, script_id_);
- if (isolate->NeedsSourcePositionsForProfiling()) {
- Script::InitLineEnds(isolate, script);
- }
+ isolate->factory()->NewScriptWithId(source, flags().script_id());
switch (natives) {
case EXTENSION_CODE:
script->set_type(Script::TYPE_EXTENSION);
@@ -187,8 +250,12 @@ Handle<Script> ParseInfo::CreateScript(LocalIsolate* isolate,
break;
}
script->set_origin_options(origin_options);
- script->set_is_repl_mode(is_repl_mode());
- if (is_eval() && !is_wrapped_as_function()) {
+ script->set_is_repl_mode(flags().is_repl_mode());
+
+ DCHECK_EQ(is_wrapped_as_function(), !maybe_wrapped_arguments.is_null());
+ if (is_wrapped_as_function()) {
+ script->set_wrapped_arguments(*maybe_wrapped_arguments.ToHandleChecked());
+ } else if (flags().is_eval()) {
script->set_compilation_type(Script::COMPILATION_TYPE_EVAL);
}
@@ -198,15 +265,15 @@ Handle<Script> ParseInfo::CreateScript(LocalIsolate* isolate,
}
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
- Handle<Script> ParseInfo::CreateScript(Isolate* isolate,
- Handle<String> source,
- ScriptOriginOptions origin_options,
- NativesFlag natives);
+ Handle<Script> ParseInfo::CreateScript(
+ Isolate* isolate, Handle<String> source,
+ MaybeHandle<FixedArray> maybe_wrapped_arguments,
+ ScriptOriginOptions origin_options, NativesFlag natives);
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
- Handle<Script> ParseInfo::CreateScript(OffThreadIsolate* isolate,
- Handle<String> source,
- ScriptOriginOptions origin_options,
- NativesFlag natives);
+ Handle<Script> ParseInfo::CreateScript(
+ OffThreadIsolate* isolate, Handle<String> source,
+ MaybeHandle<FixedArray> maybe_wrapped_arguments,
+ ScriptOriginOptions origin_options, NativesFlag natives);
AstValueFactory* ParseInfo::GetOrCreateAstValueFactory() {
if (!ast_value_factory_.get()) {
@@ -217,7 +284,7 @@ AstValueFactory* ParseInfo::GetOrCreateAstValueFactory() {
}
void ParseInfo::AllocateSourceRangeMap() {
- DCHECK(block_coverage_enabled());
+ DCHECK(flags().block_coverage_enabled());
DCHECK_NULL(source_range_map());
set_source_range_map(new (zone()) SourceRangeMap(zone()));
}
@@ -230,75 +297,34 @@ void ParseInfo::set_character_stream(
character_stream_.swap(character_stream);
}
-void ParseInfo::SetFlagsForToplevelCompile(bool is_collecting_type_profile,
- bool is_user_javascript,
- LanguageMode language_mode,
- REPLMode repl_mode) {
- set_allow_lazy_parsing();
- set_toplevel();
- set_collect_type_profile(is_user_javascript && is_collecting_type_profile);
- set_language_mode(
- stricter_language_mode(this->language_mode(), language_mode));
- set_repl_mode(repl_mode == REPLMode::kYes);
-
- if (V8_UNLIKELY(is_user_javascript && block_coverage_enabled())) {
- AllocateSourceRangeMap();
- }
-}
-
-template <typename LocalIsolate>
-void ParseInfo::SetFlagsForToplevelCompileFromScript(
- LocalIsolate* isolate, Script script, bool is_collecting_type_profile) {
- SetFlagsForFunctionFromScript(script);
- SetFlagsForToplevelCompile(is_collecting_type_profile,
- script.IsUserJavaScript(), language_mode(),
- construct_repl_mode(script.is_repl_mode()));
-
- if (script.is_wrapped()) {
- set_function_syntax_kind(FunctionSyntaxKind::kWrapped);
- }
-}
-
void ParseInfo::CheckFlagsForToplevelCompileFromScript(
Script script, bool is_collecting_type_profile) {
CheckFlagsForFunctionFromScript(script);
- DCHECK(allow_lazy_parsing());
- DCHECK(is_toplevel());
- DCHECK_EQ(collect_type_profile(),
+ DCHECK(flags().allow_lazy_parsing());
+ DCHECK(flags().is_toplevel());
+ DCHECK_EQ(flags().collect_type_profile(),
is_collecting_type_profile && script.IsUserJavaScript());
- DCHECK_EQ(is_repl_mode(), script.is_repl_mode());
+ DCHECK_EQ(flags().is_repl_mode(), script.is_repl_mode());
if (script.is_wrapped()) {
- DCHECK_EQ(function_syntax_kind(), FunctionSyntaxKind::kWrapped);
- }
-}
-
-void ParseInfo::SetFlagsForFunctionFromScript(Script script) {
- DCHECK_EQ(script_id_, script.id());
-
- set_eval(script.compilation_type() == Script::COMPILATION_TYPE_EVAL);
- set_module(script.origin_options().IsModule());
- DCHECK(!(is_eval() && is_module()));
-
- if (block_coverage_enabled() && script.IsUserJavaScript()) {
- AllocateSourceRangeMap();
+ DCHECK_EQ(flags().function_syntax_kind(), FunctionSyntaxKind::kWrapped);
}
}
void ParseInfo::CheckFlagsForFunctionFromScript(Script script) {
- DCHECK_EQ(script_id_, script.id());
- // We set "is_eval" for wrapped functions to get an outer declaration scope.
+ DCHECK_EQ(flags().script_id(), script.id());
+ // We set "is_eval" for wrapped scripts to get an outer declaration scope.
// This is a bit hacky, but ok since we can't be both eval and wrapped.
- DCHECK_EQ(is_eval() && !is_wrapped_as_function(),
+ DCHECK_EQ(flags().is_eval() && !script.is_wrapped(),
script.compilation_type() == Script::COMPILATION_TYPE_EVAL);
- DCHECK_EQ(is_module(), script.origin_options().IsModule());
- DCHECK_IMPLIES(block_coverage_enabled() && script.IsUserJavaScript(),
+ DCHECK_EQ(flags().is_module(), script.origin_options().IsModule());
+ DCHECK_IMPLIES(flags().block_coverage_enabled() && script.IsUserJavaScript(),
source_range_map() != nullptr);
}
-void ParseInfo::ParallelTasks::Enqueue(ParseInfo* outer_parse_info,
- const AstRawString* function_name,
- FunctionLiteral* literal) {
+void UnoptimizedCompileState::ParallelTasks::Enqueue(
+ ParseInfo* outer_parse_info, const AstRawString* function_name,
+ FunctionLiteral* literal) {
base::Optional<CompilerDispatcher::JobId> job_id =
dispatcher_->Enqueue(outer_parse_info, function_name, literal);
if (job_id) {
diff --git a/deps/v8/src/parsing/parse-info.h b/deps/v8/src/parsing/parse-info.h
index 4430424eb9..c774f0ae94 100644
--- a/deps/v8/src/parsing/parse-info.h
+++ b/deps/v8/src/parsing/parse-info.h
@@ -10,7 +10,9 @@
#include <vector>
#include "include/v8.h"
+#include "src/base/bit-field.h"
#include "src/base/export-template.h"
+#include "src/base/logging.h"
#include "src/common/globals.h"
#include "src/handles/handles.h"
#include "src/objects/function-kind.h"
@@ -38,24 +40,187 @@ class SourceRangeMap;
class Utf16CharacterStream;
class Zone;
+// The flags for a parse + unoptimized compile operation.
+#define FLAG_FIELDS(V, _) \
+ V(is_toplevel, bool, 1, _) \
+ V(is_eager, bool, 1, _) \
+ V(is_eval, bool, 1, _) \
+ V(outer_language_mode, LanguageMode, 1, _) \
+ V(parse_restriction, ParseRestriction, 1, _) \
+ V(is_module, bool, 1, _) \
+ V(allow_lazy_parsing, bool, 1, _) \
+ V(is_lazy_compile, bool, 1, _) \
+ V(collect_type_profile, bool, 1, _) \
+ V(coverage_enabled, bool, 1, _) \
+ V(block_coverage_enabled, bool, 1, _) \
+ V(is_asm_wasm_broken, bool, 1, _) \
+ V(class_scope_has_private_brand, bool, 1, _) \
+ V(requires_instance_members_initializer, bool, 1, _) \
+ V(has_static_private_methods_or_accessors, bool, 1, _) \
+ V(might_always_opt, bool, 1, _) \
+ V(allow_natives_syntax, bool, 1, _) \
+ V(allow_lazy_compile, bool, 1, _) \
+ V(allow_harmony_dynamic_import, bool, 1, _) \
+ V(allow_harmony_import_meta, bool, 1, _) \
+ V(allow_harmony_private_methods, bool, 1, _) \
+ V(is_oneshot_iife, bool, 1, _) \
+ V(collect_source_positions, bool, 1, _) \
+ V(allow_harmony_top_level_await, bool, 1, _) \
+ V(is_repl_mode, bool, 1, _) \
+ V(allow_harmony_logical_assignment, bool, 1, _)
+
+class V8_EXPORT_PRIVATE UnoptimizedCompileFlags {
+ public:
+ // Set-up flags for a toplevel compilation.
+ static UnoptimizedCompileFlags ForToplevelCompile(Isolate* isolate,
+ bool is_user_javascript,
+ LanguageMode language_mode,
+ REPLMode repl_mode);
+
+ // Set-up flags for a compiling a particular function (either a lazy compile
+ // or a recompile).
+ static UnoptimizedCompileFlags ForFunctionCompile(Isolate* isolate,
+ SharedFunctionInfo shared);
+
+ // Set-up flags for a full compilation of a given script.
+ static UnoptimizedCompileFlags ForScriptCompile(Isolate* isolate,
+ Script script);
+
+ // Set-up flags for a parallel toplevel function compilation, based on the
+ // flags of an existing toplevel compilation.
+ static UnoptimizedCompileFlags ForToplevelFunction(
+ const UnoptimizedCompileFlags toplevel_flags,
+ const FunctionLiteral* literal);
+
+ // Create flags for a test.
+ static UnoptimizedCompileFlags ForTest(Isolate* isolate);
+
+#define FLAG_GET_SET(NAME, TYPE, SIZE, _) \
+ TYPE NAME() const { return BitFields::NAME::decode(flags_); } \
+ UnoptimizedCompileFlags& set_##NAME(TYPE value) { \
+ flags_ = BitFields::NAME::update(flags_, value); \
+ return *this; \
+ }
+
+ FLAG_FIELDS(FLAG_GET_SET, _)
+
+ int script_id() const { return script_id_; }
+ UnoptimizedCompileFlags& set_script_id(int value) {
+ script_id_ = value;
+ return *this;
+ }
+
+ FunctionKind function_kind() const { return function_kind_; }
+ UnoptimizedCompileFlags& set_function_kind(FunctionKind value) {
+ function_kind_ = value;
+ return *this;
+ }
+
+ FunctionSyntaxKind function_syntax_kind() const {
+ return function_syntax_kind_;
+ }
+ UnoptimizedCompileFlags& set_function_syntax_kind(FunctionSyntaxKind value) {
+ function_syntax_kind_ = value;
+ return *this;
+ }
+
+ private:
+ struct BitFields {
+ DEFINE_BIT_FIELDS(FLAG_FIELDS)
+ };
+
+ UnoptimizedCompileFlags(Isolate* isolate, int script_id);
+
+ // Set function info flags based on those in either FunctionLiteral or
+ // SharedFunctionInfo |function|
+ template <typename T>
+ void SetFlagsFromFunction(T function);
+ void SetFlagsForToplevelCompile(bool is_collecting_type_profile,
+ bool is_user_javascript,
+ LanguageMode language_mode,
+ REPLMode repl_mode);
+ void SetFlagsForFunctionFromScript(Script script);
+
+ uint32_t flags_;
+ int script_id_;
+ FunctionKind function_kind_;
+ FunctionSyntaxKind function_syntax_kind_;
+};
+
+#undef FLAG_FIELDS
+class ParseInfo;
+
+// The mutable state for a parse + unoptimized compile operation.
+class V8_EXPORT_PRIVATE UnoptimizedCompileState {
+ public:
+ explicit UnoptimizedCompileState(Isolate*);
+ UnoptimizedCompileState(const UnoptimizedCompileState& other) V8_NOEXCEPT;
+
+ class ParallelTasks {
+ public:
+ explicit ParallelTasks(CompilerDispatcher* compiler_dispatcher)
+ : dispatcher_(compiler_dispatcher) {
+ DCHECK_NOT_NULL(dispatcher_);
+ }
+
+ void Enqueue(ParseInfo* outer_parse_info, const AstRawString* function_name,
+ FunctionLiteral* literal);
+
+ using EnqueuedJobsIterator =
+ std::forward_list<std::pair<FunctionLiteral*, uintptr_t>>::iterator;
+
+ EnqueuedJobsIterator begin() { return enqueued_jobs_.begin(); }
+ EnqueuedJobsIterator end() { return enqueued_jobs_.end(); }
+
+ CompilerDispatcher* dispatcher() { return dispatcher_; }
+
+ private:
+ CompilerDispatcher* dispatcher_;
+ std::forward_list<std::pair<FunctionLiteral*, uintptr_t>> enqueued_jobs_;
+ };
+
+ uint64_t hash_seed() const { return hash_seed_; }
+ AccountingAllocator* allocator() const { return allocator_; }
+ const AstStringConstants* ast_string_constants() const {
+ return ast_string_constants_;
+ }
+ Logger* logger() const { return logger_; }
+ PendingCompilationErrorHandler* pending_error_handler() {
+ return &pending_error_handler_;
+ }
+ const PendingCompilationErrorHandler* pending_error_handler() const {
+ return &pending_error_handler_;
+ }
+ ParallelTasks* parallel_tasks() const { return parallel_tasks_.get(); }
+
+ private:
+ uint64_t hash_seed_;
+ AccountingAllocator* allocator_;
+ const AstStringConstants* ast_string_constants_;
+ PendingCompilationErrorHandler pending_error_handler_;
+ Logger* logger_;
+ std::unique_ptr<ParallelTasks> parallel_tasks_;
+};
+
// A container for the inputs, configuration options, and outputs of parsing.
class V8_EXPORT_PRIVATE ParseInfo {
public:
- explicit ParseInfo(Isolate*);
- ParseInfo(Isolate* isolate, Script script);
- ParseInfo(Isolate* isolate, SharedFunctionInfo shared);
+ ParseInfo(Isolate* isolate, const UnoptimizedCompileFlags flags,
+ UnoptimizedCompileState* state);
// Creates a new parse info based on parent top-level |outer_parse_info| for
// function |literal|.
- static std::unique_ptr<ParseInfo> FromParent(
- const ParseInfo* outer_parse_info, AccountingAllocator* zone_allocator,
- const FunctionLiteral* literal, const AstRawString* function_name);
+ static std::unique_ptr<ParseInfo> ForToplevelFunction(
+ const UnoptimizedCompileFlags flags,
+ UnoptimizedCompileState* compile_state, const FunctionLiteral* literal,
+ const AstRawString* function_name);
~ParseInfo();
template <typename LocalIsolate>
EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
Handle<Script> CreateScript(LocalIsolate* isolate, Handle<String> source,
+ MaybeHandle<FixedArray> maybe_wrapped_arguments,
ScriptOriginOptions origin_options,
NativesFlag natives = NOT_NATIVES_CODE);
@@ -65,70 +230,40 @@ class V8_EXPORT_PRIVATE ParseInfo {
Zone* zone() const { return zone_.get(); }
-// Convenience accessor methods for flags.
-#define FLAG_ACCESSOR(flag, getter, setter) \
- bool getter() const { return GetFlag(flag); } \
- void setter() { SetFlag(flag); } \
- void setter(bool val) { SetFlag(flag, val); }
-
- FLAG_ACCESSOR(kToplevel, is_toplevel, set_toplevel)
- FLAG_ACCESSOR(kEager, is_eager, set_eager)
- FLAG_ACCESSOR(kEval, is_eval, set_eval)
- FLAG_ACCESSOR(kStrictMode, is_strict_mode, set_strict_mode)
- FLAG_ACCESSOR(kModule, is_module, set_module)
- FLAG_ACCESSOR(kAllowLazyParsing, allow_lazy_parsing, set_allow_lazy_parsing)
- FLAG_ACCESSOR(kLazyCompile, lazy_compile, set_lazy_compile)
- FLAG_ACCESSOR(kCollectTypeProfile, collect_type_profile,
- set_collect_type_profile)
- FLAG_ACCESSOR(kIsAsmWasmBroken, is_asm_wasm_broken, set_asm_wasm_broken)
- FLAG_ACCESSOR(kContainsAsmModule, contains_asm_module,
- set_contains_asm_module)
- FLAG_ACCESSOR(kCoverageEnabled, coverage_enabled, set_coverage_enabled)
- FLAG_ACCESSOR(kBlockCoverageEnabled, block_coverage_enabled,
- set_block_coverage_enabled)
- FLAG_ACCESSOR(kAllowEvalCache, allow_eval_cache, set_allow_eval_cache)
- FLAG_ACCESSOR(kRequiresInstanceMembersInitializer,
- requires_instance_members_initializer,
- set_requires_instance_members_initializer)
- FLAG_ACCESSOR(kClassScopeHasPrivateBrand, class_scope_has_private_brand,
- set_class_scope_has_private_brand)
- FLAG_ACCESSOR(kHasStaticPrivateMethodsOrAccessors,
- has_static_private_methods_or_accessors,
- set_has_static_private_methods_or_accessors)
- FLAG_ACCESSOR(kMightAlwaysOpt, might_always_opt, set_might_always_opt)
- FLAG_ACCESSOR(kAllowNativeSyntax, allow_natives_syntax,
- set_allow_natives_syntax)
- FLAG_ACCESSOR(kAllowLazyCompile, allow_lazy_compile, set_allow_lazy_compile)
- FLAG_ACCESSOR(kAllowNativeSyntax, allow_native_syntax,
- set_allow_native_syntax)
- FLAG_ACCESSOR(kAllowHarmonyDynamicImport, allow_harmony_dynamic_import,
- set_allow_harmony_dynamic_import)
- FLAG_ACCESSOR(kAllowHarmonyImportMeta, allow_harmony_import_meta,
- set_allow_harmony_import_meta)
- FLAG_ACCESSOR(kAllowHarmonyOptionalChaining, allow_harmony_optional_chaining,
- set_allow_harmony_optional_chaining)
- FLAG_ACCESSOR(kAllowHarmonyPrivateMethods, allow_harmony_private_methods,
- set_allow_harmony_private_methods)
- FLAG_ACCESSOR(kIsOneshotIIFE, is_oneshot_iife, set_is_oneshot_iife)
- FLAG_ACCESSOR(kCollectSourcePositions, collect_source_positions,
- set_collect_source_positions)
- FLAG_ACCESSOR(kAllowHarmonyNullish, allow_harmony_nullish,
- set_allow_harmony_nullish)
- FLAG_ACCESSOR(kAllowHarmonyTopLevelAwait, allow_harmony_top_level_await,
- set_allow_harmony_top_level_await)
- FLAG_ACCESSOR(kREPLMode, is_repl_mode, set_repl_mode)
-
-#undef FLAG_ACCESSOR
-
- void set_parse_restriction(ParseRestriction restriction) {
- SetFlag(kParseRestriction, restriction != NO_PARSE_RESTRICTION);
+ const UnoptimizedCompileFlags& flags() const { return flags_; }
+
+ // Getters for state.
+ uint64_t hash_seed() const { return state_->hash_seed(); }
+ AccountingAllocator* allocator() const { return state_->allocator(); }
+ const AstStringConstants* ast_string_constants() const {
+ return state_->ast_string_constants();
}
+ Logger* logger() const { return state_->logger(); }
+ PendingCompilationErrorHandler* pending_error_handler() {
+ return state_->pending_error_handler();
+ }
+ UnoptimizedCompileState::ParallelTasks* parallel_tasks() const {
+ return state_->parallel_tasks();
+ }
+ const UnoptimizedCompileState* state() const { return state_; }
- ParseRestriction parse_restriction() const {
- return GetFlag(kParseRestriction) ? ONLY_SINGLE_FUNCTION_LITERAL
- : NO_PARSE_RESTRICTION;
+ // Accessors for per-thread state.
+ uintptr_t stack_limit() const { return stack_limit_; }
+ RuntimeCallStats* runtime_call_stats() const { return runtime_call_stats_; }
+ void SetPerThreadState(uintptr_t stack_limit,
+ RuntimeCallStats* runtime_call_stats) {
+ stack_limit_ = stack_limit;
+ runtime_call_stats_ = runtime_call_stats;
}
+ // Accessor methods for output flags.
+ bool allow_eval_cache() const { return allow_eval_cache_; }
+ void set_allow_eval_cache(bool value) { allow_eval_cache_ = value; }
+ bool contains_asm_module() const { return contains_asm_module_; }
+ void set_contains_asm_module(bool value) { contains_asm_module_ = value; }
+ LanguageMode language_mode() const { return language_mode_; }
+ void set_language_mode(LanguageMode value) { language_mode_ = value; }
+
Utf16CharacterStream* character_stream() const {
return character_stream_.get();
}
@@ -166,44 +301,13 @@ class V8_EXPORT_PRIVATE ParseInfo {
DeclarationScope* scope() const;
- uintptr_t stack_limit() const { return stack_limit_; }
- void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; }
-
- uint64_t hash_seed() const { return hash_seed_; }
- void set_hash_seed(uint64_t hash_seed) { hash_seed_ = hash_seed; }
-
- int start_position() const { return start_position_; }
- void set_start_position(int start_position) {
- start_position_ = start_position;
- }
-
- int end_position() const { return end_position_; }
- void set_end_position(int end_position) { end_position_ = end_position; }
-
int parameters_end_pos() const { return parameters_end_pos_; }
void set_parameters_end_pos(int parameters_end_pos) {
parameters_end_pos_ = parameters_end_pos;
}
- int function_literal_id() const { return function_literal_id_; }
- void set_function_literal_id(int function_literal_id) {
- function_literal_id_ = function_literal_id;
- }
-
- FunctionKind function_kind() const { return function_kind_; }
- void set_function_kind(FunctionKind function_kind) {
- function_kind_ = function_kind;
- }
-
- FunctionSyntaxKind function_syntax_kind() const {
- return function_syntax_kind_;
- }
- void set_function_syntax_kind(FunctionSyntaxKind function_syntax_kind) {
- function_syntax_kind_ = function_syntax_kind;
- }
-
bool is_wrapped_as_function() const {
- return function_syntax_kind() == FunctionSyntaxKind::kWrapped;
+ return flags().function_syntax_kind() == FunctionSyntaxKind::kWrapped;
}
int max_function_literal_id() const { return max_function_literal_id_; }
@@ -211,163 +315,45 @@ class V8_EXPORT_PRIVATE ParseInfo {
max_function_literal_id_ = max_function_literal_id;
}
- const AstStringConstants* ast_string_constants() const {
- return ast_string_constants_;
- }
- void set_ast_string_constants(
- const AstStringConstants* ast_string_constants) {
- ast_string_constants_ = ast_string_constants;
- }
-
- RuntimeCallStats* runtime_call_stats() const { return runtime_call_stats_; }
- void set_runtime_call_stats(RuntimeCallStats* runtime_call_stats) {
- runtime_call_stats_ = runtime_call_stats;
- }
- Logger* logger() const { return logger_; }
- void set_logger(Logger* logger) { logger_ = logger; }
-
void AllocateSourceRangeMap();
SourceRangeMap* source_range_map() const { return source_range_map_; }
void set_source_range_map(SourceRangeMap* source_range_map) {
source_range_map_ = source_range_map;
}
- PendingCompilationErrorHandler* pending_error_handler() {
- return &pending_error_handler_;
- }
-
- class ParallelTasks {
- public:
- explicit ParallelTasks(CompilerDispatcher* compiler_dispatcher)
- : dispatcher_(compiler_dispatcher) {
- DCHECK(dispatcher_);
- }
-
- void Enqueue(ParseInfo* outer_parse_info, const AstRawString* function_name,
- FunctionLiteral* literal);
-
- using EnqueuedJobsIterator =
- std::forward_list<std::pair<FunctionLiteral*, uintptr_t>>::iterator;
-
- EnqueuedJobsIterator begin() { return enqueued_jobs_.begin(); }
- EnqueuedJobsIterator end() { return enqueued_jobs_.end(); }
-
- CompilerDispatcher* dispatcher() { return dispatcher_; }
-
- private:
- CompilerDispatcher* dispatcher_;
- std::forward_list<std::pair<FunctionLiteral*, uintptr_t>> enqueued_jobs_;
- };
-
- ParallelTasks* parallel_tasks() { return parallel_tasks_.get(); }
-
- void SetFlagsForToplevelCompile(bool is_collecting_type_profile,
- bool is_user_javascript,
- LanguageMode language_mode,
- REPLMode repl_mode);
-
void CheckFlagsForFunctionFromScript(Script script);
- int script_id() const { return script_id_; }
- //--------------------------------------------------------------------------
-
- LanguageMode language_mode() const {
- return construct_language_mode(is_strict_mode());
- }
- void set_language_mode(LanguageMode language_mode) {
- STATIC_ASSERT(LanguageModeSize == 2);
- set_strict_mode(is_strict(language_mode));
- }
-
private:
- ParseInfo(AccountingAllocator* zone_allocator, int script_id);
- ParseInfo(Isolate*, AccountingAllocator* zone_allocator, int script_id);
+ ParseInfo(const UnoptimizedCompileFlags flags,
+ UnoptimizedCompileState* state);
- void SetFlagsForFunctionFromScript(Script script);
-
- template <typename LocalIsolate>
- void SetFlagsForToplevelCompileFromScript(LocalIsolate* isolate,
- Script script,
- bool is_collecting_type_profile);
void CheckFlagsForToplevelCompileFromScript(Script script,
bool is_collecting_type_profile);
- // Set function info flags based on those in either FunctionLiteral or
- // SharedFunctionInfo |function|
- template <typename T>
- void SetFunctionInfo(T function);
-
- // Various configuration flags for parsing.
- enum Flag : uint32_t {
- // ---------- Input flags ---------------------------
- kToplevel = 1u << 0,
- kEager = 1u << 1,
- kEval = 1u << 2,
- kStrictMode = 1u << 3,
- kNative = 1u << 4,
- kParseRestriction = 1u << 5,
- kModule = 1u << 6,
- kAllowLazyParsing = 1u << 7,
- kLazyCompile = 1u << 8,
- kCollectTypeProfile = 1u << 9,
- kCoverageEnabled = 1u << 10,
- kBlockCoverageEnabled = 1u << 11,
- kIsAsmWasmBroken = 1u << 12,
- kAllowEvalCache = 1u << 13,
- kRequiresInstanceMembersInitializer = 1u << 14,
- kContainsAsmModule = 1u << 15,
- kMightAlwaysOpt = 1u << 16,
- kAllowLazyCompile = 1u << 17,
- kAllowNativeSyntax = 1u << 18,
- kAllowHarmonyPublicFields = 1u << 19,
- kAllowHarmonyStaticFields = 1u << 20,
- kAllowHarmonyDynamicImport = 1u << 21,
- kAllowHarmonyImportMeta = 1u << 22,
- kAllowHarmonyOptionalChaining = 1u << 23,
- kHasStaticPrivateMethodsOrAccessors = 1u << 24,
- kAllowHarmonyPrivateMethods = 1u << 25,
- kIsOneshotIIFE = 1u << 26,
- kCollectSourcePositions = 1u << 27,
- kAllowHarmonyNullish = 1u << 28,
- kAllowHarmonyTopLevelAwait = 1u << 29,
- kREPLMode = 1u << 30,
- kClassScopeHasPrivateBrand = 1u << 31,
- };
-
//------------- Inputs to parsing and scope analysis -----------------------
+ const UnoptimizedCompileFlags flags_;
+ UnoptimizedCompileState* state_;
+
std::unique_ptr<Zone> zone_;
- uint32_t flags_;
v8::Extension* extension_;
DeclarationScope* script_scope_;
uintptr_t stack_limit_;
- uint64_t hash_seed_;
- FunctionKind function_kind_;
- FunctionSyntaxKind function_syntax_kind_;
- int script_id_;
- int start_position_;
- int end_position_;
int parameters_end_pos_;
- int function_literal_id_;
int max_function_literal_id_;
//----------- Inputs+Outputs of parsing and scope analysis -----------------
std::unique_ptr<Utf16CharacterStream> character_stream_;
std::unique_ptr<ConsumedPreparseData> consumed_preparse_data_;
std::unique_ptr<AstValueFactory> ast_value_factory_;
- const class AstStringConstants* ast_string_constants_;
const AstRawString* function_name_;
RuntimeCallStats* runtime_call_stats_;
- Logger* logger_;
SourceRangeMap* source_range_map_; // Used when block coverage is enabled.
- std::unique_ptr<ParallelTasks> parallel_tasks_;
//----------- Output of parsing and scope analysis ------------------------
FunctionLiteral* literal_;
- PendingCompilationErrorHandler pending_error_handler_;
-
- void SetFlag(Flag f) { flags_ |= f; }
- void SetFlag(Flag f, bool v) { flags_ = v ? flags_ | f : flags_ & ~f; }
- bool GetFlag(Flag f) const { return (flags_ & f) != 0; }
+ bool allow_eval_cache_ : 1;
+ bool contains_asm_module_ : 1;
+ LanguageMode language_mode_ : 1;
};
} // namespace internal
diff --git a/deps/v8/src/parsing/parser-base.h b/deps/v8/src/parsing/parser-base.h
index 29e527ce2c..903ce2bb7f 100644
--- a/deps/v8/src/parsing/parser-base.h
+++ b/deps/v8/src/parsing/parser-base.h
@@ -23,6 +23,7 @@
#include "src/objects/function-kind.h"
#include "src/parsing/expression-scope.h"
#include "src/parsing/func-name-inferrer.h"
+#include "src/parsing/parse-info.h"
#include "src/parsing/scanner.h"
#include "src/parsing/token.h"
#include "src/utils/pointer-with-payload.h"
@@ -241,7 +242,7 @@ class ParserBase {
v8::Extension* extension, AstValueFactory* ast_value_factory,
PendingCompilationErrorHandler* pending_error_handler,
RuntimeCallStats* runtime_call_stats, Logger* logger,
- int script_id, bool parsing_module, bool parsing_on_main_thread)
+ UnoptimizedCompileFlags flags, bool parsing_on_main_thread)
: scope_(nullptr),
original_scope_(nullptr),
function_state_(nullptr),
@@ -252,56 +253,25 @@ class ParserBase {
runtime_call_stats_(runtime_call_stats),
logger_(logger),
parsing_on_main_thread_(parsing_on_main_thread),
- parsing_module_(parsing_module),
stack_limit_(stack_limit),
pending_error_handler_(pending_error_handler),
zone_(zone),
expression_scope_(nullptr),
scanner_(scanner),
+ flags_(flags),
function_literal_id_(0),
- script_id_(script_id),
- default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile),
- allow_natives_(false),
- allow_harmony_dynamic_import_(false),
- allow_harmony_import_meta_(false),
- allow_harmony_private_methods_(false),
- allow_harmony_top_level_await_(false),
- allow_eval_cache_(true) {
+ default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile) {
pointer_buffer_.reserve(32);
variable_buffer_.reserve(32);
}
-#define ALLOW_ACCESSORS(name) \
- bool allow_##name() const { return allow_##name##_; } \
- void set_allow_##name(bool allow) { allow_##name##_ = allow; }
+ const UnoptimizedCompileFlags& flags() const { return flags_; }
- ALLOW_ACCESSORS(natives)
- ALLOW_ACCESSORS(harmony_dynamic_import)
- ALLOW_ACCESSORS(harmony_import_meta)
- ALLOW_ACCESSORS(harmony_private_methods)
- ALLOW_ACCESSORS(harmony_top_level_await)
- ALLOW_ACCESSORS(eval_cache)
-
-#undef ALLOW_ACCESSORS
+ bool allow_eval_cache() const { return allow_eval_cache_; }
+ void set_allow_eval_cache(bool allow) { allow_eval_cache_ = allow; }
V8_INLINE bool has_error() const { return scanner()->has_parser_error(); }
- bool allow_harmony_optional_chaining() const {
- return scanner()->allow_harmony_optional_chaining();
- }
-
- void set_allow_harmony_optional_chaining(bool allow) {
- scanner()->set_allow_harmony_optional_chaining(allow);
- }
-
- bool allow_harmony_nullish() const {
- return scanner()->allow_harmony_nullish();
- }
-
- void set_allow_harmony_nullish(bool allow) {
- scanner()->set_allow_harmony_nullish(allow);
- }
-
uintptr_t stack_limit() const { return stack_limit_; }
void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; }
@@ -885,8 +855,6 @@ class ParserBase {
// Any further calls to Next or peek will return the illegal token.
if (GetCurrentStackPosition() < stack_limit_) set_stack_overflow();
}
- int script_id() { return script_id_; }
- void set_script_id(int id) { script_id_ = id; }
V8_INLINE Token::Value peek() { return scanner()->peek(); }
@@ -1077,7 +1045,7 @@ class ParserBase {
return IsResumableFunction(function_state_->kind());
}
bool is_await_allowed() const {
- return is_async_function() || (allow_harmony_top_level_await() &&
+ return is_async_function() || (flags().allow_harmony_top_level_await() &&
IsModule(function_state_->kind()));
}
const PendingCompilationErrorHandler* pending_error_handler() const {
@@ -1279,7 +1247,12 @@ class ParserBase {
// hoisted over such a scope.
void CheckConflictingVarDeclarations(DeclarationScope* scope) {
if (has_error()) return;
- Declaration* decl = scope->CheckConflictingVarDeclarations();
+ bool allowed_catch_binding_var_redeclaration = false;
+ Declaration* decl = scope->CheckConflictingVarDeclarations(
+ &allowed_catch_binding_var_redeclaration);
+ if (allowed_catch_binding_var_redeclaration) {
+ impl()->CountUsage(v8::Isolate::kVarRedeclaredCatchBinding);
+ }
if (decl != nullptr) {
// In ES6, conflicting variable bindings are early errors.
const AstRawString* name = decl->var()->raw_name();
@@ -1501,16 +1474,14 @@ class ParserBase {
FormalParametersT* parent_parameters_;
};
- class FunctionBodyParsingScope {
+ class FunctionParsingScope {
public:
- explicit FunctionBodyParsingScope(Impl* parser)
+ explicit FunctionParsingScope(Impl* parser)
: parser_(parser), expression_scope_(parser_->expression_scope_) {
parser_->expression_scope_ = nullptr;
}
- ~FunctionBodyParsingScope() {
- parser_->expression_scope_ = expression_scope_;
- }
+ ~FunctionParsingScope() { parser_->expression_scope_ = expression_scope_; }
private:
Impl* parser_;
@@ -1534,7 +1505,6 @@ class ParserBase {
RuntimeCallStats* runtime_call_stats_;
internal::Logger* logger_;
bool parsing_on_main_thread_;
- const bool parsing_module_;
uintptr_t stack_limit_;
PendingCompilationErrorHandler* pending_error_handler_;
@@ -1549,8 +1519,8 @@ class ParserBase {
Scanner* scanner_;
+ const UnoptimizedCompileFlags flags_;
int function_literal_id_;
- int script_id_;
FunctionLiteral::EagerCompileHint default_eager_compile_hint_;
@@ -1589,12 +1559,7 @@ class ParserBase {
bool accept_IN_ = true;
- bool allow_natives_;
- bool allow_harmony_dynamic_import_;
- bool allow_harmony_import_meta_;
- bool allow_harmony_private_methods_;
- bool allow_harmony_top_level_await_;
- bool allow_eval_cache_;
+ bool allow_eval_cache_ = true;
};
template <typename Impl>
@@ -1644,7 +1609,7 @@ ParserBase<Impl>::ParseAndClassifyIdentifier(Token::Value next) {
}
if (!Token::IsValidIdentifier(next, language_mode(), is_generator(),
- parsing_module_ || is_async_function())) {
+ flags().is_module() || is_async_function())) {
ReportUnexpectedToken(next);
return impl()->EmptyIdentifierString();
}
@@ -1668,7 +1633,7 @@ typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifier(
if (!Token::IsValidIdentifier(
next, language_mode(), IsGeneratorFunction(function_kind),
- parsing_module_ || IsAsyncFunction(function_kind))) {
+ flags().is_module() || IsAsyncFunction(function_kind))) {
ReportUnexpectedToken(next);
return impl()->EmptyIdentifierString();
}
@@ -1879,7 +1844,7 @@ ParserBase<Impl>::ParsePrimaryExpression() {
return ParseSuperExpression(is_new);
}
case Token::IMPORT:
- if (!allow_harmony_dynamic_import()) break;
+ if (!flags().allow_harmony_dynamic_import()) break;
return ParseImportExpressions();
case Token::LBRACK:
@@ -1942,7 +1907,7 @@ ParserBase<Impl>::ParsePrimaryExpression() {
return ParseTemplateLiteral(impl()->NullExpression(), beg_pos, false);
case Token::MOD:
- if (allow_natives() || extension_ != nullptr) {
+ if (flags().allow_natives_syntax() || extension_ != nullptr) {
return ParseV8Intrinsic();
}
break;
@@ -2188,7 +2153,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseProperty(
prop_info->kind = ParsePropertyKind::kNotSet;
return impl()->FailureExpression();
}
- if (V8_UNLIKELY(!allow_harmony_private_methods() &&
+ if (V8_UNLIKELY(!flags().allow_harmony_private_methods() &&
(IsAccessor(prop_info->kind) ||
prop_info->kind == ParsePropertyKind::kMethod))) {
ReportUnexpectedToken(Next());
@@ -2437,7 +2402,7 @@ ParserBase<Impl>::ParseClassPropertyDefinition(ClassInfo* class_info,
template <typename Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseMemberInitializer(
ClassInfo* class_info, int beg_pos, bool is_static) {
- FunctionBodyParsingScope body_parsing_scope(impl());
+ FunctionParsingScope body_parsing_scope(impl());
DeclarationScope* initializer_scope =
is_static ? class_info->static_fields_scope
: class_info->instance_members_scope;
@@ -2535,8 +2500,9 @@ ParserBase<Impl>::ParseObjectPropertyDefinition(ParsePropertyInfo* prop_info,
// IdentifierReference Initializer?
DCHECK_EQ(function_flags, ParseFunctionFlag::kIsNormal);
- if (!Token::IsValidIdentifier(name_token, language_mode(), is_generator(),
- parsing_module_ || is_async_function())) {
+ if (!Token::IsValidIdentifier(
+ name_token, language_mode(), is_generator(),
+ flags().is_module() || is_async_function())) {
ReportUnexpectedToken(Next());
return impl()->NullLiteralProperty();
}
@@ -2789,6 +2755,11 @@ ParserBase<Impl>::ParseAssignmentExpressionCoverGrammar() {
Token::Value op = peek();
if (!Token::IsArrowOrAssignmentOp(op)) return expression;
+ if ((op == Token::ASSIGN_NULLISH || op == Token::ASSIGN_OR ||
+ op == Token::ASSIGN_AND) &&
+ !flags().allow_harmony_logical_assignment()) {
+ return expression;
+ }
// Arrow functions.
if (V8_UNLIKELY(op == Token::ARROW)) {
@@ -3399,13 +3370,7 @@ ParserBase<Impl>::ParseLeftHandSideContinuation(ExpressionT result) {
if (is_optional) {
DCHECK_EQ(scanner()->current_token(), Token::QUESTION_PERIOD);
int pos = position();
- Token::Value next = Next();
- if (V8_UNLIKELY(!Token::IsPropertyName(next))) {
- ReportUnexpectedToken(next);
- return impl()->FailureExpression();
- }
- IdentifierT name = impl()->GetSymbol();
- ExpressionT key = factory()->NewStringLiteral(name, position());
+ ExpressionT key = ParsePropertyOrPrivatePropertyName();
result = factory()->NewProperty(result, key, pos, is_optional);
break;
}
@@ -3456,8 +3421,10 @@ ParserBase<Impl>::ParseMemberWithPresentNewPrefixesExpression() {
if (peek() == Token::SUPER) {
const bool is_new = true;
result = ParseSuperExpression(is_new);
- } else if (allow_harmony_dynamic_import() && peek() == Token::IMPORT &&
- (!allow_harmony_import_meta() || PeekAhead() == Token::LPAREN)) {
+ } else if (flags().allow_harmony_dynamic_import() &&
+ peek() == Token::IMPORT &&
+ (!flags().allow_harmony_import_meta() ||
+ PeekAhead() == Token::LPAREN)) {
impl()->ReportMessageAt(scanner()->peek_location(),
MessageTemplate::kImportCallNotNewExpression);
return impl()->FailureExpression();
@@ -3555,14 +3522,14 @@ ParserBase<Impl>::ParseMemberExpression() {
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseImportExpressions() {
- DCHECK(allow_harmony_dynamic_import());
+ DCHECK(flags().allow_harmony_dynamic_import());
Consume(Token::IMPORT);
int pos = position();
- if (allow_harmony_import_meta() && Check(Token::PERIOD)) {
+ if (flags().allow_harmony_import_meta() && Check(Token::PERIOD)) {
ExpectContextualKeyword(ast_value_factory()->meta_string(), "import.meta",
pos);
- if (!parsing_module_) {
+ if (!flags().is_module()) {
impl()->ReportMessageAt(scanner()->location(),
MessageTemplate::kImportMetaOutsideModule);
return impl()->FailureExpression();
@@ -3572,7 +3539,7 @@ ParserBase<Impl>::ParseImportExpressions() {
}
if (V8_UNLIKELY(peek() != Token::LPAREN)) {
- if (!parsing_module_) {
+ if (!flags().is_module()) {
impl()->ReportMessageAt(scanner()->location(),
MessageTemplate::kImportOutsideModule);
} else {
@@ -4157,8 +4124,6 @@ void ParserBase<Impl>::ParseFunctionBody(
StatementListT* body, IdentifierT function_name, int pos,
const FormalParametersT& parameters, FunctionKind kind,
FunctionSyntaxKind function_syntax_kind, FunctionBodyType body_type) {
- FunctionBodyParsingScope body_parsing_scope(impl());
-
if (IsResumableFunction(kind)) impl()->PrepareGeneratorVariables();
DeclarationScope* function_scope = parameters.scope;
@@ -4435,6 +4400,7 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
Consume(Token::LBRACE);
AcceptINScope scope(this, true);
+ FunctionParsingScope body_parsing_scope(impl());
ParseFunctionBody(&body, impl()->NullIdentifier(), kNoSourcePosition,
parameters, kind,
FunctionSyntaxKind::kAnonymousExpression,
@@ -4445,6 +4411,7 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
} else {
Consume(Token::LBRACE);
AcceptINScope scope(this, true);
+ FunctionParsingScope body_parsing_scope(impl());
ParseFunctionBody(&body, impl()->NullIdentifier(), kNoSourcePosition,
formal_parameters, kind,
FunctionSyntaxKind::kAnonymousExpression,
@@ -4454,6 +4421,7 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
} else {
// Single-expression body
has_braces = false;
+ FunctionParsingScope body_parsing_scope(impl());
ParseFunctionBody(&body, impl()->NullIdentifier(), kNoSourcePosition,
formal_parameters, kind,
FunctionSyntaxKind::kAnonymousExpression,
@@ -4493,8 +4461,9 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
const char* event_name =
is_lazy_top_level_function ? "preparse-no-resolution" : "parse";
const char* name = "arrow function";
- logger_->FunctionEvent(event_name, script_id(), ms, scope->start_position(),
- scope->end_position(), name, strlen(name));
+ logger_->FunctionEvent(event_name, flags().script_id(), ms,
+ scope->start_position(), scope->end_position(), name,
+ strlen(name));
}
return function_literal;
diff --git a/deps/v8/src/parsing/parser.cc b/deps/v8/src/parsing/parser.cc
index 2a1ad0e98b..63b8b9c6f9 100644
--- a/deps/v8/src/parsing/parser.cc
+++ b/deps/v8/src/parsing/parser.cc
@@ -15,6 +15,7 @@
#include "src/base/overflowing-math.h"
#include "src/base/platform/platform.h"
#include "src/codegen/bailout-reason.h"
+#include "src/common/globals.h"
#include "src/common/message-template.h"
#include "src/compiler-dispatcher/compiler-dispatcher.h"
#include "src/logging/counters.h"
@@ -416,13 +417,12 @@ Expression* Parser::NewV8RuntimeFunctionForFuzzing(
}
Parser::Parser(ParseInfo* info)
- : ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(),
- info->extension(), info->GetOrCreateAstValueFactory(),
- info->pending_error_handler(),
- info->runtime_call_stats(), info->logger(),
- info->script_id(), info->is_module(), true),
+ : ParserBase<Parser>(
+ info->zone(), &scanner_, info->stack_limit(), info->extension(),
+ info->GetOrCreateAstValueFactory(), info->pending_error_handler(),
+ info->runtime_call_stats(), info->logger(), info->flags(), true),
info_(info),
- scanner_(info->character_stream(), info->is_module()),
+ scanner_(info->character_stream(), flags()),
preparser_zone_(info->zone()->allocator(), ZONE_NAME),
reusable_preparser_(nullptr),
mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
@@ -445,20 +445,13 @@ Parser::Parser(ParseInfo* info)
// of functions without an outer context when setting a breakpoint through
// Debug::FindSharedFunctionInfoInScript
// We also compile eagerly for kProduceExhaustiveCodeCache.
- bool can_compile_lazily = info->allow_lazy_compile() && !info->is_eager();
+ bool can_compile_lazily = flags().allow_lazy_compile() && !flags().is_eager();
set_default_eager_compile_hint(can_compile_lazily
? FunctionLiteral::kShouldLazyCompile
: FunctionLiteral::kShouldEagerCompile);
- allow_lazy_ = info->allow_lazy_compile() && info->allow_lazy_parsing() &&
+ allow_lazy_ = flags().allow_lazy_compile() && flags().allow_lazy_parsing() &&
info->extension() == nullptr && can_compile_lazily;
- set_allow_natives(info->allow_natives_syntax());
- set_allow_harmony_dynamic_import(info->allow_harmony_dynamic_import());
- set_allow_harmony_import_meta(info->allow_harmony_import_meta());
- set_allow_harmony_nullish(info->allow_harmony_nullish());
- set_allow_harmony_optional_chaining(info->allow_harmony_optional_chaining());
- set_allow_harmony_private_methods(info->allow_harmony_private_methods());
- set_allow_harmony_top_level_await(info->allow_harmony_top_level_await());
for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
++feature) {
use_counts_[feature] = 0;
@@ -469,7 +462,7 @@ void Parser::InitializeEmptyScopeChain(ParseInfo* info) {
DCHECK_NULL(original_scope_);
DCHECK_NULL(info->script_scope());
DeclarationScope* script_scope =
- NewScriptScope(info->is_repl_mode() ? REPLMode::kYes : REPLMode::kNo);
+ NewScriptScope(flags().is_repl_mode() ? REPLMode::kYes : REPLMode::kNo);
info->set_script_scope(script_scope);
original_scope_ = script_scope;
}
@@ -485,7 +478,7 @@ void Parser::DeserializeScopeChain(
original_scope_ = Scope::DeserializeScopeChain(
isolate, zone(), *outer_scope_info, info->script_scope(),
ast_value_factory(), mode);
- if (info->is_eval() || IsArrowFunction(info->function_kind())) {
+ if (flags().is_eval() || IsArrowFunction(flags().function_kind())) {
original_scope_->GetReceiverScope()->DeserializeReceiver(
ast_value_factory());
}
@@ -515,18 +508,18 @@ void MaybeProcessSourceRanges(ParseInfo* parse_info, Expression* root,
} // namespace
-FunctionLiteral* Parser::ParseProgram(
- Isolate* isolate, Handle<Script> script, ParseInfo* info,
- MaybeHandle<ScopeInfo> maybe_outer_scope_info) {
+void Parser::ParseProgram(Isolate* isolate, Handle<Script> script,
+ ParseInfo* info,
+ MaybeHandle<ScopeInfo> maybe_outer_scope_info) {
// TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
// see comment for HistogramTimerScope class.
- DCHECK_EQ(script->id(), script_id());
+ DCHECK_EQ(script->id(), flags().script_id());
// It's OK to use the Isolate & counters here, since this function is only
// called in the main thread.
DCHECK(parsing_on_main_thread_);
RuntimeCallTimerScope runtime_timer(
- runtime_call_stats_, info->is_eval()
+ runtime_call_stats_, flags().is_eval()
? RuntimeCallCounterId::kParseEval
: RuntimeCallCounterId::kParseProgram);
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram");
@@ -546,6 +539,7 @@ FunctionLiteral* Parser::ParseProgram(
FunctionLiteral* result = DoParseProgram(isolate, info);
MaybeResetCharacterStream(info, result);
MaybeProcessSourceRanges(info, result, stack_limit_);
+ PostProcessParseResult(isolate, info, result);
HandleSourceURLComments(isolate, script);
@@ -554,14 +548,14 @@ FunctionLiteral* Parser::ParseProgram(
const char* event_name = "parse-eval";
int start = -1;
int end = -1;
- if (!info->is_eval()) {
+ if (!flags().is_eval()) {
event_name = "parse-script";
start = 0;
end = String::cast(script->source()).length();
}
- LOG(isolate, FunctionEvent(event_name, script_id(), ms, start, end, "", 0));
+ LOG(isolate,
+ FunctionEvent(event_name, flags().script_id(), ms, start, end, "", 0));
}
- return result;
}
FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
@@ -574,16 +568,14 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
ResetFunctionLiteralId();
- DCHECK(info->function_literal_id() == kFunctionLiteralIdTopLevel ||
- info->function_literal_id() == kFunctionLiteralIdInvalid);
FunctionLiteral* result = nullptr;
{
Scope* outer = original_scope_;
DCHECK_NOT_NULL(outer);
- if (info->is_eval()) {
+ if (flags().is_eval()) {
outer = NewEvalScope(outer);
- } else if (parsing_module_) {
+ } else if (flags().is_module()) {
DCHECK_EQ(outer, info->script_scope());
outer = NewModuleScope(info->script_scope());
}
@@ -594,15 +586,15 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
FunctionState function_state(&function_state_, &scope_, scope);
ScopedPtrList<Statement> body(pointer_buffer());
int beg_pos = scanner()->location().beg_pos;
- if (parsing_module_) {
- DCHECK(info->is_module());
+ if (flags().is_module()) {
+ DCHECK(flags().is_module());
PrepareGeneratorVariables();
Expression* initial_yield =
BuildInitialYield(kNoSourcePosition, kGeneratorFunction);
body.Add(
factory()->NewExpressionStatement(initial_yield, kNoSourcePosition));
- if (allow_harmony_top_level_await()) {
+ if (flags().allow_harmony_top_level_await()) {
// First parse statements into a buffer. Then, if there was a
// top level await, create an inner block and rewrite the body of the
// module as an async function. Otherwise merge the statements back
@@ -636,7 +628,7 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
} else if (info->is_wrapped_as_function()) {
DCHECK(parsing_on_main_thread_);
ParseWrapped(isolate, info, &body, scope, zone());
- } else if (info->is_repl_mode()) {
+ } else if (flags().is_repl_mode()) {
ParseREPLProgram(info, &body, scope);
} else {
// Don't count the mode in the use counters--give the program a chance
@@ -661,13 +653,13 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
}
// Internalize the ast strings in the case of eval so we can check for
// conflicting var declarations with outer scope-info-backed scopes.
- if (info->is_eval()) {
+ if (flags().is_eval()) {
DCHECK(parsing_on_main_thread_);
info->ast_value_factory()->Internalize(isolate);
}
CheckConflictingVarDeclarations(scope);
- if (info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
+ if (flags().parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
if (body.length() != 1 || !body.at(0)->IsExpressionStatement() ||
!body.at(0)
->AsExpressionStatement()
@@ -692,6 +684,33 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
return result;
}
+void Parser::PostProcessParseResult(Isolate* isolate, ParseInfo* info,
+ FunctionLiteral* literal) {
+ if (literal == nullptr) return;
+
+ info->set_literal(literal);
+ info->set_language_mode(literal->language_mode());
+ if (info->flags().is_eval()) {
+ info->set_allow_eval_cache(allow_eval_cache());
+ }
+
+ // We cannot internalize on a background thread; a foreground task will take
+ // care of calling AstValueFactory::Internalize just before compilation.
+ DCHECK_EQ(isolate != nullptr, parsing_on_main_thread_);
+ if (isolate) info->ast_value_factory()->Internalize(isolate);
+
+ {
+ RuntimeCallTimerScope runtimeTimer(info->runtime_call_stats(),
+ RuntimeCallCounterId::kCompileAnalyse,
+ RuntimeCallStats::kThreadSpecific);
+ if (!Rewriter::Rewrite(info) || !DeclarationScope::Analyze(info)) {
+ // Null out the literal to indicate that something failed.
+ info->set_literal(nullptr);
+ return;
+ }
+ }
+}
+
ZonePtrList<const AstRawString>* Parser::PrepareWrappedArguments(
Isolate* isolate, ParseInfo* info, Zone* zone) {
DCHECK(parsing_on_main_thread_);
@@ -745,7 +764,7 @@ void Parser::ParseREPLProgram(ParseInfo* info, ScopedPtrList<Statement>* body,
// completion value of the script is obtained by manually invoking
// the {Rewriter} which will return a VariableProxy referencing the
// result.
- DCHECK(info->is_repl_mode());
+ DCHECK(flags().is_repl_mode());
this->scope()->SetLanguageMode(info->language_mode());
PrepareGeneratorVariables();
@@ -791,8 +810,8 @@ Expression* Parser::WrapREPLResult(Expression* value) {
false);
}
-FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
- Handle<SharedFunctionInfo> shared_info) {
+void Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
+ Handle<SharedFunctionInfo> shared_info) {
// It's OK to use the Isolate & counters here, since this function is only
// called in the main thread.
DCHECK(parsing_on_main_thread_);
@@ -815,6 +834,10 @@ FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
Script::cast(shared_info->script()).wrapped_arguments(), isolate);
}
+ int start_position = shared_info->StartPosition();
+ int end_position = shared_info->EndPosition();
+ int function_literal_id = shared_info->function_literal_id();
+
// Initialize parser state.
Handle<String> name(shared_info->Name(), isolate);
info->set_function_name(ast_value_factory()->GetString(name));
@@ -827,9 +850,11 @@ FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
// function is in heritage position. Otherwise the function scope's skip bit
// will be correctly inherited from the outer scope.
ClassScope::HeritageParsingScope heritage(original_scope_->AsClassScope());
- result = DoParseFunction(isolate, info, info->function_name());
+ result = DoParseFunction(isolate, info, start_position, end_position,
+ function_literal_id, info->function_name());
} else {
- result = DoParseFunction(isolate, info, info->function_name());
+ result = DoParseFunction(isolate, info, start_position, end_position,
+ function_literal_id, info->function_name());
}
MaybeResetCharacterStream(info, result);
MaybeProcessSourceRanges(info, result, stack_limit_);
@@ -837,23 +862,25 @@ FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
Handle<String> inferred_name(shared_info->inferred_name(), isolate);
result->set_inferred_name(inferred_name);
}
+ PostProcessParseResult(isolate, info, result);
if (V8_UNLIKELY(FLAG_log_function_events) && result != nullptr) {
double ms = timer.Elapsed().InMillisecondsF();
- // We need to make sure that the debug-name is available.
- ast_value_factory()->Internalize(isolate);
+ // We should already be internalized by now, so the debug name will be
+ // available.
DeclarationScope* function_scope = result->scope();
std::unique_ptr<char[]> function_name = result->GetDebugName();
LOG(isolate,
- FunctionEvent("parse-function", script_id(), ms,
+ FunctionEvent("parse-function", flags().script_id(), ms,
function_scope->start_position(),
function_scope->end_position(), function_name.get(),
strlen(function_name.get())));
}
- return result;
}
FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
+ int start_position, int end_position,
+ int function_literal_id,
const AstRawString* raw_name) {
DCHECK_EQ(parsing_on_main_thread_, isolate != nullptr);
DCHECK_NOT_NULL(raw_name);
@@ -863,8 +890,8 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
fni_.PushEnclosingName(raw_name);
ResetFunctionLiteralId();
- DCHECK_LT(0, info->function_literal_id());
- SkipFunctionLiterals(info->function_literal_id() - 1);
+ DCHECK_LT(0, function_literal_id);
+ SkipFunctionLiterals(function_literal_id - 1);
ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
@@ -880,10 +907,10 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
BlockState block_state(&scope_, outer);
DCHECK(is_sloppy(outer->language_mode()) ||
is_strict(info->language_mode()));
- FunctionKind kind = info->function_kind();
- DCHECK_IMPLIES(
- IsConciseMethod(kind) || IsAccessorFunction(kind),
- info->function_syntax_kind() == FunctionSyntaxKind::kAccessorOrMethod);
+ FunctionKind kind = flags().function_kind();
+ DCHECK_IMPLIES(IsConciseMethod(kind) || IsAccessorFunction(kind),
+ flags().function_syntax_kind() ==
+ FunctionSyntaxKind::kAccessorOrMethod);
if (IsArrowFunction(kind)) {
if (IsAsyncFunction(kind)) {
@@ -906,7 +933,7 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
// not passing the ScopeInfo to the Scope constructor.
SetLanguageMode(scope, info->language_mode());
- scope->set_start_position(info->start_position());
+ scope->set_start_position(start_position);
ParserFormalParameters formals(scope);
{
ParameterDeclarationParsingScope formals_scope(this);
@@ -927,14 +954,14 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
formals.duplicate_loc = formals_scope.duplicate_location();
}
- if (GetLastFunctionLiteralId() != info->function_literal_id() - 1) {
+ if (GetLastFunctionLiteralId() != function_literal_id - 1) {
if (has_error()) return nullptr;
// If there were FunctionLiterals in the parameters, we need to
// renumber them to shift down so the next function literal id for
// the arrow function is the one requested.
AstFunctionLiteralIdReindexer reindexer(
stack_limit_,
- (info->function_literal_id() - 1) - GetLastFunctionLiteralId());
+ (function_literal_id - 1) - GetLastFunctionLiteralId());
for (auto p : formals.params) {
if (p->pattern != nullptr) reindexer.Reindex(p->pattern);
if (p->initializer() != nullptr) {
@@ -942,7 +969,7 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
}
}
ResetFunctionLiteralId();
- SkipFunctionLiterals(info->function_literal_id() - 1);
+ SkipFunctionLiterals(function_literal_id - 1);
}
Expression* expression = ParseArrowFunctionLiteral(formals);
@@ -952,7 +979,7 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
// concise body happens to be a valid expression. This is a problem
// only for arrow functions with single expression bodies, since there
// is no end token such as "}" for normal functions.
- if (scanner()->location().end_pos == info->end_position()) {
+ if (scanner()->location().end_pos == end_position) {
// The pre-parser saw an arrow function here, so the full parser
// must produce a FunctionLiteral.
DCHECK(expression->IsFunctionLiteral());
@@ -961,7 +988,7 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
} else if (IsDefaultConstructor(kind)) {
DCHECK_EQ(scope(), outer);
result = DefaultConstructor(raw_name, IsDerivedConstructor(kind),
- info->start_position(), info->end_position());
+ start_position, end_position);
} else {
ZonePtrList<const AstRawString>* arguments_for_wrapped_function =
info->is_wrapped_as_function()
@@ -969,24 +996,23 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
: nullptr;
result = ParseFunctionLiteral(
raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, kind,
- kNoSourcePosition, info->function_syntax_kind(),
+ kNoSourcePosition, flags().function_syntax_kind(),
info->language_mode(), arguments_for_wrapped_function);
}
if (has_error()) return nullptr;
result->set_requires_instance_members_initializer(
- info->requires_instance_members_initializer());
+ flags().requires_instance_members_initializer());
result->set_class_scope_has_private_brand(
- info->class_scope_has_private_brand());
+ flags().class_scope_has_private_brand());
result->set_has_static_private_methods_or_accessors(
- info->has_static_private_methods_or_accessors());
- if (info->is_oneshot_iife()) {
+ flags().has_static_private_methods_or_accessors());
+ if (flags().is_oneshot_iife()) {
result->mark_as_oneshot_iife();
}
}
- DCHECK_IMPLIES(result,
- info->function_literal_id() == result->function_literal_id());
+ DCHECK_IMPLIES(result, function_literal_id == result->function_literal_id());
return result;
}
@@ -1007,8 +1033,9 @@ Statement* Parser::ParseModuleItem() {
// We must be careful not to parse a dynamic import expression as an import
// declaration. Same for import.meta expressions.
Token::Value peek_ahead = PeekAhead();
- if ((!allow_harmony_dynamic_import() || peek_ahead != Token::LPAREN) &&
- (!allow_harmony_import_meta() || peek_ahead != Token::PERIOD)) {
+ if ((!flags().allow_harmony_dynamic_import() ||
+ peek_ahead != Token::LPAREN) &&
+ (!flags().allow_harmony_import_meta() || peek_ahead != Token::PERIOD)) {
ParseImportDeclaration();
return factory()->EmptyStatement();
}
@@ -1068,7 +1095,7 @@ ZoneChunkList<Parser::ExportClauseData>* Parser::ParseExportClause(
// caller needs to report an error.
if (!reserved_loc->IsValid() &&
!Token::IsValidIdentifier(name_tok, LanguageMode::kStrict, false,
- parsing_module_)) {
+ flags().is_module())) {
*reserved_loc = scanner()->location();
}
const AstRawString* local_name = ParsePropertyName();
@@ -1124,7 +1151,7 @@ ZonePtrList<const Parser::NamedImport>* Parser::ParseNamedImports(int pos) {
}
if (!Token::IsValidIdentifier(scanner()->current_token(),
LanguageMode::kStrict, false,
- parsing_module_)) {
+ flags().is_module())) {
ReportMessage(MessageTemplate::kUnexpectedReserved);
return nullptr;
} else if (IsEvalOrArguments(local_name)) {
@@ -1562,7 +1589,7 @@ Statement* Parser::DeclareFunction(const AstRawString* variable_name,
bool was_added;
Declare(declaration, variable_name, kind, mode, kCreatedInitialized, scope(),
&was_added, beg_pos);
- if (info()->coverage_enabled()) {
+ if (info()->flags().coverage_enabled()) {
// Force the function to be allocated when collecting source coverage, so
// that even dead functions get source coverage data.
declaration->var()->set_is_used();
@@ -2378,7 +2405,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
// parenthesis before the function means that it will be called
// immediately). bar can be parsed lazily, but we need to parse it in a mode
// that tracks unresolved variables.
- DCHECK_IMPLIES(parse_lazily(), info()->allow_lazy_compile());
+ DCHECK_IMPLIES(parse_lazily(), info()->flags().allow_lazy_compile());
DCHECK_IMPLIES(parse_lazily(), has_error() || allow_lazy_);
DCHECK_IMPLIES(parse_lazily(), extension_ == nullptr);
@@ -2477,7 +2504,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
? (is_top_level ? "preparse-no-resolution" : "preparse-resolution")
: "full-parse";
logger_->FunctionEvent(
- event_name, script_id(), ms, scope->start_position(),
+ event_name, flags().script_id(), ms, scope->start_position(),
scope->end_position(),
reinterpret_cast<const char*>(function_name->raw_data()),
function_name->byte_length());
@@ -2584,7 +2611,7 @@ bool Parser::SkipFunction(const AstRawString* function_name, FunctionKind kind,
PreParser::PreParseResult result = reusable_preparser()->PreParseFunction(
function_name, kind, function_syntax_kind, function_scope, use_counts_,
- produced_preparse_data, this->script_id());
+ produced_preparse_data);
if (result == PreParser::kPreParseStackOverflow) {
// Propagate stack overflow.
@@ -2733,6 +2760,7 @@ void Parser::ParseFunction(
bool* has_duplicate_parameters, int* expected_property_count,
int* suspend_count,
ZonePtrList<const AstRawString>* arguments_for_wrapped_function) {
+ FunctionParsingScope function_parsing_scope(this);
ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
FunctionState function_state(&function_state_, &scope_, function_scope);
@@ -2880,7 +2908,7 @@ void Parser::DeclarePrivateClassMember(ClassScope* scope,
ClassLiteralProperty::Kind kind,
bool is_static, ClassInfo* class_info) {
DCHECK_IMPLIES(kind != ClassLiteralProperty::Kind::FIELD,
- allow_harmony_private_methods());
+ flags().allow_harmony_private_methods());
if (kind == ClassLiteralProperty::Kind::FIELD) {
if (is_static) {
@@ -3085,11 +3113,11 @@ void Parser::UpdateStatistics(Isolate* isolate, Handle<Script> script) {
total_preparse_skipped_);
}
-void Parser::ParseOnBackground(ParseInfo* info) {
+void Parser::ParseOnBackground(ParseInfo* info, int start_position,
+ int end_position, int function_literal_id) {
RuntimeCallTimerScope runtimeTimer(
runtime_call_stats_, RuntimeCallCounterId::kParseBackgroundProgram);
parsing_on_main_thread_ = false;
- set_script_id(info->script_id());
DCHECK_NULL(info->literal());
FunctionLiteral* result = nullptr;
@@ -3104,19 +3132,19 @@ void Parser::ParseOnBackground(ParseInfo* info) {
// don't). We work around this by storing all the scopes which need their end
// position set at the end of the script (the top scope and possible eval
// scopes) and set their end position after we know the script length.
- if (info->is_toplevel()) {
+ if (flags().is_toplevel()) {
+ DCHECK_EQ(start_position, 0);
+ DCHECK_EQ(end_position, 0);
+ DCHECK_EQ(function_literal_id, kFunctionLiteralIdTopLevel);
result = DoParseProgram(/* isolate = */ nullptr, info);
} else {
- result =
- DoParseFunction(/* isolate = */ nullptr, info, info->function_name());
+ result = DoParseFunction(/* isolate = */ nullptr, info, start_position,
+ end_position, function_literal_id,
+ info->function_name());
}
MaybeResetCharacterStream(info, result);
MaybeProcessSourceRanges(info, result, stack_limit_);
-
- info->set_literal(result);
-
- // We cannot internalize on a background thread; a foreground task will take
- // care of calling AstValueFactory::Internalize just before compilation.
+ PostProcessParseResult(/* isolate = */ nullptr, info, result);
}
Parser::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
diff --git a/deps/v8/src/parsing/parser.h b/deps/v8/src/parsing/parser.h
index fd24ffb3e8..472c9a71ab 100644
--- a/deps/v8/src/parsing/parser.h
+++ b/deps/v8/src/parsing/parser.h
@@ -14,6 +14,7 @@
#include "src/base/compiler-specific.h"
#include "src/base/threaded-list.h"
#include "src/common/globals.h"
+#include "src/parsing/parse-info.h"
#include "src/parsing/parser-base.h"
#include "src/parsing/parsing.h"
#include "src/parsing/preparser.h"
@@ -134,7 +135,9 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
static bool IsPreParser() { return false; }
- void ParseOnBackground(ParseInfo* info);
+ // Sets the literal on |info| if parsing succeeded.
+ void ParseOnBackground(ParseInfo* info, int start_position, int end_position,
+ int function_literal_id);
// Initializes an empty scope chain for top-level scripts, or scopes which
// consist of only the native context.
@@ -207,14 +210,20 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
void PrepareGeneratorVariables();
- // Returns nullptr if parsing failed.
- FunctionLiteral* ParseProgram(Isolate* isolate, Handle<Script> script,
- ParseInfo* info,
- MaybeHandle<ScopeInfo> maybe_outer_scope_info);
+ // Sets the literal on |info| if parsing succeeded.
+ void ParseProgram(Isolate* isolate, Handle<Script> script, ParseInfo* info,
+ MaybeHandle<ScopeInfo> maybe_outer_scope_info);
+
+ // Sets the literal on |info| if parsing succeeded.
+ void ParseFunction(Isolate* isolate, ParseInfo* info,
+ Handle<SharedFunctionInfo> shared_info);
+
+ void PostProcessParseResult(Isolate* isolate, ParseInfo* info,
+ FunctionLiteral* literal);
- FunctionLiteral* ParseFunction(Isolate* isolate, ParseInfo* info,
- Handle<SharedFunctionInfo> shared_info);
FunctionLiteral* DoParseFunction(Isolate* isolate, ParseInfo* info,
+ int start_position, int end_position,
+ int function_literal_id,
const AstRawString* raw_name);
// Called by ParseProgram after setting up the scanner.
@@ -239,15 +248,9 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
if (reusable_preparser_ == nullptr) {
reusable_preparser_ = new PreParser(
&preparser_zone_, &scanner_, stack_limit_, ast_value_factory(),
- pending_error_handler(), runtime_call_stats_, logger_, -1,
- parsing_module_, parsing_on_main_thread_);
-#define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name());
- SET_ALLOW(natives);
- SET_ALLOW(harmony_dynamic_import);
- SET_ALLOW(harmony_import_meta);
- SET_ALLOW(harmony_private_methods);
- SET_ALLOW(eval_cache);
-#undef SET_ALLOW
+ pending_error_handler(), runtime_call_stats_, logger_, flags(),
+ parsing_on_main_thread_);
+ reusable_preparser_->set_allow_eval_cache(allow_eval_cache());
preparse_data_buffer_.reserve(128);
}
return reusable_preparser_;
diff --git a/deps/v8/src/parsing/parsing.cc b/deps/v8/src/parsing/parsing.cc
index 8a960cdc29..e126874d7d 100644
--- a/deps/v8/src/parsing/parsing.cc
+++ b/deps/v8/src/parsing/parsing.cc
@@ -12,6 +12,7 @@
#include "src/objects/objects-inl.h"
#include "src/parsing/parse-info.h"
#include "src/parsing/parser.h"
+#include "src/parsing/rewriter.h"
#include "src/parsing/scanner-character-streams.h"
#include "src/zone/zone-list-inl.h" // crbug.com/v8/8816
@@ -19,10 +20,27 @@ namespace v8 {
namespace internal {
namespace parsing {
+namespace {
+
+void MaybeReportErrorsAndStatistics(ParseInfo* info, Handle<Script> script,
+ Isolate* isolate, Parser* parser,
+ ReportErrorsAndStatisticsMode mode) {
+ if (mode == ReportErrorsAndStatisticsMode::kYes) {
+ if (info->literal() == nullptr) {
+ info->pending_error_handler()->PrepareErrors(isolate,
+ info->ast_value_factory());
+ info->pending_error_handler()->ReportErrors(isolate, script);
+ }
+ parser->UpdateStatistics(isolate, script);
+ }
+}
+
+} // namespace
+
bool ParseProgram(ParseInfo* info, Handle<Script> script,
MaybeHandle<ScopeInfo> maybe_outer_scope_info,
Isolate* isolate, ReportErrorsAndStatisticsMode mode) {
- DCHECK(info->is_toplevel());
+ DCHECK(info->flags().is_toplevel());
DCHECK_NULL(info->literal());
VMState<PARSER> state(isolate);
@@ -36,27 +54,11 @@ bool ParseProgram(ParseInfo* info, Handle<Script> script,
Parser parser(info);
- FunctionLiteral* result = nullptr;
// Ok to use Isolate here; this function is only called in the main thread.
DCHECK(parser.parsing_on_main_thread_);
-
- result = parser.ParseProgram(isolate, script, info, maybe_outer_scope_info);
- info->set_literal(result);
- if (result) {
- info->set_language_mode(info->literal()->language_mode());
- if (info->is_eval()) {
- info->set_allow_eval_cache(parser.allow_eval_cache());
- }
- }
-
- if (mode == ReportErrorsAndStatisticsMode::kYes) {
- if (result == nullptr) {
- info->pending_error_handler()->ReportErrors(isolate, script,
- info->ast_value_factory());
- }
- parser.UpdateStatistics(isolate, script);
- }
- return (result != nullptr);
+ parser.ParseProgram(isolate, script, info, maybe_outer_scope_info);
+ MaybeReportErrorsAndStatistics(info, script, isolate, &parser, mode);
+ return info->literal() != nullptr;
}
bool ParseProgram(ParseInfo* info, Handle<Script> script, Isolate* isolate,
@@ -66,10 +68,12 @@ bool ParseProgram(ParseInfo* info, Handle<Script> script, Isolate* isolate,
bool ParseFunction(ParseInfo* info, Handle<SharedFunctionInfo> shared_info,
Isolate* isolate, ReportErrorsAndStatisticsMode mode) {
- DCHECK(!info->is_toplevel());
+ DCHECK(!info->flags().is_toplevel());
DCHECK(!shared_info.is_null());
DCHECK_NULL(info->literal());
+ VMState<PARSER> state(isolate);
+
// Create a character stream for the parser.
Handle<Script> script(Script::cast(shared_info->script()), isolate);
Handle<String> source(String::cast(script->source()), isolate);
@@ -79,37 +83,19 @@ bool ParseFunction(ParseInfo* info, Handle<SharedFunctionInfo> shared_info,
shared_info->EndPosition()));
info->set_character_stream(std::move(stream));
- VMState<PARSER> state(isolate);
-
Parser parser(info);
- FunctionLiteral* result = nullptr;
// Ok to use Isolate here; this function is only called in the main thread.
DCHECK(parser.parsing_on_main_thread_);
-
- result = parser.ParseFunction(isolate, info, shared_info);
- info->set_literal(result);
- if (result) {
- info->ast_value_factory()->Internalize(isolate);
- if (info->is_eval()) {
- info->set_allow_eval_cache(parser.allow_eval_cache());
- }
- }
-
- if (mode == ReportErrorsAndStatisticsMode::kYes) {
- if (result == nullptr) {
- info->pending_error_handler()->ReportErrors(isolate, script,
- info->ast_value_factory());
- }
- parser.UpdateStatistics(isolate, script);
- }
- return (result != nullptr);
+ parser.ParseFunction(isolate, info, shared_info);
+ MaybeReportErrorsAndStatistics(info, script, isolate, &parser, mode);
+ return info->literal() != nullptr;
}
bool ParseAny(ParseInfo* info, Handle<SharedFunctionInfo> shared_info,
Isolate* isolate, ReportErrorsAndStatisticsMode mode) {
DCHECK(!shared_info.is_null());
- if (info->is_toplevel()) {
+ if (info->flags().is_toplevel()) {
MaybeHandle<ScopeInfo> maybe_outer_scope_info;
if (shared_info->HasOuterScopeInfo()) {
maybe_outer_scope_info =
diff --git a/deps/v8/src/parsing/pending-compilation-error-handler.cc b/deps/v8/src/parsing/pending-compilation-error-handler.cc
index 80d201d13f..f131b7ad8e 100644
--- a/deps/v8/src/parsing/pending-compilation-error-handler.cc
+++ b/deps/v8/src/parsing/pending-compilation-error-handler.cc
@@ -5,24 +5,68 @@
#include "src/parsing/pending-compilation-error-handler.h"
#include "src/ast/ast-value-factory.h"
+#include "src/base/logging.h"
#include "src/debug/debug.h"
#include "src/execution/isolate.h"
#include "src/execution/messages.h"
+#include "src/execution/off-thread-isolate.h"
#include "src/handles/handles.h"
+#include "src/heap/off-thread-factory-inl.h"
#include "src/objects/objects-inl.h"
namespace v8 {
namespace internal {
+void PendingCompilationErrorHandler::MessageDetails::SetString(
+ Handle<String> string, Isolate* isolate) {
+ DCHECK_NE(type_, kMainThreadHandle);
+ DCHECK_NE(type_, kOffThreadTransferHandle);
+ type_ = kMainThreadHandle;
+ arg_handle_ = string;
+}
+
+void PendingCompilationErrorHandler::MessageDetails::SetString(
+ Handle<String> string, OffThreadIsolate* isolate) {
+ DCHECK_NE(type_, kMainThreadHandle);
+ DCHECK_NE(type_, kOffThreadTransferHandle);
+ type_ = kOffThreadTransferHandle;
+ arg_transfer_handle_ = isolate->TransferHandle(string);
+}
+
+template <typename LocalIsolate>
+void PendingCompilationErrorHandler::MessageDetails::Prepare(
+ LocalIsolate* isolate) {
+ switch (type_) {
+ case kAstRawString:
+ return SetString(arg_->string(), isolate);
+ case kNone:
+ case kConstCharString:
+ // We can delay allocation until ArgumentString(isolate).
+ // TODO(leszeks): We don't actually have to transfer this string, since
+ // it's a root.
+ return;
+ case kMainThreadHandle:
+ case kOffThreadTransferHandle:
+ UNREACHABLE();
+ }
+}
+
Handle<String> PendingCompilationErrorHandler::MessageDetails::ArgumentString(
Isolate* isolate) const {
- if (arg_ != nullptr) return arg_->string();
- if (char_arg_ != nullptr) {
- return isolate->factory()
- ->NewStringFromUtf8(CStrVector(char_arg_))
- .ToHandleChecked();
+ switch (type_) {
+ case kMainThreadHandle:
+ return arg_handle_;
+ case kOffThreadTransferHandle:
+ return arg_transfer_handle_.ToHandle();
+ case kNone:
+ return isolate->factory()->undefined_string();
+ case kConstCharString:
+ return isolate->factory()
+ ->NewStringFromUtf8(CStrVector(char_arg_), AllocationType::kOld)
+ .ToHandleChecked();
+ case kAstRawString:
+ UNREACHABLE();
}
- return isolate->factory()->undefined_string();
}
MessageLocation PendingCompilationErrorHandler::MessageDetails::GetLocation(
@@ -37,8 +81,7 @@ void PendingCompilationErrorHandler::ReportMessageAt(int start_position,
if (has_pending_error_) return;
has_pending_error_ = true;
- error_details_ =
- MessageDetails(start_position, end_position, message, nullptr, arg);
+ error_details_ = MessageDetails(start_position, end_position, message, arg);
}
void PendingCompilationErrorHandler::ReportMessageAt(int start_position,
@@ -48,8 +91,7 @@ void PendingCompilationErrorHandler::ReportMessageAt(int start_position,
if (has_pending_error_) return;
has_pending_error_ = true;
- error_details_ =
- MessageDetails(start_position, end_position, message, arg, nullptr);
+ error_details_ = MessageDetails(start_position, end_position, message, arg);
}
void PendingCompilationErrorHandler::ReportWarningAt(int start_position,
@@ -57,11 +99,23 @@ void PendingCompilationErrorHandler::ReportWarningAt(int start_position,
MessageTemplate message,
const char* arg) {
warning_messages_.emplace_front(
- MessageDetails(start_position, end_position, message, nullptr, arg));
+ MessageDetails(start_position, end_position, message, arg));
}
-void PendingCompilationErrorHandler::ReportWarnings(Isolate* isolate,
- Handle<Script> script) {
+template <typename LocalIsolate>
+void PendingCompilationErrorHandler::PrepareWarnings(LocalIsolate* isolate) {
+ DCHECK(!has_pending_error());
+
+ for (MessageDetails& warning : warning_messages_) {
+ warning.Prepare(isolate);
+ }
+}
+template void PendingCompilationErrorHandler::PrepareWarnings(Isolate* isolate);
+template void PendingCompilationErrorHandler::PrepareWarnings(
+ OffThreadIsolate* isolate);
+
+void PendingCompilationErrorHandler::ReportWarnings(
+ Isolate* isolate, Handle<Script> script) const {
DCHECK(!has_pending_error());
for (const MessageDetails& warning : warning_messages_) {
@@ -75,27 +129,33 @@ void PendingCompilationErrorHandler::ReportWarnings(Isolate* isolate,
}
}
-void PendingCompilationErrorHandler::ReportWarnings(OffThreadIsolate* isolate,
- Handle<Script> script) {
- // TODO(leszeks): Do nothing, re-report on the main thread.
- UNREACHABLE();
+template <typename LocalIsolate>
+void PendingCompilationErrorHandler::PrepareErrors(
+ LocalIsolate* isolate, AstValueFactory* ast_value_factory) {
+ if (stack_overflow()) return;
+
+ DCHECK(has_pending_error());
+ // Internalize ast values for throwing the pending error.
+ ast_value_factory->Internalize(isolate);
+ error_details_.Prepare(isolate);
}
+template void PendingCompilationErrorHandler::PrepareErrors(
+ Isolate* isolate, AstValueFactory* ast_value_factory);
+template void PendingCompilationErrorHandler::PrepareErrors(
+ OffThreadIsolate* isolate, AstValueFactory* ast_value_factory);
-void PendingCompilationErrorHandler::ReportErrors(
- Isolate* isolate, Handle<Script> script,
- AstValueFactory* ast_value_factory) {
+void PendingCompilationErrorHandler::ReportErrors(Isolate* isolate,
+ Handle<Script> script) const {
if (stack_overflow()) {
isolate->StackOverflow();
} else {
DCHECK(has_pending_error());
- // Internalize ast values for throwing the pending error.
- ast_value_factory->Internalize(isolate);
ThrowPendingError(isolate, script);
}
}
-void PendingCompilationErrorHandler::ThrowPendingError(Isolate* isolate,
- Handle<Script> script) {
+void PendingCompilationErrorHandler::ThrowPendingError(
+ Isolate* isolate, Handle<Script> script) const {
if (!has_pending_error_) return;
MessageLocation location = error_details_.GetLocation(script);
@@ -109,7 +169,8 @@ void PendingCompilationErrorHandler::ThrowPendingError(Isolate* isolate,
}
Handle<String> PendingCompilationErrorHandler::FormatErrorMessageForTest(
- Isolate* isolate) const {
+ Isolate* isolate) {
+ error_details_.Prepare(isolate);
return MessageFormatter::Format(isolate, error_details_.message(),
error_details_.ArgumentString(isolate));
}
diff --git a/deps/v8/src/parsing/pending-compilation-error-handler.h b/deps/v8/src/parsing/pending-compilation-error-handler.h
index b854c3849e..4d15ac91ca 100644
--- a/deps/v8/src/parsing/pending-compilation-error-handler.h
+++ b/deps/v8/src/parsing/pending-compilation-error-handler.h
@@ -10,6 +10,7 @@
#include "src/base/macros.h"
#include "src/common/globals.h"
#include "src/common/message-template.h"
+#include "src/execution/off-thread-isolate.h"
#include "src/handles/handles.h"
namespace v8 {
@@ -47,15 +48,16 @@ class PendingCompilationErrorHandler {
bool has_pending_warnings() const { return !warning_messages_.empty(); }
// Handle errors detected during parsing.
- void ReportErrors(Isolate* isolate, Handle<Script> script,
- AstValueFactory* ast_value_factory);
+ template <typename LocalIsolate>
+ void PrepareErrors(LocalIsolate* isolate, AstValueFactory* ast_value_factory);
+ void ReportErrors(Isolate* isolate, Handle<Script> script) const;
// Handle warnings detected during compilation.
- void ReportWarnings(Isolate* isolate, Handle<Script> script);
- void ReportWarnings(OffThreadIsolate* isolate, Handle<Script> script);
+ template <typename LocalIsolate>
+ void PrepareWarnings(LocalIsolate* isolate);
+ void ReportWarnings(Isolate* isolate, Handle<Script> script) const;
- V8_EXPORT_PRIVATE Handle<String> FormatErrorMessageForTest(
- Isolate* isolate) const;
+ V8_EXPORT_PRIVATE Handle<String> FormatErrorMessageForTest(Isolate* isolate);
void set_unidentifiable_error() {
has_pending_error_ = true;
@@ -77,30 +79,54 @@ class PendingCompilationErrorHandler {
: start_position_(-1),
end_position_(-1),
message_(MessageTemplate::kNone),
- arg_(nullptr),
- char_arg_(nullptr) {}
+ type_(kNone) {}
MessageDetails(int start_position, int end_position,
- MessageTemplate message, const AstRawString* arg,
- const char* char_arg)
+ MessageTemplate message, const AstRawString* arg)
: start_position_(start_position),
end_position_(end_position),
message_(message),
arg_(arg),
- char_arg_(char_arg) {}
+ type_(arg ? kAstRawString : kNone) {}
+ MessageDetails(int start_position, int end_position,
+ MessageTemplate message, const char* char_arg)
+ : start_position_(start_position),
+ end_position_(end_position),
+ message_(message),
+ char_arg_(char_arg),
+ type_(char_arg_ ? kConstCharString : kNone) {}
Handle<String> ArgumentString(Isolate* isolate) const;
MessageLocation GetLocation(Handle<Script> script) const;
MessageTemplate message() const { return message_; }
+ template <typename LocalIsolate>
+ void Prepare(LocalIsolate* isolate);
+
private:
+ enum Type {
+ kNone,
+ kAstRawString,
+ kConstCharString,
+ kMainThreadHandle,
+ kOffThreadTransferHandle
+ };
+
+ void SetString(Handle<String> string, Isolate* isolate);
+ void SetString(Handle<String> string, OffThreadIsolate* isolate);
+
int start_position_;
int end_position_;
MessageTemplate message_;
- const AstRawString* arg_;
- const char* char_arg_;
+ union {
+ const AstRawString* arg_;
+ const char* char_arg_;
+ Handle<String> arg_handle_;
+ OffThreadTransferHandle<String> arg_transfer_handle_;
+ };
+ Type type_;
};
- void ThrowPendingError(Isolate* isolate, Handle<Script> script);
+ void ThrowPendingError(Isolate* isolate, Handle<Script> script) const;
bool has_pending_error_;
bool stack_overflow_;
diff --git a/deps/v8/src/parsing/preparse-data-impl.h b/deps/v8/src/parsing/preparse-data-impl.h
index 11165da5ed..707e76236d 100644
--- a/deps/v8/src/parsing/preparse-data-impl.h
+++ b/deps/v8/src/parsing/preparse-data-impl.h
@@ -158,17 +158,20 @@ class BaseConsumedPreparseData : public ConsumedPreparseData {
LanguageMode* language_mode) final;
void RestoreScopeAllocationData(DeclarationScope* scope,
- AstValueFactory* ast_value_factory) final;
+ AstValueFactory* ast_value_factory,
+ Zone* zone) final;
#ifdef DEBUG
bool VerifyDataStart();
#endif
private:
- void RestoreDataForScope(Scope* scope, AstValueFactory* ast_value_factory);
+ void RestoreDataForScope(Scope* scope, AstValueFactory* ast_value_factory,
+ Zone* zone);
void RestoreDataForVariable(Variable* var);
void RestoreDataForInnerScopes(Scope* scope,
- AstValueFactory* ast_value_factory);
+ AstValueFactory* ast_value_factory,
+ Zone* zone);
std::unique_ptr<ByteData> scope_data_;
// When consuming the data, these indexes point to the data we're going to
diff --git a/deps/v8/src/parsing/preparse-data.cc b/deps/v8/src/parsing/preparse-data.cc
index 7161861b76..d421cb868c 100644
--- a/deps/v8/src/parsing/preparse-data.cc
+++ b/deps/v8/src/parsing/preparse-data.cc
@@ -613,7 +613,7 @@ BaseConsumedPreparseData<Data>::GetDataForSkippableFunction(
template <class Data>
void BaseConsumedPreparseData<Data>::RestoreScopeAllocationData(
- DeclarationScope* scope, AstValueFactory* ast_value_factory) {
+ DeclarationScope* scope, AstValueFactory* ast_value_factory, Zone* zone) {
DCHECK_EQ(scope->scope_type(), ScopeType::FUNCTION_SCOPE);
typename ByteData::ReadingScope reading_scope(this);
@@ -628,7 +628,7 @@ void BaseConsumedPreparseData<Data>::RestoreScopeAllocationData(
DCHECK_EQ(end_position_from_data, scope->end_position());
#endif
- RestoreDataForScope(scope, ast_value_factory);
+ RestoreDataForScope(scope, ast_value_factory, zone);
// Check that we consumed all scope data.
DCHECK_EQ(scope_data_->RemainingBytes(), 0);
@@ -636,7 +636,7 @@ void BaseConsumedPreparseData<Data>::RestoreScopeAllocationData(
template <typename Data>
void BaseConsumedPreparseData<Data>::RestoreDataForScope(
- Scope* scope, AstValueFactory* ast_value_factory) {
+ Scope* scope, AstValueFactory* ast_value_factory, Zone* zone) {
if (scope->is_declaration_scope() &&
scope->AsDeclarationScope()->is_skipped_function()) {
return;
@@ -670,7 +670,7 @@ void BaseConsumedPreparseData<Data>::RestoreDataForScope(
if (scope->AsClassScope()->is_anonymous_class()) {
var = scope->AsClassScope()->DeclareClassVariable(
ast_value_factory, nullptr, kNoSourcePosition);
- AstNodeFactory factory(ast_value_factory, ast_value_factory->zone());
+ AstNodeFactory factory(ast_value_factory, zone);
Declaration* declaration =
factory.NewVariableDeclaration(kNoSourcePosition);
scope->declarations()->Add(declaration);
@@ -692,7 +692,7 @@ void BaseConsumedPreparseData<Data>::RestoreDataForScope(
if (IsSerializableVariableMode(var->mode())) RestoreDataForVariable(var);
}
- RestoreDataForInnerScopes(scope, ast_value_factory);
+ RestoreDataForInnerScopes(scope, ast_value_factory, zone);
}
template <typename Data>
@@ -732,10 +732,10 @@ void BaseConsumedPreparseData<Data>::RestoreDataForVariable(Variable* var) {
template <typename Data>
void BaseConsumedPreparseData<Data>::RestoreDataForInnerScopes(
- Scope* scope, AstValueFactory* ast_value_factory) {
+ Scope* scope, AstValueFactory* ast_value_factory, Zone* zone) {
for (Scope* inner = scope->inner_scope(); inner != nullptr;
inner = inner->sibling()) {
- RestoreDataForScope(inner, ast_value_factory);
+ RestoreDataForScope(inner, ast_value_factory, zone);
}
}
diff --git a/deps/v8/src/parsing/preparse-data.h b/deps/v8/src/parsing/preparse-data.h
index 409942f8c3..aa31326f9f 100644
--- a/deps/v8/src/parsing/preparse-data.h
+++ b/deps/v8/src/parsing/preparse-data.h
@@ -134,8 +134,6 @@ class V8_EXPORT_PRIVATE PreparseDataBuilder : public ZoneObject,
ByteData()
: byte_data_(nullptr), index_(0), free_quarters_in_last_byte_(0) {}
- ~ByteData() {}
-
void Start(std::vector<uint8_t>* buffer);
void Finalize(Zone* zone);
@@ -297,8 +295,9 @@ class ConsumedPreparseData {
// Restores the information needed for allocating the Scope's (and its
// subscopes') variables.
- virtual void RestoreScopeAllocationData(
- DeclarationScope* scope, AstValueFactory* ast_value_factory) = 0;
+ virtual void RestoreScopeAllocationData(DeclarationScope* scope,
+ AstValueFactory* ast_value_factory,
+ Zone* zone) = 0;
protected:
ConsumedPreparseData() = default;
diff --git a/deps/v8/src/parsing/preparser.cc b/deps/v8/src/parsing/preparser.cc
index 464e8e7b17..f9af109d81 100644
--- a/deps/v8/src/parsing/preparser.cc
+++ b/deps/v8/src/parsing/preparser.cc
@@ -78,7 +78,7 @@ PreParser::PreParseResult PreParser::PreParseProgram() {
// ModuleDeclarationInstantiation for Source Text Module Records creates a
// new Module Environment Record whose outer lexical environment record is
// the global scope.
- if (parsing_module_) scope = NewModuleScope(scope);
+ if (flags().is_module()) scope = NewModuleScope(scope);
FunctionState top_scope(&function_state_, &scope_, scope);
original_scope_ = scope_;
@@ -105,11 +105,9 @@ void PreParserFormalParameters::ValidateStrictMode(PreParser* preparser) const {
PreParser::PreParseResult PreParser::PreParseFunction(
const AstRawString* function_name, FunctionKind kind,
FunctionSyntaxKind function_syntax_kind, DeclarationScope* function_scope,
- int* use_counts, ProducedPreparseData** produced_preparse_data,
- int script_id) {
+ int* use_counts, ProducedPreparseData** produced_preparse_data) {
DCHECK_EQ(FUNCTION_SCOPE, function_scope->scope_type());
use_counts_ = use_counts;
- set_script_id(script_id);
#ifdef DEBUG
function_scope->set_is_being_lazily_parsed(true);
#endif
@@ -268,6 +266,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
int function_token_pos, FunctionSyntaxKind function_syntax_kind,
LanguageMode language_mode,
ZonePtrList<const AstRawString>* arguments_for_wrapped_function) {
+ FunctionParsingScope function_parsing_scope(this);
// Wrapped functions are not parsed in the preparser.
DCHECK_NULL(arguments_for_wrapped_function);
DCHECK_NE(FunctionSyntaxKind::kWrapped, function_syntax_kind);
@@ -358,7 +357,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
name_byte_length = string->byte_length();
}
logger_->FunctionEvent(
- event_name, script_id(), ms, function_scope->start_position(),
+ event_name, flags().script_id(), ms, function_scope->start_position(),
function_scope->end_position(), name, name_byte_length);
}
diff --git a/deps/v8/src/parsing/preparser.h b/deps/v8/src/parsing/preparser.h
index 3c1122ef00..5280e3d226 100644
--- a/deps/v8/src/parsing/preparser.h
+++ b/deps/v8/src/parsing/preparser.h
@@ -8,6 +8,7 @@
#include "src/ast/ast-value-factory.h"
#include "src/ast/ast.h"
#include "src/ast/scopes.h"
+#include "src/parsing/parse-info.h"
#include "src/parsing/parser-base.h"
#include "src/parsing/pending-compilation-error-handler.h"
#include "src/parsing/preparser-logger.h"
@@ -921,12 +922,11 @@ class PreParser : public ParserBase<PreParser> {
AstValueFactory* ast_value_factory,
PendingCompilationErrorHandler* pending_error_handler,
RuntimeCallStats* runtime_call_stats, Logger* logger,
- int script_id = -1, bool parsing_module = false,
- bool parsing_on_main_thread = true)
+ UnoptimizedCompileFlags flags, bool parsing_on_main_thread = true)
: ParserBase<PreParser>(zone, scanner, stack_limit, nullptr,
ast_value_factory, pending_error_handler,
- runtime_call_stats, logger, script_id,
- parsing_module, parsing_on_main_thread),
+ runtime_call_stats, logger, flags,
+ parsing_on_main_thread),
use_counts_(nullptr),
preparse_data_builder_(nullptr),
preparse_data_builder_buffer_() {
@@ -954,8 +954,7 @@ class PreParser : public ParserBase<PreParser> {
PreParseResult PreParseFunction(
const AstRawString* function_name, FunctionKind kind,
FunctionSyntaxKind function_syntax_kind, DeclarationScope* function_scope,
- int* use_counts, ProducedPreparseData** produced_preparser_scope_data,
- int script_id);
+ int* use_counts, ProducedPreparseData** produced_preparser_scope_data);
PreparseDataBuilder* preparse_data_builder() const {
return preparse_data_builder_;
diff --git a/deps/v8/src/parsing/rewriter.cc b/deps/v8/src/parsing/rewriter.cc
index 75ec661d2d..942acf13f8 100644
--- a/deps/v8/src/parsing/rewriter.cc
+++ b/deps/v8/src/parsing/rewriter.cc
@@ -17,12 +17,12 @@ namespace internal {
class Processor final : public AstVisitor<Processor> {
public:
Processor(uintptr_t stack_limit, DeclarationScope* closure_scope,
- Variable* result, AstValueFactory* ast_value_factory)
+ Variable* result, AstValueFactory* ast_value_factory, Zone* zone)
: result_(result),
replacement_(nullptr),
- zone_(ast_value_factory->zone()),
+ zone_(zone),
closure_scope_(closure_scope),
- factory_(ast_value_factory, ast_value_factory->zone()),
+ factory_(ast_value_factory, zone),
result_assigned_(false),
is_set_(false),
breakable_(false) {
@@ -31,10 +31,10 @@ class Processor final : public AstVisitor<Processor> {
}
Processor(Parser* parser, DeclarationScope* closure_scope, Variable* result,
- AstValueFactory* ast_value_factory)
+ AstValueFactory* ast_value_factory, Zone* zone)
: result_(result),
replacement_(nullptr),
- zone_(ast_value_factory->zone()),
+ zone_(zone),
closure_scope_(closure_scope),
factory_(ast_value_factory, zone_),
result_assigned_(false),
@@ -392,7 +392,7 @@ base::Optional<VariableProxy*> Rewriter::RewriteBody(
Variable* result = scope->AsDeclarationScope()->NewTemporary(
info->ast_value_factory()->dot_result_string());
Processor processor(info->stack_limit(), scope->AsDeclarationScope(),
- result, info->ast_value_factory());
+ result, info->ast_value_factory(), info->zone());
processor.Process(body);
DCHECK_IMPLIES(scope->is_module_scope(), processor.result_assigned());
@@ -400,7 +400,7 @@ base::Optional<VariableProxy*> Rewriter::RewriteBody(
int pos = kNoSourcePosition;
VariableProxy* result_value =
processor.factory()->NewVariableProxy(result, pos);
- if (!info->is_repl_mode()) {
+ if (!info->flags().is_repl_mode()) {
Statement* result_statement =
processor.factory()->NewReturnStatement(result_value, pos);
body->Add(result_statement, info->zone());
@@ -408,7 +408,10 @@ base::Optional<VariableProxy*> Rewriter::RewriteBody(
return result_value;
}
- if (processor.HasStackOverflow()) return base::nullopt;
+ if (processor.HasStackOverflow()) {
+ info->pending_error_handler()->set_stack_overflow();
+ return base::nullopt;
+ }
}
return nullptr;
}
diff --git a/deps/v8/src/parsing/scanner-inl.h b/deps/v8/src/parsing/scanner-inl.h
index fc5194f263..bd4d0284d8 100644
--- a/deps/v8/src/parsing/scanner-inl.h
+++ b/deps/v8/src/parsing/scanner-inl.h
@@ -364,14 +364,14 @@ V8_INLINE Token::Value Scanner::ScanSingleToken() {
return Select(token);
case Token::CONDITIONAL:
- // ? ?. ??
+ // ? ?. ?? ??=
Advance();
- if (V8_UNLIKELY(allow_harmony_optional_chaining() && c0_ == '.')) {
+ if (c0_ == '.') {
Advance();
if (!IsDecimalDigit(c0_)) return Token::QUESTION_PERIOD;
PushBack('.');
- } else if (V8_UNLIKELY(allow_harmony_nullish() && c0_ == '?')) {
- return Select(Token::NULLISH);
+ } else if (c0_ == '?') {
+ return Select('=', Token::ASSIGN_NULLISH, Token::NULLISH);
}
return Token::CONDITIONAL;
@@ -471,16 +471,16 @@ V8_INLINE Token::Value Scanner::ScanSingleToken() {
return Token::DIV;
case Token::BIT_AND:
- // & && &=
+ // & && &= &&=
Advance();
- if (c0_ == '&') return Select(Token::AND);
+ if (c0_ == '&') return Select('=', Token::ASSIGN_AND, Token::AND);
if (c0_ == '=') return Select(Token::ASSIGN_BIT_AND);
return Token::BIT_AND;
case Token::BIT_OR:
- // | || |=
+ // | || |= ||=
Advance();
- if (c0_ == '|') return Select(Token::OR);
+ if (c0_ == '|') return Select('=', Token::ASSIGN_OR, Token::OR);
if (c0_ == '=') return Select(Token::ASSIGN_BIT_OR);
return Token::BIT_OR;
diff --git a/deps/v8/src/parsing/scanner.cc b/deps/v8/src/parsing/scanner.cc
index 91e4183d53..52a1bf0724 100644
--- a/deps/v8/src/parsing/scanner.cc
+++ b/deps/v8/src/parsing/scanner.cc
@@ -13,6 +13,7 @@
#include "src/ast/ast-value-factory.h"
#include "src/numbers/conversions-inl.h"
#include "src/objects/bigint.h"
+#include "src/parsing/parse-info.h"
#include "src/parsing/scanner-inl.h"
#include "src/zone/zone.h"
@@ -89,12 +90,10 @@ bool Scanner::BookmarkScope::HasBeenApplied() const {
// ----------------------------------------------------------------------------
// Scanner
-Scanner::Scanner(Utf16CharacterStream* source, bool is_module)
- : source_(source),
+Scanner::Scanner(Utf16CharacterStream* source, UnoptimizedCompileFlags flags)
+ : flags_(flags),
+ source_(source),
found_html_comment_(false),
- allow_harmony_optional_chaining_(false),
- allow_harmony_nullish_(false),
- is_module_(is_module),
octal_pos_(Location::invalid()),
octal_message_(MessageTemplate::kNone) {
DCHECK_NOT_NULL(source);
@@ -190,7 +189,7 @@ Token::Value Scanner::PeekAhead() {
}
Token::Value Scanner::SkipSingleHTMLComment() {
- if (is_module_) {
+ if (flags_.is_module()) {
ReportScannerError(source_pos(), MessageTemplate::kHtmlCommentInModule);
return Token::ILLEGAL;
}
@@ -233,9 +232,9 @@ void Scanner::TryToParseSourceURLComment() {
if (!name.is_one_byte()) return;
Vector<const uint8_t> name_literal = name.one_byte_literal();
LiteralBuffer* value;
- if (name_literal == StaticCharVector("sourceURL")) {
+ if (name_literal == StaticOneByteVector("sourceURL")) {
value = &source_url_;
- } else if (name_literal == StaticCharVector("sourceMappingURL")) {
+ } else if (name_literal == StaticOneByteVector("sourceMappingURL")) {
value = &source_mapping_url_;
} else {
return;
diff --git a/deps/v8/src/parsing/scanner.h b/deps/v8/src/parsing/scanner.h
index bed63c9d4e..830067e1ad 100644
--- a/deps/v8/src/parsing/scanner.h
+++ b/deps/v8/src/parsing/scanner.h
@@ -15,6 +15,7 @@
#include "src/common/globals.h"
#include "src/common/message-template.h"
#include "src/parsing/literal-buffer.h"
+#include "src/parsing/parse-info.h"
#include "src/parsing/token.h"
#include "src/strings/char-predicates.h"
#include "src/strings/unicode.h"
@@ -269,7 +270,7 @@ class V8_EXPORT_PRIVATE Scanner {
static const int kNoOctalLocation = -1;
static const uc32 kEndOfInput = Utf16CharacterStream::kEndOfInput;
- explicit Scanner(Utf16CharacterStream* source, bool is_module);
+ explicit Scanner(Utf16CharacterStream* source, UnoptimizedCompileFlags flags);
void Initialize();
@@ -410,18 +411,6 @@ class V8_EXPORT_PRIVATE Scanner {
bool FoundHtmlComment() const { return found_html_comment_; }
- bool allow_harmony_optional_chaining() const {
- return allow_harmony_optional_chaining_;
- }
-
- void set_allow_harmony_optional_chaining(bool allow) {
- allow_harmony_optional_chaining_ = allow;
- }
-
- bool allow_harmony_nullish() const { return allow_harmony_nullish_; }
-
- void set_allow_harmony_nullish(bool allow) { allow_harmony_nullish_ = allow; }
-
const Utf16CharacterStream* stream() const { return source_; }
private:
@@ -715,6 +704,8 @@ class V8_EXPORT_PRIVATE Scanner {
const TokenDesc& next() const { return *next_; }
const TokenDesc& next_next() const { return *next_next_; }
+ UnoptimizedCompileFlags flags_;
+
TokenDesc* current_; // desc for current token (as returned by Next())
TokenDesc* next_; // desc for next token (one token look-ahead)
TokenDesc* next_next_; // desc for the token after next (after PeakAhead())
@@ -730,12 +721,6 @@ class V8_EXPORT_PRIVATE Scanner {
// Whether this scanner encountered an HTML comment.
bool found_html_comment_;
- // Harmony flags to allow ESNext features.
- bool allow_harmony_optional_chaining_;
- bool allow_harmony_nullish_;
-
- const bool is_module_;
-
// Values parsed from magic comments.
LiteralBuffer source_url_;
LiteralBuffer source_mapping_url_;
diff --git a/deps/v8/src/parsing/token.h b/deps/v8/src/parsing/token.h
index 4749945ebd..ef92238de2 100644
--- a/deps/v8/src/parsing/token.h
+++ b/deps/v8/src/parsing/token.h
@@ -31,6 +31,9 @@ namespace internal {
/* Binary operators */
/* ADD and SUB are at the end since they are UnaryOp */
#define BINARY_OP_TOKEN_LIST(T, E) \
+ E(T, NULLISH, "??", 3) \
+ E(T, OR, "||", 4) \
+ E(T, AND, "&&", 5) \
E(T, BIT_OR, "|", 6) \
E(T, BIT_XOR, "^", 7) \
E(T, BIT_AND, "&", 8) \
@@ -97,9 +100,6 @@ namespace internal {
/* IsBinaryOp() relies on this block of enum values */ \
/* being contiguous and sorted in the same order! */ \
T(COMMA, ",", 1) \
- T(NULLISH, "??", 3) \
- T(OR, "||", 4) \
- T(AND, "&&", 5) \
\
/* Unary operators, starting at ADD in BINARY_OP_TOKEN_LIST */ \
/* IsUnaryOp() relies on this block of enum values */ \
@@ -297,8 +297,8 @@ class V8_EXPORT_PRIVATE Token {
}
static Value BinaryOpForAssignment(Value op) {
- DCHECK(base::IsInRange(op, ASSIGN_BIT_OR, ASSIGN_SUB));
- Value result = static_cast<Value>(op - ASSIGN_BIT_OR + BIT_OR);
+ DCHECK(base::IsInRange(op, ASSIGN_NULLISH, ASSIGN_SUB));
+ Value result = static_cast<Value>(op - ASSIGN_NULLISH + NULLISH);
DCHECK(IsBinaryOp(result));
return result;
}