• 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 <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