1 // Copyright 2016 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_PARSING_PARSE_INFO_H_ 6 #define V8_PARSING_PARSE_INFO_H_ 7 8 #include <memory> 9 10 #include "src/base/bit-field.h" 11 #include "src/base/export-template.h" 12 #include "src/base/logging.h" 13 #include "src/common/globals.h" 14 #include "src/handles/handles.h" 15 #include "src/objects/function-kind.h" 16 #include "src/objects/function-syntax-kind.h" 17 #include "src/objects/script.h" 18 #include "src/parsing/pending-compilation-error-handler.h" 19 #include "src/parsing/preparse-data.h" 20 21 namespace v8 { 22 23 class Extension; 24 25 namespace internal { 26 27 class AccountingAllocator; 28 class AstRawString; 29 class AstStringConstants; 30 class AstValueFactory; 31 class LazyCompileDispatcher; 32 class DeclarationScope; 33 class FunctionLiteral; 34 class RuntimeCallStats; 35 class Logger; 36 class SourceRangeMap; 37 class Utf16CharacterStream; 38 class Zone; 39 40 // The flags for a parse + unoptimized compile operation. 41 #define FLAG_FIELDS(V, _) \ 42 V(is_toplevel, bool, 1, _) \ 43 V(is_eager, bool, 1, _) \ 44 V(is_eval, bool, 1, _) \ 45 V(outer_language_mode, LanguageMode, 1, _) \ 46 V(parse_restriction, ParseRestriction, 1, _) \ 47 V(is_module, bool, 1, _) \ 48 V(allow_lazy_parsing, bool, 1, _) \ 49 V(is_lazy_compile, bool, 1, _) \ 50 V(collect_type_profile, bool, 1, _) \ 51 V(coverage_enabled, bool, 1, _) \ 52 V(block_coverage_enabled, bool, 1, _) \ 53 V(is_asm_wasm_broken, bool, 1, _) \ 54 V(class_scope_has_private_brand, bool, 1, _) \ 55 V(private_name_lookup_skips_outer_class, bool, 1, _) \ 56 V(requires_instance_members_initializer, bool, 1, _) \ 57 V(has_static_private_methods_or_accessors, bool, 1, _) \ 58 V(might_always_opt, bool, 1, _) \ 59 V(allow_natives_syntax, bool, 1, _) \ 60 V(allow_lazy_compile, bool, 1, _) \ 61 V(post_parallel_compile_tasks_for_eager_toplevel, bool, 1, _) \ 62 V(post_parallel_compile_tasks_for_lazy, bool, 1, _) \ 63 V(collect_source_positions, bool, 1, _) \ 64 V(is_repl_mode, bool, 1, _) 65 66 class V8_EXPORT_PRIVATE UnoptimizedCompileFlags { 67 public: 68 // Set-up flags for a toplevel compilation. 69 static UnoptimizedCompileFlags ForToplevelCompile(Isolate* isolate, 70 bool is_user_javascript, 71 LanguageMode language_mode, 72 REPLMode repl_mode, 73 ScriptType type, bool lazy); 74 75 // Set-up flags for a compiling a particular function (either a lazy compile 76 // or a recompile). 77 static UnoptimizedCompileFlags ForFunctionCompile(Isolate* isolate, 78 SharedFunctionInfo shared); 79 80 // Set-up flags for a full compilation of a given script. 81 static UnoptimizedCompileFlags ForScriptCompile(Isolate* isolate, 82 Script script); 83 84 // Set-up flags for a parallel toplevel function compilation, based on the 85 // flags of an existing toplevel compilation. 86 static UnoptimizedCompileFlags ForToplevelFunction( 87 const UnoptimizedCompileFlags toplevel_flags, 88 const FunctionLiteral* literal); 89 90 // Create flags for a test. 91 static UnoptimizedCompileFlags ForTest(Isolate* isolate); 92 93 #define FLAG_GET_SET(NAME, TYPE, SIZE, _) \ 94 TYPE NAME() const { return BitFields::NAME::decode(flags_); } \ 95 UnoptimizedCompileFlags& set_##NAME(TYPE value) { \ 96 flags_ = BitFields::NAME::update(flags_, value); \ 97 return *this; \ 98 } 99 FLAG_FIELDS(FLAG_GET_SET,_)100 FLAG_FIELDS(FLAG_GET_SET, _) 101 102 int script_id() const { return script_id_; } set_script_id(int value)103 UnoptimizedCompileFlags& set_script_id(int value) { 104 script_id_ = value; 105 return *this; 106 } 107 function_kind()108 FunctionKind function_kind() const { return function_kind_; } set_function_kind(FunctionKind value)109 UnoptimizedCompileFlags& set_function_kind(FunctionKind value) { 110 function_kind_ = value; 111 return *this; 112 } 113 function_syntax_kind()114 FunctionSyntaxKind function_syntax_kind() const { 115 return function_syntax_kind_; 116 } set_function_syntax_kind(FunctionSyntaxKind value)117 UnoptimizedCompileFlags& set_function_syntax_kind(FunctionSyntaxKind value) { 118 function_syntax_kind_ = value; 119 return *this; 120 } 121 parsing_while_debugging()122 ParsingWhileDebugging parsing_while_debugging() const { 123 return parsing_while_debugging_; 124 } set_parsing_while_debugging(ParsingWhileDebugging value)125 UnoptimizedCompileFlags& set_parsing_while_debugging( 126 ParsingWhileDebugging value) { 127 parsing_while_debugging_ = value; 128 return *this; 129 } 130 131 private: 132 struct BitFields { 133 DEFINE_BIT_FIELDS(FLAG_FIELDS) 134 }; 135 136 UnoptimizedCompileFlags(Isolate* isolate, int script_id); 137 138 // Set function info flags based on those in either FunctionLiteral or 139 // SharedFunctionInfo |function| 140 template <typename T> 141 void SetFlagsFromFunction(T function); 142 void SetFlagsForToplevelCompile(bool is_collecting_type_profile, 143 bool is_user_javascript, 144 LanguageMode language_mode, 145 REPLMode repl_mode, ScriptType type, 146 bool lazy); 147 void SetFlagsForFunctionFromScript(Script script); 148 149 uint32_t flags_; 150 int script_id_; 151 FunctionKind function_kind_; 152 FunctionSyntaxKind function_syntax_kind_; 153 ParsingWhileDebugging parsing_while_debugging_; 154 }; 155 156 #undef FLAG_FIELDS 157 class ParseInfo; 158 159 // The mutable state for a parse + unoptimized compile operation. 160 class V8_EXPORT_PRIVATE UnoptimizedCompileState { 161 public: pending_error_handler()162 const PendingCompilationErrorHandler* pending_error_handler() const { 163 return &pending_error_handler_; 164 } pending_error_handler()165 PendingCompilationErrorHandler* pending_error_handler() { 166 return &pending_error_handler_; 167 } 168 169 private: 170 PendingCompilationErrorHandler pending_error_handler_; 171 }; 172 173 // A container for ParseInfo fields that are reusable across multiple parses and 174 // unoptimized compiles. 175 // 176 // Note that this is different from UnoptimizedCompileState, which has mutable 177 // state for a single compilation that is not reusable across multiple 178 // compilations. 179 class V8_EXPORT_PRIVATE ReusableUnoptimizedCompileState { 180 public: 181 explicit ReusableUnoptimizedCompileState(Isolate* isolate); 182 explicit ReusableUnoptimizedCompileState(LocalIsolate* isolate); 183 ~ReusableUnoptimizedCompileState(); 184 185 // The AstRawString Zone stores the AstRawStrings in the AstValueFactory that 186 // can be reused across parses, and thereforce should stay alive between 187 // parses that reuse this reusable state and its AstValueFactory. ast_raw_string_zone()188 Zone* ast_raw_string_zone() { return &ast_raw_string_zone_; } 189 190 // The single parse Zone stores the data of a single parse, and can be cleared 191 // when that parse completes. 192 // 193 // This is in "reusable" state despite being wiped per-parse, because it 194 // allows us to reuse the Zone itself, and e.g. keep the same single parse 195 // Zone pointer in the AstValueFactory. single_parse_zone()196 Zone* single_parse_zone() { return &single_parse_zone_; } 197 NotifySingleParseCompleted()198 void NotifySingleParseCompleted() { single_parse_zone_.Reset(); } 199 ast_value_factory()200 AstValueFactory* ast_value_factory() const { 201 return ast_value_factory_.get(); 202 } hash_seed()203 uint64_t hash_seed() const { return hash_seed_; } allocator()204 AccountingAllocator* allocator() const { return allocator_; } ast_string_constants()205 const AstStringConstants* ast_string_constants() const { 206 return ast_string_constants_; 207 } logger()208 Logger* logger() const { return logger_; } dispatcher()209 LazyCompileDispatcher* dispatcher() const { return dispatcher_; } 210 211 private: 212 uint64_t hash_seed_; 213 AccountingAllocator* allocator_; 214 Logger* logger_; 215 LazyCompileDispatcher* dispatcher_; 216 const AstStringConstants* ast_string_constants_; 217 Zone ast_raw_string_zone_; 218 Zone single_parse_zone_; 219 std::unique_ptr<AstValueFactory> ast_value_factory_; 220 }; 221 222 // A container for the inputs, configuration options, and outputs of parsing. 223 class V8_EXPORT_PRIVATE ParseInfo { 224 public: 225 ParseInfo(Isolate* isolate, const UnoptimizedCompileFlags flags, 226 UnoptimizedCompileState* state, 227 ReusableUnoptimizedCompileState* reusable_state); 228 ParseInfo(LocalIsolate* isolate, const UnoptimizedCompileFlags flags, 229 UnoptimizedCompileState* state, 230 ReusableUnoptimizedCompileState* reusable_state, 231 uintptr_t stack_limit); 232 233 ~ParseInfo(); 234 235 template <typename IsolateT> 236 EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) 237 Handle<Script> CreateScript(IsolateT* isolate, Handle<String> source, 238 MaybeHandle<FixedArray> maybe_wrapped_arguments, 239 ScriptOriginOptions origin_options, 240 NativesFlag natives = NOT_NATIVES_CODE); 241 zone()242 Zone* zone() const { return reusable_state_->single_parse_zone(); } 243 flags()244 const UnoptimizedCompileFlags& flags() const { return flags_; } 245 246 // Getters for reusable state. hash_seed()247 uint64_t hash_seed() const { return reusable_state_->hash_seed(); } allocator()248 AccountingAllocator* allocator() const { 249 return reusable_state_->allocator(); 250 } ast_string_constants()251 const AstStringConstants* ast_string_constants() const { 252 return reusable_state_->ast_string_constants(); 253 } logger()254 Logger* logger() const { return reusable_state_->logger(); } dispatcher()255 LazyCompileDispatcher* dispatcher() const { 256 return reusable_state_->dispatcher(); 257 } state()258 const UnoptimizedCompileState* state() const { return state_; } 259 260 // Getters for state. pending_error_handler()261 PendingCompilationErrorHandler* pending_error_handler() { 262 return state_->pending_error_handler(); 263 } 264 265 // Accessors for per-thread state. stack_limit()266 uintptr_t stack_limit() const { return stack_limit_; } runtime_call_stats()267 RuntimeCallStats* runtime_call_stats() const { return runtime_call_stats_; } 268 269 // Accessor methods for output flags. allow_eval_cache()270 bool allow_eval_cache() const { return allow_eval_cache_; } set_allow_eval_cache(bool value)271 void set_allow_eval_cache(bool value) { allow_eval_cache_ = value; } 272 273 #if V8_ENABLE_WEBASSEMBLY contains_asm_module()274 bool contains_asm_module() const { return contains_asm_module_; } set_contains_asm_module(bool value)275 void set_contains_asm_module(bool value) { contains_asm_module_ = value; } 276 #endif // V8_ENABLE_WEBASSEMBLY 277 language_mode()278 LanguageMode language_mode() const { return language_mode_; } set_language_mode(LanguageMode value)279 void set_language_mode(LanguageMode value) { language_mode_ = value; } 280 character_stream()281 Utf16CharacterStream* character_stream() const { 282 return character_stream_.get(); 283 } 284 void set_character_stream( 285 std::unique_ptr<Utf16CharacterStream> character_stream); 286 void ResetCharacterStream(); 287 extension()288 v8::Extension* extension() const { return extension_; } set_extension(v8::Extension * extension)289 void set_extension(v8::Extension* extension) { extension_ = extension; } 290 set_consumed_preparse_data(std::unique_ptr<ConsumedPreparseData> data)291 void set_consumed_preparse_data(std::unique_ptr<ConsumedPreparseData> data) { 292 consumed_preparse_data_.swap(data); 293 } consumed_preparse_data()294 ConsumedPreparseData* consumed_preparse_data() { 295 return consumed_preparse_data_.get(); 296 } 297 script_scope()298 DeclarationScope* script_scope() const { return script_scope_; } set_script_scope(DeclarationScope * script_scope)299 void set_script_scope(DeclarationScope* script_scope) { 300 script_scope_ = script_scope; 301 } 302 ast_value_factory()303 AstValueFactory* ast_value_factory() const { 304 return reusable_state_->ast_value_factory(); 305 } 306 function_name()307 const AstRawString* function_name() const { return function_name_; } set_function_name(const AstRawString * function_name)308 void set_function_name(const AstRawString* function_name) { 309 function_name_ = function_name; 310 } 311 literal()312 FunctionLiteral* literal() const { return literal_; } set_literal(FunctionLiteral * literal)313 void set_literal(FunctionLiteral* literal) { literal_ = literal; } 314 315 DeclarationScope* scope() const; 316 parameters_end_pos()317 int parameters_end_pos() const { return parameters_end_pos_; } set_parameters_end_pos(int parameters_end_pos)318 void set_parameters_end_pos(int parameters_end_pos) { 319 parameters_end_pos_ = parameters_end_pos; 320 } 321 is_wrapped_as_function()322 bool is_wrapped_as_function() const { 323 return flags().function_syntax_kind() == FunctionSyntaxKind::kWrapped; 324 } 325 max_function_literal_id()326 int max_function_literal_id() const { return max_function_literal_id_; } set_max_function_literal_id(int max_function_literal_id)327 void set_max_function_literal_id(int max_function_literal_id) { 328 max_function_literal_id_ = max_function_literal_id; 329 } 330 331 void AllocateSourceRangeMap(); source_range_map()332 SourceRangeMap* source_range_map() const { return source_range_map_; } set_source_range_map(SourceRangeMap * source_range_map)333 void set_source_range_map(SourceRangeMap* source_range_map) { 334 source_range_map_ = source_range_map; 335 } 336 337 void CheckFlagsForFunctionFromScript(Script script); 338 339 private: 340 ParseInfo(const UnoptimizedCompileFlags flags, UnoptimizedCompileState* state, 341 ReusableUnoptimizedCompileState* reusable_state, 342 uintptr_t stack_limit, RuntimeCallStats* runtime_call_stats); 343 344 void CheckFlagsForToplevelCompileFromScript(Script script, 345 bool is_collecting_type_profile); 346 347 //------------- Inputs to parsing and scope analysis ----------------------- 348 const UnoptimizedCompileFlags flags_; 349 UnoptimizedCompileState* state_; 350 ReusableUnoptimizedCompileState* reusable_state_; 351 352 v8::Extension* extension_; 353 DeclarationScope* script_scope_; 354 uintptr_t stack_limit_; 355 int parameters_end_pos_; 356 int max_function_literal_id_; 357 358 //----------- Inputs+Outputs of parsing and scope analysis ----------------- 359 std::unique_ptr<Utf16CharacterStream> character_stream_; 360 std::unique_ptr<ConsumedPreparseData> consumed_preparse_data_; 361 const AstRawString* function_name_; 362 RuntimeCallStats* runtime_call_stats_; 363 SourceRangeMap* source_range_map_; // Used when block coverage is enabled. 364 365 //----------- Output of parsing and scope analysis ------------------------ 366 FunctionLiteral* literal_; 367 bool allow_eval_cache_ : 1; 368 #if V8_ENABLE_WEBASSEMBLY 369 bool contains_asm_module_ : 1; 370 #endif // V8_ENABLE_WEBASSEMBLY 371 LanguageMode language_mode_ : 1; 372 }; 373 374 } // namespace internal 375 } // namespace v8 376 377 #endif // V8_PARSING_PARSE_INFO_H_ 378