V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
preparsed-scope-data-impl.h
1 // Copyright 2018 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_IMPL_H_
6 #define V8_PARSING_PREPARSED_SCOPE_DATA_IMPL_H_
7 
8 #include "src/parsing/preparsed-scope-data.h"
9 
10 #include "src/assert-scope.h"
11 
12 namespace v8 {
13 namespace internal {
14 
15 // Classes which are internal to prepared-scope-data.cc, but are exposed in
16 // a header for tests.
17 
19 #ifdef DEBUG
20  static constexpr int kMagicValue = 0xC0DE0DE;
21 
22  static constexpr size_t kUint32Size = 5;
23  static constexpr size_t kUint8Size = 2;
24  static constexpr size_t kQuarterMarker = 0;
25  static constexpr size_t kPlaceholderSize = kUint32Size;
26 #else
27  static constexpr size_t kUint32Size = 4;
28  static constexpr size_t kUint8Size = 1;
29  static constexpr size_t kPlaceholderSize = 0;
30 #endif
31 
32  static const size_t kSkippableFunctionDataSize =
33  4 * kUint32Size + 1 * kUint8Size;
34 };
35 
37  : public ZoneObject,
39  public:
40  explicit ByteData(Zone* zone)
41  : free_quarters_in_last_byte_(0), backing_store_(zone) {}
42  void WriteUint32(uint32_t data);
43  void WriteUint8(uint8_t data);
44  void WriteQuarter(uint8_t data);
45 
46 #ifdef DEBUG
47  // For overwriting previously written data at position 0.
48  void OverwriteFirstUint32(uint32_t data);
49 #endif
50 
51  Handle<PodArray<uint8_t>> Serialize(Isolate* isolate);
52 
53  size_t size() const { return backing_store_.size(); }
54 
55  ZoneChunkList<uint8_t>::iterator begin() { return backing_store_.begin(); }
56 
57  ZoneChunkList<uint8_t>::iterator end() { return backing_store_.end(); }
58 
59  private:
60  uint8_t free_quarters_in_last_byte_;
61  ZoneChunkList<uint8_t> backing_store_;
62 };
63 
64 template <class Data>
66  public:
68  public:
69  ByteData() {}
70 
71  // Reading from the ByteData is only allowed when a ReadingScope is on the
72  // stack. This ensures that we have a DisallowHeapAllocation in place
73  // whenever ByteData holds a raw pointer into the heap.
74  class ReadingScope {
75  public:
76  ReadingScope(ByteData* consumed_data, Data data)
77  : consumed_data_(consumed_data) {
78  consumed_data->data_ = data;
79 #ifdef DEBUG
80  consumed_data->has_data_ = true;
81 #endif
82  }
84  : ReadingScope(parent->scope_data_.get(), parent->GetScopeData()) {}
85  ~ReadingScope() {
86 #ifdef DEBUG
87  consumed_data_->has_data_ = false;
88 #endif
89  }
90 
91  private:
92  ByteData* consumed_data_;
93  DISALLOW_HEAP_ALLOCATION(no_gc);
94  };
95 
96  void SetPosition(int position) { index_ = position; }
97 
98  size_t RemainingBytes() const {
99  DCHECK(has_data_);
100  return data_.length() - index_;
101  }
102 
103  int32_t ReadUint32() {
104  DCHECK(has_data_);
105  DCHECK_GE(RemainingBytes(), kUint32Size);
106  // Check that there indeed is an integer following.
107  DCHECK_EQ(data_.get(index_++), kUint32Size);
108  int32_t result = 0;
109  byte* p = reinterpret_cast<byte*>(&result);
110  for (int i = 0; i < 4; ++i) {
111  *p++ = data_.get(index_++);
112  }
113  stored_quarters_ = 0;
114  return result;
115  }
116 
117  uint8_t ReadUint8() {
118  DCHECK(has_data_);
119  DCHECK_GE(RemainingBytes(), kUint8Size);
120  // Check that there indeed is a byte following.
121  DCHECK_EQ(data_.get(index_++), kUint8Size);
122  stored_quarters_ = 0;
123  return data_.get(index_++);
124  }
125 
126  uint8_t ReadQuarter() {
127  DCHECK(has_data_);
128  if (stored_quarters_ == 0) {
129  DCHECK_GE(RemainingBytes(), kUint8Size);
130  // Check that there indeed are quarters following.
131  DCHECK_EQ(data_.get(index_++), kQuarterMarker);
132  stored_byte_ = data_.get(index_++);
133  stored_quarters_ = 4;
134  }
135  // Read the first 2 bits from stored_byte_.
136  uint8_t result = (stored_byte_ >> 6) & 3;
137  DCHECK_LE(result, 3);
138  --stored_quarters_;
139  stored_byte_ <<= 2;
140  return result;
141  }
142 
143  private:
144  Data data_ = {};
145  int index_ = 0;
146  uint8_t stored_quarters_ = 0;
147  uint8_t stored_byte_ = 0;
148 #ifdef DEBUG
149  bool has_data_ = false;
150 #endif
151  };
152 
153  BaseConsumedPreParsedScopeData()
154  : scope_data_(new ByteData()), child_index_(0) {}
155 
156  virtual Data GetScopeData() = 0;
157 
158  virtual ProducedPreParsedScopeData* GetChildData(Zone* zone,
159  int child_index) = 0;
160 
161  ProducedPreParsedScopeData* GetDataForSkippableFunction(
162  Zone* zone, int start_position, int* end_position, int* num_parameters,
163  int* num_inner_functions, bool* uses_super_property,
164  LanguageMode* language_mode) final;
165 
166  void RestoreScopeAllocationData(DeclarationScope* scope) final;
167 
168 #ifdef DEBUG
169  void VerifyDataStart();
170 #endif
171 
172  private:
173  void RestoreData(Scope* scope);
174  void RestoreDataForVariable(Variable* var);
175  void RestoreDataForInnerScopes(Scope* scope);
176 
177  std::unique_ptr<ByteData> scope_data_;
178  // When consuming the data, these indexes point to the data we're going to
179  // consume next.
180  int child_index_;
181 
182  DISALLOW_COPY_AND_ASSIGN(BaseConsumedPreParsedScopeData);
183 };
184 
185 // Implementation of ConsumedPreParsedScopeData for on-heap data.
187  : public BaseConsumedPreParsedScopeData<PodArray<uint8_t>> {
188  public:
191 
192  PodArray<uint8_t> GetScopeData() final;
193  ProducedPreParsedScopeData* GetChildData(Zone* zone, int child_index) final;
194 
195  private:
196  Isolate* isolate_;
198 };
199 
200 // Wraps a ZoneVector<uint8_t> to have with functions named the same as
201 // PodArray<uint8_t>.
203  public:
204  ZoneVectorWrapper() = default;
205  explicit ZoneVectorWrapper(ZoneVector<uint8_t>* data) : data_(data) {}
206 
207  int length() const { return static_cast<int>(data_->size()); }
208 
209  uint8_t get(int index) const { return data_->at(index); }
210 
211  private:
212  ZoneVector<uint8_t>* data_ = nullptr;
213 };
214 
215 // A serialized PreParsedScopeData in zone memory (as apposed to being on-heap).
217  public:
219  ZoneChunkList<uint8_t>::iterator byte_data_begin,
220  ZoneChunkList<uint8_t>::iterator byte_data_end,
221  int child_length);
222 
223  Handle<PreParsedScopeData> Serialize(Isolate* isolate);
224 
225  int child_length() const { return static_cast<int>(children_.size()); }
226 
227  ZonePreParsedScopeData* get_child(int index) { return children_[index]; }
228 
229  void set_child(int index, ZonePreParsedScopeData* child) {
230  children_[index] = child;
231  }
232 
233  ZoneVector<uint8_t>* byte_data() { return &byte_data_; }
234 
235  private:
236  ZoneVector<uint8_t> byte_data_;
238 
239  DISALLOW_COPY_AND_ASSIGN(ZonePreParsedScopeData);
240 };
241 
242 // Implementation of ConsumedPreParsedScopeData for PreParsedScopeData
243 // serialized into zone memory.
245  : public BaseConsumedPreParsedScopeData<ZoneVectorWrapper> {
246  public:
248 
249  ZoneVectorWrapper GetScopeData() final;
250  ProducedPreParsedScopeData* GetChildData(Zone* zone, int child_index) final;
251 
252  private:
253  ZonePreParsedScopeData* data_;
254  ZoneVectorWrapper scope_data_wrapper_;
255 };
256 
257 } // namespace internal
258 } // namespace v8
259 
260 #endif // V8_PARSING_PREPARSED_SCOPE_DATA_IMPL_H_
Definition: libplatform.h:13
Definition: v8.h:963