Reland^5 "[parser] Introduce UnoptimizedCompileFlags"
This is a reland ofe1b93a4ff5
which was a reland of313d4844d9
which was a reland of0a59e0cb08
which was a reland of146f5375da
which was a reland ofd91679bf3a
Give up on using C++ bitfields, go back to having base::BitField and getters/setters. 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 Bug: v8:10314 Change-Id: I54bcd107a0e85cf1a2ddeef0759100547eb65652 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2157378 Reviewed-by: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org> Commit-Queue: Leszek Swirski <leszeks@chromium.org> Cr-Commit-Position: refs/heads/master@{#67309}
This commit is contained in:
parent
1262eb02ca
commit
a3228bfcab
@ -2725,7 +2725,7 @@ bool ClassScope::ResolvePrivateNames(ParseInfo* info) {
|
||||
if (var == nullptr) {
|
||||
// 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.
|
||||
DCHECK(info->is_eval() || outer_scope_->is_script_scope());
|
||||
DCHECK(info->flags().is_eval() || outer_scope_->is_script_scope());
|
||||
Scanner::Location loc = proxy->location();
|
||||
info->pending_error_handler()->ReportMessageAt(
|
||||
loc.beg_pos, loc.end_pos,
|
||||
|
@ -496,7 +496,7 @@ template <typename LocalIsolate>
|
||||
void EnsureSharedFunctionInfosArrayOnScript(Handle<Script> script,
|
||||
ParseInfo* parse_info,
|
||||
LocalIsolate* isolate) {
|
||||
DCHECK(parse_info->is_toplevel());
|
||||
DCHECK(parse_info->flags().is_toplevel());
|
||||
if (script->shared_function_infos().length() > 0) {
|
||||
DCHECK_EQ(script->shared_function_infos().length(),
|
||||
parse_info->max_function_literal_id() + 1);
|
||||
@ -529,6 +529,7 @@ CompilationJob::Status FinalizeUnoptimizedCompilationJob(
|
||||
Isolate* isolate) {
|
||||
UnoptimizedCompilationInfo* compilation_info = job->compilation_info();
|
||||
ParseInfo* parse_info = job->parse_info();
|
||||
const UnoptimizedCompileFlags flags = parse_info->flags();
|
||||
|
||||
SetSharedFunctionFlagsFromLiteral(compilation_info->literal(), *shared_info);
|
||||
|
||||
@ -540,18 +541,18 @@ CompilationJob::Status FinalizeUnoptimizedCompilationJob(
|
||||
// background compile was started in which the compiled bytecode will not be
|
||||
// missing source positions (for instance by enabling the cpu profiler). So
|
||||
// force source position collection now in that case.
|
||||
if (!parse_info->collect_source_positions() &&
|
||||
if (!flags.collect_source_positions() &&
|
||||
isolate->NeedsDetailedOptimizedCodeLineInfo()) {
|
||||
SharedFunctionInfo::EnsureSourcePositionsAvailable(isolate, shared_info);
|
||||
}
|
||||
|
||||
CodeEventListener::LogEventsAndTags log_tag;
|
||||
if (parse_info->is_toplevel()) {
|
||||
log_tag = compilation_info->is_eval() ? CodeEventListener::EVAL_TAG
|
||||
: CodeEventListener::SCRIPT_TAG;
|
||||
if (flags.is_toplevel()) {
|
||||
log_tag = flags.is_eval() ? CodeEventListener::EVAL_TAG
|
||||
: CodeEventListener::SCRIPT_TAG;
|
||||
} else {
|
||||
log_tag = parse_info->lazy_compile() ? CodeEventListener::LAZY_COMPILE_TAG
|
||||
: CodeEventListener::FUNCTION_TAG;
|
||||
log_tag = flags.is_lazy_compile() ? CodeEventListener::LAZY_COMPILE_TAG
|
||||
: CodeEventListener::FUNCTION_TAG;
|
||||
}
|
||||
job->RecordFunctionCompilation(log_tag, shared_info, isolate);
|
||||
job->RecordCompilationStats(isolate);
|
||||
@ -580,7 +581,7 @@ std::unique_ptr<UnoptimizedCompilationJob> ExecuteUnoptimizedCompileJobs(
|
||||
ParseInfo* parse_info, FunctionLiteral* literal,
|
||||
AccountingAllocator* allocator,
|
||||
UnoptimizedCompilationJobList* inner_function_jobs) {
|
||||
if (UseAsmWasm(literal, parse_info->is_asm_wasm_broken())) {
|
||||
if (UseAsmWasm(literal, parse_info->flags().is_asm_wasm_broken())) {
|
||||
std::unique_ptr<UnoptimizedCompilationJob> asm_job(
|
||||
AsmJs::NewCompilationJob(parse_info, literal, allocator));
|
||||
if (asm_job->ExecuteJob() == CompilationJob::SUCCEEDED) {
|
||||
@ -657,7 +658,7 @@ MaybeHandle<SharedFunctionInfo> GenerateUnoptimizedCodeForToplevel(
|
||||
Handle<SharedFunctionInfo> shared_info =
|
||||
Compiler::GetSharedFunctionInfo(literal, script, isolate);
|
||||
if (shared_info->is_compiled()) continue;
|
||||
if (UseAsmWasm(literal, parse_info->is_asm_wasm_broken())) {
|
||||
if (UseAsmWasm(literal, parse_info->flags().is_asm_wasm_broken())) {
|
||||
std::unique_ptr<UnoptimizedCompilationJob> asm_job(
|
||||
AsmJs::NewCompilationJob(parse_info, literal, allocator));
|
||||
if (asm_job->ExecuteJob() == CompilationJob::SUCCEEDED &&
|
||||
@ -1086,8 +1087,9 @@ MaybeHandle<SharedFunctionInfo> CompileToplevel(
|
||||
PostponeInterruptsScope postpone(isolate);
|
||||
DCHECK(!isolate->native_context().is_null());
|
||||
RuntimeCallTimerScope runtimeTimer(
|
||||
isolate, parse_info->is_eval() ? RuntimeCallCounterId::kCompileEval
|
||||
: RuntimeCallCounterId::kCompileScript);
|
||||
isolate, parse_info->flags().is_eval()
|
||||
? RuntimeCallCounterId::kCompileEval
|
||||
: RuntimeCallCounterId::kCompileScript);
|
||||
VMState<BYTECODE_COMPILER> state(isolate);
|
||||
if (parse_info->literal() == nullptr &&
|
||||
!parsing::ParseProgram(parse_info, script, maybe_outer_scope_info,
|
||||
@ -1097,12 +1099,12 @@ MaybeHandle<SharedFunctionInfo> CompileToplevel(
|
||||
// Measure how long it takes to do the compilation; only take the
|
||||
// rest of the function into account to avoid overlap with the
|
||||
// parsing statistics.
|
||||
HistogramTimer* rate = parse_info->is_eval()
|
||||
HistogramTimer* rate = parse_info->flags().is_eval()
|
||||
? isolate->counters()->compile_eval()
|
||||
: isolate->counters()->compile();
|
||||
HistogramTimerScope timer(rate);
|
||||
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
|
||||
parse_info->is_eval() ? "V8.CompileEval" : "V8.Compile");
|
||||
parse_info->flags().is_eval() ? "V8.CompileEval" : "V8.Compile");
|
||||
|
||||
// Generate the unoptimized bytecode or asm-js data.
|
||||
MaybeHandle<SharedFunctionInfo> shared_info =
|
||||
@ -1126,8 +1128,8 @@ std::unique_ptr<UnoptimizedCompilationJob> CompileOnBackgroundThread(
|
||||
"V8.CompileCodeBackground");
|
||||
RuntimeCallTimerScope runtimeTimer(
|
||||
parse_info->runtime_call_stats(),
|
||||
parse_info->is_toplevel()
|
||||
? parse_info->is_eval()
|
||||
parse_info->flags().is_toplevel()
|
||||
? parse_info->flags().is_eval()
|
||||
? RuntimeCallCounterId::kCompileBackgroundEval
|
||||
: RuntimeCallCounterId::kCompileBackgroundScript
|
||||
: RuntimeCallCounterId::kCompileBackgroundFunction);
|
||||
@ -1149,32 +1151,37 @@ MaybeHandle<SharedFunctionInfo> CompileToplevel(
|
||||
|
||||
BackgroundCompileTask::BackgroundCompileTask(ScriptStreamingData* streamed_data,
|
||||
Isolate* isolate)
|
||||
: info_(new ParseInfo(isolate)),
|
||||
off_thread_isolate_(FLAG_finalize_streaming_on_background
|
||||
? new OffThreadIsolate(isolate, info_->zone())
|
||||
: nullptr),
|
||||
: flags_(UnoptimizedCompileFlags::ForToplevelCompile(
|
||||
isolate, true, construct_language_mode(FLAG_use_strict),
|
||||
REPLMode::kNo)),
|
||||
info_(std::make_unique<ParseInfo>(isolate, flags_)),
|
||||
start_position_(0),
|
||||
end_position_(0),
|
||||
function_literal_id_(kFunctionLiteralIdTopLevel),
|
||||
stack_size_(i::FLAG_stack_size),
|
||||
worker_thread_runtime_call_stats_(
|
||||
isolate->counters()->worker_thread_runtime_call_stats()),
|
||||
allocator_(isolate->allocator()),
|
||||
timer_(isolate->counters()->compile_script_on_background()),
|
||||
language_mode_(info_->language_mode()),
|
||||
collected_source_positions_(false) {
|
||||
VMState<PARSER> state(isolate);
|
||||
|
||||
// Prepare the data for the internalization phase and compilation phase, which
|
||||
// will happen in the main thread after parsing.
|
||||
|
||||
LOG(isolate, ScriptEvent(Logger::ScriptEventType::kStreamingCompile,
|
||||
info_->script_id()));
|
||||
info_->SetFlagsForToplevelCompile(isolate->is_collecting_type_profile(), true,
|
||||
construct_language_mode(FLAG_use_strict),
|
||||
REPLMode::kNo);
|
||||
language_mode_ = info_->language_mode();
|
||||
info_->flags().script_id()));
|
||||
|
||||
std::unique_ptr<Utf16CharacterStream> stream(ScannerStream::For(
|
||||
streamed_data->source_stream.get(), streamed_data->encoding));
|
||||
info_->set_character_stream(std::move(stream));
|
||||
|
||||
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(
|
||||
@ -1182,8 +1189,13 @@ BackgroundCompileTask::BackgroundCompileTask(
|
||||
const AstRawString* function_name, const FunctionLiteral* function_literal,
|
||||
WorkerThreadRuntimeCallStats* worker_thread_runtime_stats,
|
||||
TimedHistogram* timer, int max_stack_size)
|
||||
: info_(ParseInfo::FromParent(outer_parse_info, allocator, function_literal,
|
||||
function_name)),
|
||||
: flags_(UnoptimizedCompileFlags::ForToplevelFunction(
|
||||
outer_parse_info->flags(), function_literal)),
|
||||
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),
|
||||
worker_thread_runtime_call_stats_(worker_thread_runtime_stats),
|
||||
allocator_(allocator),
|
||||
@ -1191,13 +1203,13 @@ BackgroundCompileTask::BackgroundCompileTask(
|
||||
language_mode_(info_->language_mode()),
|
||||
collected_source_positions_(false),
|
||||
finalize_on_background_thread_(false) {
|
||||
DCHECK(outer_parse_info->is_toplevel());
|
||||
DCHECK(outer_parse_info->flags().is_toplevel());
|
||||
DCHECK(!function_literal->is_toplevel());
|
||||
|
||||
// Clone the character stream so both can be accessed independently.
|
||||
std::unique_ptr<Utf16CharacterStream> character_stream =
|
||||
outer_parse_info->character_stream()->Clone();
|
||||
character_stream->Seek(function_literal->start_position());
|
||||
character_stream->Seek(start_position_);
|
||||
info_->set_character_stream(std::move(character_stream));
|
||||
|
||||
// Get preparsed scope data from the function literal.
|
||||
@ -1270,17 +1282,18 @@ void BackgroundCompileTask::Run() {
|
||||
parser_.reset(new Parser(info_.get()));
|
||||
parser_->InitializeEmptyScopeChain(info_.get());
|
||||
|
||||
parser_->ParseOnBackground(info_.get());
|
||||
parser_->ParseOnBackground(info_.get(), start_position_, end_position_,
|
||||
function_literal_id_);
|
||||
if (info_->literal() != nullptr) {
|
||||
// Parsing has succeeded, compile.
|
||||
outer_function_job_ = CompileOnBackgroundThread(info_.get(), allocator_,
|
||||
&inner_function_jobs_);
|
||||
// Save the language mode and record whether we collected source positions.
|
||||
language_mode_ = info_->language_mode();
|
||||
collected_source_positions_ = info_->collect_source_positions();
|
||||
collected_source_positions_ = info_->flags().collect_source_positions();
|
||||
|
||||
if (finalize_on_background_thread_) {
|
||||
DCHECK(info_->is_toplevel());
|
||||
DCHECK(info_->flags().is_toplevel());
|
||||
|
||||
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
|
||||
"V8.FinalizeCodeBackground");
|
||||
@ -1292,10 +1305,10 @@ void BackgroundCompileTask::Run() {
|
||||
// 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
|
||||
// merge.
|
||||
Handle<Script> script =
|
||||
info_->CreateScript(off_thread_isolate_.get(),
|
||||
off_thread_isolate_->factory()->empty_string(),
|
||||
ScriptOriginOptions(), NOT_NATIVES_CODE);
|
||||
Handle<Script> script = info_->CreateScript(
|
||||
off_thread_isolate_.get(),
|
||||
off_thread_isolate_->factory()->empty_string(), kNullMaybeHandle,
|
||||
ScriptOriginOptions(), NOT_NATIVES_CODE);
|
||||
|
||||
Handle<SharedFunctionInfo> outer_function_sfi =
|
||||
FinalizeTopLevel(info_.get(), script, off_thread_isolate_.get(),
|
||||
@ -1385,10 +1398,13 @@ bool Compiler::CollectSourcePositions(Isolate* isolate,
|
||||
HistogramTimerScope timer(isolate->counters()->collect_source_positions());
|
||||
|
||||
// Set up parse info.
|
||||
ParseInfo parse_info(isolate, *shared_info);
|
||||
parse_info.set_lazy_compile();
|
||||
parse_info.set_collect_source_positions();
|
||||
if (FLAG_allow_natives_syntax) parse_info.set_allow_natives_syntax();
|
||||
UnoptimizedCompileFlags flags =
|
||||
UnoptimizedCompileFlags::ForFunctionCompile(isolate, *shared_info);
|
||||
flags.set_is_lazy_compile(true);
|
||||
flags.set_collect_source_positions(true);
|
||||
flags.set_allow_natives_syntax(FLAG_allow_natives_syntax);
|
||||
|
||||
ParseInfo parse_info(isolate, flags);
|
||||
|
||||
// Parse and update ParseInfo with the results. Don't update parsing
|
||||
// statistics since we've already parsed the code before.
|
||||
@ -1430,7 +1446,7 @@ bool Compiler::CollectSourcePositions(Isolate* isolate,
|
||||
}
|
||||
}
|
||||
|
||||
DCHECK(job->compilation_info()->collect_source_positions());
|
||||
DCHECK(job->compilation_info()->flags().collect_source_positions());
|
||||
|
||||
// If debugging, make sure that instrumented bytecode has the source position
|
||||
// table set on it as well.
|
||||
@ -1468,8 +1484,11 @@ bool Compiler::Compile(Handle<SharedFunctionInfo> shared_info,
|
||||
AggregatedHistogramTimerScope timer(isolate->counters()->compile_lazy());
|
||||
|
||||
// Set up parse info.
|
||||
ParseInfo parse_info(isolate, *shared_info);
|
||||
parse_info.set_lazy_compile();
|
||||
UnoptimizedCompileFlags flags =
|
||||
UnoptimizedCompileFlags::ForFunctionCompile(isolate, *shared_info);
|
||||
flags.set_is_lazy_compile(true);
|
||||
|
||||
ParseInfo parse_info(isolate, flags);
|
||||
|
||||
// Check if the compiler dispatcher has shared_info enqueued for compile.
|
||||
CompilerDispatcher* dispatcher = isolate->compiler_dispatcher();
|
||||
@ -1607,7 +1626,7 @@ bool Compiler::FinalizeBackgroundCompileTask(
|
||||
isolate, RuntimeCallCounterId::kCompileFinalizeBackgroundCompileTask);
|
||||
HandleScope scope(isolate);
|
||||
ParseInfo* parse_info = task->info();
|
||||
DCHECK(!parse_info->is_toplevel());
|
||||
DCHECK(!parse_info->flags().is_toplevel());
|
||||
DCHECK(!shared_info->is_compiled());
|
||||
|
||||
Handle<Script> script(Script::cast(shared_info->script()), isolate);
|
||||
@ -1717,22 +1736,22 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
|
||||
is_compiled_scope = shared_info->is_compiled_scope();
|
||||
allow_eval_cache = true;
|
||||
} else {
|
||||
ParseInfo parse_info(isolate);
|
||||
parse_info.SetFlagsForToplevelCompile(isolate->is_collecting_type_profile(),
|
||||
true, language_mode, REPLMode::kNo);
|
||||
UnoptimizedCompileFlags flags = UnoptimizedCompileFlags::ForToplevelCompile(
|
||||
isolate, true, language_mode, REPLMode::kNo);
|
||||
flags.set_is_eval(true);
|
||||
flags.set_parse_restriction(restriction);
|
||||
|
||||
parse_info.set_eval();
|
||||
parse_info.set_parse_restriction(restriction);
|
||||
ParseInfo parse_info(isolate, flags);
|
||||
parse_info.set_parameters_end_pos(parameters_end_pos);
|
||||
DCHECK(!parse_info.is_module());
|
||||
DCHECK(!parse_info.flags().is_module());
|
||||
|
||||
MaybeHandle<ScopeInfo> maybe_outer_scope_info;
|
||||
if (!context->IsNativeContext()) {
|
||||
maybe_outer_scope_info = handle(context->scope_info(), isolate);
|
||||
}
|
||||
|
||||
script = parse_info.CreateScript(
|
||||
isolate, source, OriginOptionsForEval(outer_info->script()));
|
||||
script =
|
||||
parse_info.CreateScript(isolate, source, kNullMaybeHandle,
|
||||
OriginOptionsForEval(outer_info->script()));
|
||||
script->set_eval_from_shared(*outer_info);
|
||||
if (eval_position == kNoSourcePosition) {
|
||||
// If the position is missing, attempt to get the code offset by
|
||||
@ -2156,14 +2175,14 @@ void SetScriptFieldsFromDetails(Script script,
|
||||
}
|
||||
}
|
||||
|
||||
Handle<Script> NewScript(Isolate* isolate, ParseInfo* parse_info,
|
||||
Handle<String> source,
|
||||
Compiler::ScriptDetails script_details,
|
||||
ScriptOriginOptions origin_options,
|
||||
NativesFlag natives) {
|
||||
Handle<Script> NewScript(
|
||||
Isolate* isolate, ParseInfo* parse_info, Handle<String> source,
|
||||
Compiler::ScriptDetails script_details, ScriptOriginOptions origin_options,
|
||||
NativesFlag natives,
|
||||
MaybeHandle<FixedArray> maybe_wrapped_arguments = kNullMaybeHandle) {
|
||||
// Create a script object describing the script to be compiled.
|
||||
Handle<Script> script =
|
||||
parse_info->CreateScript(isolate, source, origin_options, natives);
|
||||
Handle<Script> script = parse_info->CreateScript(
|
||||
isolate, source, maybe_wrapped_arguments, origin_options, natives);
|
||||
SetScriptFieldsFromDetails(*script, script_details);
|
||||
LOG(isolate, ScriptDetails(*script));
|
||||
return script;
|
||||
@ -2254,21 +2273,21 @@ MaybeHandle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript(
|
||||
|
||||
if (maybe_result.is_null()) {
|
||||
// No cache entry found compile the script.
|
||||
ParseInfo parse_info(isolate);
|
||||
UnoptimizedCompileFlags flags = UnoptimizedCompileFlags::ForToplevelCompile(
|
||||
isolate, natives == NOT_NATIVES_CODE, language_mode,
|
||||
script_details.repl_mode);
|
||||
|
||||
parse_info.SetFlagsForToplevelCompile(
|
||||
isolate->is_collecting_type_profile(), natives == NOT_NATIVES_CODE,
|
||||
language_mode, script_details.repl_mode);
|
||||
flags.set_is_module(origin_options.IsModule());
|
||||
flags.set_is_eager(compile_options == ScriptCompiler::kEagerCompile);
|
||||
|
||||
parse_info.set_module(origin_options.IsModule());
|
||||
ParseInfo parse_info(isolate, flags);
|
||||
parse_info.set_extension(extension);
|
||||
parse_info.set_eager(compile_options == ScriptCompiler::kEagerCompile);
|
||||
|
||||
Handle<Script> script = NewScript(isolate, &parse_info, source,
|
||||
script_details, origin_options, natives);
|
||||
DCHECK_IMPLIES(parse_info.collect_type_profile(),
|
||||
DCHECK_IMPLIES(parse_info.flags().collect_type_profile(),
|
||||
script->IsUserJavaScript());
|
||||
DCHECK_EQ(parse_info.is_repl_mode(), script->is_repl_mode());
|
||||
DCHECK_EQ(parse_info.flags().is_repl_mode(), script->is_repl_mode());
|
||||
|
||||
// Compile the function and add it to the isolate cache.
|
||||
maybe_result =
|
||||
@ -2331,27 +2350,24 @@ MaybeHandle<JSFunction> Compiler::GetWrappedFunction(
|
||||
Handle<Script> script;
|
||||
IsCompiledScope is_compiled_scope;
|
||||
if (!maybe_result.ToHandle(&wrapped)) {
|
||||
ParseInfo parse_info(isolate);
|
||||
parse_info.SetFlagsForToplevelCompile(isolate->is_collecting_type_profile(),
|
||||
true, language_mode,
|
||||
script_details.repl_mode);
|
||||
|
||||
parse_info.set_eval(); // Use an eval scope as declaration scope.
|
||||
parse_info.set_function_syntax_kind(FunctionSyntaxKind::kWrapped);
|
||||
UnoptimizedCompileFlags flags = UnoptimizedCompileFlags::ForToplevelCompile(
|
||||
isolate, true, language_mode, script_details.repl_mode);
|
||||
flags.set_is_eval(true); // Use an eval scope as declaration scope.
|
||||
flags.set_function_syntax_kind(FunctionSyntaxKind::kWrapped);
|
||||
// TODO(delphick): Remove this and instead make the wrapped and wrapper
|
||||
// functions fully non-lazy instead thus preventing source positions from
|
||||
// being omitted.
|
||||
parse_info.set_collect_source_positions(true);
|
||||
// parse_info.set_eager(compile_options == ScriptCompiler::kEagerCompile);
|
||||
flags.set_collect_source_positions(true);
|
||||
// flags.set_eager(compile_options == ScriptCompiler::kEagerCompile);
|
||||
|
||||
ParseInfo parse_info(isolate, flags);
|
||||
MaybeHandle<ScopeInfo> maybe_outer_scope_info;
|
||||
if (!context->IsNativeContext()) {
|
||||
maybe_outer_scope_info = handle(context->scope_info(), isolate);
|
||||
}
|
||||
|
||||
script = NewScript(isolate, &parse_info, source, script_details,
|
||||
origin_options, NOT_NATIVES_CODE);
|
||||
script->set_wrapped_arguments(*arguments);
|
||||
origin_options, NOT_NATIVES_CODE, arguments);
|
||||
|
||||
Handle<SharedFunctionInfo> top_level;
|
||||
maybe_result = CompileToplevel(&parse_info, script, maybe_outer_scope_info,
|
||||
@ -2446,7 +2462,7 @@ Compiler::GetSharedFunctionInfoForStreamedScript(
|
||||
maybe_result = sfi;
|
||||
} else {
|
||||
ParseInfo* parse_info = task->info();
|
||||
DCHECK(parse_info->is_toplevel());
|
||||
DCHECK(parse_info->flags().is_toplevel());
|
||||
|
||||
// No cache entry found, finalize compilation of the script and add it to
|
||||
// the isolate cache.
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "src/execution/isolate.h"
|
||||
#include "src/logging/code-events.h"
|
||||
#include "src/objects/contexts.h"
|
||||
#include "src/parsing/parse-info.h"
|
||||
#include "src/utils/allocation.h"
|
||||
#include "src/zone/zone.h"
|
||||
|
||||
@ -399,6 +400,7 @@ class V8_EXPORT_PRIVATE BackgroundCompileTask {
|
||||
// Data needed for parsing, and data needed to to be passed between thread
|
||||
// between parsing and compilation. These need to be initialized before the
|
||||
// compilation starts.
|
||||
UnoptimizedCompileFlags flags_;
|
||||
std::unique_ptr<ParseInfo> info_;
|
||||
std::unique_ptr<Parser> parser_;
|
||||
|
||||
@ -414,6 +416,11 @@ class V8_EXPORT_PRIVATE BackgroundCompileTask {
|
||||
// This is a raw pointer to the off-thread allocated SharedFunctionInfo.
|
||||
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_;
|
||||
WorkerThreadRuntimeCallStats* worker_thread_runtime_call_stats_;
|
||||
AccountingAllocator* allocator_;
|
||||
|
@ -18,7 +18,7 @@ namespace internal {
|
||||
UnoptimizedCompilationInfo::UnoptimizedCompilationInfo(Zone* zone,
|
||||
ParseInfo* parse_info,
|
||||
FunctionLiteral* literal)
|
||||
: flags_(0), zone_(zone), feedback_vector_spec_(zone) {
|
||||
: flags_(parse_info->flags()), zone_(zone), feedback_vector_spec_(zone) {
|
||||
// NOTE: The parse_info passed here represents the global information gathered
|
||||
// during parsing, but does not represent specific details of the actual
|
||||
// function literal being compiled for this OptimizedCompilationInfo. As such,
|
||||
@ -28,13 +28,6 @@ UnoptimizedCompilationInfo::UnoptimizedCompilationInfo(Zone* zone,
|
||||
DCHECK_NOT_NULL(literal);
|
||||
literal_ = literal;
|
||||
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 {
|
||||
@ -52,7 +45,7 @@ int UnoptimizedCompilationInfo::num_parameters_including_this() const {
|
||||
|
||||
SourcePositionTableBuilder::RecordingMode
|
||||
UnoptimizedCompilationInfo::SourcePositionRecordingMode() const {
|
||||
if (collect_source_positions()) {
|
||||
if (flags().collect_source_positions()) {
|
||||
return SourcePositionTableBuilder::RECORD_SOURCE_POSITIONS;
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "src/handles/handles.h"
|
||||
#include "src/objects/feedback-vector.h"
|
||||
#include "src/objects/objects.h"
|
||||
#include "src/parsing/parse-info.h"
|
||||
#include "src/utils/utils.h"
|
||||
|
||||
namespace v8 {
|
||||
@ -35,21 +36,7 @@ class V8_EXPORT_PRIVATE UnoptimizedCompilationInfo final {
|
||||
|
||||
Zone* zone() { return zone_; }
|
||||
|
||||
// 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); }
|
||||
const UnoptimizedCompileFlags& flags() const { return flags_; }
|
||||
|
||||
// Accessors for the input data of the function being compiled.
|
||||
|
||||
@ -97,20 +84,8 @@ class V8_EXPORT_PRIVATE UnoptimizedCompilationInfo final {
|
||||
FeedbackVectorSpec* feedback_vector_spec() { return &feedback_vector_spec_; }
|
||||
|
||||
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.
|
||||
unsigned flags_;
|
||||
const UnoptimizedCompileFlags flags_;
|
||||
|
||||
// The zone from which the compilation pipeline working on this
|
||||
// OptimizedCompilationInfo allocates.
|
||||
|
@ -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
|
||||
// unit of compilation. Restriction violations cause a syntax error.
|
||||
enum ParseRestriction {
|
||||
enum ParseRestriction : bool {
|
||||
NO_PARSE_RESTRICTION, // All expressions are allowed.
|
||||
ONLY_SINGLE_FUNCTION_LITERAL // Only a single FunctionLiteral expression.
|
||||
};
|
||||
|
18
src/d8/d8.cc
18
src/d8/d8.cc
@ -544,16 +544,16 @@ bool Shell::ExecuteString(Isolate* isolate, Local<String> source,
|
||||
i::Handle<i::String> str = Utils::OpenHandle(*(source));
|
||||
|
||||
// Set up ParseInfo.
|
||||
i::ParseInfo parse_info(i_isolate);
|
||||
parse_info.set_toplevel();
|
||||
parse_info.set_allow_lazy_parsing();
|
||||
parse_info.set_language_mode(
|
||||
i::construct_language_mode(i::FLAG_use_strict));
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForToplevelCompile(
|
||||
i_isolate, true, i::construct_language_mode(i::FLAG_use_strict),
|
||||
i::REPLMode::kNo);
|
||||
|
||||
i::Handle<i::Script> script =
|
||||
parse_info.CreateScript(i_isolate, str, options.compile_options);
|
||||
if (!i::parsing::ParseProgram(&parse_info, script, i::kNullMaybeHandle,
|
||||
i_isolate)) {
|
||||
i::ParseInfo parse_info(i_isolate, flags);
|
||||
|
||||
i::Handle<i::Script> script = parse_info.CreateScript(
|
||||
i_isolate, str, i::kNullMaybeHandle, options.compile_options);
|
||||
if (!i::parsing::ParseProgram(&parse_info, script, i_isolate)) {
|
||||
fprintf(stderr, "Failed parsing\n");
|
||||
return false;
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ ScopeIterator::ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector,
|
||||
TryParseAndRetrieveScopes(strategy);
|
||||
}
|
||||
|
||||
ScopeIterator::~ScopeIterator() { delete info_; }
|
||||
ScopeIterator::~ScopeIterator() = default;
|
||||
|
||||
Handle<Object> ScopeIterator::GetFunctionDebugName() const {
|
||||
if (!function_.is_null()) return JSFunction::GetDebugName(function_);
|
||||
@ -236,36 +236,41 @@ void ScopeIterator::TryParseAndRetrieveScopes(ReparseStrategy strategy) {
|
||||
// Depending on the choosen strategy, the whole script or just
|
||||
// the closure is re-parsed for function scopes.
|
||||
Handle<Script> script(Script::cast(shared_info->script()), isolate_);
|
||||
if (scope_info->scope_type() == FUNCTION_SCOPE &&
|
||||
strategy == ReparseStrategy::kFunctionLiteral) {
|
||||
info_ = new ParseInfo(isolate_, *shared_info);
|
||||
} else {
|
||||
info_ = new ParseInfo(isolate_, *script);
|
||||
info_->set_eager();
|
||||
}
|
||||
|
||||
// Pick between flags for a single function compilation, or an eager
|
||||
// compilation of the whole script.
|
||||
UnoptimizedCompileFlags flags =
|
||||
(scope_info->scope_type() == FUNCTION_SCOPE &&
|
||||
strategy == ReparseStrategy::kFunctionLiteral)
|
||||
? UnoptimizedCompileFlags::ForFunctionCompile(isolate_, *shared_info)
|
||||
: UnoptimizedCompileFlags::ForScriptCompile(isolate_, *script)
|
||||
.set_is_eager(true);
|
||||
|
||||
MaybeHandle<ScopeInfo> maybe_outer_scope;
|
||||
if (scope_info->scope_type() == EVAL_SCOPE || script->is_wrapped()) {
|
||||
info_->set_eval();
|
||||
flags.set_is_eval(true);
|
||||
if (!context_->IsNativeContext()) {
|
||||
maybe_outer_scope = handle(context_->scope_info(), isolate_);
|
||||
}
|
||||
// Language mode may be inherited from the eval caller.
|
||||
// Retrieve it from shared function info.
|
||||
info_->set_language_mode(shared_info->language_mode());
|
||||
flags.set_outer_language_mode(shared_info->language_mode());
|
||||
} else if (scope_info->scope_type() == MODULE_SCOPE) {
|
||||
DCHECK(info_->is_module());
|
||||
DCHECK(flags.is_module());
|
||||
} else {
|
||||
DCHECK(scope_info->scope_type() == SCRIPT_SCOPE ||
|
||||
scope_info->scope_type() == FUNCTION_SCOPE);
|
||||
}
|
||||
|
||||
const bool parse_result =
|
||||
info_->is_toplevel()
|
||||
? parsing::ParseProgram(info_, script, maybe_outer_scope, isolate_)
|
||||
: parsing::ParseFunction(info_, shared_info, isolate_);
|
||||
info_ = std::make_unique<ParseInfo>(isolate_, flags);
|
||||
|
||||
if (parse_result && Rewriter::Rewrite(info_)) {
|
||||
const bool parse_result =
|
||||
flags.is_toplevel()
|
||||
? parsing::ParseProgram(info_.get(), script, maybe_outer_scope,
|
||||
isolate_)
|
||||
: parsing::ParseFunction(info_.get(), shared_info, isolate_);
|
||||
|
||||
if (parse_result && Rewriter::Rewrite(info_.get())) {
|
||||
info_->ast_value_factory()->Internalize(isolate_);
|
||||
DeclarationScope* literal_scope = info_->literal()->scope();
|
||||
|
||||
@ -280,7 +285,7 @@ void ScopeIterator::TryParseAndRetrieveScopes(ReparseStrategy strategy) {
|
||||
? scope_chain_retriever.ClosureScope()
|
||||
: literal_scope;
|
||||
|
||||
CHECK(DeclarationScope::Analyze(info_));
|
||||
CHECK(DeclarationScope::Analyze(info_.get()));
|
||||
if (ignore_nested_scopes) {
|
||||
current_scope_ = closure_scope_;
|
||||
start_scope_ = current_scope_;
|
||||
|
@ -109,7 +109,7 @@ class ScopeIterator {
|
||||
|
||||
private:
|
||||
Isolate* isolate_;
|
||||
ParseInfo* info_ = nullptr;
|
||||
std::unique_ptr<ParseInfo> info_;
|
||||
FrameInspector* const frame_inspector_ = nullptr;
|
||||
Handle<JSGeneratorObject> generator_;
|
||||
Handle<JSFunction> function_;
|
||||
|
@ -750,7 +750,6 @@ class CollectFunctionLiterals final
|
||||
bool ParseScript(Isolate* isolate, Handle<Script> script, ParseInfo* parse_info,
|
||||
bool compile_as_well, std::vector<FunctionLiteral*>* literals,
|
||||
debug::LiveEditResult* result) {
|
||||
parse_info->set_eager();
|
||||
v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
|
||||
Handle<SharedFunctionInfo> shared;
|
||||
bool success = false;
|
||||
@ -1058,15 +1057,21 @@ void LiveEdit::PatchScript(Isolate* isolate, Handle<Script> script,
|
||||
return;
|
||||
}
|
||||
|
||||
ParseInfo parse_info(isolate, *script);
|
||||
UnoptimizedCompileFlags flags =
|
||||
UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
|
||||
flags.set_is_eager(true);
|
||||
ParseInfo parse_info(isolate, flags);
|
||||
std::vector<FunctionLiteral*> literals;
|
||||
if (!ParseScript(isolate, script, &parse_info, false, &literals, result))
|
||||
return;
|
||||
|
||||
Handle<Script> new_script = isolate->factory()->CloneScript(script);
|
||||
new_script->set_source(*new_source);
|
||||
UnoptimizedCompileFlags new_flags =
|
||||
UnoptimizedCompileFlags::ForScriptCompile(isolate, *new_script);
|
||||
new_flags.set_is_eager(true);
|
||||
ParseInfo new_parse_info(isolate, new_flags);
|
||||
std::vector<FunctionLiteral*> new_literals;
|
||||
ParseInfo new_parse_info(isolate, *new_script);
|
||||
if (!ParseScript(isolate, new_script, &new_parse_info, true, &new_literals,
|
||||
result)) {
|
||||
return;
|
||||
|
@ -1252,7 +1252,8 @@ Handle<String> RenderCallSite(Isolate* isolate, Handle<Object> object,
|
||||
MessageLocation* location,
|
||||
CallPrinter::ErrorHint* hint) {
|
||||
if (ComputeLocation(isolate, location)) {
|
||||
ParseInfo info(isolate, *location->shared());
|
||||
ParseInfo info(isolate, i::UnoptimizedCompileFlags::ForFunctionCompile(
|
||||
isolate, *location->shared()));
|
||||
if (parsing::ParseAny(&info, location->shared(), isolate)) {
|
||||
info.ast_value_factory()->Internalize(isolate);
|
||||
CallPrinter printer(isolate, location->shared()->IsUserJavaScript());
|
||||
@ -1310,7 +1311,8 @@ Object ErrorUtils::ThrowSpreadArgIsNullOrUndefinedError(Isolate* isolate,
|
||||
MessageLocation location;
|
||||
Handle<String> callsite;
|
||||
if (ComputeLocation(isolate, &location)) {
|
||||
ParseInfo info(isolate, *location.shared());
|
||||
ParseInfo info(isolate, i::UnoptimizedCompileFlags::ForFunctionCompile(
|
||||
isolate, *location.shared()));
|
||||
if (parsing::ParseAny(&info, location.shared(), isolate)) {
|
||||
info.ast_value_factory()->Internalize(isolate);
|
||||
CallPrinter printer(isolate, location.shared()->IsUserJavaScript(),
|
||||
@ -1385,7 +1387,8 @@ Object ErrorUtils::ThrowLoadFromNullOrUndefined(Isolate* isolate,
|
||||
if (ComputeLocation(isolate, &location)) {
|
||||
location_computed = true;
|
||||
|
||||
ParseInfo info(isolate, *location.shared());
|
||||
ParseInfo info(isolate, i::UnoptimizedCompileFlags::ForFunctionCompile(
|
||||
isolate, *location.shared()));
|
||||
if (parsing::ParseAny(&info, location.shared(), isolate)) {
|
||||
info.ast_value_factory()->Internalize(isolate);
|
||||
CallPrinter printer(isolate, location.shared()->IsUserJavaScript());
|
||||
|
@ -1332,7 +1332,7 @@ void BytecodeGenerator::GenerateBytecodeBody() {
|
||||
if (FLAG_trace) builder()->CallRuntime(Runtime::kTraceEnter);
|
||||
|
||||
// Emit type profile call.
|
||||
if (info()->collect_type_profile()) {
|
||||
if (info()->flags().collect_type_profile()) {
|
||||
feedback_spec()->AddTypeProfileSlot();
|
||||
int num_parameters = closure_scope()->num_parameters();
|
||||
for (int i = 0; i < num_parameters; i++) {
|
||||
@ -2134,7 +2134,7 @@ void BytecodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
|
||||
DCHECK(expr->scope()->outer_scope() == current_scope());
|
||||
uint8_t flags = CreateClosureFlags::Encode(
|
||||
expr->pretenure(), closure_scope()->is_function_scope(),
|
||||
info()->might_always_opt());
|
||||
info()->flags().might_always_opt());
|
||||
size_t entry = builder()->AllocateDeferredConstantPoolEntry();
|
||||
builder()->CreateClosure(entry, GetCachedCreateClosureSlot(expr), flags);
|
||||
function_literals_.push_back(std::make_pair(expr, entry));
|
||||
@ -3197,7 +3197,7 @@ void BytecodeGenerator::BuildReturn(int source_position) {
|
||||
builder()->StoreAccumulatorInRegister(result).CallRuntime(
|
||||
Runtime::kTraceExit, result);
|
||||
}
|
||||
if (info()->collect_type_profile()) {
|
||||
if (info()->flags().collect_type_profile()) {
|
||||
builder()->CollectTypeProfile(info()->literal()->return_position());
|
||||
}
|
||||
builder()->SetReturnPosition(source_position, info()->literal());
|
||||
|
@ -191,17 +191,18 @@ void InterpreterCompilationJob::CheckAndPrintBytecodeMismatch(
|
||||
std::cerr << "Bytecode mismatch";
|
||||
#ifdef OBJECT_PRINT
|
||||
std::cerr << " found for function: ";
|
||||
Handle<String> name = parse_info()->function_name()->string();
|
||||
if (name->length() == 0) {
|
||||
std::cerr << "anonymous";
|
||||
} else {
|
||||
MaybeHandle<String> maybe_name = parse_info()->literal()->GetName(isolate);
|
||||
Handle<String> name;
|
||||
if (maybe_name.ToHandle(&name) && name->length() != 0) {
|
||||
name->StringPrint(std::cerr);
|
||||
} else {
|
||||
std::cerr << "anonymous";
|
||||
}
|
||||
Object script_name = script->GetNameOrSourceURL();
|
||||
if (script_name.IsString()) {
|
||||
std::cerr << " ";
|
||||
String::cast(script_name).StringPrint(std::cerr);
|
||||
std::cerr << ":" << parse_info()->start_position();
|
||||
std::cerr << ":" << parse_info()->literal()->start_position();
|
||||
}
|
||||
#endif
|
||||
std::cerr << "\nOriginal bytecode:\n";
|
||||
|
@ -6,6 +6,7 @@
|
||||
#define V8_OBJECTS_FUNCTION_KIND_H_
|
||||
|
||||
#include "src/base/bounds.h"
|
||||
#include "src/base/macros.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
@ -56,6 +57,9 @@ enum FunctionKind : uint8_t {
|
||||
kLastFunctionKind = kClassMembersInitializerFunction,
|
||||
};
|
||||
|
||||
constexpr int kFunctionKindBitSize = 5;
|
||||
STATIC_ASSERT(kLastFunctionKind < (1 << kFunctionKindBitSize));
|
||||
|
||||
inline bool IsArrowFunction(FunctionKind kind) {
|
||||
return base::IsInRange(kind, FunctionKind::kArrowFunction,
|
||||
FunctionKind::kAsyncArrowFunction);
|
||||
|
@ -5,6 +5,7 @@
|
||||
#ifndef 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/handles/handles-inl.h"
|
||||
@ -250,6 +251,7 @@ void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
|
||||
}
|
||||
|
||||
FunctionKind SharedFunctionInfo::kind() const {
|
||||
STATIC_ASSERT(FunctionKindBits::kSize == kFunctionKindBitSize);
|
||||
return FunctionKindBits::decode(flags());
|
||||
}
|
||||
|
||||
|
@ -20,62 +20,107 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
ParseInfo::ParseInfo(AccountingAllocator* zone_allocator, int script_id)
|
||||
: zone_(std::make_unique<Zone>(zone_allocator, ZONE_NAME)),
|
||||
flags_(0),
|
||||
extension_(nullptr),
|
||||
script_scope_(nullptr),
|
||||
stack_limit_(0),
|
||||
hash_seed_(0),
|
||||
function_kind_(FunctionKind::kNormalFunction),
|
||||
function_syntax_kind_(FunctionSyntaxKind::kDeclaration),
|
||||
UnoptimizedCompileFlags::UnoptimizedCompileFlags(Isolate* isolate,
|
||||
int script_id)
|
||||
: flags_(0),
|
||||
script_id_(script_id),
|
||||
start_position_(0),
|
||||
end_position_(0),
|
||||
parameters_end_pos_(kNoSourcePosition),
|
||||
function_literal_id_(kFunctionLiteralIdInvalid),
|
||||
max_function_literal_id_(kFunctionLiteralIdInvalid),
|
||||
character_stream_(nullptr),
|
||||
ast_value_factory_(nullptr),
|
||||
ast_string_constants_(nullptr),
|
||||
function_name_(nullptr),
|
||||
runtime_call_stats_(nullptr),
|
||||
source_range_map_(nullptr),
|
||||
literal_(nullptr) {}
|
||||
|
||||
ParseInfo::ParseInfo(Isolate* isolate, AccountingAllocator* zone_allocator,
|
||||
int script_id)
|
||||
: ParseInfo(zone_allocator, script_id) {
|
||||
set_hash_seed(HashSeed(isolate));
|
||||
set_stack_limit(isolate->stack_guard()->real_climit());
|
||||
set_runtime_call_stats(isolate->counters()->runtime_call_stats());
|
||||
set_logger(isolate->logger());
|
||||
set_ast_string_constants(isolate->ast_string_constants());
|
||||
set_collect_source_positions(!FLAG_enable_lazy_source_positions ||
|
||||
isolate->NeedsDetailedOptimizedCodeLineInfo());
|
||||
if (!isolate->is_best_effort_code_coverage()) set_coverage_enabled();
|
||||
if (isolate->is_block_code_coverage()) set_block_coverage_enabled();
|
||||
if (isolate->is_collecting_type_profile()) set_collect_type_profile();
|
||||
if (isolate->compiler_dispatcher()->IsEnabled()) {
|
||||
parallel_tasks_.reset(new ParallelTasks(isolate->compiler_dispatcher()));
|
||||
}
|
||||
function_kind_(FunctionKind::kNormalFunction),
|
||||
function_syntax_kind_(FunctionSyntaxKind::kDeclaration) {
|
||||
set_collect_type_profile(isolate->is_collecting_type_profile());
|
||||
set_coverage_enabled(!isolate->is_best_effort_code_coverage());
|
||||
set_block_coverage_enabled(isolate->is_block_code_coverage());
|
||||
set_might_always_opt(FLAG_always_opt || FLAG_prepare_always_opt);
|
||||
set_allow_lazy_compile(FLAG_lazy);
|
||||
set_allow_natives_syntax(FLAG_allow_natives_syntax);
|
||||
set_allow_lazy_compile(FLAG_lazy);
|
||||
set_allow_harmony_dynamic_import(FLAG_harmony_dynamic_import);
|
||||
set_allow_harmony_import_meta(FLAG_harmony_import_meta);
|
||||
set_allow_harmony_private_methods(FLAG_harmony_private_methods);
|
||||
set_collect_source_positions(!FLAG_enable_lazy_source_positions ||
|
||||
isolate->NeedsDetailedOptimizedCodeLineInfo());
|
||||
set_allow_harmony_top_level_await(FLAG_harmony_top_level_await);
|
||||
}
|
||||
|
||||
ParseInfo::ParseInfo(Isolate* isolate)
|
||||
: ParseInfo(isolate, isolate->allocator(), isolate->GetNextScriptId()) {
|
||||
LOG(isolate, ScriptEvent(Logger::ScriptEventType::kReserveId, script_id()));
|
||||
// static
|
||||
UnoptimizedCompileFlags UnoptimizedCompileFlags::ForFunctionCompile(
|
||||
Isolate* isolate, SharedFunctionInfo shared) {
|
||||
Script script = Script::cast(shared.script());
|
||||
|
||||
UnoptimizedCompileFlags flags(isolate, script.id());
|
||||
|
||||
flags.SetFlagsFromFunction(&shared);
|
||||
flags.SetFlagsForFunctionFromScript(script);
|
||||
|
||||
flags.set_allow_lazy_parsing(true);
|
||||
flags.set_is_asm_wasm_broken(shared.is_asm_wasm_broken());
|
||||
flags.set_is_repl_mode(shared.is_repl_mode());
|
||||
|
||||
// CollectTypeProfile uses its own feedback slots. If we have existing
|
||||
// FeedbackMetadata, we can only collect type profile if the feedback vector
|
||||
// has the appropriate slots.
|
||||
flags.set_collect_type_profile(
|
||||
isolate->is_collecting_type_profile() &&
|
||||
(shared.HasFeedbackMetadata()
|
||||
? shared.feedback_metadata().HasTypeProfileSlot()
|
||||
: script.IsUserJavaScript()));
|
||||
|
||||
// Do not support re-parsing top-level function of a wrapped script.
|
||||
DCHECK_IMPLIES(flags.is_toplevel(), !script.is_wrapped());
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
// static
|
||||
UnoptimizedCompileFlags UnoptimizedCompileFlags::ForScriptCompile(
|
||||
Isolate* isolate, Script script) {
|
||||
UnoptimizedCompileFlags flags(isolate, script.id());
|
||||
|
||||
flags.SetFlagsForFunctionFromScript(script);
|
||||
flags.SetFlagsForToplevelCompile(
|
||||
isolate->is_collecting_type_profile(), script.IsUserJavaScript(),
|
||||
flags.outer_language_mode(), construct_repl_mode(script.is_repl_mode()));
|
||||
if (script.is_wrapped()) {
|
||||
flags.set_function_syntax_kind(FunctionSyntaxKind::kWrapped);
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
// 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 ParseInfo::SetFunctionInfo(T function) {
|
||||
set_language_mode(function->language_mode());
|
||||
void UnoptimizedCompileFlags::SetFlagsFromFunction(T function) {
|
||||
set_outer_language_mode(function->language_mode());
|
||||
set_function_kind(function->kind());
|
||||
set_function_syntax_kind(function->syntax_kind());
|
||||
set_requires_instance_members_initializer(
|
||||
@ -83,55 +128,79 @@ void ParseInfo::SetFunctionInfo(T function) {
|
||||
set_class_scope_has_private_brand(function->class_scope_has_private_brand());
|
||||
set_has_static_private_methods_or_accessors(
|
||||
function->has_static_private_methods_or_accessors());
|
||||
set_toplevel(function->is_toplevel());
|
||||
set_is_toplevel(function->is_toplevel());
|
||||
set_is_oneshot_iife(function->is_oneshot_iife());
|
||||
}
|
||||
|
||||
ParseInfo::ParseInfo(Isolate* isolate, SharedFunctionInfo shared)
|
||||
: ParseInfo(isolate, isolate->allocator(),
|
||||
Script::cast(shared.script()).id()) {
|
||||
// Do not support re-parsing top-level function of a wrapped script.
|
||||
DCHECK_IMPLIES(is_toplevel(), !Script::cast(shared.script()).is_wrapped());
|
||||
|
||||
void UnoptimizedCompileFlags::SetFlagsForToplevelCompile(
|
||||
bool is_collecting_type_profile, bool is_user_javascript,
|
||||
LanguageMode language_mode, REPLMode repl_mode) {
|
||||
set_allow_lazy_parsing(true);
|
||||
set_asm_wasm_broken(shared.is_asm_wasm_broken());
|
||||
set_is_toplevel(true);
|
||||
set_collect_type_profile(is_user_javascript && is_collecting_type_profile);
|
||||
set_outer_language_mode(
|
||||
stricter_language_mode(outer_language_mode(), language_mode));
|
||||
set_is_repl_mode((repl_mode == REPLMode::kYes));
|
||||
|
||||
set_start_position(shared.StartPosition());
|
||||
set_end_position(shared.EndPosition());
|
||||
function_literal_id_ = shared.function_literal_id();
|
||||
SetFunctionInfo(&shared);
|
||||
|
||||
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()));
|
||||
set_block_coverage_enabled(block_coverage_enabled() && is_user_javascript);
|
||||
}
|
||||
|
||||
ParseInfo::ParseInfo(Isolate* isolate, Script script)
|
||||
: ParseInfo(isolate, isolate->allocator(), script.id()) {
|
||||
SetFlagsForToplevelCompileFromScript(isolate, script,
|
||||
isolate->is_collecting_type_profile());
|
||||
void UnoptimizedCompileFlags::SetFlagsForFunctionFromScript(Script script) {
|
||||
DCHECK_EQ(script_id(), script.id());
|
||||
|
||||
set_is_eval(script.compilation_type() == Script::COMPILATION_TYPE_EVAL);
|
||||
set_is_module(script.origin_options().IsModule());
|
||||
DCHECK(!(is_eval() && is_module()));
|
||||
|
||||
set_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),
|
||||
script_scope_(nullptr),
|
||||
stack_limit_(0),
|
||||
hash_seed_(0),
|
||||
parameters_end_pos_(kNoSourcePosition),
|
||||
max_function_literal_id_(kFunctionLiteralIdInvalid),
|
||||
character_stream_(nullptr),
|
||||
ast_value_factory_(nullptr),
|
||||
ast_string_constants_(nullptr),
|
||||
function_name_(nullptr),
|
||||
runtime_call_stats_(nullptr),
|
||||
source_range_map_(nullptr),
|
||||
literal_(nullptr),
|
||||
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(isolate->allocator(), flags) {
|
||||
set_hash_seed(HashSeed(isolate));
|
||||
set_stack_limit(isolate->stack_guard()->real_climit());
|
||||
set_runtime_call_stats(isolate->counters()->runtime_call_stats());
|
||||
set_logger(isolate->logger());
|
||||
set_ast_string_constants(isolate->ast_string_constants());
|
||||
if (isolate->compiler_dispatcher()->IsEnabled()) {
|
||||
parallel_tasks_.reset(new ParallelTasks(isolate->compiler_dispatcher()));
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
std::unique_ptr<ParseInfo> ParseInfo::FromParent(
|
||||
const ParseInfo* outer_parse_info, AccountingAllocator* zone_allocator,
|
||||
const FunctionLiteral* literal, const AstRawString* function_name) {
|
||||
// Can't use make_unique because the constructor is private.
|
||||
std::unique_ptr<ParseInfo> result(
|
||||
new ParseInfo(zone_allocator, outer_parse_info->script_id_));
|
||||
const ParseInfo* outer_parse_info, const UnoptimizedCompileFlags flags,
|
||||
AccountingAllocator* zone_allocator, const FunctionLiteral* literal,
|
||||
const AstRawString* function_name) {
|
||||
std::unique_ptr<ParseInfo> result(new ParseInfo(zone_allocator, flags));
|
||||
|
||||
// Replicate shared state of the outer_parse_info.
|
||||
result->flags_ = outer_parse_info->flags_;
|
||||
result->set_logger(outer_parse_info->logger());
|
||||
result->set_ast_string_constants(outer_parse_info->ast_string_constants());
|
||||
result->set_hash_seed(outer_parse_info->hash_seed());
|
||||
@ -148,10 +217,6 @@ std::unique_ptr<ParseInfo> ParseInfo::FromParent(
|
||||
// Setup function specific details.
|
||||
DCHECK(!literal->is_toplevel());
|
||||
result->set_function_name(cloned_function_name);
|
||||
result->set_start_position(literal->start_position());
|
||||
result->set_end_position(literal->end_position());
|
||||
result->set_function_literal_id(literal->function_literal_id());
|
||||
result->SetFunctionInfo(literal);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -161,14 +226,14 @@ ParseInfo::~ParseInfo() = default;
|
||||
DeclarationScope* ParseInfo::scope() const { return literal()->scope(); }
|
||||
|
||||
template <typename LocalIsolate>
|
||||
Handle<Script> ParseInfo::CreateScript(LocalIsolate* isolate,
|
||||
Handle<String> source,
|
||||
ScriptOriginOptions origin_options,
|
||||
NativesFlag natives) {
|
||||
Handle<Script> ParseInfo::CreateScript(
|
||||
LocalIsolate* isolate, Handle<String> source,
|
||||
MaybeHandle<FixedArray> maybe_wrapped_arguments,
|
||||
ScriptOriginOptions origin_options, NativesFlag natives) {
|
||||
// Create a script object describing the script to be compiled.
|
||||
DCHECK_GE(script_id_, 0);
|
||||
DCHECK_GE(flags().script_id(), 0);
|
||||
Handle<Script> script =
|
||||
isolate->factory()->NewScriptWithId(source, script_id_);
|
||||
isolate->factory()->NewScriptWithId(source, flags().script_id());
|
||||
if (isolate->NeedsSourcePositionsForProfiling()) {
|
||||
Script::InitLineEnds(isolate, script);
|
||||
}
|
||||
@ -183,8 +248,12 @@ Handle<Script> ParseInfo::CreateScript(LocalIsolate* isolate,
|
||||
break;
|
||||
}
|
||||
script->set_origin_options(origin_options);
|
||||
script->set_is_repl_mode(is_repl_mode());
|
||||
if (is_eval() && !is_wrapped_as_function()) {
|
||||
script->set_is_repl_mode(flags().is_repl_mode());
|
||||
|
||||
DCHECK_EQ(is_wrapped_as_function(), !maybe_wrapped_arguments.is_null());
|
||||
if (is_wrapped_as_function()) {
|
||||
script->set_wrapped_arguments(*maybe_wrapped_arguments.ToHandleChecked());
|
||||
} else if (flags().is_eval()) {
|
||||
script->set_compilation_type(Script::COMPILATION_TYPE_EVAL);
|
||||
}
|
||||
|
||||
@ -194,15 +263,15 @@ Handle<Script> ParseInfo::CreateScript(LocalIsolate* isolate,
|
||||
}
|
||||
|
||||
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
|
||||
Handle<Script> ParseInfo::CreateScript(Isolate* isolate,
|
||||
Handle<String> source,
|
||||
ScriptOriginOptions origin_options,
|
||||
NativesFlag natives);
|
||||
Handle<Script> ParseInfo::CreateScript(
|
||||
Isolate* isolate, Handle<String> source,
|
||||
MaybeHandle<FixedArray> maybe_wrapped_arguments,
|
||||
ScriptOriginOptions origin_options, NativesFlag natives);
|
||||
template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
|
||||
Handle<Script> ParseInfo::CreateScript(OffThreadIsolate* isolate,
|
||||
Handle<String> source,
|
||||
ScriptOriginOptions origin_options,
|
||||
NativesFlag natives);
|
||||
Handle<Script> ParseInfo::CreateScript(
|
||||
OffThreadIsolate* isolate, Handle<String> source,
|
||||
MaybeHandle<FixedArray> maybe_wrapped_arguments,
|
||||
ScriptOriginOptions origin_options, NativesFlag natives);
|
||||
|
||||
AstValueFactory* ParseInfo::GetOrCreateAstValueFactory() {
|
||||
if (!ast_value_factory_.get()) {
|
||||
@ -213,7 +282,7 @@ AstValueFactory* ParseInfo::GetOrCreateAstValueFactory() {
|
||||
}
|
||||
|
||||
void ParseInfo::AllocateSourceRangeMap() {
|
||||
DCHECK(block_coverage_enabled());
|
||||
DCHECK(flags().block_coverage_enabled());
|
||||
DCHECK_NULL(source_range_map());
|
||||
set_source_range_map(new (zone()) SourceRangeMap(zone()));
|
||||
}
|
||||
@ -226,69 +295,28 @@ void ParseInfo::set_character_stream(
|
||||
character_stream_.swap(character_stream);
|
||||
}
|
||||
|
||||
void ParseInfo::SetFlagsForToplevelCompile(bool is_collecting_type_profile,
|
||||
bool is_user_javascript,
|
||||
LanguageMode language_mode,
|
||||
REPLMode repl_mode) {
|
||||
set_allow_lazy_parsing();
|
||||
set_toplevel();
|
||||
set_collect_type_profile(is_user_javascript && is_collecting_type_profile);
|
||||
set_language_mode(
|
||||
stricter_language_mode(this->language_mode(), language_mode));
|
||||
set_repl_mode(repl_mode == REPLMode::kYes);
|
||||
|
||||
if (V8_UNLIKELY(is_user_javascript && block_coverage_enabled())) {
|
||||
AllocateSourceRangeMap();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename LocalIsolate>
|
||||
void ParseInfo::SetFlagsForToplevelCompileFromScript(
|
||||
LocalIsolate* isolate, Script script, bool is_collecting_type_profile) {
|
||||
SetFlagsForFunctionFromScript(script);
|
||||
SetFlagsForToplevelCompile(is_collecting_type_profile,
|
||||
script.IsUserJavaScript(), language_mode(),
|
||||
construct_repl_mode(script.is_repl_mode()));
|
||||
|
||||
if (script.is_wrapped()) {
|
||||
set_function_syntax_kind(FunctionSyntaxKind::kWrapped);
|
||||
}
|
||||
}
|
||||
|
||||
void ParseInfo::CheckFlagsForToplevelCompileFromScript(
|
||||
Script script, bool is_collecting_type_profile) {
|
||||
CheckFlagsForFunctionFromScript(script);
|
||||
DCHECK(allow_lazy_parsing());
|
||||
DCHECK(is_toplevel());
|
||||
DCHECK_EQ(collect_type_profile(),
|
||||
DCHECK(flags().allow_lazy_parsing());
|
||||
DCHECK(flags().is_toplevel());
|
||||
DCHECK_EQ(flags().collect_type_profile(),
|
||||
is_collecting_type_profile && script.IsUserJavaScript());
|
||||
DCHECK_EQ(is_repl_mode(), script.is_repl_mode());
|
||||
DCHECK_EQ(flags().is_repl_mode(), script.is_repl_mode());
|
||||
|
||||
if (script.is_wrapped()) {
|
||||
DCHECK_EQ(function_syntax_kind(), FunctionSyntaxKind::kWrapped);
|
||||
}
|
||||
}
|
||||
|
||||
void ParseInfo::SetFlagsForFunctionFromScript(Script script) {
|
||||
DCHECK_EQ(script_id_, script.id());
|
||||
|
||||
set_eval(script.compilation_type() == Script::COMPILATION_TYPE_EVAL);
|
||||
set_module(script.origin_options().IsModule());
|
||||
DCHECK(!(is_eval() && is_module()));
|
||||
|
||||
if (block_coverage_enabled() && script.IsUserJavaScript()) {
|
||||
AllocateSourceRangeMap();
|
||||
DCHECK_EQ(flags().function_syntax_kind(), FunctionSyntaxKind::kWrapped);
|
||||
}
|
||||
}
|
||||
|
||||
void ParseInfo::CheckFlagsForFunctionFromScript(Script script) {
|
||||
DCHECK_EQ(script_id_, script.id());
|
||||
// We set "is_eval" for wrapped functions to get an outer declaration scope.
|
||||
DCHECK_EQ(flags().script_id(), script.id());
|
||||
// We set "is_eval" for wrapped scripts to get an outer declaration scope.
|
||||
// This is a bit hacky, but ok since we can't be both eval and wrapped.
|
||||
DCHECK_EQ(is_eval() && !is_wrapped_as_function(),
|
||||
DCHECK_EQ(flags().is_eval() && !script.is_wrapped(),
|
||||
script.compilation_type() == Script::COMPILATION_TYPE_EVAL);
|
||||
DCHECK_EQ(is_module(), script.origin_options().IsModule());
|
||||
DCHECK_IMPLIES(block_coverage_enabled() && script.IsUserJavaScript(),
|
||||
DCHECK_EQ(flags().is_module(), script.origin_options().IsModule());
|
||||
DCHECK_IMPLIES(flags().block_coverage_enabled() && script.IsUserJavaScript(),
|
||||
source_range_map() != nullptr);
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "include/v8.h"
|
||||
#include "src/base/bit-field.h"
|
||||
#include "src/base/export-template.h"
|
||||
#include "src/common/globals.h"
|
||||
#include "src/handles/handles.h"
|
||||
@ -38,24 +39,132 @@ class SourceRangeMap;
|
||||
class Utf16CharacterStream;
|
||||
class Zone;
|
||||
|
||||
// The flags for a parse + unoptimized compile operation.
|
||||
#define FLAG_FIELDS(V, _) \
|
||||
V(is_toplevel, bool, 1, _) \
|
||||
V(is_eager, bool, 1, _) \
|
||||
V(is_eval, bool, 1, _) \
|
||||
V(outer_language_mode, LanguageMode, 1, _) \
|
||||
V(parse_restriction, ParseRestriction, 1, _) \
|
||||
V(is_module, bool, 1, _) \
|
||||
V(allow_lazy_parsing, bool, 1, _) \
|
||||
V(is_lazy_compile, bool, 1, _) \
|
||||
V(collect_type_profile, bool, 1, _) \
|
||||
V(coverage_enabled, bool, 1, _) \
|
||||
V(block_coverage_enabled, bool, 1, _) \
|
||||
V(is_asm_wasm_broken, bool, 1, _) \
|
||||
V(class_scope_has_private_brand, bool, 1, _) \
|
||||
V(requires_instance_members_initializer, bool, 1, _) \
|
||||
V(has_static_private_methods_or_accessors, bool, 1, _) \
|
||||
V(might_always_opt, bool, 1, _) \
|
||||
V(allow_natives_syntax, bool, 1, _) \
|
||||
V(allow_lazy_compile, bool, 1, _) \
|
||||
V(allow_harmony_dynamic_import, bool, 1, _) \
|
||||
V(allow_harmony_import_meta, bool, 1, _) \
|
||||
V(allow_harmony_private_methods, bool, 1, _) \
|
||||
V(is_oneshot_iife, bool, 1, _) \
|
||||
V(collect_source_positions, bool, 1, _) \
|
||||
V(allow_harmony_top_level_await, bool, 1, _) \
|
||||
V(is_repl_mode, bool, 1, _)
|
||||
|
||||
class V8_EXPORT_PRIVATE UnoptimizedCompileFlags {
|
||||
public:
|
||||
// Set-up flags for a toplevel compilation.
|
||||
static UnoptimizedCompileFlags ForToplevelCompile(Isolate* isolate,
|
||||
bool is_user_javascript,
|
||||
LanguageMode language_mode,
|
||||
REPLMode repl_mode);
|
||||
|
||||
// Set-up flags for a compiling a particular function (either a lazy compile
|
||||
// or a recompile).
|
||||
static UnoptimizedCompileFlags ForFunctionCompile(Isolate* isolate,
|
||||
SharedFunctionInfo shared);
|
||||
|
||||
// Set-up flags for a full compilation of a given script.
|
||||
static UnoptimizedCompileFlags ForScriptCompile(Isolate* isolate,
|
||||
Script script);
|
||||
|
||||
// Set-up flags for a parallel toplevel function compilation, based on the
|
||||
// flags of an existing toplevel compilation.
|
||||
static UnoptimizedCompileFlags ForToplevelFunction(
|
||||
const UnoptimizedCompileFlags toplevel_flags,
|
||||
const FunctionLiteral* literal);
|
||||
|
||||
// Create flags for a test.
|
||||
static UnoptimizedCompileFlags ForTest(Isolate* isolate);
|
||||
|
||||
#define FLAG_GET_SET(NAME, TYPE, SIZE, _) \
|
||||
TYPE NAME() const { return BitFields::NAME::decode(flags_); } \
|
||||
UnoptimizedCompileFlags& set_##NAME(TYPE value) { \
|
||||
flags_ = BitFields::NAME::update(flags_, value); \
|
||||
return *this; \
|
||||
}
|
||||
|
||||
FLAG_FIELDS(FLAG_GET_SET, _)
|
||||
|
||||
int script_id() const { return script_id_; }
|
||||
UnoptimizedCompileFlags& set_script_id(int value) {
|
||||
script_id_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
FunctionKind function_kind() const { return function_kind_; }
|
||||
UnoptimizedCompileFlags& set_function_kind(FunctionKind value) {
|
||||
function_kind_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
FunctionSyntaxKind function_syntax_kind() const {
|
||||
return function_syntax_kind_;
|
||||
}
|
||||
UnoptimizedCompileFlags& set_function_syntax_kind(FunctionSyntaxKind value) {
|
||||
function_syntax_kind_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
struct BitFields {
|
||||
DEFINE_BIT_FIELDS(FLAG_FIELDS)
|
||||
};
|
||||
|
||||
UnoptimizedCompileFlags(Isolate* isolate, int script_id);
|
||||
|
||||
// Set function info flags based on those in either FunctionLiteral or
|
||||
// SharedFunctionInfo |function|
|
||||
template <typename T>
|
||||
void SetFlagsFromFunction(T function);
|
||||
void SetFlagsForToplevelCompile(bool is_collecting_type_profile,
|
||||
bool is_user_javascript,
|
||||
LanguageMode language_mode,
|
||||
REPLMode repl_mode);
|
||||
void SetFlagsForFunctionFromScript(Script script);
|
||||
|
||||
uint32_t flags_;
|
||||
int script_id_;
|
||||
FunctionKind function_kind_;
|
||||
FunctionSyntaxKind function_syntax_kind_;
|
||||
};
|
||||
|
||||
#undef FLAG_FIELDS
|
||||
|
||||
// A container for the inputs, configuration options, and outputs of parsing.
|
||||
class V8_EXPORT_PRIVATE ParseInfo {
|
||||
public:
|
||||
explicit ParseInfo(Isolate*);
|
||||
ParseInfo(Isolate* isolate, Script script);
|
||||
ParseInfo(Isolate* isolate, SharedFunctionInfo shared);
|
||||
ParseInfo(Isolate*, const UnoptimizedCompileFlags flags);
|
||||
|
||||
// Creates a new parse info based on parent top-level |outer_parse_info| for
|
||||
// function |literal|.
|
||||
static std::unique_ptr<ParseInfo> FromParent(
|
||||
const ParseInfo* outer_parse_info, AccountingAllocator* zone_allocator,
|
||||
const FunctionLiteral* literal, const AstRawString* function_name);
|
||||
const ParseInfo* outer_parse_info, const UnoptimizedCompileFlags flags,
|
||||
AccountingAllocator* zone_allocator, const FunctionLiteral* literal,
|
||||
const AstRawString* function_name);
|
||||
|
||||
~ParseInfo();
|
||||
|
||||
template <typename LocalIsolate>
|
||||
EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
|
||||
Handle<Script> CreateScript(LocalIsolate* isolate, Handle<String> source,
|
||||
MaybeHandle<FixedArray> maybe_wrapped_arguments,
|
||||
ScriptOriginOptions origin_options,
|
||||
NativesFlag natives = NOT_NATIVES_CODE);
|
||||
|
||||
@ -65,65 +174,15 @@ class V8_EXPORT_PRIVATE ParseInfo {
|
||||
|
||||
Zone* zone() const { return zone_.get(); }
|
||||
|
||||
// Convenience accessor methods for flags.
|
||||
#define FLAG_ACCESSOR(flag, getter, setter) \
|
||||
bool getter() const { return GetFlag(flag); } \
|
||||
void setter() { SetFlag(flag); } \
|
||||
void setter(bool val) { SetFlag(flag, val); }
|
||||
const UnoptimizedCompileFlags& flags() const { return flags_; }
|
||||
|
||||
FLAG_ACCESSOR(kToplevel, is_toplevel, set_toplevel)
|
||||
FLAG_ACCESSOR(kEager, is_eager, set_eager)
|
||||
FLAG_ACCESSOR(kEval, is_eval, set_eval)
|
||||
FLAG_ACCESSOR(kStrictMode, is_strict_mode, set_strict_mode)
|
||||
FLAG_ACCESSOR(kModule, is_module, set_module)
|
||||
FLAG_ACCESSOR(kAllowLazyParsing, allow_lazy_parsing, set_allow_lazy_parsing)
|
||||
FLAG_ACCESSOR(kLazyCompile, lazy_compile, set_lazy_compile)
|
||||
FLAG_ACCESSOR(kCollectTypeProfile, collect_type_profile,
|
||||
set_collect_type_profile)
|
||||
FLAG_ACCESSOR(kIsAsmWasmBroken, is_asm_wasm_broken, set_asm_wasm_broken)
|
||||
FLAG_ACCESSOR(kContainsAsmModule, contains_asm_module,
|
||||
set_contains_asm_module)
|
||||
FLAG_ACCESSOR(kCoverageEnabled, coverage_enabled, set_coverage_enabled)
|
||||
FLAG_ACCESSOR(kBlockCoverageEnabled, block_coverage_enabled,
|
||||
set_block_coverage_enabled)
|
||||
FLAG_ACCESSOR(kAllowEvalCache, allow_eval_cache, set_allow_eval_cache)
|
||||
FLAG_ACCESSOR(kRequiresInstanceMembersInitializer,
|
||||
requires_instance_members_initializer,
|
||||
set_requires_instance_members_initializer)
|
||||
FLAG_ACCESSOR(kClassScopeHasPrivateBrand, class_scope_has_private_brand,
|
||||
set_class_scope_has_private_brand)
|
||||
FLAG_ACCESSOR(kHasStaticPrivateMethodsOrAccessors,
|
||||
has_static_private_methods_or_accessors,
|
||||
set_has_static_private_methods_or_accessors)
|
||||
FLAG_ACCESSOR(kMightAlwaysOpt, might_always_opt, set_might_always_opt)
|
||||
FLAG_ACCESSOR(kAllowNativeSyntax, allow_natives_syntax,
|
||||
set_allow_natives_syntax)
|
||||
FLAG_ACCESSOR(kAllowLazyCompile, allow_lazy_compile, set_allow_lazy_compile)
|
||||
FLAG_ACCESSOR(kAllowNativeSyntax, allow_native_syntax,
|
||||
set_allow_native_syntax)
|
||||
FLAG_ACCESSOR(kAllowHarmonyDynamicImport, allow_harmony_dynamic_import,
|
||||
set_allow_harmony_dynamic_import)
|
||||
FLAG_ACCESSOR(kAllowHarmonyImportMeta, allow_harmony_import_meta,
|
||||
set_allow_harmony_import_meta)
|
||||
FLAG_ACCESSOR(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;
|
||||
}
|
||||
// Accessor methods for output flags.
|
||||
bool allow_eval_cache() const { return allow_eval_cache_; }
|
||||
void set_allow_eval_cache(bool value) { allow_eval_cache_ = value; }
|
||||
bool contains_asm_module() const { return contains_asm_module_; }
|
||||
void set_contains_asm_module(bool value) { contains_asm_module_ = value; }
|
||||
LanguageMode language_mode() const { return language_mode_; }
|
||||
void set_language_mode(LanguageMode value) { language_mode_ = value; }
|
||||
|
||||
Utf16CharacterStream* character_stream() const {
|
||||
return character_stream_.get();
|
||||
@ -168,38 +227,13 @@ class V8_EXPORT_PRIVATE ParseInfo {
|
||||
uint64_t hash_seed() const { return hash_seed_; }
|
||||
void set_hash_seed(uint64_t hash_seed) { hash_seed_ = hash_seed; }
|
||||
|
||||
int start_position() const { return start_position_; }
|
||||
void set_start_position(int start_position) {
|
||||
start_position_ = start_position;
|
||||
}
|
||||
|
||||
int end_position() const { return end_position_; }
|
||||
void set_end_position(int end_position) { end_position_ = end_position; }
|
||||
|
||||
int parameters_end_pos() const { return parameters_end_pos_; }
|
||||
void set_parameters_end_pos(int parameters_end_pos) {
|
||||
parameters_end_pos_ = parameters_end_pos;
|
||||
}
|
||||
|
||||
int function_literal_id() const { return function_literal_id_; }
|
||||
void set_function_literal_id(int function_literal_id) {
|
||||
function_literal_id_ = function_literal_id;
|
||||
}
|
||||
|
||||
FunctionKind function_kind() const { return function_kind_; }
|
||||
void set_function_kind(FunctionKind function_kind) {
|
||||
function_kind_ = function_kind;
|
||||
}
|
||||
|
||||
FunctionSyntaxKind function_syntax_kind() const {
|
||||
return function_syntax_kind_;
|
||||
}
|
||||
void set_function_syntax_kind(FunctionSyntaxKind function_syntax_kind) {
|
||||
function_syntax_kind_ = function_syntax_kind;
|
||||
}
|
||||
|
||||
bool is_wrapped_as_function() const {
|
||||
return function_syntax_kind() == FunctionSyntaxKind::kWrapped;
|
||||
return flags().function_syntax_kind() == FunctionSyntaxKind::kWrapped;
|
||||
}
|
||||
|
||||
int max_function_literal_id() const { return max_function_literal_id_; }
|
||||
@ -257,93 +291,22 @@ class V8_EXPORT_PRIVATE ParseInfo {
|
||||
|
||||
ParallelTasks* parallel_tasks() { return parallel_tasks_.get(); }
|
||||
|
||||
void SetFlagsForToplevelCompile(bool is_collecting_type_profile,
|
||||
bool is_user_javascript,
|
||||
LanguageMode language_mode,
|
||||
REPLMode repl_mode);
|
||||
|
||||
void CheckFlagsForFunctionFromScript(Script script);
|
||||
|
||||
int script_id() const { return script_id_; }
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
LanguageMode language_mode() const {
|
||||
return construct_language_mode(is_strict_mode());
|
||||
}
|
||||
void set_language_mode(LanguageMode language_mode) {
|
||||
STATIC_ASSERT(LanguageModeSize == 2);
|
||||
set_strict_mode(is_strict(language_mode));
|
||||
}
|
||||
|
||||
private:
|
||||
ParseInfo(AccountingAllocator* zone_allocator, int script_id);
|
||||
ParseInfo(Isolate*, AccountingAllocator* zone_allocator, int script_id);
|
||||
ParseInfo(AccountingAllocator* zone_allocator, UnoptimizedCompileFlags flags);
|
||||
|
||||
void SetFlagsForFunctionFromScript(Script script);
|
||||
|
||||
template <typename LocalIsolate>
|
||||
void SetFlagsForToplevelCompileFromScript(LocalIsolate* isolate,
|
||||
Script script,
|
||||
bool is_collecting_type_profile);
|
||||
void CheckFlagsForToplevelCompileFromScript(Script script,
|
||||
bool is_collecting_type_profile);
|
||||
|
||||
// Set function info flags based on those in either FunctionLiteral or
|
||||
// SharedFunctionInfo |function|
|
||||
template <typename T>
|
||||
void SetFunctionInfo(T function);
|
||||
|
||||
// Various configuration flags for parsing.
|
||||
enum Flag : uint32_t {
|
||||
// ---------- Input flags ---------------------------
|
||||
kToplevel = 1u << 0,
|
||||
kEager = 1u << 1,
|
||||
kEval = 1u << 2,
|
||||
kStrictMode = 1u << 3,
|
||||
kNative = 1u << 4,
|
||||
kParseRestriction = 1u << 5,
|
||||
kModule = 1u << 6,
|
||||
kAllowLazyParsing = 1u << 7,
|
||||
kLazyCompile = 1u << 8,
|
||||
kCollectTypeProfile = 1u << 9,
|
||||
kCoverageEnabled = 1u << 10,
|
||||
kBlockCoverageEnabled = 1u << 11,
|
||||
kIsAsmWasmBroken = 1u << 12,
|
||||
kAllowEvalCache = 1u << 13,
|
||||
kRequiresInstanceMembersInitializer = 1u << 14,
|
||||
kContainsAsmModule = 1u << 15,
|
||||
kMightAlwaysOpt = 1u << 16,
|
||||
kAllowLazyCompile = 1u << 17,
|
||||
kAllowNativeSyntax = 1u << 18,
|
||||
kAllowHarmonyPublicFields = 1u << 19,
|
||||
kAllowHarmonyStaticFields = 1u << 20,
|
||||
kAllowHarmonyDynamicImport = 1u << 21,
|
||||
kAllowHarmonyImportMeta = 1u << 22,
|
||||
kAllowHarmonyOptionalChaining = 1u << 23,
|
||||
kHasStaticPrivateMethodsOrAccessors = 1u << 24,
|
||||
kAllowHarmonyPrivateMethods = 1u << 25,
|
||||
kIsOneshotIIFE = 1u << 26,
|
||||
kCollectSourcePositions = 1u << 27,
|
||||
kAllowHarmonyNullish = 1u << 28,
|
||||
kAllowHarmonyTopLevelAwait = 1u << 29,
|
||||
kREPLMode = 1u << 30,
|
||||
kClassScopeHasPrivateBrand = 1u << 31,
|
||||
};
|
||||
|
||||
//------------- Inputs to parsing and scope analysis -----------------------
|
||||
const UnoptimizedCompileFlags flags_;
|
||||
std::unique_ptr<Zone> zone_;
|
||||
uint32_t flags_;
|
||||
v8::Extension* extension_;
|
||||
DeclarationScope* script_scope_;
|
||||
uintptr_t stack_limit_;
|
||||
uint64_t hash_seed_;
|
||||
FunctionKind function_kind_;
|
||||
FunctionSyntaxKind function_syntax_kind_;
|
||||
int script_id_;
|
||||
int start_position_;
|
||||
int end_position_;
|
||||
int parameters_end_pos_;
|
||||
int function_literal_id_;
|
||||
int max_function_literal_id_;
|
||||
|
||||
//----------- Inputs+Outputs of parsing and scope analysis -----------------
|
||||
@ -360,10 +323,9 @@ class V8_EXPORT_PRIVATE ParseInfo {
|
||||
//----------- Output of parsing and scope analysis ------------------------
|
||||
FunctionLiteral* literal_;
|
||||
PendingCompilationErrorHandler pending_error_handler_;
|
||||
|
||||
void SetFlag(Flag f) { flags_ |= f; }
|
||||
void SetFlag(Flag f, bool v) { flags_ = v ? flags_ | f : flags_ & ~f; }
|
||||
bool GetFlag(Flag f) const { return (flags_ & f) != 0; }
|
||||
bool allow_eval_cache_ : 1;
|
||||
bool contains_asm_module_ : 1;
|
||||
LanguageMode language_mode_ : 1;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "src/objects/function-kind.h"
|
||||
#include "src/parsing/expression-scope.h"
|
||||
#include "src/parsing/func-name-inferrer.h"
|
||||
#include "src/parsing/parse-info.h"
|
||||
#include "src/parsing/scanner.h"
|
||||
#include "src/parsing/token.h"
|
||||
#include "src/utils/pointer-with-payload.h"
|
||||
@ -241,7 +242,7 @@ class ParserBase {
|
||||
v8::Extension* extension, AstValueFactory* ast_value_factory,
|
||||
PendingCompilationErrorHandler* pending_error_handler,
|
||||
RuntimeCallStats* runtime_call_stats, Logger* logger,
|
||||
int script_id, bool parsing_module, bool parsing_on_main_thread)
|
||||
UnoptimizedCompileFlags flags, bool parsing_on_main_thread)
|
||||
: scope_(nullptr),
|
||||
original_scope_(nullptr),
|
||||
function_state_(nullptr),
|
||||
@ -252,37 +253,22 @@ class ParserBase {
|
||||
runtime_call_stats_(runtime_call_stats),
|
||||
logger_(logger),
|
||||
parsing_on_main_thread_(parsing_on_main_thread),
|
||||
parsing_module_(parsing_module),
|
||||
stack_limit_(stack_limit),
|
||||
pending_error_handler_(pending_error_handler),
|
||||
zone_(zone),
|
||||
expression_scope_(nullptr),
|
||||
scanner_(scanner),
|
||||
flags_(flags),
|
||||
function_literal_id_(0),
|
||||
script_id_(script_id),
|
||||
default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile),
|
||||
allow_natives_(false),
|
||||
allow_harmony_dynamic_import_(false),
|
||||
allow_harmony_import_meta_(false),
|
||||
allow_harmony_private_methods_(false),
|
||||
allow_harmony_top_level_await_(false),
|
||||
allow_eval_cache_(true) {
|
||||
default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile) {
|
||||
pointer_buffer_.reserve(32);
|
||||
variable_buffer_.reserve(32);
|
||||
}
|
||||
|
||||
#define ALLOW_ACCESSORS(name) \
|
||||
bool allow_##name() const { return allow_##name##_; } \
|
||||
void set_allow_##name(bool allow) { allow_##name##_ = allow; }
|
||||
const UnoptimizedCompileFlags& flags() const { return flags_; }
|
||||
|
||||
ALLOW_ACCESSORS(natives)
|
||||
ALLOW_ACCESSORS(harmony_dynamic_import)
|
||||
ALLOW_ACCESSORS(harmony_import_meta)
|
||||
ALLOW_ACCESSORS(harmony_private_methods)
|
||||
ALLOW_ACCESSORS(harmony_top_level_await)
|
||||
ALLOW_ACCESSORS(eval_cache)
|
||||
|
||||
#undef ALLOW_ACCESSORS
|
||||
bool allow_eval_cache() const { return allow_eval_cache_; }
|
||||
void set_allow_eval_cache(bool allow) { allow_eval_cache_ = allow; }
|
||||
|
||||
V8_INLINE bool has_error() const { return scanner()->has_parser_error(); }
|
||||
|
||||
@ -869,8 +855,6 @@ class ParserBase {
|
||||
// Any further calls to Next or peek will return the illegal token.
|
||||
if (GetCurrentStackPosition() < stack_limit_) set_stack_overflow();
|
||||
}
|
||||
int script_id() { return script_id_; }
|
||||
void set_script_id(int id) { script_id_ = id; }
|
||||
|
||||
V8_INLINE Token::Value peek() { return scanner()->peek(); }
|
||||
|
||||
@ -1061,7 +1045,7 @@ class ParserBase {
|
||||
return IsResumableFunction(function_state_->kind());
|
||||
}
|
||||
bool is_await_allowed() const {
|
||||
return is_async_function() || (allow_harmony_top_level_await() &&
|
||||
return is_async_function() || (flags().allow_harmony_top_level_await() &&
|
||||
IsModule(function_state_->kind()));
|
||||
}
|
||||
const PendingCompilationErrorHandler* pending_error_handler() const {
|
||||
@ -1516,7 +1500,6 @@ class ParserBase {
|
||||
RuntimeCallStats* runtime_call_stats_;
|
||||
internal::Logger* logger_;
|
||||
bool parsing_on_main_thread_;
|
||||
const bool parsing_module_;
|
||||
uintptr_t stack_limit_;
|
||||
PendingCompilationErrorHandler* pending_error_handler_;
|
||||
|
||||
@ -1531,8 +1514,8 @@ class ParserBase {
|
||||
|
||||
Scanner* scanner_;
|
||||
|
||||
const UnoptimizedCompileFlags flags_;
|
||||
int function_literal_id_;
|
||||
int script_id_;
|
||||
|
||||
FunctionLiteral::EagerCompileHint default_eager_compile_hint_;
|
||||
|
||||
@ -1571,12 +1554,7 @@ class ParserBase {
|
||||
|
||||
bool accept_IN_ = true;
|
||||
|
||||
bool allow_natives_;
|
||||
bool allow_harmony_dynamic_import_;
|
||||
bool allow_harmony_import_meta_;
|
||||
bool allow_harmony_private_methods_;
|
||||
bool allow_harmony_top_level_await_;
|
||||
bool allow_eval_cache_;
|
||||
bool allow_eval_cache_ = true;
|
||||
};
|
||||
|
||||
template <typename Impl>
|
||||
@ -1626,7 +1604,7 @@ ParserBase<Impl>::ParseAndClassifyIdentifier(Token::Value next) {
|
||||
}
|
||||
|
||||
if (!Token::IsValidIdentifier(next, language_mode(), is_generator(),
|
||||
parsing_module_ || is_async_function())) {
|
||||
flags().is_module() || is_async_function())) {
|
||||
ReportUnexpectedToken(next);
|
||||
return impl()->EmptyIdentifierString();
|
||||
}
|
||||
@ -1650,7 +1628,7 @@ typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifier(
|
||||
|
||||
if (!Token::IsValidIdentifier(
|
||||
next, language_mode(), IsGeneratorFunction(function_kind),
|
||||
parsing_module_ || IsAsyncFunction(function_kind))) {
|
||||
flags().is_module() || IsAsyncFunction(function_kind))) {
|
||||
ReportUnexpectedToken(next);
|
||||
return impl()->EmptyIdentifierString();
|
||||
}
|
||||
@ -1861,7 +1839,7 @@ ParserBase<Impl>::ParsePrimaryExpression() {
|
||||
return ParseSuperExpression(is_new);
|
||||
}
|
||||
case Token::IMPORT:
|
||||
if (!allow_harmony_dynamic_import()) break;
|
||||
if (!flags().allow_harmony_dynamic_import()) break;
|
||||
return ParseImportExpressions();
|
||||
|
||||
case Token::LBRACK:
|
||||
@ -1924,7 +1902,7 @@ ParserBase<Impl>::ParsePrimaryExpression() {
|
||||
return ParseTemplateLiteral(impl()->NullExpression(), beg_pos, false);
|
||||
|
||||
case Token::MOD:
|
||||
if (allow_natives() || extension_ != nullptr) {
|
||||
if (flags().allow_natives_syntax() || extension_ != nullptr) {
|
||||
return ParseV8Intrinsic();
|
||||
}
|
||||
break;
|
||||
@ -2170,7 +2148,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseProperty(
|
||||
prop_info->kind = ParsePropertyKind::kNotSet;
|
||||
return impl()->FailureExpression();
|
||||
}
|
||||
if (V8_UNLIKELY(!allow_harmony_private_methods() &&
|
||||
if (V8_UNLIKELY(!flags().allow_harmony_private_methods() &&
|
||||
(IsAccessor(prop_info->kind) ||
|
||||
prop_info->kind == ParsePropertyKind::kMethod))) {
|
||||
ReportUnexpectedToken(Next());
|
||||
@ -2517,8 +2495,9 @@ ParserBase<Impl>::ParseObjectPropertyDefinition(ParsePropertyInfo* prop_info,
|
||||
// IdentifierReference Initializer?
|
||||
DCHECK_EQ(function_flags, ParseFunctionFlag::kIsNormal);
|
||||
|
||||
if (!Token::IsValidIdentifier(name_token, language_mode(), is_generator(),
|
||||
parsing_module_ || is_async_function())) {
|
||||
if (!Token::IsValidIdentifier(
|
||||
name_token, language_mode(), is_generator(),
|
||||
flags().is_module() || is_async_function())) {
|
||||
ReportUnexpectedToken(Next());
|
||||
return impl()->NullLiteralProperty();
|
||||
}
|
||||
@ -3432,8 +3411,10 @@ ParserBase<Impl>::ParseMemberWithPresentNewPrefixesExpression() {
|
||||
if (peek() == Token::SUPER) {
|
||||
const bool is_new = true;
|
||||
result = ParseSuperExpression(is_new);
|
||||
} else if (allow_harmony_dynamic_import() && peek() == Token::IMPORT &&
|
||||
(!allow_harmony_import_meta() || PeekAhead() == Token::LPAREN)) {
|
||||
} else if (flags().allow_harmony_dynamic_import() &&
|
||||
peek() == Token::IMPORT &&
|
||||
(!flags().allow_harmony_import_meta() ||
|
||||
PeekAhead() == Token::LPAREN)) {
|
||||
impl()->ReportMessageAt(scanner()->peek_location(),
|
||||
MessageTemplate::kImportCallNotNewExpression);
|
||||
return impl()->FailureExpression();
|
||||
@ -3531,14 +3512,14 @@ ParserBase<Impl>::ParseMemberExpression() {
|
||||
template <typename Impl>
|
||||
typename ParserBase<Impl>::ExpressionT
|
||||
ParserBase<Impl>::ParseImportExpressions() {
|
||||
DCHECK(allow_harmony_dynamic_import());
|
||||
DCHECK(flags().allow_harmony_dynamic_import());
|
||||
|
||||
Consume(Token::IMPORT);
|
||||
int pos = position();
|
||||
if (allow_harmony_import_meta() && Check(Token::PERIOD)) {
|
||||
if (flags().allow_harmony_import_meta() && Check(Token::PERIOD)) {
|
||||
ExpectContextualKeyword(ast_value_factory()->meta_string(), "import.meta",
|
||||
pos);
|
||||
if (!parsing_module_) {
|
||||
if (!flags().is_module()) {
|
||||
impl()->ReportMessageAt(scanner()->location(),
|
||||
MessageTemplate::kImportMetaOutsideModule);
|
||||
return impl()->FailureExpression();
|
||||
@ -3548,7 +3529,7 @@ ParserBase<Impl>::ParseImportExpressions() {
|
||||
}
|
||||
|
||||
if (V8_UNLIKELY(peek() != Token::LPAREN)) {
|
||||
if (!parsing_module_) {
|
||||
if (!flags().is_module()) {
|
||||
impl()->ReportMessageAt(scanner()->location(),
|
||||
MessageTemplate::kImportOutsideModule);
|
||||
} else {
|
||||
@ -4470,8 +4451,9 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
|
||||
const char* event_name =
|
||||
is_lazy_top_level_function ? "preparse-no-resolution" : "parse";
|
||||
const char* name = "arrow function";
|
||||
logger_->FunctionEvent(event_name, script_id(), ms, scope->start_position(),
|
||||
scope->end_position(), name, strlen(name));
|
||||
logger_->FunctionEvent(event_name, flags().script_id(), ms,
|
||||
scope->start_position(), scope->end_position(), name,
|
||||
strlen(name));
|
||||
}
|
||||
|
||||
return function_literal;
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "src/base/overflowing-math.h"
|
||||
#include "src/base/platform/platform.h"
|
||||
#include "src/codegen/bailout-reason.h"
|
||||
#include "src/common/globals.h"
|
||||
#include "src/common/message-template.h"
|
||||
#include "src/compiler-dispatcher/compiler-dispatcher.h"
|
||||
#include "src/logging/counters.h"
|
||||
@ -416,13 +417,12 @@ Expression* Parser::NewV8RuntimeFunctionForFuzzing(
|
||||
}
|
||||
|
||||
Parser::Parser(ParseInfo* info)
|
||||
: ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(),
|
||||
info->extension(), info->GetOrCreateAstValueFactory(),
|
||||
info->pending_error_handler(),
|
||||
info->runtime_call_stats(), info->logger(),
|
||||
info->script_id(), info->is_module(), true),
|
||||
: ParserBase<Parser>(
|
||||
info->zone(), &scanner_, info->stack_limit(), info->extension(),
|
||||
info->GetOrCreateAstValueFactory(), info->pending_error_handler(),
|
||||
info->runtime_call_stats(), info->logger(), info->flags(), true),
|
||||
info_(info),
|
||||
scanner_(info->character_stream(), info->is_module()),
|
||||
scanner_(info->character_stream(), flags()),
|
||||
preparser_zone_(info->zone()->allocator(), ZONE_NAME),
|
||||
reusable_preparser_(nullptr),
|
||||
mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
|
||||
@ -445,18 +445,13 @@ Parser::Parser(ParseInfo* info)
|
||||
// of functions without an outer context when setting a breakpoint through
|
||||
// Debug::FindSharedFunctionInfoInScript
|
||||
// We also compile eagerly for kProduceExhaustiveCodeCache.
|
||||
bool can_compile_lazily = info->allow_lazy_compile() && !info->is_eager();
|
||||
bool can_compile_lazily = flags().allow_lazy_compile() && !flags().is_eager();
|
||||
|
||||
set_default_eager_compile_hint(can_compile_lazily
|
||||
? FunctionLiteral::kShouldLazyCompile
|
||||
: FunctionLiteral::kShouldEagerCompile);
|
||||
allow_lazy_ = info->allow_lazy_compile() && info->allow_lazy_parsing() &&
|
||||
allow_lazy_ = flags().allow_lazy_compile() && flags().allow_lazy_parsing() &&
|
||||
info->extension() == nullptr && can_compile_lazily;
|
||||
set_allow_natives(info->allow_natives_syntax());
|
||||
set_allow_harmony_dynamic_import(info->allow_harmony_dynamic_import());
|
||||
set_allow_harmony_import_meta(info->allow_harmony_import_meta());
|
||||
set_allow_harmony_private_methods(info->allow_harmony_private_methods());
|
||||
set_allow_harmony_top_level_await(info->allow_harmony_top_level_await());
|
||||
for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
|
||||
++feature) {
|
||||
use_counts_[feature] = 0;
|
||||
@ -467,7 +462,7 @@ void Parser::InitializeEmptyScopeChain(ParseInfo* info) {
|
||||
DCHECK_NULL(original_scope_);
|
||||
DCHECK_NULL(info->script_scope());
|
||||
DeclarationScope* script_scope =
|
||||
NewScriptScope(info->is_repl_mode() ? REPLMode::kYes : REPLMode::kNo);
|
||||
NewScriptScope(flags().is_repl_mode() ? REPLMode::kYes : REPLMode::kNo);
|
||||
info->set_script_scope(script_scope);
|
||||
original_scope_ = script_scope;
|
||||
}
|
||||
@ -483,7 +478,7 @@ void Parser::DeserializeScopeChain(
|
||||
original_scope_ = Scope::DeserializeScopeChain(
|
||||
isolate, zone(), *outer_scope_info, info->script_scope(),
|
||||
ast_value_factory(), mode);
|
||||
if (info->is_eval() || IsArrowFunction(info->function_kind())) {
|
||||
if (flags().is_eval() || IsArrowFunction(flags().function_kind())) {
|
||||
original_scope_->GetReceiverScope()->DeserializeReceiver(
|
||||
ast_value_factory());
|
||||
}
|
||||
@ -518,13 +513,13 @@ FunctionLiteral* Parser::ParseProgram(
|
||||
MaybeHandle<ScopeInfo> maybe_outer_scope_info) {
|
||||
// TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
|
||||
// see comment for HistogramTimerScope class.
|
||||
DCHECK_EQ(script->id(), script_id());
|
||||
DCHECK_EQ(script->id(), flags().script_id());
|
||||
|
||||
// It's OK to use the Isolate & counters here, since this function is only
|
||||
// called in the main thread.
|
||||
DCHECK(parsing_on_main_thread_);
|
||||
RuntimeCallTimerScope runtime_timer(
|
||||
runtime_call_stats_, info->is_eval()
|
||||
runtime_call_stats_, flags().is_eval()
|
||||
? RuntimeCallCounterId::kParseEval
|
||||
: RuntimeCallCounterId::kParseProgram);
|
||||
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram");
|
||||
@ -552,12 +547,13 @@ FunctionLiteral* Parser::ParseProgram(
|
||||
const char* event_name = "parse-eval";
|
||||
int start = -1;
|
||||
int end = -1;
|
||||
if (!info->is_eval()) {
|
||||
if (!flags().is_eval()) {
|
||||
event_name = "parse-script";
|
||||
start = 0;
|
||||
end = String::cast(script->source()).length();
|
||||
}
|
||||
LOG(isolate, FunctionEvent(event_name, script_id(), ms, start, end, "", 0));
|
||||
LOG(isolate,
|
||||
FunctionEvent(event_name, flags().script_id(), ms, start, end, "", 0));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -572,16 +568,14 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
|
||||
|
||||
ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
|
||||
ResetFunctionLiteralId();
|
||||
DCHECK(info->function_literal_id() == kFunctionLiteralIdTopLevel ||
|
||||
info->function_literal_id() == kFunctionLiteralIdInvalid);
|
||||
|
||||
FunctionLiteral* result = nullptr;
|
||||
{
|
||||
Scope* outer = original_scope_;
|
||||
DCHECK_NOT_NULL(outer);
|
||||
if (info->is_eval()) {
|
||||
if (flags().is_eval()) {
|
||||
outer = NewEvalScope(outer);
|
||||
} else if (parsing_module_) {
|
||||
} else if (flags().is_module()) {
|
||||
DCHECK_EQ(outer, info->script_scope());
|
||||
outer = NewModuleScope(info->script_scope());
|
||||
}
|
||||
@ -592,15 +586,15 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
|
||||
FunctionState function_state(&function_state_, &scope_, scope);
|
||||
ScopedPtrList<Statement> body(pointer_buffer());
|
||||
int beg_pos = scanner()->location().beg_pos;
|
||||
if (parsing_module_) {
|
||||
DCHECK(info->is_module());
|
||||
if (flags().is_module()) {
|
||||
DCHECK(flags().is_module());
|
||||
|
||||
PrepareGeneratorVariables();
|
||||
Expression* initial_yield =
|
||||
BuildInitialYield(kNoSourcePosition, kGeneratorFunction);
|
||||
body.Add(
|
||||
factory()->NewExpressionStatement(initial_yield, kNoSourcePosition));
|
||||
if (allow_harmony_top_level_await()) {
|
||||
if (flags().allow_harmony_top_level_await()) {
|
||||
// First parse statements into a buffer. Then, if there was a
|
||||
// top level await, create an inner block and rewrite the body of the
|
||||
// module as an async function. Otherwise merge the statements back
|
||||
@ -634,7 +628,7 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
|
||||
} else if (info->is_wrapped_as_function()) {
|
||||
DCHECK(parsing_on_main_thread_);
|
||||
ParseWrapped(isolate, info, &body, scope, zone());
|
||||
} else if (info->is_repl_mode()) {
|
||||
} else if (flags().is_repl_mode()) {
|
||||
ParseREPLProgram(info, &body, scope);
|
||||
} else {
|
||||
// Don't count the mode in the use counters--give the program a chance
|
||||
@ -659,13 +653,13 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
|
||||
}
|
||||
// Internalize the ast strings in the case of eval so we can check for
|
||||
// conflicting var declarations with outer scope-info-backed scopes.
|
||||
if (info->is_eval()) {
|
||||
if (flags().is_eval()) {
|
||||
DCHECK(parsing_on_main_thread_);
|
||||
info->ast_value_factory()->Internalize(isolate);
|
||||
}
|
||||
CheckConflictingVarDeclarations(scope);
|
||||
|
||||
if (info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
|
||||
if (flags().parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
|
||||
if (body.length() != 1 || !body.at(0)->IsExpressionStatement() ||
|
||||
!body.at(0)
|
||||
->AsExpressionStatement()
|
||||
@ -743,7 +737,7 @@ void Parser::ParseREPLProgram(ParseInfo* info, ScopedPtrList<Statement>* body,
|
||||
// completion value of the script is obtained by manually invoking
|
||||
// the {Rewriter} which will return a VariableProxy referencing the
|
||||
// result.
|
||||
DCHECK(info->is_repl_mode());
|
||||
DCHECK(flags().is_repl_mode());
|
||||
this->scope()->SetLanguageMode(info->language_mode());
|
||||
PrepareGeneratorVariables();
|
||||
|
||||
@ -813,6 +807,10 @@ FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
|
||||
Script::cast(shared_info->script()).wrapped_arguments(), isolate);
|
||||
}
|
||||
|
||||
int start_position = shared_info->StartPosition();
|
||||
int end_position = shared_info->EndPosition();
|
||||
int function_literal_id = shared_info->function_literal_id();
|
||||
|
||||
// Initialize parser state.
|
||||
Handle<String> name(shared_info->Name(), isolate);
|
||||
info->set_function_name(ast_value_factory()->GetString(name));
|
||||
@ -825,9 +823,11 @@ FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
|
||||
// function is in heritage position. Otherwise the function scope's skip bit
|
||||
// will be correctly inherited from the outer scope.
|
||||
ClassScope::HeritageParsingScope heritage(original_scope_->AsClassScope());
|
||||
result = DoParseFunction(isolate, info, info->function_name());
|
||||
result = DoParseFunction(isolate, info, start_position, end_position,
|
||||
function_literal_id, info->function_name());
|
||||
} else {
|
||||
result = DoParseFunction(isolate, info, info->function_name());
|
||||
result = DoParseFunction(isolate, info, start_position, end_position,
|
||||
function_literal_id, info->function_name());
|
||||
}
|
||||
MaybeResetCharacterStream(info, result);
|
||||
MaybeProcessSourceRanges(info, result, stack_limit_);
|
||||
@ -843,7 +843,7 @@ FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
|
||||
DeclarationScope* function_scope = result->scope();
|
||||
std::unique_ptr<char[]> function_name = result->GetDebugName();
|
||||
LOG(isolate,
|
||||
FunctionEvent("parse-function", script_id(), ms,
|
||||
FunctionEvent("parse-function", flags().script_id(), ms,
|
||||
function_scope->start_position(),
|
||||
function_scope->end_position(), function_name.get(),
|
||||
strlen(function_name.get())));
|
||||
@ -852,6 +852,8 @@ FunctionLiteral* Parser::ParseFunction(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) {
|
||||
DCHECK_EQ(parsing_on_main_thread_, isolate != nullptr);
|
||||
DCHECK_NOT_NULL(raw_name);
|
||||
@ -861,8 +863,8 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
|
||||
fni_.PushEnclosingName(raw_name);
|
||||
|
||||
ResetFunctionLiteralId();
|
||||
DCHECK_LT(0, info->function_literal_id());
|
||||
SkipFunctionLiterals(info->function_literal_id() - 1);
|
||||
DCHECK_LT(0, function_literal_id);
|
||||
SkipFunctionLiterals(function_literal_id - 1);
|
||||
|
||||
ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
|
||||
|
||||
@ -878,10 +880,10 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
|
||||
BlockState block_state(&scope_, outer);
|
||||
DCHECK(is_sloppy(outer->language_mode()) ||
|
||||
is_strict(info->language_mode()));
|
||||
FunctionKind kind = info->function_kind();
|
||||
DCHECK_IMPLIES(
|
||||
IsConciseMethod(kind) || IsAccessorFunction(kind),
|
||||
info->function_syntax_kind() == FunctionSyntaxKind::kAccessorOrMethod);
|
||||
FunctionKind kind = flags().function_kind();
|
||||
DCHECK_IMPLIES(IsConciseMethod(kind) || IsAccessorFunction(kind),
|
||||
flags().function_syntax_kind() ==
|
||||
FunctionSyntaxKind::kAccessorOrMethod);
|
||||
|
||||
if (IsArrowFunction(kind)) {
|
||||
if (IsAsyncFunction(kind)) {
|
||||
@ -904,7 +906,7 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
|
||||
// not passing the ScopeInfo to the Scope constructor.
|
||||
SetLanguageMode(scope, info->language_mode());
|
||||
|
||||
scope->set_start_position(info->start_position());
|
||||
scope->set_start_position(start_position);
|
||||
ParserFormalParameters formals(scope);
|
||||
{
|
||||
ParameterDeclarationParsingScope formals_scope(this);
|
||||
@ -925,14 +927,14 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
|
||||
formals.duplicate_loc = formals_scope.duplicate_location();
|
||||
}
|
||||
|
||||
if (GetLastFunctionLiteralId() != info->function_literal_id() - 1) {
|
||||
if (GetLastFunctionLiteralId() != function_literal_id - 1) {
|
||||
if (has_error()) return nullptr;
|
||||
// If there were FunctionLiterals in the parameters, we need to
|
||||
// renumber them to shift down so the next function literal id for
|
||||
// the arrow function is the one requested.
|
||||
AstFunctionLiteralIdReindexer reindexer(
|
||||
stack_limit_,
|
||||
(info->function_literal_id() - 1) - GetLastFunctionLiteralId());
|
||||
(function_literal_id - 1) - GetLastFunctionLiteralId());
|
||||
for (auto p : formals.params) {
|
||||
if (p->pattern != nullptr) reindexer.Reindex(p->pattern);
|
||||
if (p->initializer() != nullptr) {
|
||||
@ -940,7 +942,7 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
|
||||
}
|
||||
}
|
||||
ResetFunctionLiteralId();
|
||||
SkipFunctionLiterals(info->function_literal_id() - 1);
|
||||
SkipFunctionLiterals(function_literal_id - 1);
|
||||
}
|
||||
|
||||
Expression* expression = ParseArrowFunctionLiteral(formals);
|
||||
@ -950,7 +952,7 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
|
||||
// concise body happens to be a valid expression. This is a problem
|
||||
// only for arrow functions with single expression bodies, since there
|
||||
// is no end token such as "}" for normal functions.
|
||||
if (scanner()->location().end_pos == info->end_position()) {
|
||||
if (scanner()->location().end_pos == end_position) {
|
||||
// The pre-parser saw an arrow function here, so the full parser
|
||||
// must produce a FunctionLiteral.
|
||||
DCHECK(expression->IsFunctionLiteral());
|
||||
@ -959,7 +961,7 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
|
||||
} else if (IsDefaultConstructor(kind)) {
|
||||
DCHECK_EQ(scope(), outer);
|
||||
result = DefaultConstructor(raw_name, IsDerivedConstructor(kind),
|
||||
info->start_position(), info->end_position());
|
||||
start_position, end_position);
|
||||
} else {
|
||||
ZonePtrList<const AstRawString>* arguments_for_wrapped_function =
|
||||
info->is_wrapped_as_function()
|
||||
@ -967,24 +969,23 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
|
||||
: nullptr;
|
||||
result = ParseFunctionLiteral(
|
||||
raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, kind,
|
||||
kNoSourcePosition, info->function_syntax_kind(),
|
||||
kNoSourcePosition, flags().function_syntax_kind(),
|
||||
info->language_mode(), arguments_for_wrapped_function);
|
||||
}
|
||||
|
||||
if (has_error()) return nullptr;
|
||||
result->set_requires_instance_members_initializer(
|
||||
info->requires_instance_members_initializer());
|
||||
flags().requires_instance_members_initializer());
|
||||
result->set_class_scope_has_private_brand(
|
||||
info->class_scope_has_private_brand());
|
||||
flags().class_scope_has_private_brand());
|
||||
result->set_has_static_private_methods_or_accessors(
|
||||
info->has_static_private_methods_or_accessors());
|
||||
if (info->is_oneshot_iife()) {
|
||||
flags().has_static_private_methods_or_accessors());
|
||||
if (flags().is_oneshot_iife()) {
|
||||
result->mark_as_oneshot_iife();
|
||||
}
|
||||
}
|
||||
|
||||
DCHECK_IMPLIES(result,
|
||||
info->function_literal_id() == result->function_literal_id());
|
||||
DCHECK_IMPLIES(result, function_literal_id == result->function_literal_id());
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1005,8 +1006,9 @@ Statement* Parser::ParseModuleItem() {
|
||||
// We must be careful not to parse a dynamic import expression as an import
|
||||
// declaration. Same for import.meta expressions.
|
||||
Token::Value peek_ahead = PeekAhead();
|
||||
if ((!allow_harmony_dynamic_import() || peek_ahead != Token::LPAREN) &&
|
||||
(!allow_harmony_import_meta() || peek_ahead != Token::PERIOD)) {
|
||||
if ((!flags().allow_harmony_dynamic_import() ||
|
||||
peek_ahead != Token::LPAREN) &&
|
||||
(!flags().allow_harmony_import_meta() || peek_ahead != Token::PERIOD)) {
|
||||
ParseImportDeclaration();
|
||||
return factory()->EmptyStatement();
|
||||
}
|
||||
@ -1066,7 +1068,7 @@ ZoneChunkList<Parser::ExportClauseData>* Parser::ParseExportClause(
|
||||
// caller needs to report an error.
|
||||
if (!reserved_loc->IsValid() &&
|
||||
!Token::IsValidIdentifier(name_tok, LanguageMode::kStrict, false,
|
||||
parsing_module_)) {
|
||||
flags().is_module())) {
|
||||
*reserved_loc = scanner()->location();
|
||||
}
|
||||
const AstRawString* local_name = ParsePropertyName();
|
||||
@ -1122,7 +1124,7 @@ ZonePtrList<const Parser::NamedImport>* Parser::ParseNamedImports(int pos) {
|
||||
}
|
||||
if (!Token::IsValidIdentifier(scanner()->current_token(),
|
||||
LanguageMode::kStrict, false,
|
||||
parsing_module_)) {
|
||||
flags().is_module())) {
|
||||
ReportMessage(MessageTemplate::kUnexpectedReserved);
|
||||
return nullptr;
|
||||
} else if (IsEvalOrArguments(local_name)) {
|
||||
@ -1560,7 +1562,7 @@ Statement* Parser::DeclareFunction(const AstRawString* variable_name,
|
||||
bool was_added;
|
||||
Declare(declaration, variable_name, kind, mode, kCreatedInitialized, scope(),
|
||||
&was_added, beg_pos);
|
||||
if (info()->coverage_enabled()) {
|
||||
if (info()->flags().coverage_enabled()) {
|
||||
// Force the function to be allocated when collecting source coverage, so
|
||||
// that even dead functions get source coverage data.
|
||||
declaration->var()->set_is_used();
|
||||
@ -2376,7 +2378,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
||||
// parenthesis before the function means that it will be called
|
||||
// immediately). bar can be parsed lazily, but we need to parse it in a mode
|
||||
// that tracks unresolved variables.
|
||||
DCHECK_IMPLIES(parse_lazily(), info()->allow_lazy_compile());
|
||||
DCHECK_IMPLIES(parse_lazily(), info()->flags().allow_lazy_compile());
|
||||
DCHECK_IMPLIES(parse_lazily(), has_error() || allow_lazy_);
|
||||
DCHECK_IMPLIES(parse_lazily(), extension_ == nullptr);
|
||||
|
||||
@ -2475,7 +2477,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
||||
? (is_top_level ? "preparse-no-resolution" : "preparse-resolution")
|
||||
: "full-parse";
|
||||
logger_->FunctionEvent(
|
||||
event_name, script_id(), ms, scope->start_position(),
|
||||
event_name, flags().script_id(), ms, scope->start_position(),
|
||||
scope->end_position(),
|
||||
reinterpret_cast<const char*>(function_name->raw_data()),
|
||||
function_name->byte_length());
|
||||
@ -2582,7 +2584,7 @@ bool Parser::SkipFunction(const AstRawString* function_name, FunctionKind kind,
|
||||
|
||||
PreParser::PreParseResult result = reusable_preparser()->PreParseFunction(
|
||||
function_name, kind, function_syntax_kind, function_scope, use_counts_,
|
||||
produced_preparse_data, this->script_id());
|
||||
produced_preparse_data);
|
||||
|
||||
if (result == PreParser::kPreParseStackOverflow) {
|
||||
// Propagate stack overflow.
|
||||
@ -2879,7 +2881,7 @@ void Parser::DeclarePrivateClassMember(ClassScope* scope,
|
||||
ClassLiteralProperty::Kind kind,
|
||||
bool is_static, ClassInfo* class_info) {
|
||||
DCHECK_IMPLIES(kind != ClassLiteralProperty::Kind::FIELD,
|
||||
allow_harmony_private_methods());
|
||||
flags().allow_harmony_private_methods());
|
||||
|
||||
if (kind == ClassLiteralProperty::Kind::FIELD) {
|
||||
if (is_static) {
|
||||
@ -3084,11 +3086,11 @@ void Parser::UpdateStatistics(Isolate* isolate, Handle<Script> script) {
|
||||
total_preparse_skipped_);
|
||||
}
|
||||
|
||||
void Parser::ParseOnBackground(ParseInfo* info) {
|
||||
void Parser::ParseOnBackground(ParseInfo* info, int start_position,
|
||||
int end_position, int function_literal_id) {
|
||||
RuntimeCallTimerScope runtimeTimer(
|
||||
runtime_call_stats_, RuntimeCallCounterId::kParseBackgroundProgram);
|
||||
parsing_on_main_thread_ = false;
|
||||
set_script_id(info->script_id());
|
||||
|
||||
DCHECK_NULL(info->literal());
|
||||
FunctionLiteral* result = nullptr;
|
||||
@ -3103,11 +3105,15 @@ void Parser::ParseOnBackground(ParseInfo* info) {
|
||||
// don't). We work around this by storing all the scopes which need their end
|
||||
// position set at the end of the script (the top scope and possible eval
|
||||
// scopes) and set their end position after we know the script length.
|
||||
if (info->is_toplevel()) {
|
||||
if (flags().is_toplevel()) {
|
||||
DCHECK_EQ(start_position, 0);
|
||||
DCHECK_EQ(end_position, 0);
|
||||
DCHECK_EQ(function_literal_id, kFunctionLiteralIdTopLevel);
|
||||
result = DoParseProgram(/* isolate = */ nullptr, info);
|
||||
} else {
|
||||
result =
|
||||
DoParseFunction(/* isolate = */ nullptr, info, info->function_name());
|
||||
result = DoParseFunction(/* isolate = */ nullptr, info, start_position,
|
||||
end_position, function_literal_id,
|
||||
info->function_name());
|
||||
}
|
||||
MaybeResetCharacterStream(info, result);
|
||||
MaybeProcessSourceRanges(info, result, stack_limit_);
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "src/base/compiler-specific.h"
|
||||
#include "src/base/threaded-list.h"
|
||||
#include "src/common/globals.h"
|
||||
#include "src/parsing/parse-info.h"
|
||||
#include "src/parsing/parser-base.h"
|
||||
#include "src/parsing/parsing.h"
|
||||
#include "src/parsing/preparser.h"
|
||||
@ -134,7 +135,8 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
|
||||
|
||||
static bool IsPreParser() { return false; }
|
||||
|
||||
void ParseOnBackground(ParseInfo* info);
|
||||
void ParseOnBackground(ParseInfo* info, int start_position, int end_position,
|
||||
int function_literal_id);
|
||||
|
||||
// Initializes an empty scope chain for top-level scripts, or scopes which
|
||||
// consist of only the native context.
|
||||
@ -215,6 +217,8 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
|
||||
FunctionLiteral* ParseFunction(Isolate* isolate, ParseInfo* info,
|
||||
Handle<SharedFunctionInfo> shared_info);
|
||||
FunctionLiteral* DoParseFunction(Isolate* isolate, ParseInfo* info,
|
||||
int start_position, int end_position,
|
||||
int function_literal_id,
|
||||
const AstRawString* raw_name);
|
||||
|
||||
// Called by ParseProgram after setting up the scanner.
|
||||
@ -239,15 +243,9 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
|
||||
if (reusable_preparser_ == nullptr) {
|
||||
reusable_preparser_ = new PreParser(
|
||||
&preparser_zone_, &scanner_, stack_limit_, ast_value_factory(),
|
||||
pending_error_handler(), runtime_call_stats_, logger_, -1,
|
||||
parsing_module_, parsing_on_main_thread_);
|
||||
#define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name());
|
||||
SET_ALLOW(natives);
|
||||
SET_ALLOW(harmony_dynamic_import);
|
||||
SET_ALLOW(harmony_import_meta);
|
||||
SET_ALLOW(harmony_private_methods);
|
||||
SET_ALLOW(eval_cache);
|
||||
#undef SET_ALLOW
|
||||
pending_error_handler(), runtime_call_stats_, logger_, flags(),
|
||||
parsing_on_main_thread_);
|
||||
reusable_preparser_->set_allow_eval_cache(allow_eval_cache());
|
||||
preparse_data_buffer_.reserve(128);
|
||||
}
|
||||
return reusable_preparser_;
|
||||
|
@ -22,7 +22,7 @@ namespace parsing {
|
||||
bool ParseProgram(ParseInfo* info, Handle<Script> script,
|
||||
MaybeHandle<ScopeInfo> maybe_outer_scope_info,
|
||||
Isolate* isolate, ReportErrorsAndStatisticsMode mode) {
|
||||
DCHECK(info->is_toplevel());
|
||||
DCHECK(info->flags().is_toplevel());
|
||||
DCHECK_NULL(info->literal());
|
||||
|
||||
VMState<PARSER> state(isolate);
|
||||
@ -44,7 +44,7 @@ bool ParseProgram(ParseInfo* info, Handle<Script> script,
|
||||
info->set_literal(result);
|
||||
if (result) {
|
||||
info->set_language_mode(info->literal()->language_mode());
|
||||
if (info->is_eval()) {
|
||||
if (info->flags().is_eval()) {
|
||||
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,
|
||||
Isolate* isolate, ReportErrorsAndStatisticsMode mode) {
|
||||
DCHECK(!info->is_toplevel());
|
||||
DCHECK(!info->flags().is_toplevel());
|
||||
DCHECK(!shared_info.is_null());
|
||||
DCHECK_NULL(info->literal());
|
||||
|
||||
@ -91,7 +91,7 @@ bool ParseFunction(ParseInfo* info, Handle<SharedFunctionInfo> shared_info,
|
||||
info->set_literal(result);
|
||||
if (result) {
|
||||
info->ast_value_factory()->Internalize(isolate);
|
||||
if (info->is_eval()) {
|
||||
if (info->flags().is_eval()) {
|
||||
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,
|
||||
Isolate* isolate, ReportErrorsAndStatisticsMode mode) {
|
||||
DCHECK(!shared_info.is_null());
|
||||
if (info->is_toplevel()) {
|
||||
if (info->flags().is_toplevel()) {
|
||||
MaybeHandle<ScopeInfo> maybe_outer_scope_info;
|
||||
if (shared_info->HasOuterScopeInfo()) {
|
||||
maybe_outer_scope_info =
|
||||
|
@ -78,7 +78,7 @@ PreParser::PreParseResult PreParser::PreParseProgram() {
|
||||
// ModuleDeclarationInstantiation for Source Text Module Records creates a
|
||||
// new Module Environment Record whose outer lexical environment record is
|
||||
// the global scope.
|
||||
if (parsing_module_) scope = NewModuleScope(scope);
|
||||
if (flags().is_module()) scope = NewModuleScope(scope);
|
||||
|
||||
FunctionState top_scope(&function_state_, &scope_, scope);
|
||||
original_scope_ = scope_;
|
||||
@ -105,11 +105,9 @@ void PreParserFormalParameters::ValidateStrictMode(PreParser* preparser) const {
|
||||
PreParser::PreParseResult PreParser::PreParseFunction(
|
||||
const AstRawString* function_name, FunctionKind kind,
|
||||
FunctionSyntaxKind function_syntax_kind, DeclarationScope* function_scope,
|
||||
int* use_counts, ProducedPreparseData** produced_preparse_data,
|
||||
int script_id) {
|
||||
int* use_counts, ProducedPreparseData** produced_preparse_data) {
|
||||
DCHECK_EQ(FUNCTION_SCOPE, function_scope->scope_type());
|
||||
use_counts_ = use_counts;
|
||||
set_script_id(script_id);
|
||||
#ifdef DEBUG
|
||||
function_scope->set_is_being_lazily_parsed(true);
|
||||
#endif
|
||||
@ -359,7 +357,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
|
||||
name_byte_length = string->byte_length();
|
||||
}
|
||||
logger_->FunctionEvent(
|
||||
event_name, script_id(), ms, function_scope->start_position(),
|
||||
event_name, flags().script_id(), ms, function_scope->start_position(),
|
||||
function_scope->end_position(), name, name_byte_length);
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "src/ast/ast-value-factory.h"
|
||||
#include "src/ast/ast.h"
|
||||
#include "src/ast/scopes.h"
|
||||
#include "src/parsing/parse-info.h"
|
||||
#include "src/parsing/parser-base.h"
|
||||
#include "src/parsing/pending-compilation-error-handler.h"
|
||||
#include "src/parsing/preparser-logger.h"
|
||||
@ -921,12 +922,11 @@ class PreParser : public ParserBase<PreParser> {
|
||||
AstValueFactory* ast_value_factory,
|
||||
PendingCompilationErrorHandler* pending_error_handler,
|
||||
RuntimeCallStats* runtime_call_stats, Logger* logger,
|
||||
int script_id = -1, bool parsing_module = false,
|
||||
bool parsing_on_main_thread = true)
|
||||
UnoptimizedCompileFlags flags, bool parsing_on_main_thread = true)
|
||||
: ParserBase<PreParser>(zone, scanner, stack_limit, nullptr,
|
||||
ast_value_factory, pending_error_handler,
|
||||
runtime_call_stats, logger, script_id,
|
||||
parsing_module, parsing_on_main_thread),
|
||||
runtime_call_stats, logger, flags,
|
||||
parsing_on_main_thread),
|
||||
use_counts_(nullptr),
|
||||
preparse_data_builder_(nullptr),
|
||||
preparse_data_builder_buffer_() {
|
||||
@ -954,8 +954,7 @@ class PreParser : public ParserBase<PreParser> {
|
||||
PreParseResult PreParseFunction(
|
||||
const AstRawString* function_name, FunctionKind kind,
|
||||
FunctionSyntaxKind function_syntax_kind, DeclarationScope* function_scope,
|
||||
int* use_counts, ProducedPreparseData** produced_preparser_scope_data,
|
||||
int script_id);
|
||||
int* use_counts, ProducedPreparseData** produced_preparser_scope_data);
|
||||
|
||||
PreparseDataBuilder* preparse_data_builder() const {
|
||||
return preparse_data_builder_;
|
||||
|
@ -400,7 +400,7 @@ base::Optional<VariableProxy*> Rewriter::RewriteBody(
|
||||
int pos = kNoSourcePosition;
|
||||
VariableProxy* result_value =
|
||||
processor.factory()->NewVariableProxy(result, pos);
|
||||
if (!info->is_repl_mode()) {
|
||||
if (!info->flags().is_repl_mode()) {
|
||||
Statement* result_statement =
|
||||
processor.factory()->NewReturnStatement(result_value, pos);
|
||||
body->Add(result_statement, info->zone());
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "src/ast/ast-value-factory.h"
|
||||
#include "src/numbers/conversions-inl.h"
|
||||
#include "src/objects/bigint.h"
|
||||
#include "src/parsing/parse-info.h"
|
||||
#include "src/parsing/scanner-inl.h"
|
||||
#include "src/zone/zone.h"
|
||||
|
||||
@ -89,10 +90,10 @@ bool Scanner::BookmarkScope::HasBeenApplied() const {
|
||||
// ----------------------------------------------------------------------------
|
||||
// Scanner
|
||||
|
||||
Scanner::Scanner(Utf16CharacterStream* source, bool is_module)
|
||||
: source_(source),
|
||||
Scanner::Scanner(Utf16CharacterStream* source, UnoptimizedCompileFlags flags)
|
||||
: flags_(flags),
|
||||
source_(source),
|
||||
found_html_comment_(false),
|
||||
is_module_(is_module),
|
||||
octal_pos_(Location::invalid()),
|
||||
octal_message_(MessageTemplate::kNone) {
|
||||
DCHECK_NOT_NULL(source);
|
||||
@ -188,7 +189,7 @@ Token::Value Scanner::PeekAhead() {
|
||||
}
|
||||
|
||||
Token::Value Scanner::SkipSingleHTMLComment() {
|
||||
if (is_module_) {
|
||||
if (flags_.is_module()) {
|
||||
ReportScannerError(source_pos(), MessageTemplate::kHtmlCommentInModule);
|
||||
return Token::ILLEGAL;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "src/common/globals.h"
|
||||
#include "src/common/message-template.h"
|
||||
#include "src/parsing/literal-buffer.h"
|
||||
#include "src/parsing/parse-info.h"
|
||||
#include "src/parsing/token.h"
|
||||
#include "src/strings/char-predicates.h"
|
||||
#include "src/strings/unicode.h"
|
||||
@ -269,7 +270,7 @@ class V8_EXPORT_PRIVATE Scanner {
|
||||
static const int kNoOctalLocation = -1;
|
||||
static const uc32 kEndOfInput = Utf16CharacterStream::kEndOfInput;
|
||||
|
||||
explicit Scanner(Utf16CharacterStream* source, bool is_module);
|
||||
explicit Scanner(Utf16CharacterStream* source, UnoptimizedCompileFlags flags);
|
||||
|
||||
void Initialize();
|
||||
|
||||
@ -703,6 +704,8 @@ class V8_EXPORT_PRIVATE Scanner {
|
||||
const TokenDesc& next() const { return *next_; }
|
||||
const TokenDesc& next_next() const { return *next_next_; }
|
||||
|
||||
UnoptimizedCompileFlags flags_;
|
||||
|
||||
TokenDesc* current_; // desc for current token (as returned by Next())
|
||||
TokenDesc* next_; // desc for next token (one token look-ahead)
|
||||
TokenDesc* next_next_; // desc for the token after next (after PeakAhead())
|
||||
@ -718,8 +721,6 @@ class V8_EXPORT_PRIVATE Scanner {
|
||||
// Whether this scanner encountered an HTML comment.
|
||||
bool found_html_comment_;
|
||||
|
||||
const bool is_module_;
|
||||
|
||||
// Values parsed from magic comments.
|
||||
LiteralBuffer source_url_;
|
||||
LiteralBuffer source_mapping_url_;
|
||||
|
@ -707,9 +707,12 @@ TEST(PreParserScopeAnalysis) {
|
||||
shared->uncompiled_data_with_preparse_data().preparse_data(),
|
||||
isolate);
|
||||
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForFunctionCompile(isolate, *shared);
|
||||
flags.set_is_lazy_compile(true);
|
||||
|
||||
// Parse the lazy function using the scope data.
|
||||
i::ParseInfo using_scope_data(isolate, *shared);
|
||||
using_scope_data.set_lazy_compile();
|
||||
i::ParseInfo using_scope_data(isolate, flags);
|
||||
using_scope_data.set_consumed_preparse_data(
|
||||
i::ConsumedPreparseData::For(isolate, produced_data_on_heap));
|
||||
CHECK(i::parsing::ParseFunction(&using_scope_data, shared, isolate));
|
||||
@ -724,8 +727,7 @@ TEST(PreParserScopeAnalysis) {
|
||||
CHECK(i::DeclarationScope::Analyze(&using_scope_data));
|
||||
|
||||
// Parse the lazy function again eagerly to produce baseline data.
|
||||
i::ParseInfo not_using_scope_data(isolate, *shared);
|
||||
not_using_scope_data.set_lazy_compile();
|
||||
i::ParseInfo not_using_scope_data(isolate, flags);
|
||||
CHECK(i::parsing::ParseFunction(¬_using_scope_data, shared, isolate));
|
||||
|
||||
// Verify that we didn't skip anything (there's no preparsed scope data,
|
||||
@ -759,7 +761,9 @@ TEST(Regress753896) {
|
||||
i::Handle<i::String> source = factory->InternalizeUtf8String(
|
||||
"function lazy() { let v = 0; if (true) { var v = 0; } }");
|
||||
i::Handle<i::Script> script = factory->NewScript(source);
|
||||
i::ParseInfo info(isolate, *script);
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
|
||||
i::ParseInfo info(isolate, flags);
|
||||
|
||||
// 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.
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "src/handles/handles-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.h"
|
||||
#include "test/cctest/cctest.h"
|
||||
@ -34,8 +35,9 @@ struct ScannerTestHelper {
|
||||
ScannerTestHelper make_scanner(const char* src) {
|
||||
ScannerTestHelper helper;
|
||||
helper.stream = ScannerStream::ForTesting(src);
|
||||
helper.scanner =
|
||||
std::unique_ptr<Scanner>(new Scanner(helper.stream.get(), false));
|
||||
helper.scanner = std::unique_ptr<Scanner>(
|
||||
new Scanner(helper.stream.get(),
|
||||
UnoptimizedCompileFlags::ForTest(CcTest::i_isolate())));
|
||||
helper.scanner->Initialize();
|
||||
return helper;
|
||||
}
|
||||
|
@ -515,6 +515,8 @@ TEST(ScanKeywords) {
|
||||
#undef KEYWORD
|
||||
{nullptr, i::Token::IDENTIFIER}};
|
||||
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForTest(CcTest::i_isolate());
|
||||
KeywordToken key_token;
|
||||
char buffer[32];
|
||||
for (int i = 0; (key_token = keywords[i]).keyword != nullptr; i++) {
|
||||
@ -523,7 +525,7 @@ TEST(ScanKeywords) {
|
||||
CHECK(static_cast<int>(sizeof(buffer)) >= length);
|
||||
{
|
||||
auto stream = i::ScannerStream::ForTesting(keyword, length);
|
||||
i::Scanner scanner(stream.get(), false);
|
||||
i::Scanner scanner(stream.get(), flags);
|
||||
scanner.Initialize();
|
||||
CHECK_EQ(key_token.token, scanner.Next());
|
||||
CHECK_EQ(i::Token::EOS, scanner.Next());
|
||||
@ -531,7 +533,7 @@ TEST(ScanKeywords) {
|
||||
// Removing characters will make keyword matching fail.
|
||||
{
|
||||
auto stream = i::ScannerStream::ForTesting(keyword, length - 1);
|
||||
i::Scanner scanner(stream.get(), false);
|
||||
i::Scanner scanner(stream.get(), flags);
|
||||
scanner.Initialize();
|
||||
CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
|
||||
CHECK_EQ(i::Token::EOS, scanner.Next());
|
||||
@ -542,7 +544,7 @@ TEST(ScanKeywords) {
|
||||
i::MemMove(buffer, keyword, length);
|
||||
buffer[length] = chars_to_append[j];
|
||||
auto stream = i::ScannerStream::ForTesting(buffer, length + 1);
|
||||
i::Scanner scanner(stream.get(), false);
|
||||
i::Scanner scanner(stream.get(), flags);
|
||||
scanner.Initialize();
|
||||
CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
|
||||
CHECK_EQ(i::Token::EOS, scanner.Next());
|
||||
@ -552,7 +554,7 @@ TEST(ScanKeywords) {
|
||||
i::MemMove(buffer, keyword, length);
|
||||
buffer[length - 1] = '_';
|
||||
auto stream = i::ScannerStream::ForTesting(buffer, length);
|
||||
i::Scanner scanner(stream.get(), false);
|
||||
i::Scanner scanner(stream.get(), flags);
|
||||
scanner.Initialize();
|
||||
CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
|
||||
CHECK_EQ(i::Token::EOS, scanner.Next());
|
||||
@ -566,6 +568,8 @@ TEST(ScanHTMLEndComments) {
|
||||
v8::Isolate* isolate = CcTest::isolate();
|
||||
i::Isolate* i_isolate = CcTest::i_isolate();
|
||||
v8::HandleScope handles(isolate);
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForTest(i_isolate);
|
||||
|
||||
// Regression test. See:
|
||||
// http://code.google.com/p/chromium/issues/detail?id=53548
|
||||
@ -619,7 +623,7 @@ TEST(ScanHTMLEndComments) {
|
||||
for (int i = 0; tests[i]; i++) {
|
||||
const char* source = tests[i];
|
||||
auto stream = i::ScannerStream::ForTesting(source);
|
||||
i::Scanner scanner(stream.get(), false);
|
||||
i::Scanner scanner(stream.get(), flags);
|
||||
scanner.Initialize();
|
||||
i::Zone zone(i_isolate->allocator(), ZONE_NAME);
|
||||
i::AstValueFactory ast_value_factory(
|
||||
@ -628,7 +632,7 @@ TEST(ScanHTMLEndComments) {
|
||||
i::PreParser preparser(&zone, &scanner, stack_limit, &ast_value_factory,
|
||||
&pending_error_handler,
|
||||
i_isolate->counters()->runtime_call_stats(),
|
||||
i_isolate->logger());
|
||||
i_isolate->logger(), flags);
|
||||
i::PreParser::PreParseResult result = preparser.PreParseProgram();
|
||||
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
|
||||
CHECK(!pending_error_handler.has_pending_error());
|
||||
@ -637,7 +641,7 @@ TEST(ScanHTMLEndComments) {
|
||||
for (int i = 0; fail_tests[i]; i++) {
|
||||
const char* source = fail_tests[i];
|
||||
auto stream = i::ScannerStream::ForTesting(source);
|
||||
i::Scanner scanner(stream.get(), false);
|
||||
i::Scanner scanner(stream.get(), flags);
|
||||
scanner.Initialize();
|
||||
i::Zone zone(i_isolate->allocator(), ZONE_NAME);
|
||||
i::AstValueFactory ast_value_factory(
|
||||
@ -646,7 +650,7 @@ TEST(ScanHTMLEndComments) {
|
||||
i::PreParser preparser(&zone, &scanner, stack_limit, &ast_value_factory,
|
||||
&pending_error_handler,
|
||||
i_isolate->counters()->runtime_call_stats(),
|
||||
i_isolate->logger());
|
||||
i_isolate->logger(), flags);
|
||||
i::PreParser::PreParseResult result = preparser.PreParseProgram();
|
||||
// Even in the case of a syntax error, kPreParseSuccess is returned.
|
||||
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
|
||||
@ -656,11 +660,15 @@ TEST(ScanHTMLEndComments) {
|
||||
}
|
||||
|
||||
TEST(ScanHtmlComments) {
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForTest(CcTest::i_isolate());
|
||||
|
||||
const char* src = "a <!-- b --> c";
|
||||
// Disallow HTML comments.
|
||||
{
|
||||
flags.set_is_module(true);
|
||||
auto stream = i::ScannerStream::ForTesting(src);
|
||||
i::Scanner scanner(stream.get(), true);
|
||||
i::Scanner scanner(stream.get(), flags);
|
||||
scanner.Initialize();
|
||||
CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
|
||||
CHECK_EQ(i::Token::ILLEGAL, scanner.Next());
|
||||
@ -668,8 +676,9 @@ TEST(ScanHtmlComments) {
|
||||
|
||||
// Skip HTML comments:
|
||||
{
|
||||
flags.set_is_module(false);
|
||||
auto stream = i::ScannerStream::ForTesting(src);
|
||||
i::Scanner scanner(stream.get(), false);
|
||||
i::Scanner scanner(stream.get(), flags);
|
||||
scanner.Initialize();
|
||||
CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
|
||||
CHECK_EQ(i::Token::EOS, scanner.Next());
|
||||
@ -693,6 +702,9 @@ class ScriptResource : public v8::String::ExternalOneByteStringResource {
|
||||
TEST(StandAlonePreParser) {
|
||||
v8::V8::Initialize();
|
||||
i::Isolate* i_isolate = CcTest::i_isolate();
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForTest(i_isolate);
|
||||
flags.set_allow_natives_syntax(true);
|
||||
|
||||
i_isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
|
||||
128 * 1024);
|
||||
@ -708,7 +720,7 @@ TEST(StandAlonePreParser) {
|
||||
uintptr_t stack_limit = i_isolate->stack_guard()->real_climit();
|
||||
for (int i = 0; programs[i]; i++) {
|
||||
auto stream = i::ScannerStream::ForTesting(programs[i]);
|
||||
i::Scanner scanner(stream.get(), false);
|
||||
i::Scanner scanner(stream.get(), flags);
|
||||
scanner.Initialize();
|
||||
|
||||
i::Zone zone(i_isolate->allocator(), ZONE_NAME);
|
||||
@ -718,8 +730,7 @@ TEST(StandAlonePreParser) {
|
||||
i::PreParser preparser(&zone, &scanner, stack_limit, &ast_value_factory,
|
||||
&pending_error_handler,
|
||||
i_isolate->counters()->runtime_call_stats(),
|
||||
i_isolate->logger());
|
||||
preparser.set_allow_natives(true);
|
||||
i_isolate->logger(), flags);
|
||||
i::PreParser::PreParseResult result = preparser.PreParseProgram();
|
||||
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
|
||||
CHECK(!pending_error_handler.has_pending_error());
|
||||
@ -729,8 +740,10 @@ TEST(StandAlonePreParser) {
|
||||
|
||||
TEST(StandAlonePreParserNoNatives) {
|
||||
v8::V8::Initialize();
|
||||
|
||||
i::Isolate* isolate = CcTest::i_isolate();
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForTest(isolate);
|
||||
|
||||
isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
|
||||
128 * 1024);
|
||||
|
||||
@ -740,7 +753,7 @@ TEST(StandAlonePreParserNoNatives) {
|
||||
uintptr_t stack_limit = isolate->stack_guard()->real_climit();
|
||||
for (int i = 0; programs[i]; i++) {
|
||||
auto stream = i::ScannerStream::ForTesting(programs[i]);
|
||||
i::Scanner scanner(stream.get(), false);
|
||||
i::Scanner scanner(stream.get(), flags);
|
||||
scanner.Initialize();
|
||||
|
||||
// Preparser defaults to disallowing natives syntax.
|
||||
@ -751,7 +764,7 @@ TEST(StandAlonePreParserNoNatives) {
|
||||
i::PreParser preparser(&zone, &scanner, stack_limit, &ast_value_factory,
|
||||
&pending_error_handler,
|
||||
isolate->counters()->runtime_call_stats(),
|
||||
isolate->logger());
|
||||
isolate->logger(), flags);
|
||||
i::PreParser::PreParseResult result = preparser.PreParseProgram();
|
||||
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
|
||||
CHECK(pending_error_handler.has_pending_error() ||
|
||||
@ -763,6 +776,8 @@ TEST(StandAlonePreParserNoNatives) {
|
||||
TEST(RegressChromium62639) {
|
||||
v8::V8::Initialize();
|
||||
i::Isolate* isolate = CcTest::i_isolate();
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForTest(isolate);
|
||||
|
||||
isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
|
||||
128 * 1024);
|
||||
@ -775,7 +790,7 @@ TEST(RegressChromium62639) {
|
||||
// failed in debug mode, and sometimes crashed in release mode.
|
||||
|
||||
auto stream = i::ScannerStream::ForTesting(program);
|
||||
i::Scanner scanner(stream.get(), false);
|
||||
i::Scanner scanner(stream.get(), flags);
|
||||
scanner.Initialize();
|
||||
i::Zone zone(isolate->allocator(), ZONE_NAME);
|
||||
i::AstValueFactory ast_value_factory(&zone, isolate->ast_string_constants(),
|
||||
@ -784,7 +799,7 @@ TEST(RegressChromium62639) {
|
||||
i::PreParser preparser(&zone, &scanner, isolate->stack_guard()->real_climit(),
|
||||
&ast_value_factory, &pending_error_handler,
|
||||
isolate->counters()->runtime_call_stats(),
|
||||
isolate->logger());
|
||||
isolate->logger(), flags);
|
||||
i::PreParser::PreParseResult result = preparser.PreParseProgram();
|
||||
// Even in the case of a syntax error, kPreParseSuccess is returned.
|
||||
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
|
||||
@ -796,6 +811,8 @@ TEST(RegressChromium62639) {
|
||||
TEST(PreParseOverflow) {
|
||||
v8::V8::Initialize();
|
||||
i::Isolate* isolate = CcTest::i_isolate();
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForTest(isolate);
|
||||
|
||||
isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
|
||||
128 * 1024);
|
||||
@ -808,7 +825,7 @@ TEST(PreParseOverflow) {
|
||||
uintptr_t stack_limit = isolate->stack_guard()->real_climit();
|
||||
|
||||
auto stream = i::ScannerStream::ForTesting(program.get(), kProgramSize);
|
||||
i::Scanner scanner(stream.get(), false);
|
||||
i::Scanner scanner(stream.get(), flags);
|
||||
scanner.Initialize();
|
||||
|
||||
i::Zone zone(isolate->allocator(), ZONE_NAME);
|
||||
@ -817,7 +834,7 @@ TEST(PreParseOverflow) {
|
||||
i::PendingCompilationErrorHandler pending_error_handler;
|
||||
i::PreParser preparser(
|
||||
&zone, &scanner, stack_limit, &ast_value_factory, &pending_error_handler,
|
||||
isolate->counters()->runtime_call_stats(), isolate->logger());
|
||||
isolate->counters()->runtime_call_stats(), isolate->logger(), flags);
|
||||
i::PreParser::PreParseResult result = preparser.PreParseProgram();
|
||||
CHECK_EQ(i::PreParser::kPreParseStackOverflow, result);
|
||||
}
|
||||
@ -826,7 +843,10 @@ void TestStreamScanner(i::Utf16CharacterStream* stream,
|
||||
i::Token::Value* expected_tokens,
|
||||
int skip_pos = 0, // Zero means not skipping.
|
||||
int skip_to = 0) {
|
||||
i::Scanner scanner(stream, false);
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForTest(CcTest::i_isolate());
|
||||
|
||||
i::Scanner scanner(stream, flags);
|
||||
scanner.Initialize();
|
||||
|
||||
int i = 0;
|
||||
@ -894,7 +914,9 @@ TEST(StreamScanner) {
|
||||
void TestScanRegExp(const char* re_source, const char* expected) {
|
||||
auto stream = i::ScannerStream::ForTesting(re_source);
|
||||
i::HandleScope scope(CcTest::i_isolate());
|
||||
i::Scanner scanner(stream.get(), false);
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForTest(CcTest::i_isolate());
|
||||
i::Scanner scanner(stream.get(), flags);
|
||||
scanner.Initialize();
|
||||
|
||||
i::Token::Value start = scanner.peek();
|
||||
@ -1056,9 +1078,11 @@ TEST(ScopeUsesArgumentsSuperThis) {
|
||||
factory->NewStringFromUtf8(i::CStrVector(program.begin()))
|
||||
.ToHandleChecked();
|
||||
i::Handle<i::Script> script = factory->NewScript(source);
|
||||
i::ParseInfo info(isolate, *script);
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
|
||||
// The information we're checking is only produced when eager parsing.
|
||||
info.set_allow_lazy_parsing(false);
|
||||
flags.set_allow_lazy_parsing(false);
|
||||
i::ParseInfo info(isolate, flags);
|
||||
CHECK(i::parsing::ParseProgram(&info, script, isolate));
|
||||
CHECK(i::Rewriter::Rewrite(&info));
|
||||
info.ast_value_factory()->Internalize(isolate);
|
||||
@ -1121,9 +1145,11 @@ static void CheckParsesToNumber(const char* source) {
|
||||
|
||||
i::Handle<i::Script> script = factory->NewScript(source_code);
|
||||
|
||||
i::ParseInfo info(isolate, *script);
|
||||
info.set_allow_lazy_parsing(false);
|
||||
info.set_toplevel(true);
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
|
||||
flags.set_allow_lazy_parsing(false);
|
||||
flags.set_is_toplevel(true);
|
||||
i::ParseInfo info(isolate, flags);
|
||||
|
||||
CHECK(i::parsing::ParseProgram(&info, script, isolate));
|
||||
|
||||
@ -1431,8 +1457,11 @@ TEST(ScopePositions) {
|
||||
.ToHandleChecked();
|
||||
CHECK_EQ(source->length(), kProgramSize);
|
||||
i::Handle<i::Script> script = factory->NewScript(source);
|
||||
i::ParseInfo info(isolate, *script);
|
||||
info.set_language_mode(source_data[i].language_mode);
|
||||
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
|
||||
flags.set_outer_language_mode(source_data[i].language_mode);
|
||||
i::ParseInfo info(isolate, flags);
|
||||
i::parsing::ParseProgram(&info, script, isolate);
|
||||
CHECK_NOT_NULL(info.literal());
|
||||
|
||||
@ -1477,7 +1506,9 @@ TEST(DiscardFunctionBody) {
|
||||
i::Handle<i::String> source_code =
|
||||
factory->NewStringFromUtf8(i::CStrVector(source)).ToHandleChecked();
|
||||
i::Handle<i::Script> script = factory->NewScript(source_code);
|
||||
i::ParseInfo info(isolate, *script);
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
|
||||
i::ParseInfo info(isolate, flags);
|
||||
i::parsing::ParseProgram(&info, script, isolate);
|
||||
function = info.literal();
|
||||
CHECK_NOT_NULL(function);
|
||||
@ -1549,13 +1580,14 @@ void SetGlobalFlags(base::EnumSet<ParserFlag> flags) {
|
||||
i::FLAG_harmony_import_meta = flags.contains(kAllowHarmonyImportMeta);
|
||||
}
|
||||
|
||||
void SetParserFlags(i::PreParser* parser, base::EnumSet<ParserFlag> flags) {
|
||||
parser->set_allow_natives(flags.contains(kAllowNatives));
|
||||
parser->set_allow_harmony_private_methods(
|
||||
void SetParserFlags(i::UnoptimizedCompileFlags* compile_flags,
|
||||
base::EnumSet<ParserFlag> flags) {
|
||||
compile_flags->set_allow_natives_syntax(flags.contains(kAllowNatives));
|
||||
compile_flags->set_allow_harmony_private_methods(
|
||||
flags.contains(kAllowHarmonyPrivateMethods));
|
||||
parser->set_allow_harmony_dynamic_import(
|
||||
compile_flags->set_allow_harmony_dynamic_import(
|
||||
flags.contains(kAllowHarmonyDynamicImport));
|
||||
parser->set_allow_harmony_import_meta(
|
||||
compile_flags->set_allow_harmony_import_meta(
|
||||
flags.contains(kAllowHarmonyImportMeta));
|
||||
}
|
||||
|
||||
@ -1566,6 +1598,11 @@ void TestParserSyncWithFlags(i::Handle<i::String> source,
|
||||
bool ignore_error_msg = false) {
|
||||
i::Isolate* isolate = CcTest::i_isolate();
|
||||
i::Factory* factory = isolate->factory();
|
||||
i::UnoptimizedCompileFlags compile_flags =
|
||||
i::UnoptimizedCompileFlags::ForToplevelCompile(
|
||||
isolate, true, LanguageMode::kSloppy, REPLMode::kNo);
|
||||
SetParserFlags(&compile_flags, flags);
|
||||
compile_flags.set_is_module(is_module);
|
||||
|
||||
uintptr_t stack_limit = isolate->stack_guard()->real_climit();
|
||||
|
||||
@ -1574,15 +1611,14 @@ void TestParserSyncWithFlags(i::Handle<i::String> source,
|
||||
if (test_preparser) {
|
||||
std::unique_ptr<i::Utf16CharacterStream> stream(
|
||||
i::ScannerStream::For(isolate, source));
|
||||
i::Scanner scanner(stream.get(), is_module);
|
||||
i::Scanner scanner(stream.get(), compile_flags);
|
||||
i::Zone zone(isolate->allocator(), ZONE_NAME);
|
||||
i::AstValueFactory ast_value_factory(&zone, isolate->ast_string_constants(),
|
||||
HashSeed(isolate));
|
||||
i::PreParser preparser(&zone, &scanner, stack_limit, &ast_value_factory,
|
||||
&pending_error_handler,
|
||||
isolate->counters()->runtime_call_stats(),
|
||||
isolate->logger(), -1, is_module);
|
||||
SetParserFlags(&preparser, flags);
|
||||
isolate->logger(), compile_flags);
|
||||
scanner.Initialize();
|
||||
i::PreParser::PreParseResult result = preparser.PreParseProgram();
|
||||
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
|
||||
@ -1592,10 +1628,9 @@ void TestParserSyncWithFlags(i::Handle<i::String> source,
|
||||
i::FunctionLiteral* function;
|
||||
{
|
||||
SetGlobalFlags(flags);
|
||||
i::Handle<i::Script> script = factory->NewScript(source);
|
||||
i::ParseInfo info(isolate, *script);
|
||||
info.set_allow_lazy_parsing(flags.contains(kAllowLazy));
|
||||
if (is_module) info.set_module();
|
||||
i::Handle<i::Script> script =
|
||||
factory->NewScriptWithId(source, compile_flags.script_id());
|
||||
i::ParseInfo info(isolate, compile_flags);
|
||||
i::parsing::ParseProgram(&info, script, isolate);
|
||||
function = info.literal();
|
||||
}
|
||||
@ -3472,8 +3507,9 @@ TEST(InnerAssignment) {
|
||||
i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
|
||||
i::Handle<i::SharedFunctionInfo> shared =
|
||||
i::handle(f->shared(), isolate);
|
||||
info =
|
||||
std::unique_ptr<i::ParseInfo>(new i::ParseInfo(isolate, *shared));
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForFunctionCompile(isolate, *shared);
|
||||
info = std::make_unique<i::ParseInfo>(isolate, flags);
|
||||
CHECK(i::parsing::ParseFunction(info.get(), shared, isolate));
|
||||
} else {
|
||||
i::Handle<i::String> source =
|
||||
@ -3481,9 +3517,10 @@ TEST(InnerAssignment) {
|
||||
source->PrintOn(stdout);
|
||||
printf("\n");
|
||||
i::Handle<i::Script> script = factory->NewScript(source);
|
||||
info =
|
||||
std::unique_ptr<i::ParseInfo>(new i::ParseInfo(isolate, *script));
|
||||
info->set_allow_lazy_parsing(false);
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
|
||||
flags.set_allow_lazy_parsing(false);
|
||||
info = std::make_unique<i::ParseInfo>(isolate, flags);
|
||||
CHECK(i::parsing::ParseProgram(info.get(), script, isolate));
|
||||
}
|
||||
CHECK(i::Compiler::Analyze(info.get()));
|
||||
@ -3590,8 +3627,10 @@ TEST(MaybeAssignedParameters) {
|
||||
i::Handle<i::Object> o = v8::Utils::OpenHandle(*v);
|
||||
i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
|
||||
i::Handle<i::SharedFunctionInfo> shared = i::handle(f->shared(), isolate);
|
||||
info = std::unique_ptr<i::ParseInfo>(new i::ParseInfo(isolate, *shared));
|
||||
info->set_allow_lazy_parsing(allow_lazy);
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForFunctionCompile(isolate, *shared);
|
||||
flags.set_allow_lazy_parsing(allow_lazy);
|
||||
info = std::make_unique<i::ParseInfo>(isolate, flags);
|
||||
CHECK(i::parsing::ParseFunction(info.get(), shared, isolate));
|
||||
CHECK(i::Compiler::Analyze(info.get()));
|
||||
CHECK_NOT_NULL(info->literal());
|
||||
@ -3626,10 +3665,12 @@ static void TestMaybeAssigned(Input input, const char* variable, bool module,
|
||||
printf("\n");
|
||||
i::Handle<i::Script> script = factory->NewScript(string);
|
||||
|
||||
std::unique_ptr<i::ParseInfo> info;
|
||||
info = std::unique_ptr<i::ParseInfo>(new i::ParseInfo(isolate, *script));
|
||||
info->set_module(module);
|
||||
info->set_allow_lazy_parsing(allow_lazy_parsing);
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
|
||||
flags.set_is_module(module);
|
||||
flags.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::Compiler::Analyze(info.get()));
|
||||
@ -7382,8 +7423,10 @@ TEST(BasicImportExportParsing) {
|
||||
// Show that parsing as a module works
|
||||
{
|
||||
i::Handle<i::Script> script = factory->NewScript(source);
|
||||
i::ParseInfo info(isolate, *script);
|
||||
info.set_module();
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
|
||||
flags.set_is_module(true);
|
||||
i::ParseInfo info(isolate, flags);
|
||||
if (!i::parsing::ParseProgram(&info, script, isolate)) {
|
||||
i::Handle<i::JSObject> exception_handle(
|
||||
i::JSObject::cast(isolate->pending_exception()), isolate);
|
||||
@ -7405,7 +7448,9 @@ TEST(BasicImportExportParsing) {
|
||||
// And that parsing a script does not.
|
||||
{
|
||||
i::Handle<i::Script> script = factory->NewScript(source);
|
||||
i::ParseInfo info(isolate, *script);
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
|
||||
i::ParseInfo info(isolate, flags);
|
||||
CHECK(!i::parsing::ParseProgram(&info, script, isolate));
|
||||
isolate->clear_pending_exception();
|
||||
}
|
||||
@ -7442,8 +7487,10 @@ TEST(NamespaceExportParsing) {
|
||||
i::Handle<i::String> source =
|
||||
factory->NewStringFromAsciiChecked(kSources[i]);
|
||||
i::Handle<i::Script> script = factory->NewScript(source);
|
||||
i::ParseInfo info(isolate, *script);
|
||||
info.set_module();
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
|
||||
flags.set_is_module(true);
|
||||
i::ParseInfo info(isolate, flags);
|
||||
CHECK(i::parsing::ParseProgram(&info, script, isolate));
|
||||
}
|
||||
}
|
||||
@ -7537,8 +7584,10 @@ TEST(ImportExportParsingErrors) {
|
||||
factory->NewStringFromAsciiChecked(kErrorSources[i]);
|
||||
|
||||
i::Handle<i::Script> script = factory->NewScript(source);
|
||||
i::ParseInfo info(isolate, *script);
|
||||
info.set_module();
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
|
||||
flags.set_is_module(true);
|
||||
i::ParseInfo info(isolate, flags);
|
||||
CHECK(!i::parsing::ParseProgram(&info, script, isolate));
|
||||
isolate->clear_pending_exception();
|
||||
}
|
||||
@ -7573,8 +7622,10 @@ TEST(ModuleTopLevelFunctionDecl) {
|
||||
factory->NewStringFromAsciiChecked(kErrorSources[i]);
|
||||
|
||||
i::Handle<i::Script> script = factory->NewScript(source);
|
||||
i::ParseInfo info(isolate, *script);
|
||||
info.set_module();
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
|
||||
flags.set_is_module(true);
|
||||
i::ParseInfo info(isolate, flags);
|
||||
CHECK(!i::parsing::ParseProgram(&info, script, isolate));
|
||||
isolate->clear_pending_exception();
|
||||
}
|
||||
@ -7770,8 +7821,10 @@ TEST(ModuleParsingInternals) {
|
||||
"export {foob};";
|
||||
i::Handle<i::String> source = factory->NewStringFromAsciiChecked(kSource);
|
||||
i::Handle<i::Script> script = factory->NewScript(source);
|
||||
i::ParseInfo info(isolate, *script);
|
||||
info.set_module();
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
|
||||
flags.set_is_module(true);
|
||||
i::ParseInfo info(isolate, flags);
|
||||
CHECK(i::parsing::ParseProgram(&info, script, isolate));
|
||||
CHECK(i::Compiler::Analyze(&info));
|
||||
i::FunctionLiteral* func = info.literal();
|
||||
@ -8013,7 +8066,9 @@ void TestLanguageMode(const char* source,
|
||||
|
||||
i::Handle<i::Script> script =
|
||||
factory->NewScript(factory->NewStringFromAsciiChecked(source));
|
||||
i::ParseInfo info(isolate, *script);
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
|
||||
i::ParseInfo info(isolate, flags);
|
||||
i::parsing::ParseProgram(&info, script, isolate);
|
||||
CHECK_NOT_NULL(info.literal());
|
||||
CHECK_EQ(expected_language_mode, info.literal()->language_mode());
|
||||
@ -10794,7 +10849,9 @@ TEST(NoPessimisticContextAllocation) {
|
||||
printf("\n");
|
||||
|
||||
i::Handle<i::Script> script = factory->NewScript(source);
|
||||
i::ParseInfo info(isolate, *script);
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
|
||||
i::ParseInfo info(isolate, flags);
|
||||
|
||||
CHECK(i::parsing::ParseProgram(&info, script, isolate));
|
||||
CHECK(i::Compiler::Analyze(&info));
|
||||
@ -11354,9 +11411,10 @@ TEST(LexicalLoopVariable) {
|
||||
i::Handle<i::String> source =
|
||||
factory->NewStringFromUtf8(i::CStrVector(program)).ToHandleChecked();
|
||||
i::Handle<i::Script> script = factory->NewScript(source);
|
||||
i::ParseInfo info(isolate, *script);
|
||||
|
||||
info.set_allow_lazy_parsing(false);
|
||||
i::UnoptimizedCompileFlags flags =
|
||||
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
|
||||
flags.set_allow_lazy_parsing(false);
|
||||
i::ParseInfo info(isolate, flags);
|
||||
CHECK(i::parsing::ParseProgram(&info, script, isolate));
|
||||
CHECK(i::Rewriter::Rewrite(&info));
|
||||
CHECK(i::DeclarationScope::Analyze(&info));
|
||||
|
@ -80,7 +80,10 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
|
||||
v8::internal::Handle<v8::internal::Script> script =
|
||||
factory->NewScript(source.ToHandleChecked());
|
||||
v8::internal::ParseInfo info(i_isolate, *script);
|
||||
v8::internal::UnoptimizedCompileFlags flags =
|
||||
v8::internal::UnoptimizedCompileFlags::ForScriptCompile(i_isolate,
|
||||
*script);
|
||||
v8::internal::ParseInfo info(i_isolate, flags);
|
||||
if (!v8::internal::parsing::ParseProgram(&info, script, i_isolate)) {
|
||||
i_isolate->OptionalRescheduleException(true);
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "src/execution/off-thread-isolate.h"
|
||||
#include "src/handles/handles-inl.h"
|
||||
#include "src/handles/handles.h"
|
||||
#include "src/handles/maybe-handles.h"
|
||||
#include "src/heap/off-thread-factory-inl.h"
|
||||
#include "src/objects/fixed-array.h"
|
||||
#include "src/objects/script.h"
|
||||
@ -55,7 +56,10 @@ class OffThreadFactoryTest : public TestWithIsolateAndZone {
|
||||
public:
|
||||
OffThreadFactoryTest()
|
||||
: TestWithIsolateAndZone(),
|
||||
parse_info_(isolate()),
|
||||
parse_info_(isolate(), UnoptimizedCompileFlags::ForToplevelCompile(
|
||||
isolate(), true,
|
||||
construct_language_mode(FLAG_use_strict),
|
||||
REPLMode::kNo)),
|
||||
off_thread_isolate_(isolate(), parse_info_.zone()) {}
|
||||
|
||||
FunctionLiteral* ParseProgram(const char* source) {
|
||||
@ -68,8 +72,6 @@ class OffThreadFactoryTest : public TestWithIsolateAndZone {
|
||||
|
||||
parse_info_.set_character_stream(
|
||||
ScannerStream::ForTesting(utf16_source.data(), utf16_source.size()));
|
||||
parse_info_.set_toplevel();
|
||||
parse_info_.set_allow_lazy_parsing();
|
||||
|
||||
{
|
||||
DisallowHeapAllocation no_allocation;
|
||||
@ -78,7 +80,7 @@ class OffThreadFactoryTest : public TestWithIsolateAndZone {
|
||||
|
||||
Parser parser(parse_info());
|
||||
parser.InitializeEmptyScopeChain(parse_info());
|
||||
parser.ParseOnBackground(parse_info());
|
||||
parser.ParseOnBackground(parse_info(), 0, 0, kFunctionLiteralIdTopLevel);
|
||||
|
||||
CHECK(DeclarationScope::Analyze(parse_info()));
|
||||
}
|
||||
@ -88,7 +90,7 @@ class OffThreadFactoryTest : public TestWithIsolateAndZone {
|
||||
|
||||
script_ = parse_info_.CreateScript(off_thread_isolate(),
|
||||
off_thread_factory()->empty_string(),
|
||||
ScriptOriginOptions());
|
||||
kNullMaybeHandle, ScriptOriginOptions());
|
||||
|
||||
// Create the SFI list on the script so that SFI SetScript works.
|
||||
Handle<WeakFixedArray> infos = off_thread_factory()->NewWeakFixedArray(
|
||||
|
@ -56,8 +56,8 @@ Handle<SharedFunctionInfo> CreateSharedFunctionInfo(
|
||||
std::unique_ptr<ParseInfo> OuterParseInfoForShared(
|
||||
Isolate* isolate, Handle<SharedFunctionInfo> shared) {
|
||||
Script script = Script::cast(shared->script());
|
||||
std::unique_ptr<ParseInfo> result =
|
||||
std::make_unique<ParseInfo>(isolate, script);
|
||||
std::unique_ptr<ParseInfo> result = std::make_unique<ParseInfo>(
|
||||
isolate, i::UnoptimizedCompileFlags::ForScriptCompile(isolate, script));
|
||||
|
||||
// Create a character stream to simulate the parser having done so for the
|
||||
// to-level ParseProgram.
|
||||
|
Loading…
Reference in New Issue
Block a user