• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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