Revert "Reland^4 "[parser] Introduce UnoptimizedCompileFlags""

This reverts commit e1b93a4ff5.

Reason for revert: MSVC failing https://ci.chromium.org/p/v8/builders/ci/V8%20Win64%20-%20msvc/13274

Original change's description:
> Reland^4 "[parser] Introduce UnoptimizedCompileFlags"
> 
> This is a reland of 313d4844d9
> which was a reland of 0a59e0cb08
> which was a reland of 146f5375da
> which was a reland of d91679bf3a
> 
> Manually zero out flags with memset, since GCC appears not to initialize
> the bitfield values to zero even with a default constructor.
> 
> Original change's description:
> > [parser] Introduce UnoptimizedCompileFlags
> >
> > UnoptimizedCompileFlags defines the input flags shared between parse and
> > compile (currently parse-only). It is set initially with some values, and
> > is immutable after being passed to ParseInfo (ParseInfo still has getters
> > for the fields, but no setters).
> >
> > Since a few of the existing flags were output flags, ParseInfo now has a
> > new output_flags field, which will eventually migrate to a ParseOutputs
> > structure.
> >
> > Bug: v8:10314
> > Change-Id: If3890a5fad883bca80a97bf9dfe44d91797dc286
> > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2096580
> > Commit-Queue: Leszek Swirski <leszeks@chromium.org>
> > Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
> > Reviewed-by: Simon Zünd <szuend@chromium.org>
> > Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
> > Cr-Commit-Position: refs/heads/master@{#66782}
> 
> TBR=ulan@chromium.org,szuend@chromium.org,rmcilroy@chromium.org
> 
> Bug: v8:10314
> Change-Id: I23bd6f9f14e9d0bbdde91aad46be1a646fd9647d
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2157372
> Reviewed-by: Leszek Swirski <leszeks@chromium.org>
> Commit-Queue: Leszek Swirski <leszeks@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#67271}

TBR=ulan@chromium.org,rmcilroy@chromium.org,leszeks@chromium.org,szuend@chromium.org

Change-Id: I0f41e847d4edae67e131cc6d0f782137ab73bac2
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: v8:10314
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2157377
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67275}
This commit is contained in:
Leszek Swirski 2020-04-21 12:13:39 +00:00 committed by Commit Bot
parent 1e6669a7e3
commit 33ea5e55ba
32 changed files with 709 additions and 729 deletions

View File

