// 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 #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 LazyCompileDispatcher; class DeclarationScope; class FunctionLiteral; class RuntimeCallStats; class V8FileLogger; 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(is_reparse, 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(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(private_name_lookup_skips_outer_class, bool, 1, _) \ V(requires_instance_members_initializer, bool, 1, _) \ V(has_static_private_methods_or_accessors, bool, 1, _) \ V(might_always_turbofan, bool, 1, _) \ V(allow_natives_syntax, bool, 1, _) \ V(allow_lazy_compile, bool, 1, _) \ V(post_parallel_compile_tasks_for_eager_toplevel, bool, 1, _) \ V(post_parallel_compile_tasks_for_lazy, bool, 1, _) \ V(collect_source_positions, 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, ScriptType type, bool lazy); // 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; } ParsingWhileDebugging parsing_while_debugging() const { return parsing_while_debugging_; } UnoptimizedCompileFlags& set_parsing_while_debugging( ParsingWhileDebugging value) { parsing_while_debugging_ = 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 void SetFlagsFromFunction(T function); void SetFlagsForToplevelCompile(bool is_user_javascript, LanguageMode language_mode, REPLMode repl_mode, ScriptType type, bool lazy); void SetFlagsForFunctionFromScript(Script script); uint32_t flags_; int script_id_; FunctionKind function_kind_; FunctionSyntaxKind function_syntax_kind_; ParsingWhileDebugging parsing_while_debugging_; }; #undef FLAG_FIELDS class ParseInfo; // The mutable state for a parse + unoptimized compile operation. class V8_EXPORT_PRIVATE UnoptimizedCompileState { public: const PendingCompilationErrorHandler* pending_error_handler() const { return &pending_error_handler_; } PendingCompilationErrorHandler* pending_error_handler() { return &pending_error_handler_; } private: PendingCompilationErrorHandler pending_error_handler_; }; // A container for ParseInfo fields that are reusable across multiple parses and // unoptimized compiles. // // Note that this is different from UnoptimizedCompileState, which has mutable // state for a single compilation that is not reusable across multiple // compilations. class V8_EXPORT_PRIVATE ReusableUnoptimizedCompileState { public: explicit ReusableUnoptimizedCompileState(Isolate* isolate); explicit ReusableUnoptimizedCompileState(LocalIsolate* isolate); ~ReusableUnoptimizedCompileState(); // The AstRawString Zone stores the AstRawStrings in the AstValueFactory that // can be reused across parses, and thereforce should stay alive between // parses that reuse this reusable state and its AstValueFactory. Zone* ast_raw_string_zone() { return &ast_raw_string_zone_; } // The single parse Zone stores the data of a single parse, and can be cleared // when that parse completes. // // This is in "reusable" state despite being wiped per-parse, because it // allows us to reuse the Zone itself, and e.g. keep the same single parse // Zone pointer in the AstValueFactory. Zone* single_parse_zone() { return &single_parse_zone_; } void NotifySingleParseCompleted() { single_parse_zone_.Reset(); } AstValueFactory* ast_value_factory() const { return ast_value_factory_.get(); } uint64_t hash_seed() const { return hash_seed_; } AccountingAllocator* allocator() const { return allocator_; } const AstStringConstants* ast_string_constants() const { return ast_string_constants_; } // TODO(cbruni): Switch this back to the main logger. V8FileLogger* v8_file_logger() const { return v8_file_logger_; } LazyCompileDispatcher* dispatcher() const { return dispatcher_; } private: uint64_t hash_seed_; AccountingAllocator* allocator_; V8FileLogger* v8_file_logger_; LazyCompileDispatcher* dispatcher_; const AstStringConstants* ast_string_constants_; Zone ast_raw_string_zone_; Zone single_parse_zone_; std::unique_ptr ast_value_factory_; }; // 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, ReusableUnoptimizedCompileState* reusable_state); ParseInfo(LocalIsolate* isolate, const UnoptimizedCompileFlags flags, UnoptimizedCompileState* state, ReusableUnoptimizedCompileState* reusable_state, uintptr_t stack_limit); ~ParseInfo(); template EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) Handle