V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
preparsed-scope-data.h
1 // Copyright 2017 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_PREPARSED_SCOPE_DATA_H_
6 #define V8_PARSING_PREPARSED_SCOPE_DATA_H_
7 
8 #include "src/globals.h"
9 #include "src/handles.h"
10 #include "src/maybe-handles.h"
11 #include "src/zone/zone-chunk-list.h"
12 #include "src/zone/zone-containers.h"
13 
14 namespace v8 {
15 namespace internal {
16 
17 template <typename T>
18 class PodArray;
19 
20 class PreParser;
21 class PreParsedScopeData;
22 class ZonePreParsedScopeData;
23 
24 /*
25 
26  Skipping inner functions.
27 
28  Consider the following code:
29  (function eager_outer() {
30  function lazy_inner() {
31  let a;
32  function skip_me() { a; }
33  }
34 
35  return lazy_inner;
36  })();
37 
38  ... lazy_inner(); ...
39 
40  When parsing the code the first time, eager_outer is parsed and lazy_inner
41  (and everything inside it) is preparsed. When lazy_inner is called, we don't
42  want to parse or preparse skip_me again. Instead, we want to skip over it,
43  since it has already been preparsed once.
44 
45  In order to be able to do this, we need to store the information needed for
46  allocating the variables in lazy_inner when we preparse it, and then later do
47  scope allocation based on that data.
48 
49  We need the following data for each scope in lazy_inner's scope tree:
50  For each Variable:
51  - is_used
52  - maybe_assigned
53  - has_forced_context_allocation
54 
55  For each Scope:
56  - inner_scope_calls_eval_.
57 
58  ProducedPreParsedScopeData implements storing the above mentioned data and
59  ConsumedPreParsedScopeData implements restoring it (= setting the context
60  allocation status of the variables in a Scope (and its subscopes) based on the
61  data).
62 
63  */
64 
66  public:
67  class ByteData;
68 
69  // Create a PreParsedScopeDataBuilder object which will collect data as we
70  // parse.
72 
73  PreParsedScopeDataBuilder* parent() const { return parent_; }
74 
75  // For gathering the inner function data and splitting it up according to the
76  // laziness boundaries. Each lazy function gets its own
77  // ProducedPreParsedScopeData, and so do all lazy functions inside it.
79  public:
80  DataGatheringScope(DeclarationScope* function_scope, PreParser* preparser);
82 
83  private:
84  PreParser* preparser_;
85  PreParsedScopeDataBuilder* builder_;
86 
87  DISALLOW_COPY_AND_ASSIGN(DataGatheringScope);
88  };
89 
90  // Saves the information needed for allocating the Scope's (and its
91  // subscopes') variables.
92  void SaveScopeAllocationData(DeclarationScope* scope);
93 
94  // In some cases, PreParser cannot produce the same Scope structure as
95  // Parser. If it happens, we're unable to produce the data that would enable
96  // skipping the inner functions of that function.
97  void Bailout() {
98  bailed_out_ = true;
99 
100  // We don't need to call Bailout on existing / future children: the only way
101  // to try to retrieve their data is through calling Serialize on the parent,
102  // and if the parent is bailed out, it won't call Serialize on its children.
103  }
104 
105  bool bailed_out() const { return bailed_out_; }
106 
107 #ifdef DEBUG
108  bool ThisOrParentBailedOut() const {
109  if (bailed_out_) {
110  return true;
111  }
112  if (parent_ == nullptr) {
113  return false;
114  }
115  return parent_->ThisOrParentBailedOut();
116  }
117 #endif // DEBUG
118 
119  bool ContainsInnerFunctions() const;
120 
121  static bool ScopeNeedsData(Scope* scope);
122  static bool ScopeIsSkippableFunctionScope(Scope* scope);
123  void AddSkippableFunction(int start_position, int end_position,
124  int num_parameters, int num_inner_functions,
125  LanguageMode language_mode,
126  bool uses_super_property);
127 
128  private:
129  friend class BuilderProducedPreParsedScopeData;
130 
131  virtual MaybeHandle<PreParsedScopeData> Serialize(Isolate* isolate);
132  virtual ZonePreParsedScopeData* Serialize(Zone* zone);
133 
134  void SaveDataForScope(Scope* scope);
135  void SaveDataForVariable(Variable* var);
136  void SaveDataForInnerScopes(Scope* scope);
137 
138  PreParsedScopeDataBuilder* parent_;
139 
140  ByteData* byte_data_;
141  ZoneChunkList<PreParsedScopeDataBuilder*> data_for_inner_functions_;
142 
143  // Whether we've given up producing the data for this function.
144  bool bailed_out_;
145 
146  DISALLOW_COPY_AND_ASSIGN(PreParsedScopeDataBuilder);
147 };
148 
150  public:
151  // If there is data (if the Scope contains skippable inner functions), move
152  // the data into the heap and return a Handle to it; otherwise return a null
153  // MaybeHandle.
154  virtual MaybeHandle<PreParsedScopeData> Serialize(Isolate* isolate) = 0;
155 
156  // If there is data (if the Scope contains skippable inner functions), return
157  // an off-heap ZonePreParsedScopeData representing the data; otherwise
158  // return nullptr.
159  virtual ZonePreParsedScopeData* Serialize(Zone* zone) = 0;
160 
161  // Create a ProducedPreParsedScopeData which is a proxy for a previous
162  // produced PreParsedScopeData in zone.
164  Zone* zone);
165 
166  // Create a ProducedPreParsedScopeData which is a proxy for a previous
167  // produced PreParsedScopeData on the heap.
169  Zone* zone);
170 
171  // Create a ProducedPreParsedScopeData which is a proxy for a previous
172  // produced PreParsedScopeData in zone.
174  Zone* zone);
175 };
176 
178  public:
179  // Creates a ConsumedPreParsedScopeData representing the data of an on-heap
180  // PreParsedScopeData |data|.
181  static std::unique_ptr<ConsumedPreParsedScopeData> For(
182  Isolate* isolate, Handle<PreParsedScopeData> data);
183 
184  // Creates a ConsumedPreParsedScopeData representing the data of an off-heap
185  // ZonePreParsedScopeData |data|.
186  static std::unique_ptr<ConsumedPreParsedScopeData> For(
187  Zone* zone, ZonePreParsedScopeData* data);
188 
189  virtual ~ConsumedPreParsedScopeData() = default;
190 
191  virtual ProducedPreParsedScopeData* GetDataForSkippableFunction(
192  Zone* zone, int start_position, int* end_position, int* num_parameters,
193  int* num_inner_functions, bool* uses_super_property,
194  LanguageMode* language_mode) = 0;
195 
196  // Restores the information needed for allocating the Scope's (and its
197  // subscopes') variables.
198  virtual void RestoreScopeAllocationData(DeclarationScope* scope) = 0;
199 
200  protected:
201  ConsumedPreParsedScopeData() = default;
202 
203  private:
204  DISALLOW_COPY_AND_ASSIGN(ConsumedPreParsedScopeData);
205 };
206 
207 } // namespace internal
208 } // namespace v8
209 
210 #endif // V8_PARSING_PREPARSED_SCOPE_DATA_H_
Definition: libplatform.h:13