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#include "src/parsing/preparse-data.h"
6
7#include <vector>
8
9#include "src/ast/scopes.h"
10#include "src/ast/variables.h"
11#include "src/base/logging.h"
12#include "src/base/platform/wrappers.h"
13#include "src/handles/handles.h"
14#include "src/objects/objects-inl.h"
15#include "src/objects/shared-function-info.h"
16#include "src/parsing/parser.h"
17#include "src/parsing/preparse-data-impl.h"
18#include "src/parsing/preparser.h"
19#include "src/roots/roots.h"
20#include "src/zone/zone-list-inl.h"  // crbug.com/v8/8816
21#include "src/zone/zone-utils.h"
22
23namespace v8 {
24namespace internal {
25
26namespace {
27
28using ScopeSloppyEvalCanExtendVarsBit = base::BitField8<bool, 0, 1>;
29using InnerScopeCallsEvalField = ScopeSloppyEvalCanExtendVarsBit::Next<bool, 1>;
30using NeedsPrivateNameContextChainRecalcField =
31    InnerScopeCallsEvalField::Next<bool, 1>;
32using ShouldSaveClassVariableIndexField =
33    NeedsPrivateNameContextChainRecalcField::Next<bool, 1>;
34
35using VariableMaybeAssignedField = base::BitField8<bool, 0, 1>;
36using VariableContextAllocatedField = VariableMaybeAssignedField::Next<bool, 1>;
37
38using HasDataField = base::BitField<bool, 0, 1>;
39using LengthEqualsParametersField = HasDataField::Next<bool, 1>;
40using NumberOfParametersField = LengthEqualsParametersField::Next<uint16_t, 16>;
41
42using LanguageField = base::BitField8<LanguageMode, 0, 1>;
43using UsesSuperField = LanguageField::Next<bool, 1>;
44STATIC_ASSERT(LanguageModeSize <= LanguageField::kNumValues);
45
46}  // namespace
47
48/*
49
50  Internal data format for the backing store of PreparseDataBuilder and
51  PreparseData::scope_data (on the heap):
52
53  (Skippable function data:)
54  ------------------------------------
55  | scope_data_start (debug only)    |
56  ------------------------------------
57  | data for inner function n        |
58  | ...                              |
59  ------------------------------------
60  | data for inner function 1        |
61  | ...                              |
62  ------------------------------------
63  (Scope allocation data:)             << scope_data_start points here in debug
64  ------------------------------------
65  magic value (debug only)
66  ------------------------------------
67  scope positions (debug only)
68  ------------------------------------
69  | scope type << only in debug      |
70  | eval                             |
71  | ----------------------           |
72  | | data for variables |           |
73  | | ...                |           |
74  | ----------------------           |
75  ------------------------------------
76  ------------------------------------
77  | data for inner scope m           | << but not for function scopes
78  | ...                              |
79  ------------------------------------
80  ...
81  ------------------------------------
82  | data for inner scope 1           |
83  | ...                              |
84  ------------------------------------
85
86  PreparseData::child_data is an array of PreparseData objects, one
87  for each skippable inner function.
88
89  ConsumedPreparseData wraps a PreparseData and reads data from it.
90
91 */
92
93PreparseDataBuilder::PreparseDataBuilder(Zone* zone,
94                                         PreparseDataBuilder* parent_builder,
95                                         std::vector<void*>* children_buffer)
96    : parent_(parent_builder),
97      byte_data_(),
98      children_buffer_(children_buffer),
99      function_scope_(nullptr),
100      function_length_(-1),
101      num_inner_functions_(0),
102      num_inner_with_data_(0),
103      bailed_out_(false),
104      has_data_(false) {}
105
106void PreparseDataBuilder::DataGatheringScope::Start(
107    DeclarationScope* function_scope) {
108  Zone* main_zone = preparser_->main_zone();
109  builder_ = main_zone->New<PreparseDataBuilder>(
110      main_zone, preparser_->preparse_data_builder(),
111      preparser_->preparse_data_builder_buffer());
112  preparser_->set_preparse_data_builder(builder_);
113  function_scope->set_preparse_data_builder(builder_);
114}
115
116void PreparseDataBuilder::DataGatheringScope::Close() {
117  PreparseDataBuilder* parent = builder_->parent_;
118  preparser_->set_preparse_data_builder(parent);
119  builder_->FinalizeChildren(preparser_->main_zone());
120
121  if (parent == nullptr) return;
122  if (!builder_->HasDataForParent()) return;
123  parent->AddChild(builder_);
124}
125
126void PreparseDataBuilder::ByteData::Start(std::vector<uint8_t>* buffer) {
127  DCHECK(!is_finalized_);
128  byte_data_ = buffer;
129  DCHECK_EQ(byte_data_->size(), 0);
130  DCHECK_EQ(index_, 0);
131}
132
133// This struct is just a type tag for Zone::NewArray<T>(size_t) call.
134struct RawPreparseData {};
135
136void PreparseDataBuilder::ByteData::Finalize(Zone* zone) {
137  uint8_t* raw_zone_data = zone->NewArray<uint8_t, RawPreparseData>(index_);
138  memcpy(raw_zone_data, byte_data_->data(), index_);
139  byte_data_->resize(0);
140  zone_byte_data_ = base::Vector<uint8_t>(raw_zone_data, index_);
141#ifdef DEBUG
142  is_finalized_ = true;
143#endif
144}
145
146void PreparseDataBuilder::ByteData::Reserve(size_t bytes) {
147  // Make sure we have at least {bytes} capacity left in the buffer_.
148  DCHECK_LE(length(), byte_data_->size());
149  size_t capacity = byte_data_->size() - length();
150  if (capacity >= bytes) return;
151  size_t delta = bytes - capacity;
152  byte_data_->insert(byte_data_->end(), delta, 0);
153}
154
155int PreparseDataBuilder::ByteData::length() const { return index_; }
156
157void PreparseDataBuilder::ByteData::Add(uint8_t byte) {
158  DCHECK_LE(0, index_);
159  DCHECK_LT(index_, byte_data_->size());
160  (*byte_data_)[index_++] = byte;
161}
162
163#ifdef DEBUG
164void PreparseDataBuilder::ByteData::WriteUint32(uint32_t data) {
165  DCHECK(!is_finalized_);
166  Add(kUint32Size);
167  Add(data & 0xFF);
168  Add((data >> 8) & 0xFF);
169  Add((data >> 16) & 0xFF);
170  Add((data >> 24) & 0xFF);
171  free_quarters_in_last_byte_ = 0;
172}
173
174void PreparseDataBuilder::ByteData::SaveCurrentSizeAtFirstUint32() {
175  int current_length = length();
176  index_ = 0;
177  CHECK_EQ(byte_data_->at(0), kUint32Size);
178  WriteUint32(current_length);
179  index_ = current_length;
180}
181#endif
182
183void PreparseDataBuilder::ByteData::WriteVarint32(uint32_t data) {
184#ifdef DEBUG
185  // Save expected item size in debug mode.
186  Add(kVarint32MinSize);
187#endif
188  // See ValueSerializer::WriteVarint.
189  do {
190    uint8_t next_byte = (data & 0x7F);
191    data >>= 7;
192    // Add continue bit.
193    if (data) next_byte |= 0x80;
194    Add(next_byte & 0xFF);
195  } while (data);
196#ifdef DEBUG
197  Add(kVarint32EndMarker);
198#endif
199  free_quarters_in_last_byte_ = 0;
200}
201
202void PreparseDataBuilder::ByteData::WriteUint8(uint8_t data) {
203  DCHECK(!is_finalized_);
204#ifdef DEBUG
205  // Save expected item size in debug mode.
206  Add(kUint8Size);
207#endif
208  Add(data);
209  free_quarters_in_last_byte_ = 0;
210}
211
212void PreparseDataBuilder::ByteData::WriteQuarter(uint8_t data) {
213  DCHECK(!is_finalized_);
214  DCHECK_LE(data, 3);
215  if (free_quarters_in_last_byte_ == 0) {
216#ifdef DEBUG
217    // Save a marker in debug mode.
218    Add(kQuarterMarker);
219#endif
220    Add(0);
221    free_quarters_in_last_byte_ = 3;
222  } else {
223    --free_quarters_in_last_byte_;
224  }
225
226  uint8_t shift_amount = free_quarters_in_last_byte_ * 2;
227  DCHECK_EQ(byte_data_->at(index_ - 1) & (3 << shift_amount), 0);
228  (*byte_data_)[index_ - 1] |= (data << shift_amount);
229}
230
231void PreparseDataBuilder::DataGatheringScope::SetSkippableFunction(
232    DeclarationScope* function_scope, int function_length,
233    int num_inner_functions) {
234  DCHECK_NULL(builder_->function_scope_);
235  builder_->function_scope_ = function_scope;
236  DCHECK_EQ(builder_->num_inner_functions_, 0);
237  builder_->function_length_ = function_length;
238  builder_->num_inner_functions_ = num_inner_functions;
239  builder_->parent_->has_data_ = true;
240}
241
242bool PreparseDataBuilder::HasInnerFunctions() const {
243  return !children_.empty();
244}
245
246bool PreparseDataBuilder::HasData() const { return !bailed_out_ && has_data_; }
247
248bool PreparseDataBuilder::HasDataForParent() const {
249  return HasData() || function_scope_ != nullptr;
250}
251
252void PreparseDataBuilder::AddChild(PreparseDataBuilder* child) {
253  DCHECK(!finalized_children_);
254  children_buffer_.Add(child);
255}
256
257void PreparseDataBuilder::FinalizeChildren(Zone* zone) {
258  DCHECK(!finalized_children_);
259  base::Vector<PreparseDataBuilder*> children =
260      CloneVector(zone, children_buffer_.ToConstVector());
261  children_buffer_.Rewind();
262  children_ = children;
263#ifdef DEBUG
264  finalized_children_ = true;
265#endif
266}
267
268bool PreparseDataBuilder::ScopeNeedsData(Scope* scope) {
269  if (scope->is_function_scope()) {
270    // Default constructors don't need data (they cannot contain inner functions
271    // defined by the user). Other functions do.
272    return !IsDefaultConstructor(scope->AsDeclarationScope()->function_kind());
273  }
274  if (!scope->is_hidden()) {
275    for (Variable* var : *scope->locals()) {
276      if (IsSerializableVariableMode(var->mode())) return true;
277    }
278  }
279  for (Scope* inner = scope->inner_scope(); inner != nullptr;
280       inner = inner->sibling()) {
281    if (ScopeNeedsData(inner)) return true;
282  }
283  return false;
284}
285
286bool PreparseDataBuilder::SaveDataForSkippableFunction(
287    PreparseDataBuilder* builder) {
288  DeclarationScope* function_scope = builder->function_scope_;
289  // Start position is used for a sanity check when consuming the data, we could
290  // remove it in the future if we're very pressed for space but it's been good
291  // at catching bugs in the wild so far.
292  byte_data_.WriteVarint32(function_scope->start_position());
293  byte_data_.WriteVarint32(function_scope->end_position());
294
295  bool has_data = builder->HasData();
296  bool length_equals_parameters =
297      function_scope->num_parameters() == builder->function_length_;
298  uint32_t has_data_and_num_parameters =
299      HasDataField::encode(has_data) |
300      LengthEqualsParametersField::encode(length_equals_parameters) |
301      NumberOfParametersField::encode(function_scope->num_parameters());
302  byte_data_.WriteVarint32(has_data_and_num_parameters);
303  if (!length_equals_parameters) {
304    byte_data_.WriteVarint32(builder->function_length_);
305  }
306  byte_data_.WriteVarint32(builder->num_inner_functions_);
307
308  uint8_t language_and_super =
309      LanguageField::encode(function_scope->language_mode()) |
310      UsesSuperField::encode(function_scope->uses_super_property());
311  byte_data_.WriteQuarter(language_and_super);
312  return has_data;
313}
314
315void PreparseDataBuilder::SaveScopeAllocationData(DeclarationScope* scope,
316                                                  Parser* parser) {
317  if (!has_data_) return;
318  DCHECK(HasInnerFunctions());
319
320  byte_data_.Start(parser->preparse_data_buffer());
321
322#ifdef DEBUG
323  // Reserve Uint32 for scope_data_start debug info.
324  byte_data_.Reserve(kUint32Size);
325  byte_data_.WriteUint32(0);
326#endif
327  byte_data_.Reserve(children_.size() * kSkippableFunctionMaxDataSize);
328  DCHECK(finalized_children_);
329  for (const auto& builder : children_) {
330    // Keep track of functions with inner data. {children_} contains also the
331    // builders that have no inner functions at all.
332    if (SaveDataForSkippableFunction(builder)) num_inner_with_data_++;
333  }
334
335  // Don't save incomplete scope information when bailed out.
336  if (!bailed_out_) {
337#ifdef DEBUG
338  // function data items, kSkippableMinFunctionDataSize each.
339  CHECK_GE(byte_data_.length(), kPlaceholderSize);
340  CHECK_LE(byte_data_.length(), std::numeric_limits<uint32_t>::max());
341
342  byte_data_.SaveCurrentSizeAtFirstUint32();
343  // For a data integrity check, write a value between data about skipped
344  // inner funcs and data about variables.
345  byte_data_.Reserve(kUint32Size * 3);
346  byte_data_.WriteUint32(kMagicValue);
347  byte_data_.WriteUint32(scope->start_position());
348  byte_data_.WriteUint32(scope->end_position());
349#endif
350
351  if (ScopeNeedsData(scope)) SaveDataForScope(scope);
352  }
353  byte_data_.Finalize(parser->factory()->zone());
354}
355
356void PreparseDataBuilder::SaveDataForScope(Scope* scope) {
357  DCHECK_NE(scope->end_position(), kNoSourcePosition);
358  DCHECK(ScopeNeedsData(scope));
359
360#ifdef DEBUG
361  byte_data_.Reserve(kUint8Size);
362  byte_data_.WriteUint8(scope->scope_type());
363#endif
364
365  uint8_t scope_data_flags =
366      ScopeSloppyEvalCanExtendVarsBit::encode(
367          scope->is_declaration_scope() &&
368          scope->AsDeclarationScope()->sloppy_eval_can_extend_vars()) |
369      InnerScopeCallsEvalField::encode(scope->inner_scope_calls_eval()) |
370      NeedsPrivateNameContextChainRecalcField::encode(
371          scope->is_function_scope() &&
372          scope->AsDeclarationScope()
373              ->needs_private_name_context_chain_recalc()) |
374      ShouldSaveClassVariableIndexField::encode(
375          scope->is_class_scope() &&
376          scope->AsClassScope()->should_save_class_variable_index());
377  byte_data_.Reserve(kUint8Size);
378  byte_data_.WriteUint8(scope_data_flags);
379
380  if (scope->is_function_scope()) {
381    Variable* function = scope->AsDeclarationScope()->function_var();
382    if (function != nullptr) SaveDataForVariable(function);
383  }
384
385  for (Variable* var : *scope->locals()) {
386    if (IsSerializableVariableMode(var->mode())) SaveDataForVariable(var);
387  }
388
389  SaveDataForInnerScopes(scope);
390}
391
392void PreparseDataBuilder::SaveDataForVariable(Variable* var) {
393#ifdef DEBUG
394  // Store the variable name in debug mode; this way we can check that we
395  // restore data to the correct variable.
396  const AstRawString* name = var->raw_name();
397  byte_data_.Reserve(kUint32Size + (name->length() + 1) * kUint8Size);
398  byte_data_.WriteUint8(name->is_one_byte());
399  byte_data_.WriteUint32(name->length());
400  for (int i = 0; i < name->length(); ++i) {
401    byte_data_.WriteUint8(name->raw_data()[i]);
402  }
403#endif
404
405  byte variable_data = VariableMaybeAssignedField::encode(
406                           var->maybe_assigned() == kMaybeAssigned) |
407                       VariableContextAllocatedField::encode(
408                           var->has_forced_context_allocation());
409  byte_data_.Reserve(kUint8Size);
410  byte_data_.WriteQuarter(variable_data);
411}
412
413void PreparseDataBuilder::SaveDataForInnerScopes(Scope* scope) {
414  // Inner scopes are stored in the reverse order, but we'd like to write the
415  // data in the logical order. There might be many inner scopes, so we don't
416  // want to recurse here.
417  for (Scope* inner = scope->inner_scope(); inner != nullptr;
418       inner = inner->sibling()) {
419    if (inner->IsSkippableFunctionScope()) {
420      // Don't save data about function scopes, since they'll have their own
421      // PreparseDataBuilder where their data is saved.
422      DCHECK_NOT_NULL(inner->AsDeclarationScope()->preparse_data_builder());
423      continue;
424    }
425    if (!ScopeNeedsData(inner)) continue;
426    SaveDataForScope(inner);
427  }
428}
429
430
431Handle<PreparseData> PreparseDataBuilder::ByteData::CopyToHeap(
432    Isolate* isolate, int children_length) {
433  DCHECK(is_finalized_);
434  int data_length = zone_byte_data_.length();
435  Handle<PreparseData> data =
436      isolate->factory()->NewPreparseData(data_length, children_length);
437  data->copy_in(0, zone_byte_data_.begin(), data_length);
438  return data;
439}
440
441Handle<PreparseData> PreparseDataBuilder::ByteData::CopyToLocalHeap(
442    LocalIsolate* isolate, int children_length) {
443  DCHECK(is_finalized_);
444  int data_length = zone_byte_data_.length();
445  Handle<PreparseData> data =
446      isolate->factory()->NewPreparseData(data_length, children_length);
447  data->copy_in(0, zone_byte_data_.begin(), data_length);
448  return data;
449}
450
451Handle<PreparseData> PreparseDataBuilder::Serialize(Isolate* isolate) {
452  DCHECK(HasData());
453  DCHECK(!ThisOrParentBailedOut());
454  Handle<PreparseData> data =
455      byte_data_.CopyToHeap(isolate, num_inner_with_data_);
456  int i = 0;
457  DCHECK(finalized_children_);
458  for (const auto& builder : children_) {
459    if (!builder->HasData()) continue;
460    Handle<PreparseData> child_data = builder->Serialize(isolate);
461    data->set_child(i++, *child_data);
462  }
463  DCHECK_EQ(i, data->children_length());
464  return data;
465}
466
467Handle<PreparseData> PreparseDataBuilder::Serialize(LocalIsolate* isolate) {
468  DCHECK(HasData());
469  DCHECK(!ThisOrParentBailedOut());
470  Handle<PreparseData> data =
471      byte_data_.CopyToLocalHeap(isolate, num_inner_with_data_);
472  int i = 0;
473  DCHECK(finalized_children_);
474  for (const auto& builder : children_) {
475    if (!builder->HasData()) continue;
476    Handle<PreparseData> child_data = builder->Serialize(isolate);
477    data->set_child(i++, *child_data);
478  }
479  DCHECK_EQ(i, data->children_length());
480  return data;
481}
482
483ZonePreparseData* PreparseDataBuilder::Serialize(Zone* zone) {
484  DCHECK(HasData());
485  DCHECK(!ThisOrParentBailedOut());
486  ZonePreparseData* data = byte_data_.CopyToZone(zone, num_inner_with_data_);
487  int i = 0;
488  DCHECK(finalized_children_);
489  for (const auto& builder : children_) {
490    if (!builder->HasData()) continue;
491    ZonePreparseData* child = builder->Serialize(zone);
492    data->set_child(i++, child);
493  }
494  DCHECK_EQ(i, data->children_length());
495  return data;
496}
497
498class BuilderProducedPreparseData final : public ProducedPreparseData {
499 public:
500  explicit BuilderProducedPreparseData(PreparseDataBuilder* builder)
501      : builder_(builder) {
502    DCHECK(builder->HasData());
503  }
504
505  Handle<PreparseData> Serialize(Isolate* isolate) final {
506    return builder_->Serialize(isolate);
507  }
508
509  Handle<PreparseData> Serialize(LocalIsolate* isolate) final {
510    return builder_->Serialize(isolate);
511  }
512
513  ZonePreparseData* Serialize(Zone* zone) final {
514    return builder_->Serialize(zone);
515  }
516
517 private:
518  PreparseDataBuilder* builder_;
519};
520
521class OnHeapProducedPreparseData final : public ProducedPreparseData {
522 public:
523  explicit OnHeapProducedPreparseData(Handle<PreparseData> data)
524      : data_(data) {}
525
526  Handle<PreparseData> Serialize(Isolate* isolate) final {
527    DCHECK(!data_->is_null());
528    return data_;
529  }
530
531  Handle<PreparseData> Serialize(LocalIsolate* isolate) final {
532    DCHECK(!data_->is_null());
533    DCHECK_IMPLIES(!isolate->is_main_thread(),
534                   isolate->heap()->ContainsLocalHandle(data_.location()));
535    return data_;
536  }
537
538  ZonePreparseData* Serialize(Zone* zone) final {
539    // Not required.
540    UNREACHABLE();
541  }
542
543 private:
544  Handle<PreparseData> data_;
545};
546
547class ZoneProducedPreparseData final : public ProducedPreparseData {
548 public:
549  explicit ZoneProducedPreparseData(ZonePreparseData* data) : data_(data) {}
550
551  Handle<PreparseData> Serialize(Isolate* isolate) final {
552    return data_->Serialize(isolate);
553  }
554
555  Handle<PreparseData> Serialize(LocalIsolate* isolate) final {
556    return data_->Serialize(isolate);
557  }
558
559  ZonePreparseData* Serialize(Zone* zone) final {
560    base::Vector<uint8_t> data(data_->byte_data()->data(),
561                               data_->byte_data()->size());
562    return zone->New<ZonePreparseData>(zone, &data, data_->children_length());
563  }
564
565 private:
566  ZonePreparseData* data_;
567};
568
569ProducedPreparseData* ProducedPreparseData::For(PreparseDataBuilder* builder,
570                                                Zone* zone) {
571  return zone->New<BuilderProducedPreparseData>(builder);
572}
573
574ProducedPreparseData* ProducedPreparseData::For(Handle<PreparseData> data,
575                                                Zone* zone) {
576  return zone->New<OnHeapProducedPreparseData>(data);
577}
578
579ProducedPreparseData* ProducedPreparseData::For(ZonePreparseData* data,
580                                                Zone* zone) {
581  return zone->New<ZoneProducedPreparseData>(data);
582}
583
584template <class Data>
585ProducedPreparseData*
586BaseConsumedPreparseData<Data>::GetDataForSkippableFunction(
587    Zone* zone, int start_position, int* end_position, int* num_parameters,
588    int* function_length, int* num_inner_functions, bool* uses_super_property,
589    LanguageMode* language_mode) {
590  // The skippable function *must* be the next function in the data. Use the
591  // start position as a sanity check.
592  typename ByteData::ReadingScope reading_scope(this);
593  CHECK(scope_data_->HasRemainingBytes(
594      PreparseByteDataConstants::kSkippableFunctionMinDataSize));
595  int start_position_from_data = scope_data_->ReadVarint32();
596  CHECK_EQ(start_position, start_position_from_data);
597  *end_position = scope_data_->ReadVarint32();
598  DCHECK_GT(*end_position, start_position);
599
600  uint32_t has_data_and_num_parameters = scope_data_->ReadVarint32();
601  bool has_data = HasDataField::decode(has_data_and_num_parameters);
602  *num_parameters =
603      NumberOfParametersField::decode(has_data_and_num_parameters);
604  bool length_equals_parameters =
605      LengthEqualsParametersField::decode(has_data_and_num_parameters);
606  if (length_equals_parameters) {
607    *function_length = *num_parameters;
608  } else {
609    *function_length = scope_data_->ReadVarint32();
610  }
611  *num_inner_functions = scope_data_->ReadVarint32();
612
613  uint8_t language_and_super = scope_data_->ReadQuarter();
614  *language_mode = LanguageMode(LanguageField::decode(language_and_super));
615  *uses_super_property = UsesSuperField::decode(language_and_super);
616
617  if (!has_data) return nullptr;
618
619  // Retrieve the corresponding PreparseData and associate it to the
620  // skipped function. If the skipped functions contains inner functions, those
621  // can be skipped when the skipped function is eagerly parsed.
622  return GetChildData(zone, child_index_++);
623}
624
625template <class Data>
626void BaseConsumedPreparseData<Data>::RestoreScopeAllocationData(
627    DeclarationScope* scope, AstValueFactory* ast_value_factory, Zone* zone) {
628  DCHECK_EQ(scope->scope_type(), ScopeType::FUNCTION_SCOPE);
629  typename ByteData::ReadingScope reading_scope(this);
630
631#ifdef DEBUG
632  int magic_value_from_data = scope_data_->ReadUint32();
633  // Check that we've consumed all inner function data.
634  DCHECK_EQ(magic_value_from_data, ByteData::kMagicValue);
635
636  int start_position_from_data = scope_data_->ReadUint32();
637  int end_position_from_data = scope_data_->ReadUint32();
638  DCHECK_EQ(start_position_from_data, scope->start_position());
639  DCHECK_EQ(end_position_from_data, scope->end_position());
640#endif
641
642  RestoreDataForScope(scope, ast_value_factory, zone);
643
644  // Check that we consumed all scope data.
645  DCHECK_EQ(scope_data_->RemainingBytes(), 0);
646}
647
648template <typename Data>
649void BaseConsumedPreparseData<Data>::RestoreDataForScope(
650    Scope* scope, AstValueFactory* ast_value_factory, Zone* zone) {
651  if (scope->is_declaration_scope() &&
652      scope->AsDeclarationScope()->is_skipped_function()) {
653    return;
654  }
655
656  // It's possible that scope is not present in the data at all (since PreParser
657  // doesn't create the corresponding scope). In this case, the Scope won't
658  // contain any variables for which we need the data.
659  if (!PreparseDataBuilder::ScopeNeedsData(scope)) return;
660
661  // scope_type is stored only in debug mode.
662  DCHECK_EQ(scope_data_->ReadUint8(), scope->scope_type());
663
664  CHECK(scope_data_->HasRemainingBytes(ByteData::kUint8Size));
665  uint32_t scope_data_flags = scope_data_->ReadUint8();
666  if (ScopeSloppyEvalCanExtendVarsBit::decode(scope_data_flags)) {
667    scope->RecordEvalCall();
668  }
669  if (InnerScopeCallsEvalField::decode(scope_data_flags)) {
670    scope->RecordInnerScopeEvalCall();
671  }
672  if (NeedsPrivateNameContextChainRecalcField::decode(scope_data_flags)) {
673    scope->AsDeclarationScope()->RecordNeedsPrivateNameContextChainRecalc();
674  }
675  if (ShouldSaveClassVariableIndexField::decode(scope_data_flags)) {
676    Variable* var = scope->AsClassScope()->class_variable();
677    // An anonymous class whose class variable needs to be saved might not
678    // have the class variable created during reparse since we skip parsing
679    // the inner scopes that contain potential access to static private
680    // methods. So create it now.
681    if (var == nullptr) {
682      DCHECK(scope->AsClassScope()->is_anonymous_class());
683      var = scope->AsClassScope()->DeclareClassVariable(
684          ast_value_factory, nullptr, kNoSourcePosition);
685      AstNodeFactory factory(ast_value_factory, zone);
686      Declaration* declaration =
687          factory.NewVariableDeclaration(kNoSourcePosition);
688      scope->declarations()->Add(declaration);
689      declaration->set_var(var);
690    }
691    var->set_is_used();
692    var->ForceContextAllocation();
693    scope->AsClassScope()->set_should_save_class_variable_index();
694  }
695
696  if (scope->is_function_scope()) {
697    Variable* function = scope->AsDeclarationScope()->function_var();
698    if (function != nullptr) RestoreDataForVariable(function);
699  }
700  for (Variable* var : *scope->locals()) {
701    if (IsSerializableVariableMode(var->mode())) RestoreDataForVariable(var);
702  }
703
704  RestoreDataForInnerScopes(scope, ast_value_factory, zone);
705}
706
707template <typename Data>
708void BaseConsumedPreparseData<Data>::RestoreDataForVariable(Variable* var) {
709#ifdef DEBUG
710  const AstRawString* name = var->raw_name();
711  bool data_one_byte = scope_data_->ReadUint8();
712  DCHECK_IMPLIES(name->is_one_byte(), data_one_byte);
713  DCHECK_EQ(scope_data_->ReadUint32(), static_cast<uint32_t>(name->length()));
714  if (!name->is_one_byte() && data_one_byte) {
715    // It's possible that "name" is a two-byte representation of the string
716    // stored in the data.
717    for (int i = 0; i < 2 * name->length(); i += 2) {
718#if defined(V8_TARGET_LITTLE_ENDIAN)
719      DCHECK_EQ(scope_data_->ReadUint8(), name->raw_data()[i]);
720      DCHECK_EQ(0, name->raw_data()[i + 1]);
721#else
722      DCHECK_EQ(scope_data_->ReadUint8(), name->raw_data()[i + 1]);
723      DCHECK_EQ(0, name->raw_data()[i]);
724#endif  // V8_TARGET_LITTLE_ENDIAN
725    }
726  } else {
727    for (int i = 0; i < name->length(); ++i) {
728      DCHECK_EQ(scope_data_->ReadUint8(), name->raw_data()[i]);
729    }
730  }
731#endif
732  uint8_t variable_data = scope_data_->ReadQuarter();
733  if (VariableMaybeAssignedField::decode(variable_data)) {
734    var->SetMaybeAssigned();
735  }
736  if (VariableContextAllocatedField::decode(variable_data)) {
737    var->set_is_used();
738    var->ForceContextAllocation();
739  }
740}
741
742template <typename Data>
743void BaseConsumedPreparseData<Data>::RestoreDataForInnerScopes(
744    Scope* scope, AstValueFactory* ast_value_factory, Zone* zone) {
745  for (Scope* inner = scope->inner_scope(); inner != nullptr;
746       inner = inner->sibling()) {
747    RestoreDataForScope(inner, ast_value_factory, zone);
748  }
749}
750
751#ifdef DEBUG
752template <class Data>
753bool BaseConsumedPreparseData<Data>::VerifyDataStart() {
754  typename ByteData::ReadingScope reading_scope(this);
755  // The first uint32 contains the size of the skippable function data.
756  int scope_data_start = scope_data_->ReadUint32();
757  scope_data_->SetPosition(scope_data_start);
758  CHECK_EQ(scope_data_->ReadUint32(), ByteData::kMagicValue);
759  // The first data item is scope_data_start. Skip over it.
760  scope_data_->SetPosition(ByteData::kPlaceholderSize);
761  return true;
762}
763#endif
764
765PreparseData OnHeapConsumedPreparseData::GetScopeData() { return *data_; }
766
767ProducedPreparseData* OnHeapConsumedPreparseData::GetChildData(Zone* zone,
768                                                               int index) {
769  DisallowGarbageCollection no_gc;
770  Handle<PreparseData> child_data_handle(data_->get_child(index), isolate_);
771  return ProducedPreparseData::For(child_data_handle, zone);
772}
773
774OnHeapConsumedPreparseData::OnHeapConsumedPreparseData(
775    LocalIsolate* isolate, Handle<PreparseData> data)
776    : BaseConsumedPreparseData<PreparseData>(), isolate_(isolate), data_(data) {
777  DCHECK_NOT_NULL(isolate);
778  DCHECK(data->IsPreparseData());
779  DCHECK(VerifyDataStart());
780}
781
782ZonePreparseData::ZonePreparseData(Zone* zone, base::Vector<uint8_t>* byte_data,
783                                   int children_length)
784    : byte_data_(byte_data->begin(), byte_data->end(), zone),
785      children_(children_length, zone) {}
786
787Handle<PreparseData> ZonePreparseData::Serialize(Isolate* isolate) {
788  int data_size = static_cast<int>(byte_data()->size());
789  int child_data_length = children_length();
790  Handle<PreparseData> result =
791      isolate->factory()->NewPreparseData(data_size, child_data_length);
792  result->copy_in(0, byte_data()->data(), data_size);
793
794  for (int i = 0; i < child_data_length; i++) {
795    ZonePreparseData* child = get_child(i);
796    DCHECK_NOT_NULL(child);
797    Handle<PreparseData> child_data = child->Serialize(isolate);
798    result->set_child(i, *child_data);
799  }
800  return result;
801}
802
803Handle<PreparseData> ZonePreparseData::Serialize(LocalIsolate* isolate) {
804  int data_size = static_cast<int>(byte_data()->size());
805  int child_data_length = children_length();
806  Handle<PreparseData> result =
807      isolate->factory()->NewPreparseData(data_size, child_data_length);
808  result->copy_in(0, byte_data()->data(), data_size);
809
810  for (int i = 0; i < child_data_length; i++) {
811    ZonePreparseData* child = get_child(i);
812    DCHECK_NOT_NULL(child);
813    Handle<PreparseData> child_data = child->Serialize(isolate);
814    result->set_child(i, *child_data);
815  }
816  return result;
817}
818
819ZoneConsumedPreparseData::ZoneConsumedPreparseData(Zone* zone,
820                                                   ZonePreparseData* data)
821    : data_(data), scope_data_wrapper_(data_->byte_data()) {
822  DCHECK(VerifyDataStart());
823}
824
825ZoneVectorWrapper ZoneConsumedPreparseData::GetScopeData() {
826  return scope_data_wrapper_;
827}
828
829ProducedPreparseData* ZoneConsumedPreparseData::GetChildData(Zone* zone,
830                                                             int child_index) {
831  CHECK_GT(data_->children_length(), child_index);
832  ZonePreparseData* child_data = data_->get_child(child_index);
833  if (child_data == nullptr) return nullptr;
834  return ProducedPreparseData::For(child_data, zone);
835}
836
837std::unique_ptr<ConsumedPreparseData> ConsumedPreparseData::For(
838    Isolate* isolate, Handle<PreparseData> data) {
839  return ConsumedPreparseData::For(isolate->main_thread_local_isolate(), data);
840}
841
842std::unique_ptr<ConsumedPreparseData> ConsumedPreparseData::For(
843    LocalIsolate* isolate, Handle<PreparseData> data) {
844  DCHECK(!data.is_null());
845  return std::make_unique<OnHeapConsumedPreparseData>(isolate, data);
846}
847
848std::unique_ptr<ConsumedPreparseData> ConsumedPreparseData::For(
849    Zone* zone, ZonePreparseData* data) {
850  if (data == nullptr) return {};
851  return std::make_unique<ZoneConsumedPreparseData>(zone, data);
852}
853
854}  // namespace internal
855}  // namespace v8
856