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