| // 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_ |