11cb0ef41Sopenharmony_ci// Copyright 2018 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#ifndef V8_PARSING_PREPARSE_DATA_IMPL_H_ 61cb0ef41Sopenharmony_ci#define V8_PARSING_PREPARSE_DATA_IMPL_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include <memory> 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci#include "src/common/assert-scope.h" 111cb0ef41Sopenharmony_ci#include "src/parsing/preparse-data.h" 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_cinamespace v8 { 141cb0ef41Sopenharmony_cinamespace internal { 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ci// Classes which are internal to prepared-scope-data.cc, but are exposed in 171cb0ef41Sopenharmony_ci// a header for tests. 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ci// Wraps a ZoneVector<uint8_t> to have with functions named the same as 201cb0ef41Sopenharmony_ci// PodArray<uint8_t>. 211cb0ef41Sopenharmony_ciclass ZoneVectorWrapper { 221cb0ef41Sopenharmony_ci public: 231cb0ef41Sopenharmony_ci ZoneVectorWrapper() = default; 241cb0ef41Sopenharmony_ci explicit ZoneVectorWrapper(ZoneVector<uint8_t>* data) : data_(data) {} 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ci int data_length() const { return static_cast<int>(data_->size()); } 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ci uint8_t get(int index) const { return data_->at(index); } 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_ci private: 311cb0ef41Sopenharmony_ci ZoneVector<uint8_t>* data_ = nullptr; 321cb0ef41Sopenharmony_ci}; 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_citemplate <class Data> 351cb0ef41Sopenharmony_ciclass BaseConsumedPreparseData : public ConsumedPreparseData { 361cb0ef41Sopenharmony_ci public: 371cb0ef41Sopenharmony_ci class ByteData : public PreparseByteDataConstants { 381cb0ef41Sopenharmony_ci public: 391cb0ef41Sopenharmony_ci // Reading from the ByteData is only allowed when a ReadingScope is on the 401cb0ef41Sopenharmony_ci // stack. This ensures that we have a DisallowGarbageCollection in place 411cb0ef41Sopenharmony_ci // whenever ByteData holds a raw pointer into the heap. 421cb0ef41Sopenharmony_ci class V8_NODISCARD ReadingScope { 431cb0ef41Sopenharmony_ci public: 441cb0ef41Sopenharmony_ci ReadingScope(ByteData* consumed_data, Data data) 451cb0ef41Sopenharmony_ci : consumed_data_(consumed_data) { 461cb0ef41Sopenharmony_ci consumed_data->data_ = data; 471cb0ef41Sopenharmony_ci#ifdef DEBUG 481cb0ef41Sopenharmony_ci consumed_data->has_data_ = true; 491cb0ef41Sopenharmony_ci#endif 501cb0ef41Sopenharmony_ci } 511cb0ef41Sopenharmony_ci explicit ReadingScope(BaseConsumedPreparseData<Data>* parent) 521cb0ef41Sopenharmony_ci : ReadingScope(parent->scope_data_.get(), parent->GetScopeData()) {} 531cb0ef41Sopenharmony_ci ~ReadingScope() { 541cb0ef41Sopenharmony_ci#ifdef DEBUG 551cb0ef41Sopenharmony_ci consumed_data_->has_data_ = false; 561cb0ef41Sopenharmony_ci#endif 571cb0ef41Sopenharmony_ci } 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ci private: 601cb0ef41Sopenharmony_ci ByteData* consumed_data_; 611cb0ef41Sopenharmony_ci DISALLOW_GARBAGE_COLLECTION(no_gc) 621cb0ef41Sopenharmony_ci }; 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_ci void SetPosition(int position) { 651cb0ef41Sopenharmony_ci DCHECK_LE(position, data_.data_length()); 661cb0ef41Sopenharmony_ci index_ = position; 671cb0ef41Sopenharmony_ci } 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_ci size_t RemainingBytes() const { 701cb0ef41Sopenharmony_ci DCHECK(has_data_); 711cb0ef41Sopenharmony_ci DCHECK_LE(index_, data_.data_length()); 721cb0ef41Sopenharmony_ci return data_.data_length() - index_; 731cb0ef41Sopenharmony_ci } 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci bool HasRemainingBytes(size_t bytes) const { 761cb0ef41Sopenharmony_ci DCHECK(has_data_); 771cb0ef41Sopenharmony_ci return index_ <= data_.data_length() && bytes <= RemainingBytes(); 781cb0ef41Sopenharmony_ci } 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ci int32_t ReadUint32() { 811cb0ef41Sopenharmony_ci DCHECK(has_data_); 821cb0ef41Sopenharmony_ci DCHECK(HasRemainingBytes(kUint32Size)); 831cb0ef41Sopenharmony_ci // Check that there indeed is an integer following. 841cb0ef41Sopenharmony_ci DCHECK_EQ(data_.get(index_++), kUint32Size); 851cb0ef41Sopenharmony_ci int32_t result = data_.get(index_) + (data_.get(index_ + 1) << 8) + 861cb0ef41Sopenharmony_ci (data_.get(index_ + 2) << 16) + 871cb0ef41Sopenharmony_ci (data_.get(index_ + 3) << 24); 881cb0ef41Sopenharmony_ci index_ += 4; 891cb0ef41Sopenharmony_ci stored_quarters_ = 0; 901cb0ef41Sopenharmony_ci return result; 911cb0ef41Sopenharmony_ci } 921cb0ef41Sopenharmony_ci 931cb0ef41Sopenharmony_ci int32_t ReadVarint32() { 941cb0ef41Sopenharmony_ci DCHECK(HasRemainingBytes(kVarint32MinSize)); 951cb0ef41Sopenharmony_ci DCHECK_EQ(data_.get(index_++), kVarint32MinSize); 961cb0ef41Sopenharmony_ci int32_t value = 0; 971cb0ef41Sopenharmony_ci bool has_another_byte; 981cb0ef41Sopenharmony_ci unsigned shift = 0; 991cb0ef41Sopenharmony_ci do { 1001cb0ef41Sopenharmony_ci uint8_t byte = data_.get(index_++); 1011cb0ef41Sopenharmony_ci value |= static_cast<int32_t>(byte & 0x7F) << shift; 1021cb0ef41Sopenharmony_ci shift += 7; 1031cb0ef41Sopenharmony_ci has_another_byte = byte & 0x80; 1041cb0ef41Sopenharmony_ci } while (has_another_byte); 1051cb0ef41Sopenharmony_ci DCHECK_EQ(data_.get(index_++), kVarint32EndMarker); 1061cb0ef41Sopenharmony_ci stored_quarters_ = 0; 1071cb0ef41Sopenharmony_ci return value; 1081cb0ef41Sopenharmony_ci } 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_ci uint8_t ReadUint8() { 1111cb0ef41Sopenharmony_ci DCHECK(has_data_); 1121cb0ef41Sopenharmony_ci DCHECK(HasRemainingBytes(kUint8Size)); 1131cb0ef41Sopenharmony_ci // Check that there indeed is a byte following. 1141cb0ef41Sopenharmony_ci DCHECK_EQ(data_.get(index_++), kUint8Size); 1151cb0ef41Sopenharmony_ci stored_quarters_ = 0; 1161cb0ef41Sopenharmony_ci return data_.get(index_++); 1171cb0ef41Sopenharmony_ci } 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci uint8_t ReadQuarter() { 1201cb0ef41Sopenharmony_ci DCHECK(has_data_); 1211cb0ef41Sopenharmony_ci if (stored_quarters_ == 0) { 1221cb0ef41Sopenharmony_ci DCHECK(HasRemainingBytes(kUint8Size)); 1231cb0ef41Sopenharmony_ci // Check that there indeed are quarters following. 1241cb0ef41Sopenharmony_ci DCHECK_EQ(data_.get(index_++), kQuarterMarker); 1251cb0ef41Sopenharmony_ci stored_byte_ = data_.get(index_++); 1261cb0ef41Sopenharmony_ci stored_quarters_ = 4; 1271cb0ef41Sopenharmony_ci } 1281cb0ef41Sopenharmony_ci // Read the first 2 bits from stored_byte_. 1291cb0ef41Sopenharmony_ci uint8_t result = (stored_byte_ >> 6) & 3; 1301cb0ef41Sopenharmony_ci DCHECK_LE(result, 3); 1311cb0ef41Sopenharmony_ci --stored_quarters_; 1321cb0ef41Sopenharmony_ci stored_byte_ <<= 2; 1331cb0ef41Sopenharmony_ci return result; 1341cb0ef41Sopenharmony_ci } 1351cb0ef41Sopenharmony_ci 1361cb0ef41Sopenharmony_ci private: 1371cb0ef41Sopenharmony_ci Data data_ = {}; 1381cb0ef41Sopenharmony_ci int index_ = 0; 1391cb0ef41Sopenharmony_ci uint8_t stored_quarters_ = 0; 1401cb0ef41Sopenharmony_ci uint8_t stored_byte_ = 0; 1411cb0ef41Sopenharmony_ci#ifdef DEBUG 1421cb0ef41Sopenharmony_ci bool has_data_ = false; 1431cb0ef41Sopenharmony_ci#endif 1441cb0ef41Sopenharmony_ci }; 1451cb0ef41Sopenharmony_ci 1461cb0ef41Sopenharmony_ci BaseConsumedPreparseData() : scope_data_(new ByteData()), child_index_(0) {} 1471cb0ef41Sopenharmony_ci BaseConsumedPreparseData(const BaseConsumedPreparseData&) = delete; 1481cb0ef41Sopenharmony_ci BaseConsumedPreparseData& operator=(const BaseConsumedPreparseData&) = delete; 1491cb0ef41Sopenharmony_ci 1501cb0ef41Sopenharmony_ci virtual Data GetScopeData() = 0; 1511cb0ef41Sopenharmony_ci 1521cb0ef41Sopenharmony_ci virtual ProducedPreparseData* GetChildData(Zone* zone, int child_index) = 0; 1531cb0ef41Sopenharmony_ci 1541cb0ef41Sopenharmony_ci ProducedPreparseData* GetDataForSkippableFunction( 1551cb0ef41Sopenharmony_ci Zone* zone, int start_position, int* end_position, int* num_parameters, 1561cb0ef41Sopenharmony_ci int* function_length, int* num_inner_functions, bool* uses_super_property, 1571cb0ef41Sopenharmony_ci LanguageMode* language_mode) final; 1581cb0ef41Sopenharmony_ci 1591cb0ef41Sopenharmony_ci void RestoreScopeAllocationData(DeclarationScope* scope, 1601cb0ef41Sopenharmony_ci AstValueFactory* ast_value_factory, 1611cb0ef41Sopenharmony_ci Zone* zone) final; 1621cb0ef41Sopenharmony_ci 1631cb0ef41Sopenharmony_ci#ifdef DEBUG 1641cb0ef41Sopenharmony_ci bool VerifyDataStart(); 1651cb0ef41Sopenharmony_ci#endif 1661cb0ef41Sopenharmony_ci 1671cb0ef41Sopenharmony_ci private: 1681cb0ef41Sopenharmony_ci void RestoreDataForScope(Scope* scope, AstValueFactory* ast_value_factory, 1691cb0ef41Sopenharmony_ci Zone* zone); 1701cb0ef41Sopenharmony_ci void RestoreDataForVariable(Variable* var); 1711cb0ef41Sopenharmony_ci void RestoreDataForInnerScopes(Scope* scope, 1721cb0ef41Sopenharmony_ci AstValueFactory* ast_value_factory, 1731cb0ef41Sopenharmony_ci Zone* zone); 1741cb0ef41Sopenharmony_ci 1751cb0ef41Sopenharmony_ci std::unique_ptr<ByteData> scope_data_; 1761cb0ef41Sopenharmony_ci // When consuming the data, these indexes point to the data we're going to 1771cb0ef41Sopenharmony_ci // consume next. 1781cb0ef41Sopenharmony_ci int child_index_; 1791cb0ef41Sopenharmony_ci}; 1801cb0ef41Sopenharmony_ci 1811cb0ef41Sopenharmony_ci// Implementation of ConsumedPreparseData for on-heap data. 1821cb0ef41Sopenharmony_ciclass OnHeapConsumedPreparseData final 1831cb0ef41Sopenharmony_ci : public BaseConsumedPreparseData<PreparseData> { 1841cb0ef41Sopenharmony_ci public: 1851cb0ef41Sopenharmony_ci OnHeapConsumedPreparseData(LocalIsolate* isolate, Handle<PreparseData> data); 1861cb0ef41Sopenharmony_ci 1871cb0ef41Sopenharmony_ci PreparseData GetScopeData() final; 1881cb0ef41Sopenharmony_ci ProducedPreparseData* GetChildData(Zone* zone, int child_index) final; 1891cb0ef41Sopenharmony_ci 1901cb0ef41Sopenharmony_ci private: 1911cb0ef41Sopenharmony_ci LocalIsolate* isolate_; 1921cb0ef41Sopenharmony_ci Handle<PreparseData> data_; 1931cb0ef41Sopenharmony_ci}; 1941cb0ef41Sopenharmony_ci 1951cb0ef41Sopenharmony_ci// A serialized PreparseData in zone memory (as apposed to being on-heap). 1961cb0ef41Sopenharmony_ciclass ZonePreparseData : public ZoneObject { 1971cb0ef41Sopenharmony_ci public: 1981cb0ef41Sopenharmony_ci V8_EXPORT_PRIVATE ZonePreparseData(Zone* zone, 1991cb0ef41Sopenharmony_ci base::Vector<uint8_t>* byte_data, 2001cb0ef41Sopenharmony_ci int child_length); 2011cb0ef41Sopenharmony_ci 2021cb0ef41Sopenharmony_ci ZonePreparseData(const ZonePreparseData&) = delete; 2031cb0ef41Sopenharmony_ci ZonePreparseData& operator=(const ZonePreparseData&) = delete; 2041cb0ef41Sopenharmony_ci 2051cb0ef41Sopenharmony_ci Handle<PreparseData> Serialize(Isolate* isolate); 2061cb0ef41Sopenharmony_ci Handle<PreparseData> Serialize(LocalIsolate* isolate); 2071cb0ef41Sopenharmony_ci 2081cb0ef41Sopenharmony_ci int children_length() const { return static_cast<int>(children_.size()); } 2091cb0ef41Sopenharmony_ci 2101cb0ef41Sopenharmony_ci ZonePreparseData* get_child(int index) { return children_[index]; } 2111cb0ef41Sopenharmony_ci 2121cb0ef41Sopenharmony_ci void set_child(int index, ZonePreparseData* child) { 2131cb0ef41Sopenharmony_ci DCHECK_NOT_NULL(child); 2141cb0ef41Sopenharmony_ci children_[index] = child; 2151cb0ef41Sopenharmony_ci } 2161cb0ef41Sopenharmony_ci 2171cb0ef41Sopenharmony_ci ZoneVector<uint8_t>* byte_data() { return &byte_data_; } 2181cb0ef41Sopenharmony_ci 2191cb0ef41Sopenharmony_ci private: 2201cb0ef41Sopenharmony_ci ZoneVector<uint8_t> byte_data_; 2211cb0ef41Sopenharmony_ci ZoneVector<ZonePreparseData*> children_; 2221cb0ef41Sopenharmony_ci}; 2231cb0ef41Sopenharmony_ci 2241cb0ef41Sopenharmony_ciZonePreparseData* PreparseDataBuilder::ByteData::CopyToZone( 2251cb0ef41Sopenharmony_ci Zone* zone, int children_length) { 2261cb0ef41Sopenharmony_ci DCHECK(is_finalized_); 2271cb0ef41Sopenharmony_ci return zone->New<ZonePreparseData>(zone, &zone_byte_data_, children_length); 2281cb0ef41Sopenharmony_ci} 2291cb0ef41Sopenharmony_ci 2301cb0ef41Sopenharmony_ci// Implementation of ConsumedPreparseData for PreparseData 2311cb0ef41Sopenharmony_ci// serialized into zone memory. 2321cb0ef41Sopenharmony_ciclass ZoneConsumedPreparseData final 2331cb0ef41Sopenharmony_ci : public BaseConsumedPreparseData<ZoneVectorWrapper> { 2341cb0ef41Sopenharmony_ci public: 2351cb0ef41Sopenharmony_ci ZoneConsumedPreparseData(Zone* zone, ZonePreparseData* data); 2361cb0ef41Sopenharmony_ci 2371cb0ef41Sopenharmony_ci ZoneVectorWrapper GetScopeData() final; 2381cb0ef41Sopenharmony_ci ProducedPreparseData* GetChildData(Zone* zone, int child_index) final; 2391cb0ef41Sopenharmony_ci 2401cb0ef41Sopenharmony_ci private: 2411cb0ef41Sopenharmony_ci ZonePreparseData* data_; 2421cb0ef41Sopenharmony_ci ZoneVectorWrapper scope_data_wrapper_; 2431cb0ef41Sopenharmony_ci}; 2441cb0ef41Sopenharmony_ci 2451cb0ef41Sopenharmony_ci} // namespace internal 2461cb0ef41Sopenharmony_ci} // namespace v8 2471cb0ef41Sopenharmony_ci 2481cb0ef41Sopenharmony_ci#endif // V8_PARSING_PREPARSE_DATA_IMPL_H_ 249