blob: d99ddcda89cbb32a62d20088ff662413ee6838af [file] [log] [blame]
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_PARSING_PARSE_INFO_H_
#define V8_PARSING_PARSE_INFO_H_
#include <map>
#include <memory>
#include <vector>
#include "include/v8.h"
#include "src/base/bit-field.h"
#include "src/base/export-template.h"
#include "src/base/logging.h"
#include "src/common/globals.h"
#include "src/handles/handles.h"
#include "src/objects/function-kind.h"
#include "src/objects/function-syntax-kind.h"
#include "src/objects/script.h"
#include "src/parsing/pending-compilation-error-handler.h"
#include "src/parsing/preparse-data.h"
namespace v8 {
class Extension;
namespace internal {
class AccountingAllocator;
class AstRawString;
class AstStringConstants;
class AstValueFactory;
class CompilerDispatcher;
class DeclarationScope;
class FunctionLiteral;
class RuntimeCallStats;
class Logger;
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_private_methods, bool, 1, _) \
V(is_oneshot_iife, bool, 1, _) \
V(collect_source_positions, bool, 1, _) \
V(allow_harmony_top_level_await, bool, 1, _) \
V(is_repl_mode, bool, 1, _) \
V(allow_harmony_logical_assignment, bool, 1, _)
class V8_EXPORT_PRIVATE UnoptimizedCompileFlags {
public:
// Set-up flags for a toplevel compilation.
static UnoptimizedCompileFlags ForToplevelCompile(Isolate* isolate,
bool is_user_javascript,
LanguageMode language_mode,
REPLMode repl_mode);
// Set-up flags for a compiling a particular function (either a lazy compile
// or a recompile).
static UnoptimizedCompileFlags ForFunctionCompile(Isolate* isolate,
SharedFunctionInfo shared);
// Set-up flags for a full compilation of a given script.
static UnoptimizedCompileFlags ForScriptCompile(Isolate* isolate,
Script script);
// Set-up flags for a parallel toplevel function compilation, based on the
// flags of an existing toplevel compilation.
static UnoptimizedCompileFlags ForToplevelFunction(
const UnoptimizedCompileFlags toplevel_flags,
const FunctionLiteral* literal);
// Create flags for a test.
static UnoptimizedCompileFlags ForTest(Isolate* isolate);
#define FLAG_GET_SET(NAME, TYPE, SIZE, _) \
TYPE NAME() const { return BitFields::NAME::decode(flags_); } \
UnoptimizedCompileFlags& set_##NAME(TYPE value) { \
flags_ = BitFields::NAME::update(flags_, value); \
return *this; \
}
FLAG_FIELDS(FLAG_GET_SET, _)
int script_id() const { return script_id_; }
UnoptimizedCompileFlags& set_script_id(int value) {
script_id_ = value;
return *this;
}
FunctionKind function_kind() const { return function_kind_; }
UnoptimizedCompileFlags& set_function_kind(FunctionKind value) {
function_kind_ = value;
return *this;
}
FunctionSyntaxKind function_syntax_kind() const {
return function_syntax_kind_;
}
UnoptimizedCompileFlags& set_function_syntax_kind(FunctionSyntaxKind value) {
function_syntax_kind_ = value;
return *this;
}
private:
struct BitFields {
DEFINE_BIT_FIELDS(FLAG_FIELDS)
};
UnoptimizedCompileFlags(Isolate* isolate, int script_id);
// Set function info flags based on those in either FunctionLiteral or
// SharedFunctionInfo |function|
template <typename T>
void SetFlagsFromFunction(T function);
void SetFlagsForToplevelCompile(bool is_collecting_type_profile,
bool is_user_javascript,
LanguageMode language_mode,
REPLMode repl_mode);
void SetFlagsForFunctionFromScript(Script script);
uint32_t flags_;
int script_id_;
FunctionKind function_kind_;
FunctionSyntaxKind function_syntax_kind_;
};
#undef FLAG_FIELDS
class ParseInfo;
// The mutable state for a parse + unoptimized compile operation.
class V8_EXPORT_PRIVATE UnoptimizedCompileState {
public:
explicit UnoptimizedCompileState(Isolate*);
UnoptimizedCompileState(const UnoptimizedCompileState& other) V8_NOEXCEPT;
class ParallelTasks {
public:
explicit ParallelTasks(CompilerDispatcher* compiler_dispatcher)
: dispatcher_(compiler_dispatcher) {
DCHECK_NOT_NULL(dispatcher_);
}
void Enqueue(ParseInfo* outer_parse_info, const AstRawString* function_name,
FunctionLiteral* literal);
using EnqueuedJobsIterator =
std::forward_list<std::pair<FunctionLiteral*, uintptr_t>>::iterator;
EnqueuedJobsIterator begin() { return enqueued_jobs_.begin(); }
EnqueuedJobsIterator end() { return enqueued_jobs_.end(); }
CompilerDispatcher* dispatcher() { return dispatcher_; }
private:
CompilerDispatcher* dispatcher_;
std::forward_list<std::pair<FunctionLiteral*, uintptr_t>> enqueued_jobs_;
};
uint64_t hash_seed() const { return hash_seed_; }
AccountingAllocator* allocator() const { return allocator_; }
const AstStringConstants* ast_string_constants() const {
return ast_string_constants_;
}
Logger* logger() const { return logger_; }
PendingCompilationErrorHandler* pending_error_handler() {
return &pending_error_handler_;
}
const PendingCompilationErrorHandler* pending_error_handler() const {
return &pending_error_handler_;
}
ParallelTasks* parallel_tasks() const { return parallel_tasks_.get(); }
private:
uint64_t hash_seed_;
AccountingAllocator* allocator_;
const AstStringConstants* ast_string_constants_;
PendingCompilationErrorHandler pending_error_handler_;
Logger* logger_;
std::unique_ptr<ParallelTasks> parallel_tasks_;
};
// A container for the inputs, configuration options, and outputs of parsing.
class V8_EXPORT_PRIVATE ParseInfo {
public:
ParseInfo(Isolate* isolate, const UnoptimizedCompileFlags flags,
UnoptimizedCompileState* state);
// Creates a new parse info based on parent top-level |outer_parse_info| for
// function |literal|.
static std::unique_ptr<ParseInfo> ForToplevelFunction(
const UnoptimizedCompileFlags flags,
UnoptimizedCompileState* compile_state, const FunctionLiteral* literal,
const AstRawString* function_name);
~ParseInfo();
template <typename LocalIsolate>
EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
Handle<Script> CreateScript(LocalIsolate* isolate, Handle<String> source,
MaybeHandle<FixedArray> maybe_wrapped_arguments,
ScriptOriginOptions origin_options,
NativesFlag natives = NOT_NATIVES_CODE);
// Either returns the ast-value-factory associcated with this ParseInfo, or
// creates and returns a new factory if none exists.
AstValueFactory* GetOrCreateAstValueFactory();
Zone* zone() const { return zone_.get(); }
const UnoptimizedCompileFlags& flags() const { return flags_; }
// Getters for state.
uint64_t hash_seed() const { return state_->hash_seed(); }
AccountingAllocator* allocator() const { return state_->allocator(); }
const AstStringConstants* ast_string_constants() const {
return state_->ast_string_constants();
}
Logger* logger() const { return state_->logger(); }
PendingCompilationErrorHandler* pending_error_handler() {
return state_->pending_error_handler();
}
UnoptimizedCompileState::ParallelTasks* parallel_tasks() const {
return state_->parallel_tasks();
}
const UnoptimizedCompileState* state() const { return state_; }
// Accessors for per-thread state.
uintptr_t stack_limit() const { return stack_limit_; }
RuntimeCallStats* runtime_call_stats() const { return runtime_call_stats_; }
void SetPerThreadState(uintptr_t stack_limit,
RuntimeCallStats* runtime_call_stats) {
stack_limit_ = stack_limit;
runtime_call_stats_ = runtime_call_stats;
}
// Accessor methods for output flags.
bool allow_eval_cache() const { return allow_eval_cache_; }
void set_allow_eval_cache(bool value) { allow_eval_cache_ = value; }
bool contains_asm_module() const { return contains_asm_module_; }
void set_contains_asm_module(bool value) { contains_asm_module_ = value; }
LanguageMode language_mode() const { return language_mode_; }
void set_language_mode(LanguageMode value) { language_mode_ = value; }
Utf16CharacterStream* character_stream() const {
return character_stream_.get();
}
void set_character_stream(
std::unique_ptr<Utf16CharacterStream> character_stream);
void ResetCharacterStream();
v8::Extension* extension() const { return extension_; }
void set_extension(v8::Extension* extension) { extension_ = extension; }
void set_consumed_preparse_data(std::unique_ptr<ConsumedPreparseData> data) {
consumed_preparse_data_.swap(data);
}
ConsumedPreparseData* consumed_preparse_data() {
return consumed_preparse_data_.get();
}
DeclarationScope* script_scope() const { return script_scope_; }
void set_script_scope(DeclarationScope* script_scope) {
script_scope_ = script_scope;
}
AstValueFactory* ast_value_factory() const {
DCHECK(ast_value_factory_.get());
return ast_value_factory_.get();
}
const AstRawString* function_name() const { return function_name_; }
void set_function_name(const AstRawString* function_name) {
function_name_ = function_name;
}
FunctionLiteral* literal() const { return literal_; }
void set_literal(FunctionLiteral* literal) { literal_ = literal; }
DeclarationScope* scope() const;
int parameters_end_pos() const { return parameters_end_pos_; }
void set_parameters_end_pos(int parameters_end_pos) {
parameters_end_pos_ = parameters_end_pos;
}
bool is_wrapped_as_function() const {
return flags().function_syntax_kind() == FunctionSyntaxKind::kWrapped;
}
int max_function_literal_id() const { return max_function_literal_id_; }
void set_max_function_literal_id(int max_function_literal_id) {
max_function_literal_id_ = max_function_literal_id;
}
void AllocateSourceRangeMap();
SourceRangeMap* source_range_map() const { return source_range_map_; }
void set_source_range_map(SourceRangeMap* source_range_map) {
source_range_map_ = source_range_map;
}
void CheckFlagsForFunctionFromScript(Script script);
private:
ParseInfo(const UnoptimizedCompileFlags flags,
UnoptimizedCompileState* state);
void CheckFlagsForToplevelCompileFromScript(Script script,
bool is_collecting_type_profile);
//------------- Inputs to parsing and scope analysis -----------------------
const UnoptimizedCompileFlags flags_;
UnoptimizedCompileState* state_;
std::unique_ptr<Zone> zone_;
v8::Extension* extension_;
DeclarationScope* script_scope_;
uintptr_t stack_limit_;
int parameters_end_pos_;
int max_function_literal_id_;
//----------- Inputs+Outputs of parsing and scope analysis -----------------
std::unique_ptr<Utf16CharacterStream> character_stream_;
std::unique_ptr<ConsumedPreparseData> consumed_preparse_data_;
std::unique_ptr<AstValueFactory> ast_value_factory_;
const AstRawString* function_name_;
RuntimeCallStats* runtime_call_stats_;
SourceRangeMap* source_range_map_; // Used when block coverage is enabled.
//----------- Output of parsing and scope analysis ------------------------
FunctionLiteral* literal_;
bool allow_eval_cache_ : 1;
bool contains_asm_module_ : 1;
LanguageMode language_mode_ : 1;
};
} // namespace internal
} // namespace v8
#endif // V8_PARSING_PARSE_INFO_H_