@ -2725,7 +2725,7 @@ bool ClassScope::ResolvePrivateNames(ParseInfo* info) {
if (var == nullptr) { if (var == nullptr) {
// It's only possible to fail to resolve private names here if // It's only possible to fail to resolve private names here if
// this is at the top level or the private name is accessed through eval. // this is at the top level or the private name is accessed through eval.
DCHECK(info->flags().is_eval || outer_scope_->is_script_scope()); DCHECK(info->is_eval() || outer_scope_->is_script_scope());
Scanner::Location loc = proxy->location(); Scanner::Location loc = proxy->location();
info->pending_error_handler()->ReportMessageAt( info->pending_error_handler()->ReportMessageAt(
loc.beg_pos, loc.end_pos, loc.beg_pos, loc.end_pos,

View File

@ -496,7 +496,7 @@ template <typename LocalIsolate>
void EnsureSharedFunctionInfosArrayOnScript(Handle<Script> script, void EnsureSharedFunctionInfosArrayOnScript(Handle<Script> script,
ParseInfo* parse_info, ParseInfo* parse_info,
LocalIsolate* isolate) { LocalIsolate* isolate) {
DCHECK(parse_info->flags().is_toplevel); DCHECK(parse_info->is_toplevel());
if (script->shared_function_infos().length() > 0) { if (script->shared_function_infos().length() > 0) {
DCHECK_EQ(script->shared_function_infos().length(), DCHECK_EQ(script->shared_function_infos().length(),
parse_info->max_function_literal_id() + 1); parse_info->max_function_literal_id() + 1);
@ -529,7 +529,6 @@ CompilationJob::Status FinalizeUnoptimizedCompilationJob(
Isolate* isolate) { Isolate* isolate) {
UnoptimizedCompilationInfo* compilation_info = job->compilation_info(); UnoptimizedCompilationInfo* compilation_info = job->compilation_info();
ParseInfo* parse_info = job->parse_info(); ParseInfo* parse_info = job->parse_info();
const UnoptimizedCompileFlags flags = parse_info->flags();
SetSharedFunctionFlagsFromLiteral(compilation_info->literal(), *shared_info); SetSharedFunctionFlagsFromLiteral(compilation_info->literal(), *shared_info);
@ -541,18 +540,18 @@ CompilationJob::Status FinalizeUnoptimizedCompilationJob(
// background compile was started in which the compiled bytecode will not be // background compile was started in which the compiled bytecode will not be
// missing source positions (for instance by enabling the cpu profiler). So // missing source positions (for instance by enabling the cpu profiler). So
// force source position collection now in that case. // force source position collection now in that case.
if (!flags.collect_source_positions && if (!parse_info->collect_source_positions() &&
isolate->NeedsDetailedOptimizedCodeLineInfo()) { isolate->NeedsDetailedOptimizedCodeLineInfo()) {
SharedFunctionInfo::EnsureSourcePositionsAvailable(isolate, shared_info); SharedFunctionInfo::EnsureSourcePositionsAvailable(isolate, shared_info);
} }
CodeEventListener::LogEventsAndTags log_tag; CodeEventListener::LogEventsAndTags log_tag;
if (flags.is_toplevel) { if (parse_info->is_toplevel()) {
log_tag = flags.is_eval ? CodeEventListener::EVAL_TAG log_tag = compilation_info->is_eval() ? CodeEventListener::EVAL_TAG
: CodeEventListener::SCRIPT_TAG; : CodeEventListener::SCRIPT_TAG;
} else { } else {
log_tag = flags.is_lazy_compile ? CodeEventListener::LAZY_COMPILE_TAG log_tag = parse_info->lazy_compile() ? CodeEventListener::LAZY_COMPILE_TAG
: CodeEventListener::FUNCTION_TAG; : CodeEventListener::FUNCTION_TAG;
} }
job->RecordFunctionCompilation(log_tag, shared_info, isolate); job->RecordFunctionCompilation(log_tag, shared_info, isolate);
job->RecordCompilationStats(isolate); job->RecordCompilationStats(isolate);
@ -581,7 +580,7 @@ std::unique_ptr<UnoptimizedCompilationJob> ExecuteUnoptimizedCompileJobs(
ParseInfo* parse_info, FunctionLiteral* literal, ParseInfo* parse_info, FunctionLiteral* literal,
AccountingAllocator* allocator, AccountingAllocator* allocator,
UnoptimizedCompilationJobList* inner_function_jobs) { UnoptimizedCompilationJobList* inner_function_jobs) {
if (UseAsmWasm(literal, parse_info->flags().is_asm_wasm_broken)) { if (UseAsmWasm(literal, parse_info->is_asm_wasm_broken())) {
std::unique_ptr<UnoptimizedCompilationJob> asm_job( std::unique_ptr<UnoptimizedCompilationJob> asm_job(
AsmJs::NewCompilationJob(parse_info, literal, allocator)); AsmJs::NewCompilationJob(parse_info, literal, allocator));
if (asm_job->ExecuteJob() == CompilationJob::SUCCEEDED) { if (asm_job->ExecuteJob() == CompilationJob::SUCCEEDED) {
@ -658,7 +657,7 @@ MaybeHandle<SharedFunctionInfo> GenerateUnoptimizedCodeForToplevel(
Handle<SharedFunctionInfo> shared_info = Handle<SharedFunctionInfo> shared_info =
Compiler::GetSharedFunctionInfo(literal, script, isolate); Compiler::GetSharedFunctionInfo(literal, script, isolate);
if (shared_info->is_compiled()) continue; if (shared_info->is_compiled()) continue;
if (UseAsmWasm(literal, parse_info->flags().is_asm_wasm_broken)) { if (UseAsmWasm(literal, parse_info->is_asm_wasm_broken())) {
std::unique_ptr<UnoptimizedCompilationJob> asm_job( std::unique_ptr<UnoptimizedCompilationJob> asm_job(
AsmJs::NewCompilationJob(parse_info, literal, allocator)); AsmJs::NewCompilationJob(parse_info, literal, allocator));
if (asm_job->ExecuteJob() == CompilationJob::SUCCEEDED && if (asm_job->ExecuteJob() == CompilationJob::SUCCEEDED &&
@ -1087,9 +1086,8 @@ MaybeHandle<SharedFunctionInfo> CompileToplevel(
PostponeInterruptsScope postpone(isolate); PostponeInterruptsScope postpone(isolate);
DCHECK(!isolate->native_context().is_null()); DCHECK(!isolate->native_context().is_null());
RuntimeCallTimerScope runtimeTimer( RuntimeCallTimerScope runtimeTimer(
isolate, parse_info->flags().is_eval isolate, parse_info->is_eval() ? RuntimeCallCounterId::kCompileEval
? RuntimeCallCounterId::kCompileEval : RuntimeCallCounterId::kCompileScript);
: RuntimeCallCounterId::kCompileScript);
VMState<BYTECODE_COMPILER> state(isolate); VMState<BYTECODE_COMPILER> state(isolate);
if (parse_info->literal() == nullptr && if (parse_info->literal() == nullptr &&
!parsing::ParseProgram(parse_info, script, maybe_outer_scope_info, !parsing::ParseProgram(parse_info, script, maybe_outer_scope_info,
@ -1099,12 +1097,12 @@ MaybeHandle<SharedFunctionInfo> CompileToplevel(
// Measure how long it takes to do the compilation; only take the // Measure how long it takes to do the compilation; only take the
// rest of the function into account to avoid overlap with the // rest of the function into account to avoid overlap with the
// parsing statistics. // parsing statistics.
HistogramTimer* rate = parse_info->flags().is_eval HistogramTimer* rate = parse_info->is_eval()
? isolate->counters()->compile_eval() ? isolate->counters()->compile_eval()
: isolate->counters()->compile(); : isolate->counters()->compile();
HistogramTimerScope timer(rate); HistogramTimerScope timer(rate);
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
parse_info->flags().is_eval ? "V8.CompileEval" : "V8.Compile"); parse_info->is_eval() ? "V8.CompileEval" : "V8.Compile");
// Generate the unoptimized bytecode or asm-js data. // Generate the unoptimized bytecode or asm-js data.
MaybeHandle<SharedFunctionInfo> shared_info = MaybeHandle<SharedFunctionInfo> shared_info =
@ -1128,8 +1126,8 @@ std::unique_ptr<UnoptimizedCompilationJob> CompileOnBackgroundThread(
"V8.CompileCodeBackground"); "V8.CompileCodeBackground");
RuntimeCallTimerScope runtimeTimer( RuntimeCallTimerScope runtimeTimer(
parse_info->runtime_call_stats(), parse_info->runtime_call_stats(),
parse_info->flags().is_toplevel parse_info->is_toplevel()
? parse_info->flags().is_eval ? parse_info->is_eval()
? RuntimeCallCounterId::kCompileBackgroundEval ? RuntimeCallCounterId::kCompileBackgroundEval
: RuntimeCallCounterId::kCompileBackgroundScript : RuntimeCallCounterId::kCompileBackgroundScript
: RuntimeCallCounterId::kCompileBackgroundFunction); : RuntimeCallCounterId::kCompileBackgroundFunction);
@ -1151,37 +1149,32 @@ MaybeHandle<SharedFunctionInfo> CompileToplevel(
BackgroundCompileTask::BackgroundCompileTask(ScriptStreamingData* streamed_data, BackgroundCompileTask::BackgroundCompileTask(ScriptStreamingData* streamed_data,
Isolate* isolate) Isolate* isolate)
: flags_(UnoptimizedCompileFlags::ForToplevelCompile( : info_(new ParseInfo(isolate)),
isolate, true, construct_language_mode(FLAG_use_strict), off_thread_isolate_(FLAG_finalize_streaming_on_background
REPLMode::kNo)), ? new OffThreadIsolate(isolate, info_->zone())
info_(std::make_unique<ParseInfo>(isolate, flags_)), : nullptr),
start_position_(0),
end_position_(0),
function_literal_id_(kFunctionLiteralIdTopLevel),
stack_size_(i::FLAG_stack_size), stack_size_(i::FLAG_stack_size),
worker_thread_runtime_call_stats_( worker_thread_runtime_call_stats_(
isolate->counters()->worker_thread_runtime_call_stats()), isolate->counters()->worker_thread_runtime_call_stats()),
allocator_(isolate->allocator()), allocator_(isolate->allocator()),
timer_(isolate->counters()->compile_script_on_background()), timer_(isolate->counters()->compile_script_on_background()),
language_mode_(info_->language_mode()),
collected_source_positions_(false) { collected_source_positions_(false) {
VMState<PARSER> state(isolate); VMState<PARSER> state(isolate);
// Prepare the data for the internalization phase and compilation phase, which // Prepare the data for the internalization phase and compilation phase, which
// will happen in the main thread after parsing. // will happen in the main thread after parsing.
LOG(isolate, ScriptEvent(Logger::ScriptEventType::kStreamingCompile, LOG(isolate, ScriptEvent(Logger::ScriptEventType::kStreamingCompile,
info_->flags().script_id)); info_->script_id()));
info_->SetFlagsForToplevelCompile(isolate->is_collecting_type_profile(), true,
construct_language_mode(FLAG_use_strict),
REPLMode::kNo);
language_mode_ = info_->language_mode();
std::unique_ptr<Utf16CharacterStream> stream(ScannerStream::For( std::unique_ptr<Utf16CharacterStream> stream(ScannerStream::For(
streamed_data->source_stream.get(), streamed_data->encoding)); streamed_data->source_stream.get(), streamed_data->encoding));
info_->set_character_stream(std::move(stream)); info_->set_character_stream(std::move(stream));
finalize_on_background_thread_ = FLAG_finalize_streaming_on_background; finalize_on_background_thread_ = FLAG_finalize_streaming_on_background;
if (finalize_on_background_thread()) {
off_thread_isolate_ =
std::make_unique<OffThreadIsolate>(isolate, info_->zone());
}
} }
BackgroundCompileTask::BackgroundCompileTask( BackgroundCompileTask::BackgroundCompileTask(
@ -1189,13 +1182,8 @@ BackgroundCompileTask::BackgroundCompileTask(
const AstRawString* function_name, const FunctionLiteral* function_literal, const AstRawString* function_name, const FunctionLiteral* function_literal,
WorkerThreadRuntimeCallStats* worker_thread_runtime_stats, WorkerThreadRuntimeCallStats* worker_thread_runtime_stats,
TimedHistogram* timer, int max_stack_size) TimedHistogram* timer, int max_stack_size)
: flags_(UnoptimizedCompileFlags::ForToplevelFunction( : info_(ParseInfo::FromParent(outer_parse_info, allocator, function_literal,
outer_parse_info->flags(), function_literal)), function_name)),
info_(ParseInfo::FromParent(outer_parse_info, flags_, allocator,
function_literal, function_name)),
start_position_(function_literal->start_position()),
end_position_(function_literal->end_position()),
function_literal_id_(function_literal->function_literal_id()),
stack_size_(max_stack_size), stack_size_(max_stack_size),
worker_thread_runtime_call_stats_(worker_thread_runtime_stats), worker_thread_runtime_call_stats_(worker_thread_runtime_stats),
allocator_(allocator), allocator_(allocator),
@ -1203,13 +1191,13 @@ BackgroundCompileTask::BackgroundCompileTask(
language_mode_(info_->language_mode()), language_mode_(info_->language_mode()),
collected_source_positions_(false), collected_source_positions_(false),
finalize_on_background_thread_(false) { finalize_on_background_thread_(false) {
DCHECK(outer_parse_info->flags().is_toplevel); DCHECK(outer_parse_info->is_toplevel());
DCHECK(!function_literal->is_toplevel()); DCHECK(!function_literal->is_toplevel());
// Clone the character stream so both can be accessed independently. // Clone the character stream so both can be accessed independently.
std::unique_ptr<Utf16CharacterStream> character_stream = std::unique_ptr<Utf16CharacterStream> character_stream =
outer_parse_info->character_stream()->Clone(); outer_parse_info->character_stream()->Clone();
character_stream->Seek(start_position_); character_stream->Seek(function_literal->start_position());
info_->set_character_stream(std::move(character_stream)); info_->set_character_stream(std::move(character_stream));
// Get preparsed scope data from the function literal. // Get preparsed scope data from the function literal.
@ -1282,18 +1270,17 @@ void BackgroundCompileTask::Run() {
parser_.reset(new Parser(info_.get())); parser_.reset(new Parser(info_.get()));
parser_->InitializeEmptyScopeChain(info_.get()); parser_->InitializeEmptyScopeChain(info_.get());
parser_->ParseOnBackground(info_.get(), start_position_, end_position_, parser_->ParseOnBackground(info_.get());
function_literal_id_);
if (info_->literal() != nullptr) { if (info_->literal() != nullptr) {
// Parsing has succeeded, compile. // Parsing has succeeded, compile.
outer_function_job_ = CompileOnBackgroundThread(info_.get(), allocator_, outer_function_job_ = CompileOnBackgroundThread(info_.get(), allocator_,
&inner_function_jobs_); &inner_function_jobs_);
// Save the language mode and record whether we collected source positions. // Save the language mode and record whether we collected source positions.
language_mode_ = info_->language_mode(); language_mode_ = info_->language_mode();
collected_source_positions_ = info_->flags().collect_source_positions; collected_source_positions_ = info_->collect_source_positions();
if (finalize_on_background_thread_) { if (finalize_on_background_thread_) {
DCHECK(info_->flags().is_toplevel); DCHECK(info_->is_toplevel());
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
"V8.FinalizeCodeBackground"); "V8.FinalizeCodeBackground");
@ -1305,10 +1292,10 @@ void BackgroundCompileTask::Run() {
// We don't have the script source or the script origin yet, so use a few // We don't have the script source or the script origin yet, so use a few
// default values for them. These will be fixed up during the main-thread // default values for them. These will be fixed up during the main-thread
// merge. // merge.
Handle<Script> script = info_->CreateScript( Handle<Script> script =
off_thread_isolate_.get(), info_->CreateScript(off_thread_isolate_.get(),
off_thread_isolate_->factory()->empty_string(), kNullMaybeHandle, off_thread_isolate_->factory()->empty_string(),
ScriptOriginOptions(), NOT_NATIVES_CODE); ScriptOriginOptions(), NOT_NATIVES_CODE);
Handle<SharedFunctionInfo> outer_function_sfi = Handle<SharedFunctionInfo> outer_function_sfi =
FinalizeTopLevel(info_.get(), script, off_thread_isolate_.get(), FinalizeTopLevel(info_.get(), script, off_thread_isolate_.get(),
@ -1398,13 +1385,10 @@ bool Compiler::CollectSourcePositions(Isolate* isolate,
HistogramTimerScope timer(isolate->counters()->collect_source_positions()); HistogramTimerScope timer(isolate->counters()->collect_source_positions());
// Set up parse info. // Set up parse info.
UnoptimizedCompileFlags flags = ParseInfo parse_info(isolate, *shared_info);
UnoptimizedCompileFlags::ForFunctionCompile(isolate, *shared_info); parse_info.set_lazy_compile();
flags.is_lazy_compile = true; parse_info.set_collect_source_positions();
flags.collect_source_positions = true; if (FLAG_allow_natives_syntax) parse_info.set_allow_natives_syntax();
flags.allow_natives_syntax = FLAG_allow_natives_syntax;
ParseInfo parse_info(isolate, flags);
// Parse and update ParseInfo with the results. Don't update parsing // Parse and update ParseInfo with the results. Don't update parsing
// statistics since we've already parsed the code before. // statistics since we've already parsed the code before.
@ -1446,7 +1430,7 @@ bool Compiler::CollectSourcePositions(Isolate* isolate,
} }
} }
DCHECK(job->compilation_info()->flags().collect_source_positions); DCHECK(job->compilation_info()->collect_source_positions());
// If debugging, make sure that instrumented bytecode has the source position // If debugging, make sure that instrumented bytecode has the source position
// table set on it as well. // table set on it as well.
@ -1484,11 +1468,8 @@ bool Compiler::Compile(Handle<SharedFunctionInfo> shared_info,
AggregatedHistogramTimerScope timer(isolate->counters()->compile_lazy()); AggregatedHistogramTimerScope timer(isolate->counters()->compile_lazy());
// Set up parse info. // Set up parse info.
UnoptimizedCompileFlags flags = ParseInfo parse_info(isolate, *shared_info);
UnoptimizedCompileFlags::ForFunctionCompile(isolate, *shared_info); parse_info.set_lazy_compile();
flags.is_lazy_compile = true;
ParseInfo parse_info(isolate, flags);
// Check if the compiler dispatcher has shared_info enqueued for compile. // Check if the compiler dispatcher has shared_info enqueued for compile.
CompilerDispatcher* dispatcher = isolate->compiler_dispatcher(); CompilerDispatcher* dispatcher = isolate->compiler_dispatcher();
@ -1626,7 +1607,7 @@ bool Compiler::FinalizeBackgroundCompileTask(
isolate, RuntimeCallCounterId::kCompileFinalizeBackgroundCompileTask); isolate, RuntimeCallCounterId::kCompileFinalizeBackgroundCompileTask);
HandleScope scope(isolate); HandleScope scope(isolate);
ParseInfo* parse_info = task->info(); ParseInfo* parse_info = task->info();
DCHECK(!parse_info->flags().is_toplevel); DCHECK(!parse_info->is_toplevel());
DCHECK(!shared_info->is_compiled()); DCHECK(!shared_info->is_compiled());
Handle<Script> script(Script::cast(shared_info->script()), isolate); Handle<Script> script(Script::cast(shared_info->script()), isolate);
@ -1736,22 +1717,22 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
is_compiled_scope = shared_info->is_compiled_scope(); is_compiled_scope = shared_info->is_compiled_scope();
allow_eval_cache = true; allow_eval_cache = true;
} else { } else {
UnoptimizedCompileFlags flags = UnoptimizedCompileFlags::ForToplevelCompile( ParseInfo parse_info(isolate);
isolate, true, language_mode, REPLMode::kNo); parse_info.SetFlagsForToplevelCompile(isolate->is_collecting_type_profile(),
flags.is_eval = true; true, language_mode, REPLMode::kNo);
flags.parse_restriction = restriction;
ParseInfo parse_info(isolate, flags); parse_info.set_eval();
parse_info.set_parse_restriction(restriction);
parse_info.set_parameters_end_pos(parameters_end_pos); parse_info.set_parameters_end_pos(parameters_end_pos);
DCHECK(!parse_info.flags().is_module); DCHECK(!parse_info.is_module());
MaybeHandle<ScopeInfo> maybe_outer_scope_info; MaybeHandle<ScopeInfo> maybe_outer_scope_info;
if (!context->IsNativeContext()) { if (!context->IsNativeContext()) {
maybe_outer_scope_info = handle(context->scope_info(), isolate); maybe_outer_scope_info = handle(context->scope_info(), isolate);
} }
script =
parse_info.CreateScript(isolate, source, kNullMaybeHandle, script = parse_info.CreateScript(
OriginOptionsForEval(outer_info->script())); isolate, source, OriginOptionsForEval(outer_info->script()));
script->set_eval_from_shared(*outer_info); script->set_eval_from_shared(*outer_info);
if (eval_position == kNoSourcePosition) { if (eval_position == kNoSourcePosition) {
// If the position is missing, attempt to get the code offset by // If the position is missing, attempt to get the code offset by
@ -2175,14 +2156,14 @@ void SetScriptFieldsFromDetails(Script script,
} }
} }
Handle<Script> NewScript( Handle<Script> NewScript(Isolate* isolate, ParseInfo* parse_info,
Isolate* isolate, ParseInfo* parse_info, Handle<String> source, Handle<String> source,
Compiler::ScriptDetails script_details, ScriptOriginOptions origin_options, Compiler::ScriptDetails script_details,
NativesFlag natives, ScriptOriginOptions origin_options,
MaybeHandle<FixedArray> maybe_wrapped_arguments = kNullMaybeHandle) { NativesFlag natives) {
// Create a script object describing the script to be compiled. // Create a script object describing the script to be compiled.
Handle<Script> script = parse_info->CreateScript( Handle<Script> script =
isolate, source, maybe_wrapped_arguments, origin_options, natives); parse_info->CreateScript(isolate, source, origin_options, natives);
SetScriptFieldsFromDetails(*script, script_details); SetScriptFieldsFromDetails(*script, script_details);
LOG(isolate, ScriptDetails(*script)); LOG(isolate, ScriptDetails(*script));
return script; return script;
@ -2273,21 +2254,21 @@ MaybeHandle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript(
if (maybe_result.is_null()) { if (maybe_result.is_null()) {
// No cache entry found compile the script. // No cache entry found compile the script.
UnoptimizedCompileFlags flags = UnoptimizedCompileFlags::ForToplevelCompile( ParseInfo parse_info(isolate);
isolate, natives == NOT_NATIVES_CODE, language_mode,
script_details.repl_mode);
flags.is_module = origin_options.IsModule(); parse_info.SetFlagsForToplevelCompile(
flags.is_eager = compile_options == ScriptCompiler::kEagerCompile; isolate->is_collecting_type_profile(), natives == NOT_NATIVES_CODE,
language_mode, script_details.repl_mode);
ParseInfo parse_info(isolate, flags); parse_info.set_module(origin_options.IsModule());
parse_info.set_extension(extension); parse_info.set_extension(extension);
parse_info.set_eager(compile_options == ScriptCompiler::kEagerCompile);
Handle<Script> script = NewScript(isolate, &parse_info, source, Handle<Script> script = NewScript(isolate, &parse_info, source,
script_details, origin_options, natives); script_details, origin_options, natives);
DCHECK_IMPLIES(parse_info.flags().collect_type_profile, DCHECK_IMPLIES(parse_info.collect_type_profile(),
script->IsUserJavaScript()); script->IsUserJavaScript());
DCHECK_EQ(parse_info.flags().is_repl_mode, script->is_repl_mode()); DCHECK_EQ(parse_info.is_repl_mode(), script->is_repl_mode());
// Compile the function and add it to the isolate cache. // Compile the function and add it to the isolate cache.
maybe_result = maybe_result =
@ -2350,24 +2331,27 @@ MaybeHandle<JSFunction> Compiler::GetWrappedFunction(
Handle<Script> script; Handle<Script> script;
IsCompiledScope is_compiled_scope; IsCompiledScope is_compiled_scope;
if (!maybe_result.ToHandle(&wrapped)) { if (!maybe_result.ToHandle(&wrapped)) {
UnoptimizedCompileFlags flags = UnoptimizedCompileFlags::ForToplevelCompile( ParseInfo parse_info(isolate);
isolate, true, language_mode, script_details.repl_mode); parse_info.SetFlagsForToplevelCompile(isolate->is_collecting_type_profile(),
flags.is_eval = true; // Use an eval scope as declaration scope. true, language_mode,
flags.function_syntax_kind = FunctionSyntaxKind::kWrapped; script_details.repl_mode);
parse_info.set_eval(); // Use an eval scope as declaration scope.
parse_info.set_function_syntax_kind(FunctionSyntaxKind::kWrapped);
// TODO(delphick): Remove this and instead make the wrapped and wrapper // TODO(delphick): Remove this and instead make the wrapped and wrapper
// functions fully non-lazy instead thus preventing source positions from // functions fully non-lazy instead thus preventing source positions from
// being omitted. // being omitted.
flags.collect_source_positions = true; parse_info.set_collect_source_positions(true);
// flags.eager = compile_options == ScriptCompiler::kEagerCompile; // parse_info.set_eager(compile_options == ScriptCompiler::kEagerCompile);
ParseInfo parse_info(isolate, flags);
MaybeHandle<ScopeInfo> maybe_outer_scope_info; MaybeHandle<ScopeInfo> maybe_outer_scope_info;
if (!context->IsNativeContext()) { if (!context->IsNativeContext()) {
maybe_outer_scope_info = handle(context->scope_info(), isolate); maybe_outer_scope_info = handle(context->scope_info(), isolate);
} }
script = NewScript(isolate, &parse_info, source, script_details, script = NewScript(isolate, &parse_info, source, script_details,
origin_options, NOT_NATIVES_CODE, arguments); origin_options, NOT_NATIVES_CODE);
script->set_wrapped_arguments(*arguments);
Handle<SharedFunctionInfo> top_level; Handle<SharedFunctionInfo> top_level;
maybe_result = CompileToplevel(&parse_info, script, maybe_outer_scope_info, maybe_result = CompileToplevel(&parse_info, script, maybe_outer_scope_info,
@ -2462,7 +2446,7 @@ Compiler::GetSharedFunctionInfoForStreamedScript(
maybe_result = sfi; maybe_result = sfi;
} else { } else {
ParseInfo* parse_info = task->info(); ParseInfo* parse_info = task->info();
DCHECK(parse_info->flags().is_toplevel); DCHECK(parse_info->is_toplevel());
// No cache entry found, finalize compilation of the script and add it to // No cache entry found, finalize compilation of the script and add it to
// the isolate cache. // the isolate cache.

View File

@ -14,7 +14,6 @@
#include "src/execution/isolate.h" #include "src/execution/isolate.h"
#include "src/logging/code-events.h" #include "src/logging/code-events.h"
#include "src/objects/contexts.h" #include "src/objects/contexts.h"
#include "src/parsing/parse-info.h"
#include "src/utils/allocation.h" #include "src/utils/allocation.h"
#include "src/zone/zone.h" #include "src/zone/zone.h"
@ -400,7 +399,6 @@ class V8_EXPORT_PRIVATE BackgroundCompileTask {
// Data needed for parsing, and data needed to to be passed between thread // Data needed for parsing, and data needed to to be passed between thread
// between parsing and compilation. These need to be initialized before the // between parsing and compilation. These need to be initialized before the
// compilation starts. // compilation starts.
UnoptimizedCompileFlags flags_;
std::unique_ptr<ParseInfo> info_; std::unique_ptr<ParseInfo> info_;
std::unique_ptr<Parser> parser_; std::unique_ptr<Parser> parser_;
@ -416,11 +414,6 @@ class V8_EXPORT_PRIVATE BackgroundCompileTask {
// This is a raw pointer to the off-thread allocated SharedFunctionInfo. // This is a raw pointer to the off-thread allocated SharedFunctionInfo.
SharedFunctionInfo outer_function_sfi_; SharedFunctionInfo outer_function_sfi_;
// Single function data for top-level function compilation.
int start_position_;
int end_position_;
int function_literal_id_;
int stack_size_; int stack_size_;
WorkerThreadRuntimeCallStats* worker_thread_runtime_call_stats_; WorkerThreadRuntimeCallStats* worker_thread_runtime_call_stats_;
AccountingAllocator* allocator_; AccountingAllocator* allocator_;

View File

@ -18,7 +18,7 @@ namespace internal {
UnoptimizedCompilationInfo::UnoptimizedCompilationInfo(Zone* zone, UnoptimizedCompilationInfo::UnoptimizedCompilationInfo(Zone* zone,
ParseInfo* parse_info, ParseInfo* parse_info,
FunctionLiteral* literal) FunctionLiteral* literal)
: flags_(parse_info->flags()), zone_(zone), feedback_vector_spec_(zone) { : flags_(0), zone_(zone), feedback_vector_spec_(zone) {
// NOTE: The parse_info passed here represents the global information gathered // NOTE: The parse_info passed here represents the global information gathered
// during parsing, but does not represent specific details of the actual // during parsing, but does not represent specific details of the actual
// function literal being compiled for this OptimizedCompilationInfo. As such, // function literal being compiled for this OptimizedCompilationInfo. As such,
@ -28,6 +28,13 @@ UnoptimizedCompilationInfo::UnoptimizedCompilationInfo(Zone* zone,
DCHECK_NOT_NULL(literal); DCHECK_NOT_NULL(literal);
literal_ = literal; literal_ = literal;
source_range_map_ = parse_info->source_range_map(); source_range_map_ = parse_info->source_range_map();
if (parse_info->is_eval()) MarkAsEval();
if (parse_info->collect_type_profile()) MarkAsCollectTypeProfile();
if (parse_info->might_always_opt()) MarkAsMightAlwaysOpt();
if (parse_info->collect_source_positions()) {
MarkAsForceCollectSourcePositions();
}
} }
DeclarationScope* UnoptimizedCompilationInfo::scope() const { DeclarationScope* UnoptimizedCompilationInfo::scope() const {
@ -45,7 +52,7 @@ int UnoptimizedCompilationInfo::num_parameters_including_this() const {
SourcePositionTableBuilder::RecordingMode SourcePositionTableBuilder::RecordingMode
UnoptimizedCompilationInfo::SourcePositionRecordingMode() const { UnoptimizedCompilationInfo::SourcePositionRecordingMode() const {
if (flags().collect_source_positions) { if (collect_source_positions()) {
return SourcePositionTableBuilder::RECORD_SOURCE_POSITIONS; return SourcePositionTableBuilder::RECORD_SOURCE_POSITIONS;
} }

View File

@ -12,7 +12,6 @@
#include "src/handles/handles.h" #include "src/handles/handles.h"
#include "src/objects/feedback-vector.h" #include "src/objects/feedback-vector.h"
#include "src/objects/objects.h" #include "src/objects/objects.h"
#include "src/parsing/parse-info.h"
#include "src/utils/utils.h" #include "src/utils/utils.h"
namespace v8 { namespace v8 {
@ -36,7 +35,21 @@ class V8_EXPORT_PRIVATE UnoptimizedCompilationInfo final {
Zone* zone() { return zone_; } Zone* zone() { return zone_; }
const UnoptimizedCompileFlags& flags() const { return flags_; } // Compilation flag accessors.
void MarkAsEval() { SetFlag(kIsEval); }
bool is_eval() const { return GetFlag(kIsEval); }
void MarkAsCollectTypeProfile() { SetFlag(kCollectTypeProfile); }
bool collect_type_profile() const { return GetFlag(kCollectTypeProfile); }
void MarkAsForceCollectSourcePositions() { SetFlag(kCollectSourcePositions); }
bool collect_source_positions() const {
return GetFlag(kCollectSourcePositions);
}
void MarkAsMightAlwaysOpt() { SetFlag(kMightAlwaysOpt); }
bool might_always_opt() const { return GetFlag(kMightAlwaysOpt); }
// Accessors for the input data of the function being compiled. // Accessors for the input data of the function being compiled.
@ -84,8 +97,20 @@ class V8_EXPORT_PRIVATE UnoptimizedCompilationInfo final {
FeedbackVectorSpec* feedback_vector_spec() { return &feedback_vector_spec_; } FeedbackVectorSpec* feedback_vector_spec() { return &feedback_vector_spec_; }
private: private:
// Various configuration flags for a compilation, as well as some properties
// of the compiled code produced by a compilation.
enum Flag {
kIsEval = 1 << 0,
kCollectTypeProfile = 1 << 1,
kMightAlwaysOpt = 1 << 2,
kCollectSourcePositions = 1 << 3,
};
void SetFlag(Flag flag) { flags_ |= flag; }
bool GetFlag(Flag flag) const { return (flags_ & flag) != 0; }
// Compilation flags. // Compilation flags.
const UnoptimizedCompileFlags flags_; unsigned flags_;
// The zone from which the compilation pipeline working on this // The zone from which the compilation pipeline working on this
// OptimizedCompilationInfo allocates. // OptimizedCompilationInfo allocates.

View File

@ -837,7 +837,7 @@ enum NativesFlag { NOT_NATIVES_CODE, EXTENSION_CODE, INSPECTOR_CODE };
// ParseRestriction is used to restrict the set of valid statements in a // ParseRestriction is used to restrict the set of valid statements in a
// unit of compilation. Restriction violations cause a syntax error. // unit of compilation. Restriction violations cause a syntax error.
enum ParseRestriction : bool { enum ParseRestriction {
NO_PARSE_RESTRICTION, // All expressions are allowed. NO_PARSE_RESTRICTION, // All expressions are allowed.
ONLY_SINGLE_FUNCTION_LITERAL // Only a single FunctionLiteral expression. ONLY_SINGLE_FUNCTION_LITERAL // Only a single FunctionLiteral expression.
}; };

View File

@ -544,16 +544,16 @@ bool Shell::ExecuteString(Isolate* isolate, Local<String> source,
i::Handle<i::String> str = Utils::OpenHandle(*(source)); i::Handle<i::String> str = Utils::OpenHandle(*(source));
// Set up ParseInfo. // Set up ParseInfo.
i::UnoptimizedCompileFlags flags = i::ParseInfo parse_info(i_isolate);
i::UnoptimizedCompileFlags::ForToplevelCompile( parse_info.set_toplevel();
i_isolate, true, i::construct_language_mode(i::FLAG_use_strict), parse_info.set_allow_lazy_parsing();
i::REPLMode::kNo); parse_info.set_language_mode(
i::construct_language_mode(i::FLAG_use_strict));
i::ParseInfo parse_info(i_isolate, flags); i::Handle<i::Script> script =
parse_info.CreateScript(i_isolate, str, options.compile_options);
i::Handle<i::Script> script = parse_info.CreateScript( if (!i::parsing::ParseProgram(&parse_info, script, i::kNullMaybeHandle,
i_isolate, str, i::kNullMaybeHandle, options.compile_options); i_isolate)) {
if (!i::parsing::ParseProgram(&parse_info, script, i_isolate)) {
fprintf(stderr, "Failed parsing\n"); fprintf(stderr, "Failed parsing\n");
return false; return false;
} }

View File

@ -40,7 +40,7 @@ ScopeIterator::ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector,
TryParseAndRetrieveScopes(strategy); TryParseAndRetrieveScopes(strategy);
} }
ScopeIterator::~ScopeIterator() = default; ScopeIterator::~ScopeIterator() { delete info_; }
Handle<Object> ScopeIterator::GetFunctionDebugName() const { Handle<Object> ScopeIterator::GetFunctionDebugName() const {
if (!function_.is_null()) return JSFunction::GetDebugName(function_); if (!function_.is_null()) return JSFunction::GetDebugName(function_);
@ -236,41 +236,36 @@ void ScopeIterator::TryParseAndRetrieveScopes(ReparseStrategy strategy) {
// Depending on the choosen strategy, the whole script or just // Depending on the choosen strategy, the whole script or just
// the closure is re-parsed for function scopes. // the closure is re-parsed for function scopes.
Handle<Script> script(Script::cast(shared_info->script()), isolate_); Handle<Script> script(Script::cast(shared_info->script()), isolate_);
UnoptimizedCompileFlags flags;
if (scope_info->scope_type() == FUNCTION_SCOPE && if (scope_info->scope_type() == FUNCTION_SCOPE &&
strategy == ReparseStrategy::kFunctionLiteral) { strategy == ReparseStrategy::kFunctionLiteral) {
flags = UnoptimizedCompileFlags::ForFunctionCompile(isolate_, *shared_info); info_ = new ParseInfo(isolate_, *shared_info);
} else { } else {
flags = UnoptimizedCompileFlags::ForScriptCompile(isolate_, *script); info_ = new ParseInfo(isolate_, *script);
flags.is_eager = true; info_->set_eager();
} }
MaybeHandle<ScopeInfo> maybe_outer_scope; MaybeHandle<ScopeInfo> maybe_outer_scope;
if (scope_info->scope_type() == EVAL_SCOPE || script->is_wrapped()) { if (scope_info->scope_type() == EVAL_SCOPE || script->is_wrapped()) {
flags.is_eval = true; info_->set_eval();
if (!context_->IsNativeContext()) { if (!context_->IsNativeContext()) {
maybe_outer_scope = handle(context_->scope_info(), isolate_); maybe_outer_scope = handle(context_->scope_info(), isolate_);
} }
// Language mode may be inherited from the eval caller. // Language mode may be inherited from the eval caller.
// Retrieve it from shared function info. // Retrieve it from shared function info.
flags.outer_language_mode = shared_info->language_mode(); info_->set_language_mode(shared_info->language_mode());
} else if (scope_info->scope_type() == MODULE_SCOPE) { } else if (scope_info->scope_type() == MODULE_SCOPE) {
DCHECK(flags.is_module); DCHECK(info_->is_module());
} else { } else {
DCHECK(scope_info->scope_type() == SCRIPT_SCOPE || DCHECK(scope_info->scope_type() == SCRIPT_SCOPE ||
scope_info->scope_type() == FUNCTION_SCOPE); scope_info->scope_type() == FUNCTION_SCOPE);
} }
info_ = std::make_unique<ParseInfo>(isolate_, flags);
const bool parse_result = const bool parse_result =
flags.is_toplevel info_->is_toplevel()
? parsing::ParseProgram(info_.get(), script, maybe_outer_scope, ? parsing::ParseProgram(info_, script, maybe_outer_scope, isolate_)
isolate_) : parsing::ParseFunction(info_, shared_info, isolate_);
: parsing::ParseFunction(info_.get(), shared_info, isolate_);
if (parse_result && Rewriter::Rewrite(info_.get())) { if (parse_result && Rewriter::Rewrite(info_)) {
info_->ast_value_factory()->Internalize(isolate_); info_->ast_value_factory()->Internalize(isolate_);
DeclarationScope* literal_scope = info_->literal()->scope(); DeclarationScope* literal_scope = info_->literal()->scope();
@ -285,7 +280,7 @@ void ScopeIterator::TryParseAndRetrieveScopes(ReparseStrategy strategy) {
? scope_chain_retriever.ClosureScope() ? scope_chain_retriever.ClosureScope()
: literal_scope; : literal_scope;
CHECK(DeclarationScope::Analyze(info_.get())); CHECK(DeclarationScope::Analyze(info_));
if (ignore_nested_scopes) { if (ignore_nested_scopes) {
current_scope_ = closure_scope_; current_scope_ = closure_scope_;
start_scope_ = current_scope_; start_scope_ = current_scope_;

View File

@ -109,7 +109,7 @@ class ScopeIterator {
private: private:
Isolate* isolate_; Isolate* isolate_;
std::unique_ptr<ParseInfo> info_; ParseInfo* info_ = nullptr;
FrameInspector* const frame_inspector_ = nullptr; FrameInspector* const frame_inspector_ = nullptr;
Handle<JSGeneratorObject> generator_; Handle<JSGeneratorObject> generator_;
Handle<JSFunction> function_; Handle<JSFunction> function_;

View File

@ -750,6 +750,7 @@ class CollectFunctionLiterals final
bool ParseScript(Isolate* isolate, Handle<Script> script, ParseInfo* parse_info, bool ParseScript(Isolate* isolate, Handle<Script> script, ParseInfo* parse_info,
bool compile_as_well, std::vector<FunctionLiteral*>* literals, bool compile_as_well, std::vector<FunctionLiteral*>* literals,
debug::LiveEditResult* result) { debug::LiveEditResult* result) {
parse_info->set_eager();
v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate)); v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
Handle<SharedFunctionInfo> shared; Handle<SharedFunctionInfo> shared;
bool success = false; bool success = false;
@ -1057,21 +1058,15 @@ void LiveEdit::PatchScript(Isolate* isolate, Handle<Script> script,
return; return;
} }
UnoptimizedCompileFlags flags = ParseInfo parse_info(isolate, *script);
UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
flags.is_eager = true;
ParseInfo parse_info(isolate, flags);
std::vector<FunctionLiteral*> literals; std::vector<FunctionLiteral*> literals;
if (!ParseScript(isolate, script, &parse_info, false, &literals, result)) if (!ParseScript(isolate, script, &parse_info, false, &literals, result))
return; return;
Handle<Script> new_script = isolate->factory()->CloneScript(script); Handle<Script> new_script = isolate->factory()->CloneScript(script);
new_script->set_source(*new_source); new_script->set_source(*new_source);
UnoptimizedCompileFlags new_flags =
UnoptimizedCompileFlags::ForScriptCompile(isolate, *new_script);
new_flags.is_eager = true;
ParseInfo new_parse_info(isolate, new_flags);
std::vector<FunctionLiteral*> new_literals; std::vector<FunctionLiteral*> new_literals;
ParseInfo new_parse_info(isolate, *new_script);
if (!ParseScript(isolate, new_script, &new_parse_info, true, &new_literals, if (!ParseScript(isolate, new_script, &new_parse_info, true, &new_literals,
result)) { result)) {
return; return;

View File

@ -1252,8 +1252,7 @@ Handle<String> RenderCallSite(Isolate* isolate, Handle<Object> object,
MessageLocation* location, MessageLocation* location,
CallPrinter::ErrorHint* hint) { CallPrinter::ErrorHint* hint) {
if (ComputeLocation(isolate, location)) { if (ComputeLocation(isolate, location)) {
ParseInfo info(isolate, i::UnoptimizedCompileFlags::ForFunctionCompile( ParseInfo info(isolate, *location->shared());
isolate, *location->shared()));
if (parsing::ParseAny(&info, location->shared(), isolate)) { if (parsing::ParseAny(&info, location->shared(), isolate)) {
info.ast_value_factory()->Internalize(isolate); info.ast_value_factory()->Internalize(isolate);
CallPrinter printer(isolate, location->shared()->IsUserJavaScript()); CallPrinter printer(isolate, location->shared()->IsUserJavaScript());
@ -1311,8 +1310,7 @@ Object ErrorUtils::ThrowSpreadArgIsNullOrUndefinedError(Isolate* isolate,
MessageLocation location; MessageLocation location;
Handle<String> callsite; Handle<String> callsite;
if (ComputeLocation(isolate, &location)) { if (ComputeLocation(isolate, &location)) {
ParseInfo info(isolate, i::UnoptimizedCompileFlags::ForFunctionCompile( ParseInfo info(isolate, *location.shared());
isolate, *location.shared()));
if (parsing::ParseAny(&info, location.shared(), isolate)) { if (parsing::ParseAny(&info, location.shared(), isolate)) {
info.ast_value_factory()->Internalize(isolate); info.ast_value_factory()->Internalize(isolate);
CallPrinter printer(isolate, location.shared()->IsUserJavaScript(), CallPrinter printer(isolate, location.shared()->IsUserJavaScript(),
@ -1387,8 +1385,7 @@ Object ErrorUtils::ThrowLoadFromNullOrUndefined(Isolate* isolate,
if (ComputeLocation(isolate, &location)) { if (ComputeLocation(isolate, &location)) {
location_computed = true; location_computed = true;
ParseInfo info(isolate, i::UnoptimizedCompileFlags::ForFunctionCompile( ParseInfo info(isolate, *location.shared());
isolate, *location.shared()));
if (parsing::ParseAny(&info, location.shared(), isolate)) { if (parsing::ParseAny(&info, location.shared(), isolate)) {
info.ast_value_factory()->Internalize(isolate); info.ast_value_factory()->Internalize(isolate);
CallPrinter printer(isolate, location.shared()->IsUserJavaScript()); CallPrinter printer(isolate, location.shared()->IsUserJavaScript());

View File

@ -1332,7 +1332,7 @@ void BytecodeGenerator::GenerateBytecodeBody() {
if (FLAG_trace) builder()->CallRuntime(Runtime::kTraceEnter); if (FLAG_trace) builder()->CallRuntime(Runtime::kTraceEnter);
// Emit type profile call. // Emit type profile call.
if (info()->flags().collect_type_profile) { if (info()->collect_type_profile()) {
feedback_spec()->AddTypeProfileSlot(); feedback_spec()->AddTypeProfileSlot();
int num_parameters = closure_scope()->num_parameters(); int num_parameters = closure_scope()->num_parameters();
for (int i = 0; i < num_parameters; i++) { for (int i = 0; i < num_parameters; i++) {
@ -2134,7 +2134,7 @@ void BytecodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
DCHECK(expr->scope()->outer_scope() == current_scope()); DCHECK(expr->scope()->outer_scope() == current_scope());
uint8_t flags = CreateClosureFlags::Encode( uint8_t flags = CreateClosureFlags::Encode(
expr->pretenure(), closure_scope()->is_function_scope(), expr->pretenure(), closure_scope()->is_function_scope(),
info()->flags().might_always_opt); info()->might_always_opt());
size_t entry = builder()->AllocateDeferredConstantPoolEntry(); size_t entry = builder()->AllocateDeferredConstantPoolEntry();
builder()->CreateClosure(entry, GetCachedCreateClosureSlot(expr), flags); builder()->CreateClosure(entry, GetCachedCreateClosureSlot(expr), flags);
function_literals_.push_back(std::make_pair(expr, entry)); function_literals_.push_back(std::make_pair(expr, entry));
@ -3197,7 +3197,7 @@ void BytecodeGenerator::BuildReturn(int source_position) {
builder()->StoreAccumulatorInRegister(result).CallRuntime( builder()->StoreAccumulatorInRegister(result).CallRuntime(
Runtime::kTraceExit, result); Runtime::kTraceExit, result);
} }
if (info()->flags().collect_type_profile) { if (info()->collect_type_profile()) {
builder()->CollectTypeProfile(info()->literal()->return_position()); builder()->CollectTypeProfile(info()->literal()->return_position());
} }
builder()->SetReturnPosition(source_position, info()->literal()); builder()->SetReturnPosition(source_position, info()->literal());

View File

@ -191,18 +191,17 @@ void InterpreterCompilationJob::CheckAndPrintBytecodeMismatch(
std::cerr << "Bytecode mismatch"; std::cerr << "Bytecode mismatch";
#ifdef OBJECT_PRINT #ifdef OBJECT_PRINT
std::cerr << " found for function: "; std::cerr << " found for function: ";
MaybeHandle<String> maybe_name = parse_info()->literal()->GetName(isolate); Handle<String> name = parse_info()->function_name()->string();
Handle<String> name; if (name->length() == 0) {
if (maybe_name.ToHandle(&name) && name->length() != 0) {
name->StringPrint(std::cerr);
} else {
std::cerr << "anonymous"; std::cerr << "anonymous";
} else {
name->StringPrint(std::cerr);
} }
Object script_name = script->GetNameOrSourceURL(); Object script_name = script->GetNameOrSourceURL();
if (script_name.IsString()) { if (script_name.IsString()) {
std::cerr << " "; std::cerr << " ";
String::cast(script_name).StringPrint(std::cerr); String::cast(script_name).StringPrint(std::cerr);
std::cerr << ":" << parse_info()->literal()->start_position(); std::cerr << ":" << parse_info()->start_position();
} }
#endif #endif
std::cerr << "\nOriginal bytecode:\n"; std::cerr << "\nOriginal bytecode:\n";

View File

@ -6,7 +6,6 @@
#define V8_OBJECTS_FUNCTION_KIND_H_ #define V8_OBJECTS_FUNCTION_KIND_H_
#include "src/base/bounds.h" #include "src/base/bounds.h"
#include "src/base/macros.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
@ -57,9 +56,6 @@ enum FunctionKind : uint8_t {
kLastFunctionKind = kClassMembersInitializerFunction, kLastFunctionKind = kClassMembersInitializerFunction,
}; };
constexpr int kFunctionKindBitSize = 5;
STATIC_ASSERT(kLastFunctionKind < (1 << kFunctionKindBitSize));
inline bool IsArrowFunction(FunctionKind kind) { inline bool IsArrowFunction(FunctionKind kind) {
return base::IsInRange(kind, FunctionKind::kArrowFunction, return base::IsInRange(kind, FunctionKind::kArrowFunction,
FunctionKind::kAsyncArrowFunction); FunctionKind::kAsyncArrowFunction);

View File

@ -5,7 +5,6 @@
#ifndef V8_OBJECTS_SHARED_FUNCTION_INFO_INL_H_ #ifndef V8_OBJECTS_SHARED_FUNCTION_INFO_INL_H_
#define V8_OBJECTS_SHARED_FUNCTION_INFO_INL_H_ #define V8_OBJECTS_SHARED_FUNCTION_INFO_INL_H_
#include "src/base/macros.h"
#include "src/objects/shared-function-info.h" #include "src/objects/shared-function-info.h"
#include "src/handles/handles-inl.h" #include "src/handles/handles-inl.h"
@ -251,7 +250,6 @@ void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
} }
FunctionKind SharedFunctionInfo::kind() const { FunctionKind SharedFunctionInfo::kind() const {
STATIC_ASSERT(FunctionKindBits::kSize == kFunctionKindBitSize);
return FunctionKindBits::decode(flags()); return FunctionKindBits::decode(flags());
} }

View File

@ -20,154 +20,20 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
UnoptimizedCompileFlags::UnoptimizedCompileFlags(Isolate* isolate, ParseInfo::ParseInfo(AccountingAllocator* zone_allocator, int script_id)
int script_id) { : zone_(std::make_unique<Zone>(zone_allocator, ZONE_NAME)),
// Zero initialize the fields. Ideally we'd use default initializers on the flags_(0),
// fields themselves, but default bitfield values are not supported until
// C++20.
memset(this, 0, sizeof(*this));
collect_type_profile = isolate->is_collecting_type_profile();
coverage_enabled = !isolate->is_best_effort_code_coverage();
block_coverage_enabled = isolate->is_block_code_coverage();
might_always_opt = FLAG_always_opt || FLAG_prepare_always_opt;
allow_natives_syntax = FLAG_allow_natives_syntax;
allow_lazy_compile = FLAG_lazy;
allow_harmony_dynamic_import = FLAG_harmony_dynamic_import;
allow_harmony_import_meta = FLAG_harmony_import_meta;
allow_harmony_private_methods = FLAG_harmony_private_methods;
collect_source_positions = !FLAG_enable_lazy_source_positions ||
isolate->NeedsDetailedOptimizedCodeLineInfo();
allow_harmony_top_level_await = FLAG_harmony_top_level_await;
this->script_id = script_id;
function_kind = FunctionKind::kNormalFunction;
function_syntax_kind = FunctionSyntaxKind::kDeclaration;
}
// 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.allow_lazy_parsing = true;
flags.is_asm_wasm_broken = shared.is_asm_wasm_broken();
flags.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.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.function_syntax_kind = FunctionSyntaxKind::kWrapped;
}
return flags;
}
// 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, -1);
}
template <typename T>
void UnoptimizedCompileFlags::SetFlagsFromFunction(T function) {
outer_language_mode = function->language_mode();
function_kind = function->kind();
function_syntax_kind = function->syntax_kind();
requires_instance_members_initializer =
function->requires_instance_members_initializer();
class_scope_has_private_brand = function->class_scope_has_private_brand();
has_static_private_methods_or_accessors =
function->has_static_private_methods_or_accessors();
is_toplevel = function->is_toplevel();
is_oneshot_iife = function->is_oneshot_iife();
}
void UnoptimizedCompileFlags::SetFlagsForToplevelCompile(
bool is_collecting_type_profile, bool is_user_javascript,
LanguageMode language_mode, REPLMode repl_mode) {
allow_lazy_parsing = true;
is_toplevel = true;
collect_type_profile = is_user_javascript && is_collecting_type_profile;
outer_language_mode =
stricter_language_mode(outer_language_mode, language_mode);
is_repl_mode = (repl_mode == REPLMode::kYes);
block_coverage_enabled = block_coverage_enabled && is_user_javascript;
}
void UnoptimizedCompileFlags::SetFlagsForFunctionFromScript(Script script) {
DCHECK_EQ(script_id, script.id());
is_eval = script.compilation_type() == Script::COMPILATION_TYPE_EVAL;
is_module = script.origin_options().IsModule();
DCHECK(!(is_eval && is_module));
block_coverage_enabled = block_coverage_enabled && script.IsUserJavaScript();
}
ParseInfo::ParseInfo(AccountingAllocator* zone_allocator,
UnoptimizedCompileFlags flags)
: flags_(flags),
zone_(std::make_unique<Zone>(zone_allocator, ZONE_NAME)),
extension_(nullptr), extension_(nullptr),
script_scope_(nullptr), script_scope_(nullptr),
stack_limit_(0), stack_limit_(0),
hash_seed_(0), hash_seed_(0),
function_kind_(FunctionKind::kNormalFunction),
function_syntax_kind_(FunctionSyntaxKind::kDeclaration),
script_id_(script_id),
start_position_(0),
end_position_(0),
parameters_end_pos_(kNoSourcePosition), parameters_end_pos_(kNoSourcePosition),
function_literal_id_(kFunctionLiteralIdInvalid),
max_function_literal_id_(kFunctionLiteralIdInvalid), max_function_literal_id_(kFunctionLiteralIdInvalid),
character_stream_(nullptr), character_stream_(nullptr),
ast_value_factory_(nullptr), ast_value_factory_(nullptr),
@ -175,35 +41,97 @@ ParseInfo::ParseInfo(AccountingAllocator* zone_allocator,
function_name_(nullptr), function_name_(nullptr),
runtime_call_stats_(nullptr), runtime_call_stats_(nullptr),
source_range_map_(nullptr), source_range_map_(nullptr),
literal_(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, UnoptimizedCompileFlags flags) ParseInfo::ParseInfo(Isolate* isolate, AccountingAllocator* zone_allocator,
: ParseInfo(isolate->allocator(), flags) { int script_id)
: ParseInfo(zone_allocator, script_id) {
set_hash_seed(HashSeed(isolate)); set_hash_seed(HashSeed(isolate));
set_stack_limit(isolate->stack_guard()->real_climit()); set_stack_limit(isolate->stack_guard()->real_climit());
set_runtime_call_stats(isolate->counters()->runtime_call_stats()); set_runtime_call_stats(isolate->counters()->runtime_call_stats());
set_logger(isolate->logger()); set_logger(isolate->logger());
set_ast_string_constants(isolate->ast_string_constants()); 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()) { if (isolate->compiler_dispatcher()->IsEnabled()) {
parallel_tasks_.reset(new ParallelTasks(isolate->compiler_dispatcher())); parallel_tasks_.reset(new ParallelTasks(isolate->compiler_dispatcher()));
} }
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_harmony_dynamic_import(FLAG_harmony_dynamic_import);
set_allow_harmony_import_meta(FLAG_harmony_import_meta);
set_allow_harmony_private_methods(FLAG_harmony_private_methods);
set_allow_harmony_top_level_await(FLAG_harmony_top_level_await);
}
ParseInfo::ParseInfo(Isolate* isolate)
: ParseInfo(isolate, isolate->allocator(), isolate->GetNextScriptId()) {
LOG(isolate, ScriptEvent(Logger::ScriptEventType::kReserveId, script_id()));
}
template <typename T>
void ParseInfo::SetFunctionInfo(T function) {
set_language_mode(function->language_mode());
set_function_kind(function->kind());
set_function_syntax_kind(function->syntax_kind());
set_requires_instance_members_initializer(
function->requires_instance_members_initializer());
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_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.
DCHECK_IMPLIES(is_toplevel(), !Script::cast(shared.script()).is_wrapped());
set_allow_lazy_parsing(true);
set_asm_wasm_broken(shared.is_asm_wasm_broken());
set_start_position(shared.StartPosition());
set_end_position(shared.EndPosition());
function_literal_id_ = shared.function_literal_id();
SetFunctionInfo(&shared);
Script script = Script::cast(shared.script());
SetFlagsForFunctionFromScript(script);
set_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.
set_collect_type_profile(
isolate->is_collecting_type_profile() &&
(shared.HasFeedbackMetadata()
? shared.feedback_metadata().HasTypeProfileSlot()
: script.IsUserJavaScript()));
}
ParseInfo::ParseInfo(Isolate* isolate, Script script)
: ParseInfo(isolate, isolate->allocator(), script.id()) {
SetFlagsForToplevelCompileFromScript(isolate, script,
isolate->is_collecting_type_profile());
} }
// static // static
std::unique_ptr<ParseInfo> ParseInfo::FromParent( std::unique_ptr<ParseInfo> ParseInfo::FromParent(
const ParseInfo* outer_parse_info, const UnoptimizedCompileFlags flags, const ParseInfo* outer_parse_info, AccountingAllocator* zone_allocator,
AccountingAllocator* zone_allocator, const FunctionLiteral* literal, const FunctionLiteral* literal, const AstRawString* function_name) {
const AstRawString* function_name) { // Can't use make_unique because the constructor is private.
std::unique_ptr<ParseInfo> result(new ParseInfo(zone_allocator, flags)); std::unique_ptr<ParseInfo> result(
new ParseInfo(zone_allocator, outer_parse_info->script_id_));
// Replicate shared state of the outer_parse_info. // Replicate shared state of the outer_parse_info.
result->flags_ = outer_parse_info->flags_;
result->set_logger(outer_parse_info->logger()); result->set_logger(outer_parse_info->logger());
result->set_ast_string_constants(outer_parse_info->ast_string_constants()); result->set_ast_string_constants(outer_parse_info->ast_string_constants());
result->set_hash_seed(outer_parse_info->hash_seed()); result->set_hash_seed(outer_parse_info->hash_seed());
@ -220,6 +148,10 @@ std::unique_ptr<ParseInfo> ParseInfo::FromParent(
// Setup function specific details. // Setup function specific details.
DCHECK(!literal->is_toplevel()); DCHECK(!literal->is_toplevel());
result->set_function_name(cloned_function_name); 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; return result;
} }
@ -229,14 +161,14 @@ ParseInfo::~ParseInfo() = default;
DeclarationScope* ParseInfo::scope() const { return literal()->scope(); } DeclarationScope* ParseInfo::scope() const { return literal()->scope(); }
template <typename LocalIsolate> template <typename LocalIsolate>
Handle<Script> ParseInfo::CreateScript( Handle<Script> ParseInfo::CreateScript(LocalIsolate* isolate,
LocalIsolate* isolate, Handle<String> source, Handle<String> source,
MaybeHandle<FixedArray> maybe_wrapped_arguments, ScriptOriginOptions origin_options,
ScriptOriginOptions origin_options, NativesFlag natives) { NativesFlag natives) {
// Create a script object describing the script to be compiled. // Create a script object describing the script to be compiled.
DCHECK_GE(flags().script_id, 0); DCHECK_GE(script_id_, 0);
Handle<Script> script = Handle<Script> script =
isolate->factory()->NewScriptWithId(source, flags().script_id); isolate->factory()->NewScriptWithId(source, script_id_);
if (isolate->NeedsSourcePositionsForProfiling()) { if (isolate->NeedsSourcePositionsForProfiling()) {
Script::InitLineEnds(isolate, script); Script::InitLineEnds(isolate, script);
} }
@ -251,12 +183,8 @@ Handle<Script> ParseInfo::CreateScript(
break; break;
} }
script->set_origin_options(origin_options); script->set_origin_options(origin_options);
script->set_is_repl_mode(flags().is_repl_mode); script->set_is_repl_mode(is_repl_mode());
if (is_eval() && !is_wrapped_as_function()) {
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); script->set_compilation_type(Script::COMPILATION_TYPE_EVAL);
} }
@ -266,15 +194,15 @@ Handle<Script> ParseInfo::CreateScript(
} }
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
Handle<Script> ParseInfo::CreateScript( Handle<Script> ParseInfo::CreateScript(Isolate* isolate,
Isolate* isolate, Handle<String> source, Handle<String> source,
MaybeHandle<FixedArray> maybe_wrapped_arguments, ScriptOriginOptions origin_options,
ScriptOriginOptions origin_options, NativesFlag natives); NativesFlag natives);
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
Handle<Script> ParseInfo::CreateScript( Handle<Script> ParseInfo::CreateScript(OffThreadIsolate* isolate,
OffThreadIsolate* isolate, Handle<String> source, Handle<String> source,
MaybeHandle<FixedArray> maybe_wrapped_arguments, ScriptOriginOptions origin_options,
ScriptOriginOptions origin_options, NativesFlag natives); NativesFlag natives);
AstValueFactory* ParseInfo::GetOrCreateAstValueFactory() { AstValueFactory* ParseInfo::GetOrCreateAstValueFactory() {
if (!ast_value_factory_.get()) { if (!ast_value_factory_.get()) {
@ -285,7 +213,7 @@ AstValueFactory* ParseInfo::GetOrCreateAstValueFactory() {
} }
void ParseInfo::AllocateSourceRangeMap() { void ParseInfo::AllocateSourceRangeMap() {
DCHECK(flags().block_coverage_enabled); DCHECK(block_coverage_enabled());
DCHECK_NULL(source_range_map()); DCHECK_NULL(source_range_map());
set_source_range_map(new (zone()) SourceRangeMap(zone())); set_source_range_map(new (zone()) SourceRangeMap(zone()));
} }
@ -298,28 +226,69 @@ void ParseInfo::set_character_stream(
character_stream_.swap(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( void ParseInfo::CheckFlagsForToplevelCompileFromScript(
Script script, bool is_collecting_type_profile) { Script script, bool is_collecting_type_profile) {
CheckFlagsForFunctionFromScript(script); CheckFlagsForFunctionFromScript(script);
DCHECK(flags().allow_lazy_parsing); DCHECK(allow_lazy_parsing());
DCHECK(flags().is_toplevel); DCHECK(is_toplevel());
DCHECK_EQ(flags().collect_type_profile, DCHECK_EQ(collect_type_profile(),
is_collecting_type_profile && script.IsUserJavaScript()); is_collecting_type_profile && script.IsUserJavaScript());
DCHECK_EQ(flags().is_repl_mode, script.is_repl_mode()); DCHECK_EQ(is_repl_mode(), script.is_repl_mode());
if (script.is_wrapped()) { if (script.is_wrapped()) {
DCHECK_EQ(flags().function_syntax_kind, FunctionSyntaxKind::kWrapped); 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();
} }
} }
void ParseInfo::CheckFlagsForFunctionFromScript(Script script) { void ParseInfo::CheckFlagsForFunctionFromScript(Script script) {
DCHECK_EQ(flags().script_id, script.id()); DCHECK_EQ(script_id_, script.id());
// We set "is_eval" for wrapped scripts to get an outer declaration scope. // We set "is_eval" for wrapped functions to get an outer declaration scope.
// This is a bit hacky, but ok since we can't be both eval and wrapped. // This is a bit hacky, but ok since we can't be both eval and wrapped.
DCHECK_EQ(flags().is_eval && !script.is_wrapped(), DCHECK_EQ(is_eval() && !is_wrapped_as_function(),
script.compilation_type() == Script::COMPILATION_TYPE_EVAL); script.compilation_type() == Script::COMPILATION_TYPE_EVAL);
DCHECK_EQ(flags().is_module, script.origin_options().IsModule()); DCHECK_EQ(is_module(), script.origin_options().IsModule());
DCHECK_IMPLIES(flags().block_coverage_enabled && script.IsUserJavaScript(), DCHECK_IMPLIES(block_coverage_enabled() && script.IsUserJavaScript(),
source_range_map() != nullptr); source_range_map() != nullptr);
} }

View File

@ -38,97 +38,24 @@ class SourceRangeMap;
class Utf16CharacterStream; class Utf16CharacterStream;
class Zone; class Zone;
// The flags for a parse + unoptimized compile operation.
class V8_EXPORT_PRIVATE UnoptimizedCompileFlags {
public:
UnoptimizedCompileFlags() = default;
// 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);
bool is_toplevel : 1;
bool is_eager : 1;
bool is_eval : 1;
LanguageMode outer_language_mode : 1;
ParseRestriction parse_restriction : 1;
bool is_module : 1;
bool allow_lazy_parsing : 1;
bool is_lazy_compile : 1;
bool collect_type_profile : 1;
bool coverage_enabled : 1;
bool block_coverage_enabled : 1;
bool is_asm_wasm_broken : 1;
bool class_scope_has_private_brand : 1;
bool requires_instance_members_initializer : 1;
bool has_static_private_methods_or_accessors : 1;
bool might_always_opt : 1;
bool allow_natives_syntax : 1;
bool allow_lazy_compile : 1;
bool allow_harmony_dynamic_import : 1;
bool allow_harmony_import_meta : 1;
bool allow_harmony_private_methods : 1;
bool is_oneshot_iife : 1;
bool collect_source_positions : 1;
bool allow_harmony_top_level_await : 1;
bool is_repl_mode : 1;
int script_id;
FunctionKind function_kind;
FunctionSyntaxKind function_syntax_kind;
private:
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);
};
// A container for the inputs, configuration options, and outputs of parsing. // A container for the inputs, configuration options, and outputs of parsing.
class V8_EXPORT_PRIVATE ParseInfo { class V8_EXPORT_PRIVATE ParseInfo {
public: public:
ParseInfo(Isolate*, const UnoptimizedCompileFlags flags); explicit ParseInfo(Isolate*);
ParseInfo(Isolate* isolate, Script script);
ParseInfo(Isolate* isolate, SharedFunctionInfo shared);
// Creates a new parse info based on parent top-level |outer_parse_info| for // Creates a new parse info based on parent top-level |outer_parse_info| for
// function |literal|. // function |literal|.
static std::unique_ptr<ParseInfo> FromParent( static std::unique_ptr<ParseInfo> FromParent(
const ParseInfo* outer_parse_info, const UnoptimizedCompileFlags flags, const ParseInfo* outer_parse_info, AccountingAllocator* zone_allocator,
AccountingAllocator* zone_allocator, const FunctionLiteral* literal, const FunctionLiteral* literal, const AstRawString* function_name);
const AstRawString* function_name);
~ParseInfo(); ~ParseInfo();
template <typename LocalIsolate> template <typename LocalIsolate>
EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
Handle<Script> CreateScript(LocalIsolate* isolate, Handle<String> source, Handle<Script> CreateScript(LocalIsolate* isolate, Handle<String> source,
MaybeHandle<FixedArray> maybe_wrapped_arguments,
ScriptOriginOptions origin_options, ScriptOriginOptions origin_options,
NativesFlag natives = NOT_NATIVES_CODE); NativesFlag natives = NOT_NATIVES_CODE);
@ -138,15 +65,65 @@ class V8_EXPORT_PRIVATE ParseInfo {
Zone* zone() const { return zone_.get(); } Zone* zone() const { return zone_.get(); }
const UnoptimizedCompileFlags& flags() const { return flags_; } // 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); }
// Accessor methods for output flags. FLAG_ACCESSOR(kToplevel, is_toplevel, set_toplevel)
bool allow_eval_cache() const { return allow_eval_cache_; } FLAG_ACCESSOR(kEager, is_eager, set_eager)
void set_allow_eval_cache(bool value) { allow_eval_cache_ = value; } FLAG_ACCESSOR(kEval, is_eval, set_eval)
bool contains_asm_module() const { return contains_asm_module_; } FLAG_ACCESSOR(kStrictMode, is_strict_mode, set_strict_mode)
void set_contains_asm_module(bool value) { contains_asm_module_ = value; } FLAG_ACCESSOR(kModule, is_module, set_module)
LanguageMode language_mode() const { return language_mode_; } FLAG_ACCESSOR(kAllowLazyParsing, allow_lazy_parsing, set_allow_lazy_parsing)
void set_language_mode(LanguageMode value) { language_mode_ = value; } 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(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(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);
}
ParseRestriction parse_restriction() const {
return GetFlag(kParseRestriction) ? ONLY_SINGLE_FUNCTION_LITERAL
: NO_PARSE_RESTRICTION;
}
Utf16CharacterStream* character_stream() const { Utf16CharacterStream* character_stream() const {
return character_stream_.get(); return character_stream_.get();
@ -191,13 +168,38 @@ class V8_EXPORT_PRIVATE ParseInfo {
uint64_t hash_seed() const { return hash_seed_; } uint64_t hash_seed() const { return hash_seed_; }
void set_hash_seed(uint64_t hash_seed) { hash_seed_ = 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_; } int parameters_end_pos() const { return parameters_end_pos_; }
void set_parameters_end_pos(int parameters_end_pos) { void set_parameters_end_pos(int parameters_end_pos) {
parameters_end_pos_ = 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 { bool is_wrapped_as_function() const {
return flags().function_syntax_kind == FunctionSyntaxKind::kWrapped; return function_syntax_kind() == FunctionSyntaxKind::kWrapped;
} }
int max_function_literal_id() const { return max_function_literal_id_; } int max_function_literal_id() const { return max_function_literal_id_; }
@ -255,22 +257,93 @@ class V8_EXPORT_PRIVATE ParseInfo {
ParallelTasks* parallel_tasks() { return parallel_tasks_.get(); } 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); void CheckFlagsForFunctionFromScript(Script script);
private: int script_id() const { return script_id_; }
ParseInfo(AccountingAllocator* zone_allocator, UnoptimizedCompileFlags flags); //--------------------------------------------------------------------------
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);
void SetFlagsForFunctionFromScript(Script script);
template <typename LocalIsolate>
void SetFlagsForToplevelCompileFromScript(LocalIsolate* isolate,
Script script,
bool is_collecting_type_profile);
void CheckFlagsForToplevelCompileFromScript(Script script, void CheckFlagsForToplevelCompileFromScript(Script script,
bool is_collecting_type_profile); 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 ----------------------- //------------- Inputs to parsing and scope analysis -----------------------
const UnoptimizedCompileFlags flags_;
std::unique_ptr<Zone> zone_; std::unique_ptr<Zone> zone_;
uint32_t flags_;
v8::Extension* extension_; v8::Extension* extension_;
DeclarationScope* script_scope_; DeclarationScope* script_scope_;
uintptr_t stack_limit_; uintptr_t stack_limit_;
uint64_t hash_seed_; 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 parameters_end_pos_;
int function_literal_id_;
int max_function_literal_id_; int max_function_literal_id_;
//----------- Inputs+Outputs of parsing and scope analysis ----------------- //----------- Inputs+Outputs of parsing and scope analysis -----------------
@ -287,9 +360,10 @@ class V8_EXPORT_PRIVATE ParseInfo {
//----------- Output of parsing and scope analysis ------------------------ //----------- Output of parsing and scope analysis ------------------------
FunctionLiteral* literal_; FunctionLiteral* literal_;
PendingCompilationErrorHandler pending_error_handler_; PendingCompilationErrorHandler pending_error_handler_;
bool allow_eval_cache_ : 1;
bool contains_asm_module_ : 1; void SetFlag(Flag f) { flags_ |= f; }
LanguageMode language_mode_ : 1; void SetFlag(Flag f, bool v) { flags_ = v ? flags_ | f : flags_ & ~f; }
bool GetFlag(Flag f) const { return (flags_ & f) != 0; }
}; };
} // namespace internal } // namespace internal

View File

@ -23,7 +23,6 @@
#include "src/objects/function-kind.h" #include "src/objects/function-kind.h"
#include "src/parsing/expression-scope.h" #include "src/parsing/expression-scope.h"
#include "src/parsing/func-name-inferrer.h" #include "src/parsing/func-name-inferrer.h"
#include "src/parsing/parse-info.h"
#include "src/parsing/scanner.h" #include "src/parsing/scanner.h"
#include "src/parsing/token.h" #include "src/parsing/token.h"
#include "src/utils/pointer-with-payload.h" #include "src/utils/pointer-with-payload.h"
@ -242,7 +241,7 @@ class ParserBase {
v8::Extension* extension, AstValueFactory* ast_value_factory, v8::Extension* extension, AstValueFactory* ast_value_factory,
PendingCompilationErrorHandler* pending_error_handler, PendingCompilationErrorHandler* pending_error_handler,
RuntimeCallStats* runtime_call_stats, Logger* logger, RuntimeCallStats* runtime_call_stats, Logger* logger,
UnoptimizedCompileFlags flags, bool parsing_on_main_thread) int script_id, bool parsing_module, bool parsing_on_main_thread)
: scope_(nullptr), : scope_(nullptr),
original_scope_(nullptr), original_scope_(nullptr),
function_state_(nullptr), function_state_(nullptr),
@ -253,22 +252,37 @@ class ParserBase {
runtime_call_stats_(runtime_call_stats), runtime_call_stats_(runtime_call_stats),
logger_(logger), logger_(logger),
parsing_on_main_thread_(parsing_on_main_thread), parsing_on_main_thread_(parsing_on_main_thread),
parsing_module_(parsing_module),
stack_limit_(stack_limit), stack_limit_(stack_limit),
pending_error_handler_(pending_error_handler), pending_error_handler_(pending_error_handler),
zone_(zone), zone_(zone),
expression_scope_(nullptr), expression_scope_(nullptr),
scanner_(scanner), scanner_(scanner),
flags_(flags),
function_literal_id_(0), function_literal_id_(0),
default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile) { 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) {
pointer_buffer_.reserve(32); pointer_buffer_.reserve(32);
variable_buffer_.reserve(32); variable_buffer_.reserve(32);
} }
const UnoptimizedCompileFlags& flags() const { return flags_; } #define ALLOW_ACCESSORS(name) \
bool allow_##name() const { return allow_##name##_; } \
void set_allow_##name(bool allow) { allow_##name##_ = allow; }
bool allow_eval_cache() const { return allow_eval_cache_; } ALLOW_ACCESSORS(natives)
void set_allow_eval_cache(bool allow) { allow_eval_cache_ = allow; } 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
V8_INLINE bool has_error() const { return scanner()->has_parser_error(); } V8_INLINE bool has_error() const { return scanner()->has_parser_error(); }
@ -855,6 +869,8 @@ class ParserBase {
// Any further calls to Next or peek will return the illegal token. // Any further calls to Next or peek will return the illegal token.
if (GetCurrentStackPosition() < stack_limit_) set_stack_overflow(); 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(); } V8_INLINE Token::Value peek() { return scanner()->peek(); }
@ -1045,7 +1061,7 @@ class ParserBase {
return IsResumableFunction(function_state_->kind()); return IsResumableFunction(function_state_->kind());
} }
bool is_await_allowed() const { bool is_await_allowed() const {
return is_async_function() || (flags().allow_harmony_top_level_await && return is_async_function() || (allow_harmony_top_level_await() &&
IsModule(function_state_->kind())); IsModule(function_state_->kind()));
} }
const PendingCompilationErrorHandler* pending_error_handler() const { const PendingCompilationErrorHandler* pending_error_handler() const {
@ -1500,6 +1516,7 @@ class ParserBase {
RuntimeCallStats* runtime_call_stats_; RuntimeCallStats* runtime_call_stats_;
internal::Logger* logger_; internal::Logger* logger_;
bool parsing_on_main_thread_; bool parsing_on_main_thread_;
const bool parsing_module_;
uintptr_t stack_limit_; uintptr_t stack_limit_;
PendingCompilationErrorHandler* pending_error_handler_; PendingCompilationErrorHandler* pending_error_handler_;
@ -1514,8 +1531,8 @@ class ParserBase {
Scanner* scanner_; Scanner* scanner_;
const UnoptimizedCompileFlags flags_;
int function_literal_id_; int function_literal_id_;
int script_id_;
FunctionLiteral::EagerCompileHint default_eager_compile_hint_; FunctionLiteral::EagerCompileHint default_eager_compile_hint_;
@ -1554,7 +1571,12 @@ class ParserBase {
bool accept_IN_ = true; bool accept_IN_ = true;
bool allow_eval_cache_ = 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_;
}; };
template <typename Impl> template <typename Impl>
@ -1604,7 +1626,7 @@ ParserBase<Impl>::ParseAndClassifyIdentifier(Token::Value next) {
} }
if (!Token::IsValidIdentifier(next, language_mode(), is_generator(), if (!Token::IsValidIdentifier(next, language_mode(), is_generator(),
flags().is_module || is_async_function())) { parsing_module_ || is_async_function())) {
ReportUnexpectedToken(next); ReportUnexpectedToken(next);
return impl()->EmptyIdentifierString(); return impl()->EmptyIdentifierString();
} }
@ -1628,7 +1650,7 @@ typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifier(
if (!Token::IsValidIdentifier( if (!Token::IsValidIdentifier(
next, language_mode(), IsGeneratorFunction(function_kind), next, language_mode(), IsGeneratorFunction(function_kind),
flags().is_module || IsAsyncFunction(function_kind))) { parsing_module_ || IsAsyncFunction(function_kind))) {
ReportUnexpectedToken(next); ReportUnexpectedToken(next);
return impl()->EmptyIdentifierString(); return impl()->EmptyIdentifierString();
} }
@ -1839,7 +1861,7 @@ ParserBase<Impl>::ParsePrimaryExpression() {
return ParseSuperExpression(is_new); return ParseSuperExpression(is_new);
} }
case Token::IMPORT: case Token::IMPORT:
if (!flags().allow_harmony_dynamic_import) break; if (!allow_harmony_dynamic_import()) break;
return ParseImportExpressions(); return ParseImportExpressions();
case Token::LBRACK: case Token::LBRACK:
@ -1902,7 +1924,7 @@ ParserBase<Impl>::ParsePrimaryExpression() {
return ParseTemplateLiteral(impl()->NullExpression(), beg_pos, false); return ParseTemplateLiteral(impl()->NullExpression(), beg_pos, false);
case Token::MOD: case Token::MOD:
if (flags().allow_natives_syntax || extension_ != nullptr) { if (allow_natives() || extension_ != nullptr) {
return ParseV8Intrinsic(); return ParseV8Intrinsic();
} }
break; break;
@ -2148,7 +2170,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseProperty(
prop_info->kind = ParsePropertyKind::kNotSet; prop_info->kind = ParsePropertyKind::kNotSet;
return impl()->FailureExpression(); return impl()->FailureExpression();
} }
if (V8_UNLIKELY(!flags().allow_harmony_private_methods && if (V8_UNLIKELY(!allow_harmony_private_methods() &&
(IsAccessor(prop_info->kind) || (IsAccessor(prop_info->kind) ||
prop_info->kind == ParsePropertyKind::kMethod))) { prop_info->kind == ParsePropertyKind::kMethod))) {
ReportUnexpectedToken(Next()); ReportUnexpectedToken(Next());
@ -2496,7 +2518,7 @@ ParserBase<Impl>::ParseObjectPropertyDefinition(ParsePropertyInfo* prop_info,
DCHECK_EQ(function_flags, ParseFunctionFlag::kIsNormal); DCHECK_EQ(function_flags, ParseFunctionFlag::kIsNormal);
if (!Token::IsValidIdentifier(name_token, language_mode(), is_generator(), if (!Token::IsValidIdentifier(name_token, language_mode(), is_generator(),
flags().is_module || is_async_function())) { parsing_module_ || is_async_function())) {
ReportUnexpectedToken(Next()); ReportUnexpectedToken(Next());
return impl()->NullLiteralProperty(); return impl()->NullLiteralProperty();
} }
@ -3410,9 +3432,8 @@ ParserBase<Impl>::ParseMemberWithPresentNewPrefixesExpression() {
if (peek() == Token::SUPER) { if (peek() == Token::SUPER) {
const bool is_new = true; const bool is_new = true;
result = ParseSuperExpression(is_new); result = ParseSuperExpression(is_new);
} else if (flags().allow_harmony_dynamic_import && peek() == Token::IMPORT && } else if (allow_harmony_dynamic_import() && peek() == Token::IMPORT &&
(!flags().allow_harmony_import_meta || (!allow_harmony_import_meta() || PeekAhead() == Token::LPAREN)) {
PeekAhead() == Token::LPAREN)) {
impl()->ReportMessageAt(scanner()->peek_location(), impl()->ReportMessageAt(scanner()->peek_location(),
MessageTemplate::kImportCallNotNewExpression); MessageTemplate::kImportCallNotNewExpression);
return impl()->FailureExpression(); return impl()->FailureExpression();
@ -3510,14 +3531,14 @@ ParserBase<Impl>::ParseMemberExpression() {
template <typename Impl> template <typename Impl>
typename ParserBase<Impl>::ExpressionT typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseImportExpressions() { ParserBase<Impl>::ParseImportExpressions() {
DCHECK(flags().allow_harmony_dynamic_import); DCHECK(allow_harmony_dynamic_import());
Consume(Token::IMPORT); Consume(Token::IMPORT);
int pos = position(); int pos = position();
if (flags().allow_harmony_import_meta && Check(Token::PERIOD)) { if (allow_harmony_import_meta() && Check(Token::PERIOD)) {
ExpectContextualKeyword(ast_value_factory()->meta_string(), "import.meta", ExpectContextualKeyword(ast_value_factory()->meta_string(), "import.meta",
pos); pos);
if (!flags().is_module) { if (!parsing_module_) {
impl()->ReportMessageAt(scanner()->location(), impl()->ReportMessageAt(scanner()->location(),
MessageTemplate::kImportMetaOutsideModule); MessageTemplate::kImportMetaOutsideModule);
return impl()->FailureExpression(); return impl()->FailureExpression();
@ -3527,7 +3548,7 @@ ParserBase<Impl>::ParseImportExpressions() {
} }
if (V8_UNLIKELY(peek() != Token::LPAREN)) { if (V8_UNLIKELY(peek() != Token::LPAREN)) {
if (!flags().is_module) { if (!parsing_module_) {
impl()->ReportMessageAt(scanner()->location(), impl()->ReportMessageAt(scanner()->location(),
MessageTemplate::kImportOutsideModule); MessageTemplate::kImportOutsideModule);
} else { } else {
@ -4449,9 +4470,8 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
const char* event_name = const char* event_name =
is_lazy_top_level_function ? "preparse-no-resolution" : "parse"; is_lazy_top_level_function ? "preparse-no-resolution" : "parse";
const char* name = "arrow function"; const char* name = "arrow function";
logger_->FunctionEvent(event_name, flags().script_id, ms, logger_->FunctionEvent(event_name, script_id(), ms, scope->start_position(),
scope->start_position(), scope->end_position(), name, scope->end_position(), name, strlen(name));
strlen(name));
} }
return function_literal; return function_literal;

View File

@ -15,7 +15,6 @@
#include "src/base/overflowing-math.h" #include "src/base/overflowing-math.h"
#include "src/base/platform/platform.h" #include "src/base/platform/platform.h"
#include "src/codegen/bailout-reason.h" #include "src/codegen/bailout-reason.h"
#include "src/common/globals.h"
#include "src/common/message-template.h" #include "src/common/message-template.h"
#include "src/compiler-dispatcher/compiler-dispatcher.h" #include "src/compiler-dispatcher/compiler-dispatcher.h"
#include "src/logging/counters.h" #include "src/logging/counters.h"
@ -417,12 +416,13 @@ Expression* Parser::NewV8RuntimeFunctionForFuzzing(
} }
Parser::Parser(ParseInfo* info) Parser::Parser(ParseInfo* info)
: ParserBase<Parser>( : ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(),
info->zone(), &scanner_, info->stack_limit(), info->extension(), info->extension(), info->GetOrCreateAstValueFactory(),
info->GetOrCreateAstValueFactory(), info->pending_error_handler(), info->pending_error_handler(),
info->runtime_call_stats(), info->logger(), info->flags(), true), info->runtime_call_stats(), info->logger(),
info->script_id(), info->is_module(), true),
info_(info), info_(info),
scanner_(info->character_stream(), flags()), scanner_(info->character_stream(), info->is_module()),
preparser_zone_(info->zone()->allocator(), ZONE_NAME), preparser_zone_(info->zone()->allocator(), ZONE_NAME),
reusable_preparser_(nullptr), reusable_preparser_(nullptr),
mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
@ -445,13 +445,18 @@ Parser::Parser(ParseInfo* info)
// of functions without an outer context when setting a breakpoint through // of functions without an outer context when setting a breakpoint through
// Debug::FindSharedFunctionInfoInScript // Debug::FindSharedFunctionInfoInScript
// We also compile eagerly for kProduceExhaustiveCodeCache. // We also compile eagerly for kProduceExhaustiveCodeCache.
bool can_compile_lazily = flags().allow_lazy_compile && !flags().is_eager; bool can_compile_lazily = info->allow_lazy_compile() && !info->is_eager();
set_default_eager_compile_hint(can_compile_lazily set_default_eager_compile_hint(can_compile_lazily
? FunctionLiteral::kShouldLazyCompile ? FunctionLiteral::kShouldLazyCompile
: FunctionLiteral::kShouldEagerCompile); : FunctionLiteral::kShouldEagerCompile);
allow_lazy_ = flags().allow_lazy_compile && flags().allow_lazy_parsing && allow_lazy_ = info->allow_lazy_compile() && info->allow_lazy_parsing() &&
info->extension() == nullptr && can_compile_lazily; 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_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; for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
++feature) { ++feature) {
use_counts_[feature] = 0; use_counts_[feature] = 0;
@ -462,7 +467,7 @@ void Parser::InitializeEmptyScopeChain(ParseInfo* info) {
DCHECK_NULL(original_scope_); DCHECK_NULL(original_scope_);
DCHECK_NULL(info->script_scope()); DCHECK_NULL(info->script_scope());
DeclarationScope* script_scope = DeclarationScope* script_scope =
NewScriptScope(flags().is_repl_mode ? REPLMode::kYes : REPLMode::kNo); NewScriptScope(info->is_repl_mode() ? REPLMode::kYes : REPLMode::kNo);
info->set_script_scope(script_scope); info->set_script_scope(script_scope);
original_scope_ = script_scope; original_scope_ = script_scope;
} }
@ -478,7 +483,7 @@ void Parser::DeserializeScopeChain(
original_scope_ = Scope::DeserializeScopeChain( original_scope_ = Scope::DeserializeScopeChain(
isolate, zone(), *outer_scope_info, info->script_scope(), isolate, zone(), *outer_scope_info, info->script_scope(),
ast_value_factory(), mode); ast_value_factory(), mode);
if (flags().is_eval || IsArrowFunction(flags().function_kind)) { if (info->is_eval() || IsArrowFunction(info->function_kind())) {
original_scope_->GetReceiverScope()->DeserializeReceiver( original_scope_->GetReceiverScope()->DeserializeReceiver(
ast_value_factory()); ast_value_factory());
} }
@ -513,13 +518,13 @@ FunctionLiteral* Parser::ParseProgram(
MaybeHandle<ScopeInfo> maybe_outer_scope_info) { MaybeHandle<ScopeInfo> maybe_outer_scope_info) {
// TODO(bmeurer): We temporarily need to pass allow_nesting = true here, // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
// see comment for HistogramTimerScope class. // see comment for HistogramTimerScope class.
DCHECK_EQ(script->id(), flags().script_id); DCHECK_EQ(script->id(), script_id());
// It's OK to use the Isolate & counters here, since this function is only // It's OK to use the Isolate & counters here, since this function is only
// called in the main thread. // called in the main thread.
DCHECK(parsing_on_main_thread_); DCHECK(parsing_on_main_thread_);
RuntimeCallTimerScope runtime_timer( RuntimeCallTimerScope runtime_timer(
runtime_call_stats_, flags().is_eval runtime_call_stats_, info->is_eval()
? RuntimeCallCounterId::kParseEval ? RuntimeCallCounterId::kParseEval
: RuntimeCallCounterId::kParseProgram); : RuntimeCallCounterId::kParseProgram);
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram"); TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram");
@ -547,13 +552,12 @@ FunctionLiteral* Parser::ParseProgram(
const char* event_name = "parse-eval"; const char* event_name = "parse-eval";
int start = -1; int start = -1;
int end = -1; int end = -1;
if (!flags().is_eval) { if (!info->is_eval()) {
event_name = "parse-script"; event_name = "parse-script";
start = 0; start = 0;
end = String::cast(script->source()).length(); end = String::cast(script->source()).length();
} }
LOG(isolate, LOG(isolate, FunctionEvent(event_name, script_id(), ms, start, end, "", 0));
FunctionEvent(event_name, flags().script_id, ms, start, end, "", 0));
} }
return result; return result;
} }
@ -568,14 +572,16 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY); ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
ResetFunctionLiteralId(); ResetFunctionLiteralId();
DCHECK(info->function_literal_id() == kFunctionLiteralIdTopLevel ||
info->function_literal_id() == kFunctionLiteralIdInvalid);
FunctionLiteral* result = nullptr; FunctionLiteral* result = nullptr;
{ {
Scope* outer = original_scope_; Scope* outer = original_scope_;
DCHECK_NOT_NULL(outer); DCHECK_NOT_NULL(outer);
if (flags().is_eval) { if (info->is_eval()) {
outer = NewEvalScope(outer); outer = NewEvalScope(outer);
} else if (flags().is_module) { } else if (parsing_module_) {
DCHECK_EQ(outer, info->script_scope()); DCHECK_EQ(outer, info->script_scope());
outer = NewModuleScope(info->script_scope()); outer = NewModuleScope(info->script_scope());
} }
@ -586,15 +592,15 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
FunctionState function_state(&function_state_, &scope_, scope); FunctionState function_state(&function_state_, &scope_, scope);
ScopedPtrList<Statement> body(pointer_buffer()); ScopedPtrList<Statement> body(pointer_buffer());
int beg_pos = scanner()->location().beg_pos; int beg_pos = scanner()->location().beg_pos;
if (flags().is_module) { if (parsing_module_) {
DCHECK(flags().is_module); DCHECK(info->is_module());
PrepareGeneratorVariables(); PrepareGeneratorVariables();
Expression* initial_yield = Expression* initial_yield =
BuildInitialYield(kNoSourcePosition, kGeneratorFunction); BuildInitialYield(kNoSourcePosition, kGeneratorFunction);
body.Add( body.Add(
factory()->NewExpressionStatement(initial_yield, kNoSourcePosition)); factory()->NewExpressionStatement(initial_yield, kNoSourcePosition));
if (flags().allow_harmony_top_level_await) { if (allow_harmony_top_level_await()) {
// First parse statements into a buffer. Then, if there was a // First parse statements into a buffer. Then, if there was a
// top level await, create an inner block and rewrite the body of the // top level await, create an inner block and rewrite the body of the
// module as an async function. Otherwise merge the statements back // module as an async function. Otherwise merge the statements back
@ -628,7 +634,7 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
} else if (info->is_wrapped_as_function()) { } else if (info->is_wrapped_as_function()) {
DCHECK(parsing_on_main_thread_); DCHECK(parsing_on_main_thread_);
ParseWrapped(isolate, info, &body, scope, zone()); ParseWrapped(isolate, info, &body, scope, zone());
} else if (flags().is_repl_mode) { } else if (info->is_repl_mode()) {
ParseREPLProgram(info, &body, scope); ParseREPLProgram(info, &body, scope);
} else { } else {
// Don't count the mode in the use counters--give the program a chance // Don't count the mode in the use counters--give the program a chance
@ -653,13 +659,13 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
} }
// Internalize the ast strings in the case of eval so we can check for // Internalize the ast strings in the case of eval so we can check for
// conflicting var declarations with outer scope-info-backed scopes. // conflicting var declarations with outer scope-info-backed scopes.
if (flags().is_eval) { if (info->is_eval()) {
DCHECK(parsing_on_main_thread_); DCHECK(parsing_on_main_thread_);
info->ast_value_factory()->Internalize(isolate); info->ast_value_factory()->Internalize(isolate);
} }
CheckConflictingVarDeclarations(scope); CheckConflictingVarDeclarations(scope);
if (flags().parse_restriction == ONLY_SINGLE_FUNCTION_LITERAL) { if (info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
if (body.length() != 1 || !body.at(0)->IsExpressionStatement() || if (body.length() != 1 || !body.at(0)->IsExpressionStatement() ||
!body.at(0) !body.at(0)
->AsExpressionStatement() ->AsExpressionStatement()
@ -737,7 +743,7 @@ void Parser::ParseREPLProgram(ParseInfo* info, ScopedPtrList<Statement>* body,
// completion value of the script is obtained by manually invoking // completion value of the script is obtained by manually invoking
// the {Rewriter} which will return a VariableProxy referencing the // the {Rewriter} which will return a VariableProxy referencing the
// result. // result.
DCHECK(flags().is_repl_mode); DCHECK(info->is_repl_mode());
this->scope()->SetLanguageMode(info->language_mode()); this->scope()->SetLanguageMode(info->language_mode());
PrepareGeneratorVariables(); PrepareGeneratorVariables();
@ -807,10 +813,6 @@ FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
Script::cast(shared_info->script()).wrapped_arguments(), isolate); 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. // Initialize parser state.
Handle<String> name(shared_info->Name(), isolate); Handle<String> name(shared_info->Name(), isolate);
info->set_function_name(ast_value_factory()->GetString(name)); info->set_function_name(ast_value_factory()->GetString(name));
@ -823,11 +825,9 @@ FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
// function is in heritage position. Otherwise the function scope's skip bit // function is in heritage position. Otherwise the function scope's skip bit
// will be correctly inherited from the outer scope. // will be correctly inherited from the outer scope.
ClassScope::HeritageParsingScope heritage(original_scope_->AsClassScope()); ClassScope::HeritageParsingScope heritage(original_scope_->AsClassScope());
result = DoParseFunction(isolate, info, start_position, end_position, result = DoParseFunction(isolate, info, info->function_name());
function_literal_id, info->function_name());
} else { } else {
result = DoParseFunction(isolate, info, start_position, end_position, result = DoParseFunction(isolate, info, info->function_name());
function_literal_id, info->function_name());
} }
MaybeResetCharacterStream(info, result); MaybeResetCharacterStream(info, result);
MaybeProcessSourceRanges(info, result, stack_limit_); MaybeProcessSourceRanges(info, result, stack_limit_);
@ -843,7 +843,7 @@ FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
DeclarationScope* function_scope = result->scope(); DeclarationScope* function_scope = result->scope();
std::unique_ptr<char[]> function_name = result->GetDebugName(); std::unique_ptr<char[]> function_name = result->GetDebugName();
LOG(isolate, LOG(isolate,
FunctionEvent("parse-function", flags().script_id, ms, FunctionEvent("parse-function", script_id(), ms,
function_scope->start_position(), function_scope->start_position(),
function_scope->end_position(), function_name.get(), function_scope->end_position(), function_name.get(),
strlen(function_name.get()))); strlen(function_name.get())));
@ -852,8 +852,6 @@ FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
} }
FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info, FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
int start_position, int end_position,
int function_literal_id,
const AstRawString* raw_name) { const AstRawString* raw_name) {
DCHECK_EQ(parsing_on_main_thread_, isolate != nullptr); DCHECK_EQ(parsing_on_main_thread_, isolate != nullptr);
DCHECK_NOT_NULL(raw_name); DCHECK_NOT_NULL(raw_name);
@ -863,8 +861,8 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
fni_.PushEnclosingName(raw_name); fni_.PushEnclosingName(raw_name);
ResetFunctionLiteralId(); ResetFunctionLiteralId();
DCHECK_LT(0, function_literal_id); DCHECK_LT(0, info->function_literal_id());
SkipFunctionLiterals(function_literal_id - 1); SkipFunctionLiterals(info->function_literal_id() - 1);
ParsingModeScope parsing_mode(this, PARSE_EAGERLY); ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
@ -880,10 +878,10 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
BlockState block_state(&scope_, outer); BlockState block_state(&scope_, outer);
DCHECK(is_sloppy(outer->language_mode()) || DCHECK(is_sloppy(outer->language_mode()) ||
is_strict(info->language_mode())); is_strict(info->language_mode()));
FunctionKind kind = flags().function_kind; FunctionKind kind = info->function_kind();
DCHECK_IMPLIES( DCHECK_IMPLIES(
IsConciseMethod(kind) || IsAccessorFunction(kind), IsConciseMethod(kind) || IsAccessorFunction(kind),
flags().function_syntax_kind == FunctionSyntaxKind::kAccessorOrMethod); info->function_syntax_kind() == FunctionSyntaxKind::kAccessorOrMethod);
if (IsArrowFunction(kind)) { if (IsArrowFunction(kind)) {
if (IsAsyncFunction(kind)) { if (IsAsyncFunction(kind)) {
@ -906,7 +904,7 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
// not passing the ScopeInfo to the Scope constructor. // not passing the ScopeInfo to the Scope constructor.
SetLanguageMode(scope, info->language_mode()); SetLanguageMode(scope, info->language_mode());
scope->set_start_position(start_position); scope->set_start_position(info->start_position());
ParserFormalParameters formals(scope); ParserFormalParameters formals(scope);
{ {
ParameterDeclarationParsingScope formals_scope(this); ParameterDeclarationParsingScope formals_scope(this);
@ -927,14 +925,14 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
formals.duplicate_loc = formals_scope.duplicate_location(); formals.duplicate_loc = formals_scope.duplicate_location();
} }
if (GetLastFunctionLiteralId() != function_literal_id - 1) { if (GetLastFunctionLiteralId() != info->function_literal_id() - 1) {
if (has_error()) return nullptr; if (has_error()) return nullptr;
// If there were FunctionLiterals in the parameters, we need to // If there were FunctionLiterals in the parameters, we need to
// renumber them to shift down so the next function literal id for // renumber them to shift down so the next function literal id for
// the arrow function is the one requested. // the arrow function is the one requested.
AstFunctionLiteralIdReindexer reindexer( AstFunctionLiteralIdReindexer reindexer(
stack_limit_, stack_limit_,
(function_literal_id - 1) - GetLastFunctionLiteralId()); (info->function_literal_id() - 1) - GetLastFunctionLiteralId());
for (auto p : formals.params) { for (auto p : formals.params) {
if (p->pattern != nullptr) reindexer.Reindex(p->pattern); if (p->pattern != nullptr) reindexer.Reindex(p->pattern);
if (p->initializer() != nullptr) { if (p->initializer() != nullptr) {
@ -942,7 +940,7 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
} }
} }
ResetFunctionLiteralId(); ResetFunctionLiteralId();
SkipFunctionLiterals(function_literal_id - 1); SkipFunctionLiterals(info->function_literal_id() - 1);
} }
Expression* expression = ParseArrowFunctionLiteral(formals); Expression* expression = ParseArrowFunctionLiteral(formals);
@ -952,7 +950,7 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
// concise body happens to be a valid expression. This is a problem // concise body happens to be a valid expression. This is a problem
// only for arrow functions with single expression bodies, since there // only for arrow functions with single expression bodies, since there
// is no end token such as "}" for normal functions. // is no end token such as "}" for normal functions.
if (scanner()->location().end_pos == end_position) { if (scanner()->location().end_pos == info->end_position()) {
// The pre-parser saw an arrow function here, so the full parser // The pre-parser saw an arrow function here, so the full parser
// must produce a FunctionLiteral. // must produce a FunctionLiteral.
DCHECK(expression->IsFunctionLiteral()); DCHECK(expression->IsFunctionLiteral());
@ -961,7 +959,7 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
} else if (IsDefaultConstructor(kind)) { } else if (IsDefaultConstructor(kind)) {
DCHECK_EQ(scope(), outer); DCHECK_EQ(scope(), outer);
result = DefaultConstructor(raw_name, IsDerivedConstructor(kind), result = DefaultConstructor(raw_name, IsDerivedConstructor(kind),
start_position, end_position); info->start_position(), info->end_position());
} else { } else {
ZonePtrList<const AstRawString>* arguments_for_wrapped_function = ZonePtrList<const AstRawString>* arguments_for_wrapped_function =
info->is_wrapped_as_function() info->is_wrapped_as_function()
@ -969,23 +967,24 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
: nullptr; : nullptr;
result = ParseFunctionLiteral( result = ParseFunctionLiteral(
raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, kind, raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, kind,
kNoSourcePosition, flags().function_syntax_kind, kNoSourcePosition, info->function_syntax_kind(),
info->language_mode(), arguments_for_wrapped_function); info->language_mode(), arguments_for_wrapped_function);
} }
if (has_error()) return nullptr; if (has_error()) return nullptr;
result->set_requires_instance_members_initializer( result->set_requires_instance_members_initializer(
flags().requires_instance_members_initializer); info->requires_instance_members_initializer());
result->set_class_scope_has_private_brand( result->set_class_scope_has_private_brand(
flags().class_scope_has_private_brand); info->class_scope_has_private_brand());
result->set_has_static_private_methods_or_accessors( result->set_has_static_private_methods_or_accessors(
flags().has_static_private_methods_or_accessors); info->has_static_private_methods_or_accessors());
if (flags().is_oneshot_iife) { if (info->is_oneshot_iife()) {
result->mark_as_oneshot_iife(); result->mark_as_oneshot_iife();
} }
} }
DCHECK_IMPLIES(result, function_literal_id == result->function_literal_id()); DCHECK_IMPLIES(result,
info->function_literal_id() == result->function_literal_id());
return result; return result;
} }
@ -1006,9 +1005,8 @@ Statement* Parser::ParseModuleItem() {
// We must be careful not to parse a dynamic import expression as an import // We must be careful not to parse a dynamic import expression as an import
// declaration. Same for import.meta expressions. // declaration. Same for import.meta expressions.
Token::Value peek_ahead = PeekAhead(); Token::Value peek_ahead = PeekAhead();
if ((!flags().allow_harmony_dynamic_import || if ((!allow_harmony_dynamic_import() || peek_ahead != Token::LPAREN) &&
peek_ahead != Token::LPAREN) && (!allow_harmony_import_meta() || peek_ahead != Token::PERIOD)) {
(!flags().allow_harmony_import_meta || peek_ahead != Token::PERIOD)) {
ParseImportDeclaration(); ParseImportDeclaration();
return factory()->EmptyStatement(); return factory()->EmptyStatement();
} }
@ -1068,7 +1066,7 @@ ZoneChunkList<Parser::ExportClauseData>* Parser::ParseExportClause(
// caller needs to report an error. // caller needs to report an error.
if (!reserved_loc->IsValid() && if (!reserved_loc->IsValid() &&
!Token::IsValidIdentifier(name_tok, LanguageMode::kStrict, false, !Token::IsValidIdentifier(name_tok, LanguageMode::kStrict, false,
flags().is_module)) { parsing_module_)) {
*reserved_loc = scanner()->location(); *reserved_loc = scanner()->location();
} }
const AstRawString* local_name = ParsePropertyName(); const AstRawString* local_name = ParsePropertyName();
@ -1124,7 +1122,7 @@ ZonePtrList<const Parser::NamedImport>* Parser::ParseNamedImports(int pos) {
} }
if (!Token::IsValidIdentifier(scanner()->current_token(), if (!Token::IsValidIdentifier(scanner()->current_token(),
LanguageMode::kStrict, false, LanguageMode::kStrict, false,
flags().is_module)) { parsing_module_)) {
ReportMessage(MessageTemplate::kUnexpectedReserved); ReportMessage(MessageTemplate::kUnexpectedReserved);
return nullptr; return nullptr;
} else if (IsEvalOrArguments(local_name)) { } else if (IsEvalOrArguments(local_name)) {
@ -1562,7 +1560,7 @@ Statement* Parser::DeclareFunction(const AstRawString* variable_name,
bool was_added; bool was_added;
Declare(declaration, variable_name, kind, mode, kCreatedInitialized, scope(), Declare(declaration, variable_name, kind, mode, kCreatedInitialized, scope(),
&was_added, beg_pos); &was_added, beg_pos);
if (info()->flags().coverage_enabled) { if (info()->coverage_enabled()) {
// Force the function to be allocated when collecting source coverage, so // Force the function to be allocated when collecting source coverage, so
// that even dead functions get source coverage data. // that even dead functions get source coverage data.
declaration->var()->set_is_used(); declaration->var()->set_is_used();
@ -2378,7 +2376,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
// parenthesis before the function means that it will be called // 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 // immediately). bar can be parsed lazily, but we need to parse it in a mode
// that tracks unresolved variables. // that tracks unresolved variables.
DCHECK_IMPLIES(parse_lazily(), info()->flags().allow_lazy_compile); DCHECK_IMPLIES(parse_lazily(), info()->allow_lazy_compile());
DCHECK_IMPLIES(parse_lazily(), has_error() || allow_lazy_); DCHECK_IMPLIES(parse_lazily(), has_error() || allow_lazy_);
DCHECK_IMPLIES(parse_lazily(), extension_ == nullptr); DCHECK_IMPLIES(parse_lazily(), extension_ == nullptr);
@ -2477,7 +2475,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
? (is_top_level ? "preparse-no-resolution" : "preparse-resolution") ? (is_top_level ? "preparse-no-resolution" : "preparse-resolution")
: "full-parse"; : "full-parse";
logger_->FunctionEvent( logger_->FunctionEvent(
event_name, flags().script_id, ms, scope->start_position(), event_name, script_id(), ms, scope->start_position(),
scope->end_position(), scope->end_position(),
reinterpret_cast<const char*>(function_name->raw_data()), reinterpret_cast<const char*>(function_name->raw_data()),
function_name->byte_length()); function_name->byte_length());
@ -2584,7 +2582,7 @@ bool Parser::SkipFunction(const AstRawString* function_name, FunctionKind kind,
PreParser::PreParseResult result = reusable_preparser()->PreParseFunction( PreParser::PreParseResult result = reusable_preparser()->PreParseFunction(
function_name, kind, function_syntax_kind, function_scope, use_counts_, function_name, kind, function_syntax_kind, function_scope, use_counts_,
produced_preparse_data); produced_preparse_data, this->script_id());
if (result == PreParser::kPreParseStackOverflow) { if (result == PreParser::kPreParseStackOverflow) {
// Propagate stack overflow. // Propagate stack overflow.
@ -2881,7 +2879,7 @@ void Parser::DeclarePrivateClassMember(ClassScope* scope,
ClassLiteralProperty::Kind kind, ClassLiteralProperty::Kind kind,
bool is_static, ClassInfo* class_info) { bool is_static, ClassInfo* class_info) {
DCHECK_IMPLIES(kind != ClassLiteralProperty::Kind::FIELD, DCHECK_IMPLIES(kind != ClassLiteralProperty::Kind::FIELD,
flags().allow_harmony_private_methods); allow_harmony_private_methods());
if (kind == ClassLiteralProperty::Kind::FIELD) { if (kind == ClassLiteralProperty::Kind::FIELD) {
if (is_static) { if (is_static) {
@ -3086,11 +3084,11 @@ void Parser::UpdateStatistics(Isolate* isolate, Handle<Script> script) {
total_preparse_skipped_); total_preparse_skipped_);
} }
void Parser::ParseOnBackground(ParseInfo* info, int start_position, void Parser::ParseOnBackground(ParseInfo* info) {
int end_position, int function_literal_id) {
RuntimeCallTimerScope runtimeTimer( RuntimeCallTimerScope runtimeTimer(
runtime_call_stats_, RuntimeCallCounterId::kParseBackgroundProgram); runtime_call_stats_, RuntimeCallCounterId::kParseBackgroundProgram);
parsing_on_main_thread_ = false; parsing_on_main_thread_ = false;
set_script_id(info->script_id());
DCHECK_NULL(info->literal()); DCHECK_NULL(info->literal());
FunctionLiteral* result = nullptr; FunctionLiteral* result = nullptr;
@ -3105,15 +3103,11 @@ void Parser::ParseOnBackground(ParseInfo* info, int start_position,
// don't). We work around this by storing all the scopes which need their end // 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 // 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. // scopes) and set their end position after we know the script length.
if (flags().is_toplevel) { if (info->is_toplevel()) {
DCHECK_EQ(start_position, 0);
DCHECK_EQ(end_position, 0);
DCHECK_EQ(function_literal_id, kFunctionLiteralIdTopLevel);
result = DoParseProgram(/* isolate = */ nullptr, info); result = DoParseProgram(/* isolate = */ nullptr, info);
} else { } else {
result = DoParseFunction(/* isolate = */ nullptr, info, start_position, result =
end_position, function_literal_id, DoParseFunction(/* isolate = */ nullptr, info, info->function_name());
info->function_name());
} }
MaybeResetCharacterStream(info, result); MaybeResetCharacterStream(info, result);
MaybeProcessSourceRanges(info, result, stack_limit_); MaybeProcessSourceRanges(info, result, stack_limit_);

View File

@ -14,7 +14,6 @@
#include "src/base/compiler-specific.h" #include "src/base/compiler-specific.h"
#include "src/base/threaded-list.h" #include "src/base/threaded-list.h"
#include "src/common/globals.h" #include "src/common/globals.h"
#include "src/parsing/parse-info.h"
#include "src/parsing/parser-base.h" #include "src/parsing/parser-base.h"
#include "src/parsing/parsing.h" #include "src/parsing/parsing.h"
#include "src/parsing/preparser.h" #include "src/parsing/preparser.h"
@ -135,8 +134,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
static bool IsPreParser() { return false; } static bool IsPreParser() { return false; }
void ParseOnBackground(ParseInfo* info, int start_position, int end_position, void ParseOnBackground(ParseInfo* info);
int function_literal_id);
// Initializes an empty scope chain for top-level scripts, or scopes which // Initializes an empty scope chain for top-level scripts, or scopes which
// consist of only the native context. // consist of only the native context.
@ -217,8 +215,6 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
FunctionLiteral* ParseFunction(Isolate* isolate, ParseInfo* info, FunctionLiteral* ParseFunction(Isolate* isolate, ParseInfo* info,
Handle<SharedFunctionInfo> shared_info); Handle<SharedFunctionInfo> shared_info);
FunctionLiteral* DoParseFunction(Isolate* isolate, ParseInfo* info, FunctionLiteral* DoParseFunction(Isolate* isolate, ParseInfo* info,
int start_position, int end_position,
int function_literal_id,
const AstRawString* raw_name); const AstRawString* raw_name);
// Called by ParseProgram after setting up the scanner. // Called by ParseProgram after setting up the scanner.
@ -243,9 +239,15 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
if (reusable_preparser_ == nullptr) { if (reusable_preparser_ == nullptr) {
reusable_preparser_ = new PreParser( reusable_preparser_ = new PreParser(
&preparser_zone_, &scanner_, stack_limit_, ast_value_factory(), &preparser_zone_, &scanner_, stack_limit_, ast_value_factory(),
pending_error_handler(), runtime_call_stats_, logger_, flags(), pending_error_handler(), runtime_call_stats_, logger_, -1,
parsing_on_main_thread_); parsing_module_, parsing_on_main_thread_);
reusable_preparser_->set_allow_eval_cache(allow_eval_cache()); #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
preparse_data_buffer_.reserve(128); preparse_data_buffer_.reserve(128);
} }
return reusable_preparser_; return reusable_preparser_;

View File

@ -22,7 +22,7 @@ namespace parsing {
bool ParseProgram(ParseInfo* info, Handle<Script> script, bool ParseProgram(ParseInfo* info, Handle<Script> script,
MaybeHandle<ScopeInfo> maybe_outer_scope_info, MaybeHandle<ScopeInfo> maybe_outer_scope_info,
Isolate* isolate, ReportErrorsAndStatisticsMode mode) { Isolate* isolate, ReportErrorsAndStatisticsMode mode) {
DCHECK(info->flags().is_toplevel); DCHECK(info->is_toplevel());
DCHECK_NULL(info->literal()); DCHECK_NULL(info->literal());
VMState<PARSER> state(isolate); VMState<PARSER> state(isolate);
@ -44,7 +44,7 @@ bool ParseProgram(ParseInfo* info, Handle<Script> script,
info->set_literal(result); info->set_literal(result);
if (result) { if (result) {
info->set_language_mode(info->literal()->language_mode()); info->set_language_mode(info->literal()->language_mode());
if (info->flags().is_eval) { if (info->is_eval()) {
info->set_allow_eval_cache(parser.allow_eval_cache()); info->set_allow_eval_cache(parser.allow_eval_cache());
} }
} }
@ -66,7 +66,7 @@ bool ParseProgram(ParseInfo* info, Handle<Script> script, Isolate* isolate,
bool ParseFunction(ParseInfo* info, Handle<SharedFunctionInfo> shared_info, bool ParseFunction(ParseInfo* info, Handle<SharedFunctionInfo> shared_info,
Isolate* isolate, ReportErrorsAndStatisticsMode mode) { Isolate* isolate, ReportErrorsAndStatisticsMode mode) {
DCHECK(!info->flags().is_toplevel); DCHECK(!info->is_toplevel());
DCHECK(!shared_info.is_null()); DCHECK(!shared_info.is_null());
DCHECK_NULL(info->literal()); DCHECK_NULL(info->literal());
@ -91,7 +91,7 @@ bool ParseFunction(ParseInfo* info, Handle<SharedFunctionInfo> shared_info,
info->set_literal(result); info->set_literal(result);
if (result) { if (result) {
info->ast_value_factory()->Internalize(isolate); info->ast_value_factory()->Internalize(isolate);
if (info->flags().is_eval) { if (info->is_eval()) {
info->set_allow_eval_cache(parser.allow_eval_cache()); info->set_allow_eval_cache(parser.allow_eval_cache());
} }
} }
@ -109,7 +109,7 @@ bool ParseFunction(ParseInfo* info, Handle<SharedFunctionInfo> shared_info,
bool ParseAny(ParseInfo* info, Handle<SharedFunctionInfo> shared_info, bool ParseAny(ParseInfo* info, Handle<SharedFunctionInfo> shared_info,
Isolate* isolate, ReportErrorsAndStatisticsMode mode) { Isolate* isolate, ReportErrorsAndStatisticsMode mode) {
DCHECK(!shared_info.is_null()); DCHECK(!shared_info.is_null());
if (info->flags().is_toplevel) { if (info->is_toplevel()) {
MaybeHandle<ScopeInfo> maybe_outer_scope_info; MaybeHandle<ScopeInfo> maybe_outer_scope_info;
if (shared_info->HasOuterScopeInfo()) { if (shared_info->HasOuterScopeInfo()) {
maybe_outer_scope_info = maybe_outer_scope_info =

View File

@ -78,7 +78,7 @@ PreParser::PreParseResult PreParser::PreParseProgram() {
// ModuleDeclarationInstantiation for Source Text Module Records creates a // ModuleDeclarationInstantiation for Source Text Module Records creates a
// new Module Environment Record whose outer lexical environment record is // new Module Environment Record whose outer lexical environment record is
// the global scope. // the global scope.
if (flags().is_module) scope = NewModuleScope(scope); if (parsing_module_) scope = NewModuleScope(scope);
FunctionState top_scope(&function_state_, &scope_, scope); FunctionState top_scope(&function_state_, &scope_, scope);
original_scope_ = scope_; original_scope_ = scope_;
@ -105,9 +105,11 @@ void PreParserFormalParameters::ValidateStrictMode(PreParser* preparser) const {
PreParser::PreParseResult PreParser::PreParseFunction( PreParser::PreParseResult PreParser::PreParseFunction(
const AstRawString* function_name, FunctionKind kind, const AstRawString* function_name, FunctionKind kind,
FunctionSyntaxKind function_syntax_kind, DeclarationScope* function_scope, FunctionSyntaxKind function_syntax_kind, DeclarationScope* function_scope,
int* use_counts, ProducedPreparseData** produced_preparse_data) { int* use_counts, ProducedPreparseData** produced_preparse_data,
int script_id) {
DCHECK_EQ(FUNCTION_SCOPE, function_scope->scope_type()); DCHECK_EQ(FUNCTION_SCOPE, function_scope->scope_type());
use_counts_ = use_counts; use_counts_ = use_counts;
set_script_id(script_id);
#ifdef DEBUG #ifdef DEBUG
function_scope->set_is_being_lazily_parsed(true); function_scope->set_is_being_lazily_parsed(true);
#endif #endif
@ -357,7 +359,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
name_byte_length = string->byte_length(); name_byte_length = string->byte_length();
} }
logger_->FunctionEvent( logger_->FunctionEvent(
event_name, flags().script_id, ms, function_scope->start_position(), event_name, script_id(), ms, function_scope->start_position(),
function_scope->end_position(), name, name_byte_length); function_scope->end_position(), name, name_byte_length);
} }

View File

@ -8,7 +8,6 @@
#include "src/ast/ast-value-factory.h" #include "src/ast/ast-value-factory.h"
#include "src/ast/ast.h" #include "src/ast/ast.h"
#include "src/ast/scopes.h" #include "src/ast/scopes.h"
#include "src/parsing/parse-info.h"
#include "src/parsing/parser-base.h" #include "src/parsing/parser-base.h"
#include "src/parsing/pending-compilation-error-handler.h" #include "src/parsing/pending-compilation-error-handler.h"
#include "src/parsing/preparser-logger.h" #include "src/parsing/preparser-logger.h"
@ -922,11 +921,12 @@ class PreParser : public ParserBase<PreParser> {
AstValueFactory* ast_value_factory, AstValueFactory* ast_value_factory,
PendingCompilationErrorHandler* pending_error_handler, PendingCompilationErrorHandler* pending_error_handler,
RuntimeCallStats* runtime_call_stats, Logger* logger, RuntimeCallStats* runtime_call_stats, Logger* logger,
UnoptimizedCompileFlags flags, bool parsing_on_main_thread = true) int script_id = -1, bool parsing_module = false,
bool parsing_on_main_thread = true)
: ParserBase<PreParser>(zone, scanner, stack_limit, nullptr, : ParserBase<PreParser>(zone, scanner, stack_limit, nullptr,
ast_value_factory, pending_error_handler, ast_value_factory, pending_error_handler,
runtime_call_stats, logger, flags, runtime_call_stats, logger, script_id,
parsing_on_main_thread), parsing_module, parsing_on_main_thread),
use_counts_(nullptr), use_counts_(nullptr),
preparse_data_builder_(nullptr), preparse_data_builder_(nullptr),
preparse_data_builder_buffer_() { preparse_data_builder_buffer_() {
@ -954,7 +954,8 @@ class PreParser : public ParserBase<PreParser> {
PreParseResult PreParseFunction( PreParseResult PreParseFunction(
const AstRawString* function_name, FunctionKind kind, const AstRawString* function_name, FunctionKind kind,
FunctionSyntaxKind function_syntax_kind, DeclarationScope* function_scope, FunctionSyntaxKind function_syntax_kind, DeclarationScope* function_scope,
int* use_counts, ProducedPreparseData** produced_preparser_scope_data); int* use_counts, ProducedPreparseData** produced_preparser_scope_data,
int script_id);
PreparseDataBuilder* preparse_data_builder() const { PreparseDataBuilder* preparse_data_builder() const {
return preparse_data_builder_; return preparse_data_builder_;

View File

@ -400,7 +400,7 @@ base::Optional<VariableProxy*> Rewriter::RewriteBody(
int pos = kNoSourcePosition; int pos = kNoSourcePosition;
VariableProxy* result_value = VariableProxy* result_value =
processor.factory()->NewVariableProxy(result, pos); processor.factory()->NewVariableProxy(result, pos);
if (!info->flags().is_repl_mode) { if (!info->is_repl_mode()) {
Statement* result_statement = Statement* result_statement =
processor.factory()->NewReturnStatement(result_value, pos); processor.factory()->NewReturnStatement(result_value, pos);
body->Add(result_statement, info->zone()); body->Add(result_statement, info->zone());

View File

@ -13,7 +13,6 @@
#include "src/ast/ast-value-factory.h" #include "src/ast/ast-value-factory.h"
#include "src/numbers/conversions-inl.h" #include "src/numbers/conversions-inl.h"
#include "src/objects/bigint.h" #include "src/objects/bigint.h"
#include "src/parsing/parse-info.h"
#include "src/parsing/scanner-inl.h" #include "src/parsing/scanner-inl.h"
#include "src/zone/zone.h" #include "src/zone/zone.h"
@ -90,10 +89,10 @@ bool Scanner::BookmarkScope::HasBeenApplied() const {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Scanner // Scanner
Scanner::Scanner(Utf16CharacterStream* source, UnoptimizedCompileFlags flags) Scanner::Scanner(Utf16CharacterStream* source, bool is_module)
: flags_(flags), : source_(source),
source_(source),
found_html_comment_(false), found_html_comment_(false),
is_module_(is_module),
octal_pos_(Location::invalid()), octal_pos_(Location::invalid()),
octal_message_(MessageTemplate::kNone) { octal_message_(MessageTemplate::kNone) {
DCHECK_NOT_NULL(source); DCHECK_NOT_NULL(source);
@ -189,7 +188,7 @@ Token::Value Scanner::PeekAhead() {
} }
Token::Value Scanner::SkipSingleHTMLComment() { Token::Value Scanner::SkipSingleHTMLComment() {
if (flags_.is_module) { if (is_module_) {
ReportScannerError(source_pos(), MessageTemplate::kHtmlCommentInModule); ReportScannerError(source_pos(), MessageTemplate::kHtmlCommentInModule);
return Token::ILLEGAL; return Token::ILLEGAL;
} }

View File

@ -15,7 +15,6 @@
#include "src/common/globals.h" #include "src/common/globals.h"
#include "src/common/message-template.h" #include "src/common/message-template.h"
#include "src/parsing/literal-buffer.h" #include "src/parsing/literal-buffer.h"
#include "src/parsing/parse-info.h"
#include "src/parsing/token.h" #include "src/parsing/token.h"
#include "src/strings/char-predicates.h" #include "src/strings/char-predicates.h"
#include "src/strings/unicode.h" #include "src/strings/unicode.h"
@ -270,7 +269,7 @@ class V8_EXPORT_PRIVATE Scanner {
static const int kNoOctalLocation = -1; static const int kNoOctalLocation = -1;
static const uc32 kEndOfInput = Utf16CharacterStream::kEndOfInput; static const uc32 kEndOfInput = Utf16CharacterStream::kEndOfInput;
explicit Scanner(Utf16CharacterStream* source, UnoptimizedCompileFlags flags); explicit Scanner(Utf16CharacterStream* source, bool is_module);
void Initialize(); void Initialize();
@ -704,8 +703,6 @@ class V8_EXPORT_PRIVATE Scanner {
const TokenDesc& next() const { return *next_; } const TokenDesc& next() const { return *next_; }
const TokenDesc& next_next() const { return *next_next_; } const TokenDesc& next_next() const { return *next_next_; }
UnoptimizedCompileFlags flags_;
TokenDesc* current_; // desc for current token (as returned by Next()) TokenDesc* current_; // desc for current token (as returned by Next())
TokenDesc* next_; // desc for next token (one token look-ahead) TokenDesc* next_; // desc for next token (one token look-ahead)
TokenDesc* next_next_; // desc for the token after next (after PeakAhead()) TokenDesc* next_next_; // desc for the token after next (after PeakAhead())
@ -721,6 +718,8 @@ class V8_EXPORT_PRIVATE Scanner {
// Whether this scanner encountered an HTML comment. // Whether this scanner encountered an HTML comment.
bool found_html_comment_; bool found_html_comment_;
const bool is_module_;
// Values parsed from magic comments. // Values parsed from magic comments.
LiteralBuffer source_url_; LiteralBuffer source_url_;
LiteralBuffer source_mapping_url_; LiteralBuffer source_mapping_url_;

View File

@ -707,12 +707,9 @@ TEST(PreParserScopeAnalysis) {
shared->uncompiled_data_with_preparse_data().preparse_data(), shared->uncompiled_data_with_preparse_data().preparse_data(),
isolate); isolate);
i::UnoptimizedCompileFlags flags =
i::UnoptimizedCompileFlags::ForFunctionCompile(isolate, *shared);
flags.is_lazy_compile = true;
// Parse the lazy function using the scope data. // Parse the lazy function using the scope data.
i::ParseInfo using_scope_data(isolate, flags); i::ParseInfo using_scope_data(isolate, *shared);
using_scope_data.set_lazy_compile();
using_scope_data.set_consumed_preparse_data( using_scope_data.set_consumed_preparse_data(
i::ConsumedPreparseData::For(isolate, produced_data_on_heap)); i::ConsumedPreparseData::For(isolate, produced_data_on_heap));
CHECK(i::parsing::ParseFunction(&using_scope_data, shared, isolate)); CHECK(i::parsing::ParseFunction(&using_scope_data, shared, isolate));
@ -727,7 +724,8 @@ TEST(PreParserScopeAnalysis) {
CHECK(i::DeclarationScope::Analyze(&using_scope_data)); CHECK(i::DeclarationScope::Analyze(&using_scope_data));
// Parse the lazy function again eagerly to produce baseline data. // Parse the lazy function again eagerly to produce baseline data.
i::ParseInfo not_using_scope_data(isolate, flags); i::ParseInfo not_using_scope_data(isolate, *shared);
not_using_scope_data.set_lazy_compile();
CHECK(i::parsing::ParseFunction(&not_using_scope_data, shared, isolate)); CHECK(i::parsing::ParseFunction(&not_using_scope_data, shared, isolate));
// Verify that we didn't skip anything (there's no preparsed scope data, // Verify that we didn't skip anything (there's no preparsed scope data,
@ -761,9 +759,7 @@ TEST(Regress753896) {
i::Handle<i::String> source = factory->InternalizeUtf8String( i::Handle<i::String> source = factory->InternalizeUtf8String(
"function lazy() { let v = 0; if (true) { var v = 0; } }"); "function lazy() { let v = 0; if (true) { var v = 0; } }");
i::Handle<i::Script> script = factory->NewScript(source); i::Handle<i::Script> script = factory->NewScript(source);
i::UnoptimizedCompileFlags flags = i::ParseInfo info(isolate, *script);
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
i::ParseInfo info(isolate, flags);
// We don't assert that parsing succeeded or that it failed; currently the // We don't assert that parsing succeeded or that it failed; currently the
// error is not detected inside lazy functions, but it might be in the future. // error is not detected inside lazy functions, but it might be in the future.

View File

@ -7,7 +7,6 @@
#include "src/handles/handles-inl.h" #include "src/handles/handles-inl.h"
#include "src/objects/objects-inl.h" #include "src/objects/objects-inl.h"
#include "src/parsing/parse-info.h"
#include "src/parsing/scanner-character-streams.h" #include "src/parsing/scanner-character-streams.h"
#include "src/parsing/scanner.h" #include "src/parsing/scanner.h"
#include "test/cctest/cctest.h" #include "test/cctest/cctest.h"
@ -35,9 +34,8 @@ struct ScannerTestHelper {
ScannerTestHelper make_scanner(const char* src) { ScannerTestHelper make_scanner(const char* src) {
ScannerTestHelper helper; ScannerTestHelper helper;
helper.stream = ScannerStream::ForTesting(src); helper.stream = ScannerStream::ForTesting(src);
helper.scanner = std::unique_ptr<Scanner>( helper.scanner =
new Scanner(helper.stream.get(), std::unique_ptr<Scanner>(new Scanner(helper.stream.get(), false));
UnoptimizedCompileFlags::ForTest(CcTest::i_isolate())));
helper.scanner->Initialize(); helper.scanner->Initialize();
return helper; return helper;
} }

View File

@ -515,8 +515,6 @@ TEST(ScanKeywords) {
#undef KEYWORD #undef KEYWORD
{nullptr, i::Token::IDENTIFIER}}; {nullptr, i::Token::IDENTIFIER}};
i::UnoptimizedCompileFlags flags =
i::UnoptimizedCompileFlags::ForTest(CcTest::i_isolate());
KeywordToken key_token; KeywordToken key_token;
char buffer[32]; char buffer[32];
for (int i = 0; (key_token = keywords[i]).keyword != nullptr; i++) { for (int i = 0; (key_token = keywords[i]).keyword != nullptr; i++) {
@ -525,7 +523,7 @@ TEST(ScanKeywords) {
CHECK(static_cast<int>(sizeof(buffer)) >= length); CHECK(static_cast<int>(sizeof(buffer)) >= length);
{ {
auto stream = i::ScannerStream::ForTesting(keyword, length); auto stream = i::ScannerStream::ForTesting(keyword, length);
i::Scanner scanner(stream.get(), flags); i::Scanner scanner(stream.get(), false);
scanner.Initialize(); scanner.Initialize();
CHECK_EQ(key_token.token, scanner.Next()); CHECK_EQ(key_token.token, scanner.Next());
CHECK_EQ(i::Token::EOS, scanner.Next()); CHECK_EQ(i::Token::EOS, scanner.Next());
@ -533,7 +531,7 @@ TEST(ScanKeywords) {
// Removing characters will make keyword matching fail. // Removing characters will make keyword matching fail.
{ {
auto stream = i::ScannerStream::ForTesting(keyword, length - 1); auto stream = i::ScannerStream::ForTesting(keyword, length - 1);
i::Scanner scanner(stream.get(), flags); i::Scanner scanner(stream.get(), false);
scanner.Initialize(); scanner.Initialize();
CHECK_EQ(i::Token::IDENTIFIER, scanner.Next()); CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
CHECK_EQ(i::Token::EOS, scanner.Next()); CHECK_EQ(i::Token::EOS, scanner.Next());
@ -544,7 +542,7 @@ TEST(ScanKeywords) {
i::MemMove(buffer, keyword, length); i::MemMove(buffer, keyword, length);
buffer[length] = chars_to_append[j]; buffer[length] = chars_to_append[j];
auto stream = i::ScannerStream::ForTesting(buffer, length + 1); auto stream = i::ScannerStream::ForTesting(buffer, length + 1);
i::Scanner scanner(stream.get(), flags); i::Scanner scanner(stream.get(), false);
scanner.Initialize(); scanner.Initialize();
CHECK_EQ(i::Token::IDENTIFIER, scanner.Next()); CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
CHECK_EQ(i::Token::EOS, scanner.Next()); CHECK_EQ(i::Token::EOS, scanner.Next());
@ -554,7 +552,7 @@ TEST(ScanKeywords) {
i::MemMove(buffer, keyword, length); i::MemMove(buffer, keyword, length);
buffer[length - 1] = '_'; buffer[length - 1] = '_';
auto stream = i::ScannerStream::ForTesting(buffer, length); auto stream = i::ScannerStream::ForTesting(buffer, length);
i::Scanner scanner(stream.get(), flags); i::Scanner scanner(stream.get(), false);
scanner.Initialize(); scanner.Initialize();
CHECK_EQ(i::Token::IDENTIFIER, scanner.Next()); CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
CHECK_EQ(i::Token::EOS, scanner.Next()); CHECK_EQ(i::Token::EOS, scanner.Next());
@ -568,8 +566,6 @@ TEST(ScanHTMLEndComments) {
v8::Isolate* isolate = CcTest::isolate(); v8::Isolate* isolate = CcTest::isolate();
i::Isolate* i_isolate = CcTest::i_isolate(); i::Isolate* i_isolate = CcTest::i_isolate();
v8::HandleScope handles(isolate); v8::HandleScope handles(isolate);
i::UnoptimizedCompileFlags flags =
i::UnoptimizedCompileFlags::ForTest(i_isolate);
// Regression test. See: // Regression test. See:
// http://code.google.com/p/chromium/issues/detail?id=53548 // http://code.google.com/p/chromium/issues/detail?id=53548
@ -623,7 +619,7 @@ TEST(ScanHTMLEndComments) {
for (int i = 0; tests[i]; i++) { for (int i = 0; tests[i]; i++) {
const char* source = tests[i]; const char* source = tests[i];
auto stream = i::ScannerStream::ForTesting(source); auto stream = i::ScannerStream::ForTesting(source);
i::Scanner scanner(stream.get(), flags); i::Scanner scanner(stream.get(), false);
scanner.Initialize(); scanner.Initialize();
i::Zone zone(i_isolate->allocator(), ZONE_NAME); i::Zone zone(i_isolate->allocator(), ZONE_NAME);
i::AstValueFactory ast_value_factory( i::AstValueFactory ast_value_factory(
@ -632,7 +628,7 @@ TEST(ScanHTMLEndComments) {
i::PreParser preparser(&zone, &scanner, stack_limit, &ast_value_factory, i::PreParser preparser(&zone, &scanner, stack_limit, &ast_value_factory,
&pending_error_handler, &pending_error_handler,
i_isolate->counters()->runtime_call_stats(), i_isolate->counters()->runtime_call_stats(),
i_isolate->logger(), flags); i_isolate->logger());
i::PreParser::PreParseResult result = preparser.PreParseProgram(); i::PreParser::PreParseResult result = preparser.PreParseProgram();
CHECK_EQ(i::PreParser::kPreParseSuccess, result); CHECK_EQ(i::PreParser::kPreParseSuccess, result);
CHECK(!pending_error_handler.has_pending_error()); CHECK(!pending_error_handler.has_pending_error());
@ -641,7 +637,7 @@ TEST(ScanHTMLEndComments) {
for (int i = 0; fail_tests[i]; i++) { for (int i = 0; fail_tests[i]; i++) {
const char* source = fail_tests[i]; const char* source = fail_tests[i];
auto stream = i::ScannerStream::ForTesting(source); auto stream = i::ScannerStream::ForTesting(source);
i::Scanner scanner(stream.get(), flags); i::Scanner scanner(stream.get(), false);
scanner.Initialize(); scanner.Initialize();
i::Zone zone(i_isolate->allocator(), ZONE_NAME); i::Zone zone(i_isolate->allocator(), ZONE_NAME);
i::AstValueFactory ast_value_factory( i::AstValueFactory ast_value_factory(
@ -650,7 +646,7 @@ TEST(ScanHTMLEndComments) {
i::PreParser preparser(&zone, &scanner, stack_limit, &ast_value_factory, i::PreParser preparser(&zone, &scanner, stack_limit, &ast_value_factory,
&pending_error_handler, &pending_error_handler,
i_isolate->counters()->runtime_call_stats(), i_isolate->counters()->runtime_call_stats(),
i_isolate->logger(), flags); i_isolate->logger());
i::PreParser::PreParseResult result = preparser.PreParseProgram(); i::PreParser::PreParseResult result = preparser.PreParseProgram();
// Even in the case of a syntax error, kPreParseSuccess is returned. // Even in the case of a syntax error, kPreParseSuccess is returned.
CHECK_EQ(i::PreParser::kPreParseSuccess, result); CHECK_EQ(i::PreParser::kPreParseSuccess, result);
@ -660,15 +656,11 @@ TEST(ScanHTMLEndComments) {
} }
TEST(ScanHtmlComments) { TEST(ScanHtmlComments) {
i::UnoptimizedCompileFlags flags =
i::UnoptimizedCompileFlags::ForTest(CcTest::i_isolate());
const char* src = "a <!-- b --> c"; const char* src = "a <!-- b --> c";
// Disallow HTML comments. // Disallow HTML comments.
{ {
flags.is_module = true;
auto stream = i::ScannerStream::ForTesting(src); auto stream = i::ScannerStream::ForTesting(src);
i::Scanner scanner(stream.get(), flags); i::Scanner scanner(stream.get(), true);
scanner.Initialize(); scanner.Initialize();
CHECK_EQ(i::Token::IDENTIFIER, scanner.Next()); CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
CHECK_EQ(i::Token::ILLEGAL, scanner.Next()); CHECK_EQ(i::Token::ILLEGAL, scanner.Next());
@ -676,9 +668,8 @@ TEST(ScanHtmlComments) {
// Skip HTML comments: // Skip HTML comments:
{ {
flags.is_module = false;
auto stream = i::ScannerStream::ForTesting(src); auto stream = i::ScannerStream::ForTesting(src);
i::Scanner scanner(stream.get(), flags); i::Scanner scanner(stream.get(), false);
scanner.Initialize(); scanner.Initialize();
CHECK_EQ(i::Token::IDENTIFIER, scanner.Next()); CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
CHECK_EQ(i::Token::EOS, scanner.Next()); CHECK_EQ(i::Token::EOS, scanner.Next());
@ -702,9 +693,6 @@ class ScriptResource : public v8::String::ExternalOneByteStringResource {
TEST(StandAlonePreParser) { TEST(StandAlonePreParser) {
v8::V8::Initialize(); v8::V8::Initialize();
i::Isolate* i_isolate = CcTest::i_isolate(); i::Isolate* i_isolate = CcTest::i_isolate();
i::UnoptimizedCompileFlags flags =
i::UnoptimizedCompileFlags::ForTest(i_isolate);
flags.allow_natives_syntax = true;
i_isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() - i_isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
128 * 1024); 128 * 1024);
@ -720,7 +708,7 @@ TEST(StandAlonePreParser) {
uintptr_t stack_limit = i_isolate->stack_guard()->real_climit(); uintptr_t stack_limit = i_isolate->stack_guard()->real_climit();
for (int i = 0; programs[i]; i++) { for (int i = 0; programs[i]; i++) {
auto stream = i::ScannerStream::ForTesting(programs[i]); auto stream = i::ScannerStream::ForTesting(programs[i]);
i::Scanner scanner(stream.get(), flags); i::Scanner scanner(stream.get(), false);
scanner.Initialize(); scanner.Initialize();
i::Zone zone(i_isolate->allocator(), ZONE_NAME); i::Zone zone(i_isolate->allocator(), ZONE_NAME);
@ -730,7 +718,8 @@ TEST(StandAlonePreParser) {
i::PreParser preparser(&zone, &scanner, stack_limit, &ast_value_factory, i::PreParser preparser(&zone, &scanner, stack_limit, &ast_value_factory,
&pending_error_handler, &pending_error_handler,
i_isolate->counters()->runtime_call_stats(), i_isolate->counters()->runtime_call_stats(),
i_isolate->logger(), flags); i_isolate->logger());
preparser.set_allow_natives(true);
i::PreParser::PreParseResult result = preparser.PreParseProgram(); i::PreParser::PreParseResult result = preparser.PreParseProgram();
CHECK_EQ(i::PreParser::kPreParseSuccess, result); CHECK_EQ(i::PreParser::kPreParseSuccess, result);
CHECK(!pending_error_handler.has_pending_error()); CHECK(!pending_error_handler.has_pending_error());
@ -740,10 +729,8 @@ TEST(StandAlonePreParser) {
TEST(StandAlonePreParserNoNatives) { TEST(StandAlonePreParserNoNatives) {
v8::V8::Initialize(); v8::V8::Initialize();
i::Isolate* isolate = CcTest::i_isolate();
i::UnoptimizedCompileFlags flags =
i::UnoptimizedCompileFlags::ForTest(isolate);
i::Isolate* isolate = CcTest::i_isolate();
isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() - isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
128 * 1024); 128 * 1024);
@ -753,7 +740,7 @@ TEST(StandAlonePreParserNoNatives) {
uintptr_t stack_limit = isolate->stack_guard()->real_climit(); uintptr_t stack_limit = isolate->stack_guard()->real_climit();
for (int i = 0; programs[i]; i++) { for (int i = 0; programs[i]; i++) {
auto stream = i::ScannerStream::ForTesting(programs[i]); auto stream = i::ScannerStream::ForTesting(programs[i]);
i::Scanner scanner(stream.get(), flags); i::Scanner scanner(stream.get(), false);
scanner.Initialize(); scanner.Initialize();
// Preparser defaults to disallowing natives syntax. // Preparser defaults to disallowing natives syntax.
@ -764,7 +751,7 @@ TEST(StandAlonePreParserNoNatives) {
i::PreParser preparser(&zone, &scanner, stack_limit, &ast_value_factory, i::PreParser preparser(&zone, &scanner, stack_limit, &ast_value_factory,
&pending_error_handler, &pending_error_handler,
isolate->counters()->runtime_call_stats(), isolate->counters()->runtime_call_stats(),
isolate->logger(), flags); isolate->logger());
i::PreParser::PreParseResult result = preparser.PreParseProgram(); i::PreParser::PreParseResult result = preparser.PreParseProgram();
CHECK_EQ(i::PreParser::kPreParseSuccess, result); CHECK_EQ(i::PreParser::kPreParseSuccess, result);
CHECK(pending_error_handler.has_pending_error() || CHECK(pending_error_handler.has_pending_error() ||
@ -776,8 +763,6 @@ TEST(StandAlonePreParserNoNatives) {
TEST(RegressChromium62639) { TEST(RegressChromium62639) {
v8::V8::Initialize(); v8::V8::Initialize();
i::Isolate* isolate = CcTest::i_isolate(); i::Isolate* isolate = CcTest::i_isolate();
i::UnoptimizedCompileFlags flags =
i::UnoptimizedCompileFlags::ForTest(isolate);
isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() - isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
128 * 1024); 128 * 1024);
@ -790,7 +775,7 @@ TEST(RegressChromium62639) {
// failed in debug mode, and sometimes crashed in release mode. // failed in debug mode, and sometimes crashed in release mode.
auto stream = i::ScannerStream::ForTesting(program); auto stream = i::ScannerStream::ForTesting(program);
i::Scanner scanner(stream.get(), flags); i::Scanner scanner(stream.get(), false);
scanner.Initialize(); scanner.Initialize();
i::Zone zone(isolate->allocator(), ZONE_NAME); i::Zone zone(isolate->allocator(), ZONE_NAME);
i::AstValueFactory ast_value_factory(&zone, isolate->ast_string_constants(), i::AstValueFactory ast_value_factory(&zone, isolate->ast_string_constants(),
@ -799,7 +784,7 @@ TEST(RegressChromium62639) {
i::PreParser preparser(&zone, &scanner, isolate->stack_guard()->real_climit(), i::PreParser preparser(&zone, &scanner, isolate->stack_guard()->real_climit(),
&ast_value_factory, &pending_error_handler, &ast_value_factory, &pending_error_handler,
isolate->counters()->runtime_call_stats(), isolate->counters()->runtime_call_stats(),
isolate->logger(), flags); isolate->logger());
i::PreParser::PreParseResult result = preparser.PreParseProgram(); i::PreParser::PreParseResult result = preparser.PreParseProgram();
// Even in the case of a syntax error, kPreParseSuccess is returned. // Even in the case of a syntax error, kPreParseSuccess is returned.
CHECK_EQ(i::PreParser::kPreParseSuccess, result); CHECK_EQ(i::PreParser::kPreParseSuccess, result);
@ -811,8 +796,6 @@ TEST(RegressChromium62639) {
TEST(PreParseOverflow) { TEST(PreParseOverflow) {
v8::V8::Initialize(); v8::V8::Initialize();
i::Isolate* isolate = CcTest::i_isolate(); i::Isolate* isolate = CcTest::i_isolate();
i::UnoptimizedCompileFlags flags =
i::UnoptimizedCompileFlags::ForTest(isolate);
isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() - isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
128 * 1024); 128 * 1024);
@ -825,7 +808,7 @@ TEST(PreParseOverflow) {
uintptr_t stack_limit = isolate->stack_guard()->real_climit(); uintptr_t stack_limit = isolate->stack_guard()->real_climit();
auto stream = i::ScannerStream::ForTesting(program.get(), kProgramSize); auto stream = i::ScannerStream::ForTesting(program.get(), kProgramSize);
i::Scanner scanner(stream.get(), flags); i::Scanner scanner(stream.get(), false);
scanner.Initialize(); scanner.Initialize();
i::Zone zone(isolate->allocator(), ZONE_NAME); i::Zone zone(isolate->allocator(), ZONE_NAME);
@ -834,7 +817,7 @@ TEST(PreParseOverflow) {
i::PendingCompilationErrorHandler pending_error_handler; i::PendingCompilationErrorHandler pending_error_handler;
i::PreParser preparser( i::PreParser preparser(
&zone, &scanner, stack_limit, &ast_value_factory, &pending_error_handler, &zone, &scanner, stack_limit, &ast_value_factory, &pending_error_handler,
isolate->counters()->runtime_call_stats(), isolate->logger(), flags); isolate->counters()->runtime_call_stats(), isolate->logger());
i::PreParser::PreParseResult result = preparser.PreParseProgram(); i::PreParser::PreParseResult result = preparser.PreParseProgram();
CHECK_EQ(i::PreParser::kPreParseStackOverflow, result); CHECK_EQ(i::PreParser::kPreParseStackOverflow, result);
} }
@ -843,10 +826,7 @@ void TestStreamScanner(i::Utf16CharacterStream* stream,
i::Token::Value* expected_tokens, i::Token::Value* expected_tokens,
int skip_pos = 0, // Zero means not skipping. int skip_pos = 0, // Zero means not skipping.
int skip_to = 0) { int skip_to = 0) {
i::UnoptimizedCompileFlags flags = i::Scanner scanner(stream, false);
i::UnoptimizedCompileFlags::ForTest(CcTest::i_isolate());
i::Scanner scanner(stream, flags);
scanner.Initialize(); scanner.Initialize();
int i = 0; int i = 0;
@ -914,9 +894,7 @@ TEST(StreamScanner) {
void TestScanRegExp(const char* re_source, const char* expected) { void TestScanRegExp(const char* re_source, const char* expected) {
auto stream = i::ScannerStream::ForTesting(re_source); auto stream = i::ScannerStream::ForTesting(re_source);
i::HandleScope scope(CcTest::i_isolate()); i::HandleScope scope(CcTest::i_isolate());
i::UnoptimizedCompileFlags flags = i::Scanner scanner(stream.get(), false);
i::UnoptimizedCompileFlags::ForTest(CcTest::i_isolate());
i::Scanner scanner(stream.get(), flags);
scanner.Initialize(); scanner.Initialize();
i::Token::Value start = scanner.peek(); i::Token::Value start = scanner.peek();
@ -1078,11 +1056,9 @@ TEST(ScopeUsesArgumentsSuperThis) {
factory->NewStringFromUtf8(i::CStrVector(program.begin())) factory->NewStringFromUtf8(i::CStrVector(program.begin()))
.ToHandleChecked(); .ToHandleChecked();
i::Handle<i::Script> script = factory->NewScript(source); i::Handle<i::Script> script = factory->NewScript(source);
i::UnoptimizedCompileFlags flags = i::ParseInfo info(isolate, *script);
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
// The information we're checking is only produced when eager parsing. // The information we're checking is only produced when eager parsing.
flags.allow_lazy_parsing = false; info.set_allow_lazy_parsing(false);
i::ParseInfo info(isolate, flags);
CHECK(i::parsing::ParseProgram(&info, script, isolate)); CHECK(i::parsing::ParseProgram(&info, script, isolate));
CHECK(i::Rewriter::Rewrite(&info)); CHECK(i::Rewriter::Rewrite(&info));
info.ast_value_factory()->Internalize(isolate); info.ast_value_factory()->Internalize(isolate);
@ -1145,11 +1121,9 @@ static void CheckParsesToNumber(const char* source) {
i::Handle<i::Script> script = factory->NewScript(source_code); i::Handle<i::Script> script = factory->NewScript(source_code);
i::UnoptimizedCompileFlags flags = i::ParseInfo info(isolate, *script);
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script); info.set_allow_lazy_parsing(false);
flags.allow_lazy_parsing = false; info.set_toplevel(true);
flags.is_toplevel = true;
i::ParseInfo info(isolate, flags);
CHECK(i::parsing::ParseProgram(&info, script, isolate)); CHECK(i::parsing::ParseProgram(&info, script, isolate));
@ -1457,11 +1431,8 @@ TEST(ScopePositions) {
.ToHandleChecked(); .ToHandleChecked();
CHECK_EQ(source->length(), kProgramSize); CHECK_EQ(source->length(), kProgramSize);
i::Handle<i::Script> script = factory->NewScript(source); i::Handle<i::Script> script = factory->NewScript(source);
i::ParseInfo info(isolate, *script);
i::UnoptimizedCompileFlags flags = info.set_language_mode(source_data[i].language_mode);
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
flags.outer_language_mode = source_data[i].language_mode;
i::ParseInfo info(isolate, flags);
i::parsing::ParseProgram(&info, script, isolate); i::parsing::ParseProgram(&info, script, isolate);
CHECK_NOT_NULL(info.literal()); CHECK_NOT_NULL(info.literal());
@ -1506,9 +1477,7 @@ TEST(DiscardFunctionBody) {
i::Handle<i::String> source_code = i::Handle<i::String> source_code =
factory->NewStringFromUtf8(i::CStrVector(source)).ToHandleChecked(); factory->NewStringFromUtf8(i::CStrVector(source)).ToHandleChecked();
i::Handle<i::Script> script = factory->NewScript(source_code); i::Handle<i::Script> script = factory->NewScript(source_code);
i::UnoptimizedCompileFlags flags = i::ParseInfo info(isolate, *script);
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
i::ParseInfo info(isolate, flags);
i::parsing::ParseProgram(&info, script, isolate); i::parsing::ParseProgram(&info, script, isolate);
function = info.literal(); function = info.literal();
CHECK_NOT_NULL(function); CHECK_NOT_NULL(function);
@ -1580,15 +1549,14 @@ void SetGlobalFlags(base::EnumSet<ParserFlag> flags) {
i::FLAG_harmony_import_meta = flags.contains(kAllowHarmonyImportMeta); i::FLAG_harmony_import_meta = flags.contains(kAllowHarmonyImportMeta);
} }
void SetParserFlags(i::UnoptimizedCompileFlags* compile_flags, void SetParserFlags(i::PreParser* parser, base::EnumSet<ParserFlag> flags) {
base::EnumSet<ParserFlag> flags) { parser->set_allow_natives(flags.contains(kAllowNatives));
compile_flags->allow_natives_syntax = flags.contains(kAllowNatives); parser->set_allow_harmony_private_methods(
compile_flags->allow_harmony_private_methods = flags.contains(kAllowHarmonyPrivateMethods));
flags.contains(kAllowHarmonyPrivateMethods); parser->set_allow_harmony_dynamic_import(
compile_flags->allow_harmony_dynamic_import = flags.contains(kAllowHarmonyDynamicImport));
flags.contains(kAllowHarmonyDynamicImport); parser->set_allow_harmony_import_meta(
compile_flags->allow_harmony_import_meta = flags.contains(kAllowHarmonyImportMeta));
flags.contains(kAllowHarmonyImportMeta);
} }
void TestParserSyncWithFlags(i::Handle<i::String> source, void TestParserSyncWithFlags(i::Handle<i::String> source,
@ -1598,11 +1566,6 @@ void TestParserSyncWithFlags(i::Handle<i::String> source,
bool ignore_error_msg = false) { bool ignore_error_msg = false) {
i::Isolate* isolate = CcTest::i_isolate(); i::Isolate* isolate = CcTest::i_isolate();
i::Factory* factory = isolate->factory(); i::Factory* factory = isolate->factory();
i::UnoptimizedCompileFlags compile_flags =
i::UnoptimizedCompileFlags::ForToplevelCompile(
isolate, true, LanguageMode::kSloppy, REPLMode::kNo);
SetParserFlags(&compile_flags, flags);
compile_flags.is_module = is_module;
uintptr_t stack_limit = isolate->stack_guard()->real_climit(); uintptr_t stack_limit = isolate->stack_guard()->real_climit();
@ -1611,14 +1574,15 @@ void TestParserSyncWithFlags(i::Handle<i::String> source,
if (test_preparser) { if (test_preparser) {
std::unique_ptr<i::Utf16CharacterStream> stream( std::unique_ptr<i::Utf16CharacterStream> stream(
i::ScannerStream::For(isolate, source)); i::ScannerStream::For(isolate, source));
i::Scanner scanner(stream.get(), compile_flags); i::Scanner scanner(stream.get(), is_module);
i::Zone zone(isolate->allocator(), ZONE_NAME); i::Zone zone(isolate->allocator(), ZONE_NAME);
i::AstValueFactory ast_value_factory(&zone, isolate->ast_string_constants(), i::AstValueFactory ast_value_factory(&zone, isolate->ast_string_constants(),
HashSeed(isolate)); HashSeed(isolate));
i::PreParser preparser(&zone, &scanner, stack_limit, &ast_value_factory, i::PreParser preparser(&zone, &scanner, stack_limit, &ast_value_factory,
&pending_error_handler, &pending_error_handler,
isolate->counters()->runtime_call_stats(), isolate->counters()->runtime_call_stats(),
isolate->logger(), compile_flags); isolate->logger(), -1, is_module);
SetParserFlags(&preparser, flags);
scanner.Initialize(); scanner.Initialize();
i::PreParser::PreParseResult result = preparser.PreParseProgram(); i::PreParser::PreParseResult result = preparser.PreParseProgram();
CHECK_EQ(i::PreParser::kPreParseSuccess, result); CHECK_EQ(i::PreParser::kPreParseSuccess, result);
@ -1628,9 +1592,10 @@ void TestParserSyncWithFlags(i::Handle<i::String> source,
i::FunctionLiteral* function; i::FunctionLiteral* function;
{ {
SetGlobalFlags(flags); SetGlobalFlags(flags);
i::Handle<i::Script> script = i::Handle<i::Script> script = factory->NewScript(source);
factory->NewScriptWithId(source, compile_flags.script_id); i::ParseInfo info(isolate, *script);
i::ParseInfo info(isolate, compile_flags); info.set_allow_lazy_parsing(flags.contains(kAllowLazy));
if (is_module) info.set_module();
i::parsing::ParseProgram(&info, script, isolate); i::parsing::ParseProgram(&info, script, isolate);
function = info.literal(); function = info.literal();
} }
@ -3507,9 +3472,8 @@ TEST(InnerAssignment) {
i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o); i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
i::Handle<i::SharedFunctionInfo> shared = i::Handle<i::SharedFunctionInfo> shared =
i::handle(f->shared(), isolate); i::handle(f->shared(), isolate);
i::UnoptimizedCompileFlags flags = info =
i::UnoptimizedCompileFlags::ForFunctionCompile(isolate, *shared); std::unique_ptr<i::ParseInfo>(new i::ParseInfo(isolate, *shared));
info = std::make_unique<i::ParseInfo>(isolate, flags);
CHECK(i::parsing::ParseFunction(info.get(), shared, isolate)); CHECK(i::parsing::ParseFunction(info.get(), shared, isolate));
} else { } else {
i::Handle<i::String> source = i::Handle<i::String> source =
@ -3517,10 +3481,9 @@ TEST(InnerAssignment) {
source->PrintOn(stdout); source->PrintOn(stdout);
printf("\n"); printf("\n");
i::Handle<i::Script> script = factory->NewScript(source); i::Handle<i::Script> script = factory->NewScript(source);
i::UnoptimizedCompileFlags flags = info =
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script); std::unique_ptr<i::ParseInfo>(new i::ParseInfo(isolate, *script));
flags.allow_lazy_parsing = false; info->set_allow_lazy_parsing(false);
info = std::make_unique<i::ParseInfo>(isolate, flags);
CHECK(i::parsing::ParseProgram(info.get(), script, isolate)); CHECK(i::parsing::ParseProgram(info.get(), script, isolate));
} }
CHECK(i::Compiler::Analyze(info.get())); CHECK(i::Compiler::Analyze(info.get()));
@ -3627,10 +3590,8 @@ TEST(MaybeAssignedParameters) {
i::Handle<i::Object> o = v8::Utils::OpenHandle(*v); i::Handle<i::Object> o = v8::Utils::OpenHandle(*v);
i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o); i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
i::Handle<i::SharedFunctionInfo> shared = i::handle(f->shared(), isolate); i::Handle<i::SharedFunctionInfo> shared = i::handle(f->shared(), isolate);
i::UnoptimizedCompileFlags flags = info = std::unique_ptr<i::ParseInfo>(new i::ParseInfo(isolate, *shared));
i::UnoptimizedCompileFlags::ForFunctionCompile(isolate, *shared); info->set_allow_lazy_parsing(allow_lazy);
flags.allow_lazy_parsing = allow_lazy;
info = std::make_unique<i::ParseInfo>(isolate, flags);
CHECK(i::parsing::ParseFunction(info.get(), shared, isolate)); CHECK(i::parsing::ParseFunction(info.get(), shared, isolate));
CHECK(i::Compiler::Analyze(info.get())); CHECK(i::Compiler::Analyze(info.get()));
CHECK_NOT_NULL(info->literal()); CHECK_NOT_NULL(info->literal());
@ -3665,12 +3626,10 @@ static void TestMaybeAssigned(Input input, const char* variable, bool module,
printf("\n"); printf("\n");
i::Handle<i::Script> script = factory->NewScript(string); i::Handle<i::Script> script = factory->NewScript(string);
i::UnoptimizedCompileFlags flags = std::unique_ptr<i::ParseInfo> info;
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script); info = std::unique_ptr<i::ParseInfo>(new i::ParseInfo(isolate, *script));
flags.is_module = module; info->set_module(module);
flags.allow_lazy_parsing = allow_lazy_parsing; info->set_allow_lazy_parsing(allow_lazy_parsing);
std::unique_ptr<i::ParseInfo> info =
std::make_unique<i::ParseInfo>(isolate, flags);
CHECK(i::parsing::ParseProgram(info.get(), script, isolate)); CHECK(i::parsing::ParseProgram(info.get(), script, isolate));
CHECK(i::Compiler::Analyze(info.get())); CHECK(i::Compiler::Analyze(info.get()));
@ -7423,10 +7382,8 @@ TEST(BasicImportExportParsing) {
// Show that parsing as a module works // Show that parsing as a module works
{ {
i::Handle<i::Script> script = factory->NewScript(source); i::Handle<i::Script> script = factory->NewScript(source);
i::UnoptimizedCompileFlags flags = i::ParseInfo info(isolate, *script);
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script); info.set_module();
flags.is_module = true;
i::ParseInfo info(isolate, flags);
if (!i::parsing::ParseProgram(&info, script, isolate)) { if (!i::parsing::ParseProgram(&info, script, isolate)) {
i::Handle<i::JSObject> exception_handle( i::Handle<i::JSObject> exception_handle(
i::JSObject::cast(isolate->pending_exception()), isolate); i::JSObject::cast(isolate->pending_exception()), isolate);
@ -7448,9 +7405,7 @@ TEST(BasicImportExportParsing) {
// And that parsing a script does not. // And that parsing a script does not.
{ {
i::Handle<i::Script> script = factory->NewScript(source); i::Handle<i::Script> script = factory->NewScript(source);
i::UnoptimizedCompileFlags flags = i::ParseInfo info(isolate, *script);
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
i::ParseInfo info(isolate, flags);
CHECK(!i::parsing::ParseProgram(&info, script, isolate)); CHECK(!i::parsing::ParseProgram(&info, script, isolate));
isolate->clear_pending_exception(); isolate->clear_pending_exception();
} }
@ -7487,10 +7442,8 @@ TEST(NamespaceExportParsing) {
i::Handle<i::String> source = i::Handle<i::String> source =
factory->NewStringFromAsciiChecked(kSources[i]); factory->NewStringFromAsciiChecked(kSources[i]);
i::Handle<i::Script> script = factory->NewScript(source); i::Handle<i::Script> script = factory->NewScript(source);
i::UnoptimizedCompileFlags flags = i::ParseInfo info(isolate, *script);
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script); info.set_module();
flags.is_module = true;
i::ParseInfo info(isolate, flags);
CHECK(i::parsing::ParseProgram(&info, script, isolate)); CHECK(i::parsing::ParseProgram(&info, script, isolate));
} }
} }
@ -7584,10 +7537,8 @@ TEST(ImportExportParsingErrors) {
factory->NewStringFromAsciiChecked(kErrorSources[i]); factory->NewStringFromAsciiChecked(kErrorSources[i]);
i::Handle<i::Script> script = factory->NewScript(source); i::Handle<i::Script> script = factory->NewScript(source);
i::UnoptimizedCompileFlags flags = i::ParseInfo info(isolate, *script);
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script); info.set_module();
flags.is_module = true;
i::ParseInfo info(isolate, flags);
CHECK(!i::parsing::ParseProgram(&info, script, isolate)); CHECK(!i::parsing::ParseProgram(&info, script, isolate));
isolate->clear_pending_exception(); isolate->clear_pending_exception();
} }
@ -7622,10 +7573,8 @@ TEST(ModuleTopLevelFunctionDecl) {
factory->NewStringFromAsciiChecked(kErrorSources[i]); factory->NewStringFromAsciiChecked(kErrorSources[i]);
i::Handle<i::Script> script = factory->NewScript(source); i::Handle<i::Script> script = factory->NewScript(source);
i::UnoptimizedCompileFlags flags = i::ParseInfo info(isolate, *script);
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script); info.set_module();
flags.is_module = true;
i::ParseInfo info(isolate, flags);
CHECK(!i::parsing::ParseProgram(&info, script, isolate)); CHECK(!i::parsing::ParseProgram(&info, script, isolate));
isolate->clear_pending_exception(); isolate->clear_pending_exception();
} }
@ -7821,10 +7770,8 @@ TEST(ModuleParsingInternals) {
"export {foob};"; "export {foob};";
i::Handle<i::String> source = factory->NewStringFromAsciiChecked(kSource); i::Handle<i::String> source = factory->NewStringFromAsciiChecked(kSource);
i::Handle<i::Script> script = factory->NewScript(source); i::Handle<i::Script> script = factory->NewScript(source);
i::UnoptimizedCompileFlags flags = i::ParseInfo info(isolate, *script);
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script); info.set_module();
flags.is_module = true;
i::ParseInfo info(isolate, flags);
CHECK(i::parsing::ParseProgram(&info, script, isolate)); CHECK(i::parsing::ParseProgram(&info, script, isolate));
CHECK(i::Compiler::Analyze(&info)); CHECK(i::Compiler::Analyze(&info));
i::FunctionLiteral* func = info.literal(); i::FunctionLiteral* func = info.literal();
@ -8066,9 +8013,7 @@ void TestLanguageMode(const char* source,
i::Handle<i::Script> script = i::Handle<i::Script> script =
factory->NewScript(factory->NewStringFromAsciiChecked(source)); factory->NewScript(factory->NewStringFromAsciiChecked(source));
i::UnoptimizedCompileFlags flags = i::ParseInfo info(isolate, *script);
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
i::ParseInfo info(isolate, flags);
i::parsing::ParseProgram(&info, script, isolate); i::parsing::ParseProgram(&info, script, isolate);
CHECK_NOT_NULL(info.literal()); CHECK_NOT_NULL(info.literal());
CHECK_EQ(expected_language_mode, info.literal()->language_mode()); CHECK_EQ(expected_language_mode, info.literal()->language_mode());
@ -10849,9 +10794,7 @@ TEST(NoPessimisticContextAllocation) {
printf("\n"); printf("\n");
i::Handle<i::Script> script = factory->NewScript(source); i::Handle<i::Script> script = factory->NewScript(source);
i::UnoptimizedCompileFlags flags = i::ParseInfo info(isolate, *script);
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
i::ParseInfo info(isolate, flags);
CHECK(i::parsing::ParseProgram(&info, script, isolate)); CHECK(i::parsing::ParseProgram(&info, script, isolate));
CHECK(i::Compiler::Analyze(&info)); CHECK(i::Compiler::Analyze(&info));
@ -11411,10 +11354,9 @@ TEST(LexicalLoopVariable) {
i::Handle<i::String> source = i::Handle<i::String> source =
factory->NewStringFromUtf8(i::CStrVector(program)).ToHandleChecked(); factory->NewStringFromUtf8(i::CStrVector(program)).ToHandleChecked();
i::Handle<i::Script> script = factory->NewScript(source); i::Handle<i::Script> script = factory->NewScript(source);
i::UnoptimizedCompileFlags flags = i::ParseInfo info(isolate, *script);
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
flags.allow_lazy_parsing = false; info.set_allow_lazy_parsing(false);
i::ParseInfo info(isolate, flags);
CHECK(i::parsing::ParseProgram(&info, script, isolate)); CHECK(i::parsing::ParseProgram(&info, script, isolate));
CHECK(i::Rewriter::Rewrite(&info)); CHECK(i::Rewriter::Rewrite(&info));
CHECK(i::DeclarationScope::Analyze(&info)); CHECK(i::DeclarationScope::Analyze(&info));

View File

@ -80,10 +80,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
v8::internal::Handle<v8::internal::Script> script = v8::internal::Handle<v8::internal::Script> script =
factory->NewScript(source.ToHandleChecked()); factory->NewScript(source.ToHandleChecked());
v8::internal::UnoptimizedCompileFlags flags = v8::internal::ParseInfo info(i_isolate, *script);
v8::internal::UnoptimizedCompileFlags::ForScriptCompile(i_isolate,
*script);
v8::internal::ParseInfo info(i_isolate, flags);
if (!v8::internal::parsing::ParseProgram(&info, script, i_isolate)) { if (!v8::internal::parsing::ParseProgram(&info, script, i_isolate)) {
i_isolate->OptionalRescheduleException(true); i_isolate->OptionalRescheduleException(true);
} }

View File

@ -15,7 +15,6 @@
#include "src/execution/off-thread-isolate.h" #include "src/execution/off-thread-isolate.h"
#include "src/handles/handles-inl.h" #include "src/handles/handles-inl.h"
#include "src/handles/handles.h" #include "src/handles/handles.h"
#include "src/handles/maybe-handles.h"
#include "src/heap/off-thread-factory-inl.h" #include "src/heap/off-thread-factory-inl.h"
#include "src/objects/fixed-array.h" #include "src/objects/fixed-array.h"
#include "src/objects/script.h" #include "src/objects/script.h"
@ -56,10 +55,7 @@ class OffThreadFactoryTest : public TestWithIsolateAndZone {
public: public:
OffThreadFactoryTest() OffThreadFactoryTest()
: TestWithIsolateAndZone(), : TestWithIsolateAndZone(),
parse_info_(isolate(), UnoptimizedCompileFlags::ForToplevelCompile( parse_info_(isolate()),
isolate(), true,
construct_language_mode(FLAG_use_strict),
REPLMode::kNo)),
off_thread_isolate_(isolate(), parse_info_.zone()) {} off_thread_isolate_(isolate(), parse_info_.zone()) {}
FunctionLiteral* ParseProgram(const char* source) { FunctionLiteral* ParseProgram(const char* source) {
@ -72,6 +68,8 @@ class OffThreadFactoryTest : public TestWithIsolateAndZone {
parse_info_.set_character_stream( parse_info_.set_character_stream(
ScannerStream::ForTesting(utf16_source.data(), utf16_source.size())); ScannerStream::ForTesting(utf16_source.data(), utf16_source.size()));
parse_info_.set_toplevel();
parse_info_.set_allow_lazy_parsing();
{ {
DisallowHeapAllocation no_allocation; DisallowHeapAllocation no_allocation;
@ -80,7 +78,7 @@ class OffThreadFactoryTest : public TestWithIsolateAndZone {
Parser parser(parse_info()); Parser parser(parse_info());
parser.InitializeEmptyScopeChain(parse_info()); parser.InitializeEmptyScopeChain(parse_info());
parser.ParseOnBackground(parse_info(), 0, 0, kFunctionLiteralIdTopLevel); parser.ParseOnBackground(parse_info());
CHECK(DeclarationScope::Analyze(parse_info())); CHECK(DeclarationScope::Analyze(parse_info()));
} }
@ -90,7 +88,7 @@ class OffThreadFactoryTest : public TestWithIsolateAndZone {
script_ = parse_info_.CreateScript(off_thread_isolate(), script_ = parse_info_.CreateScript(off_thread_isolate(),
off_thread_factory()->empty_string(), off_thread_factory()->empty_string(),
kNullMaybeHandle, ScriptOriginOptions()); ScriptOriginOptions());
// Create the SFI list on the script so that SFI SetScript works. // Create the SFI list on the script so that SFI SetScript works.
Handle<WeakFixedArray> infos = off_thread_factory()->NewWeakFixedArray( Handle<WeakFixedArray> infos = off_thread_factory()->NewWeakFixedArray(

View File

@ -56,8 +56,8 @@ Handle<SharedFunctionInfo> CreateSharedFunctionInfo(
std::unique_ptr<ParseInfo> OuterParseInfoForShared( std::unique_ptr<ParseInfo> OuterParseInfoForShared(
Isolate* isolate, Handle<SharedFunctionInfo> shared) { Isolate* isolate, Handle<SharedFunctionInfo> shared) {
Script script = Script::cast(shared->script()); Script script = Script::cast(shared->script());
std::unique_ptr<ParseInfo> result = std::make_unique<ParseInfo>( std::unique_ptr<ParseInfo> result =
isolate, i::UnoptimizedCompileFlags::ForScriptCompile(isolate, script)); std::make_unique<ParseInfo>(isolate, script);
// Create a character stream to simulate the parser having done so for the // Create a character stream to simulate the parser having done so for the
// to-level ParseProgram. // to-level ParseProgram.