diff options
Diffstat (limited to 'deps/v8/src/parsing/preparse-data-impl.h')
-rw-r--r-- | deps/v8/src/parsing/preparse-data-impl.h | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/deps/v8/src/parsing/preparse-data-impl.h b/deps/v8/src/parsing/preparse-data-impl.h new file mode 100644 index 0000000000..7d1f0feed8 --- /dev/null +++ b/deps/v8/src/parsing/preparse-data-impl.h @@ -0,0 +1,234 @@ +// Copyright 2018 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_PARSING_PREPARSE_DATA_IMPL_H_ +#define V8_PARSING_PREPARSE_DATA_IMPL_H_ + +#include "src/parsing/preparse-data.h" + +#include "src/assert-scope.h" + +namespace v8 { +namespace internal { + +// Classes which are internal to prepared-scope-data.cc, but are exposed in +// a header for tests. + +// Wraps a ZoneVector<uint8_t> to have with functions named the same as +// PodArray<uint8_t>. +class ZoneVectorWrapper { + public: + ZoneVectorWrapper() = default; + explicit ZoneVectorWrapper(ZoneVector<uint8_t>* data) : data_(data) {} + + int data_length() const { return static_cast<int>(data_->size()); } + + uint8_t get(int index) const { return data_->at(index); } + + private: + ZoneVector<uint8_t>* data_ = nullptr; +}; + +template <class Data> +class BaseConsumedPreparseData : public ConsumedPreparseData { + public: + class ByteData : public PreparseByteDataConstants { + public: + ByteData() {} + + // Reading from the ByteData is only allowed when a ReadingScope is on the + // stack. This ensures that we have a DisallowHeapAllocation in place + // whenever ByteData holds a raw pointer into the heap. + class ReadingScope { + public: + ReadingScope(ByteData* consumed_data, Data data) + : consumed_data_(consumed_data) { + consumed_data->data_ = data; +#ifdef DEBUG + consumed_data->has_data_ = true; +#endif + } + explicit ReadingScope(BaseConsumedPreparseData<Data>* parent) + : ReadingScope(parent->scope_data_.get(), parent->GetScopeData()) {} + ~ReadingScope() { +#ifdef DEBUG + consumed_data_->has_data_ = false; +#endif + } + + private: + ByteData* consumed_data_; + DISALLOW_HEAP_ALLOCATION(no_gc); + }; + + void SetPosition(int position) { + DCHECK_LE(position, data_.data_length()); + index_ = position; + } + + size_t RemainingBytes() const { + DCHECK(has_data_); + DCHECK_LE(index_, data_.data_length()); + return data_.data_length() - index_; + } + + bool HasRemainingBytes(size_t bytes) const { + DCHECK(has_data_); + return index_ <= data_.data_length() && bytes <= RemainingBytes(); + } + + int32_t ReadUint32() { + DCHECK(has_data_); + DCHECK(HasRemainingBytes(kUint32Size)); + // Check that there indeed is an integer following. + DCHECK_EQ(data_.get(index_++), kUint32Size); + int32_t result = data_.get(index_) + (data_.get(index_ + 1) << 8) + + (data_.get(index_ + 2) << 16) + + (data_.get(index_ + 3) << 24); + index_ += 4; + stored_quarters_ = 0; + return result; + } + + int32_t ReadVarint32() { + DCHECK(HasRemainingBytes(kVarintMinSize)); + DCHECK_EQ(data_.get(index_++), kVarintMinSize); + int32_t value = 0; + bool has_another_byte; + unsigned shift = 0; + do { + uint8_t byte = data_.get(index_++); + value |= static_cast<int32_t>(byte & 0x7F) << shift; + shift += 7; + has_another_byte = byte & 0x80; + } while (has_another_byte); + DCHECK_EQ(data_.get(index_++), kVarintEndMarker); + stored_quarters_ = 0; + return value; + } + + uint8_t ReadUint8() { + DCHECK(has_data_); + DCHECK(HasRemainingBytes(kUint8Size)); + // Check that there indeed is a byte following. + DCHECK_EQ(data_.get(index_++), kUint8Size); + stored_quarters_ = 0; + return data_.get(index_++); + } + + uint8_t ReadQuarter() { + DCHECK(has_data_); + if (stored_quarters_ == 0) { + DCHECK(HasRemainingBytes(kUint8Size)); + // Check that there indeed are quarters following. + DCHECK_EQ(data_.get(index_++), kQuarterMarker); + stored_byte_ = data_.get(index_++); + stored_quarters_ = 4; + } + // Read the first 2 bits from stored_byte_. + uint8_t result = (stored_byte_ >> 6) & 3; + DCHECK_LE(result, 3); + --stored_quarters_; + stored_byte_ <<= 2; + return result; + } + + private: + Data data_ = {}; + int index_ = 0; + uint8_t stored_quarters_ = 0; + uint8_t stored_byte_ = 0; +#ifdef DEBUG + bool has_data_ = false; +#endif + }; + + BaseConsumedPreparseData() : scope_data_(new ByteData()), child_index_(0) {} + + virtual Data GetScopeData() = 0; + + virtual ProducedPreparseData* GetChildData(Zone* zone, int child_index) = 0; + + ProducedPreparseData* GetDataForSkippableFunction( + Zone* zone, int start_position, int* end_position, int* num_parameters, + int* num_inner_functions, bool* uses_super_property, + LanguageMode* language_mode) final; + + void RestoreScopeAllocationData(DeclarationScope* scope) final; + +#ifdef DEBUG + bool VerifyDataStart(); +#endif + + private: + void RestoreDataForScope(Scope* scope); + void RestoreDataForVariable(Variable* var); + void RestoreDataForInnerScopes(Scope* scope); + + std::unique_ptr<ByteData> scope_data_; + // When consuming the data, these indexes point to the data we're going to + // consume next. + int child_index_; + + DISALLOW_COPY_AND_ASSIGN(BaseConsumedPreparseData); +}; + +// Implementation of ConsumedPreparseData for on-heap data. +class OnHeapConsumedPreparseData final + : public BaseConsumedPreparseData<PreparseData> { + public: + OnHeapConsumedPreparseData(Isolate* isolate, Handle<PreparseData> data); + + PreparseData GetScopeData() final; + ProducedPreparseData* GetChildData(Zone* zone, int child_index) final; + + private: + Isolate* isolate_; + Handle<PreparseData> data_; +}; + +// A serialized PreparseData in zone memory (as apposed to being on-heap). +class ZonePreparseData : public ZoneObject { + public: + ZonePreparseData(Zone* zone, Vector<uint8_t>* byte_data, int child_length); + + Handle<PreparseData> Serialize(Isolate* isolate); + + int children_length() const { return static_cast<int>(children_.size()); } + + ZonePreparseData* get_child(int index) { return children_[index]; } + + void set_child(int index, ZonePreparseData* child) { + DCHECK_NOT_NULL(child); + children_[index] = child; + } + + ZoneVector<uint8_t>* byte_data() { return &byte_data_; } + + private: + ZoneVector<uint8_t> byte_data_; + ZoneVector<ZonePreparseData*> children_; + + DISALLOW_COPY_AND_ASSIGN(ZonePreparseData); +}; + +// Implementation of ConsumedPreparseData for PreparseData +// serialized into zone memory. +class ZoneConsumedPreparseData final + : public BaseConsumedPreparseData<ZoneVectorWrapper> { + public: + ZoneConsumedPreparseData(Zone* zone, ZonePreparseData* data); + + ZoneVectorWrapper GetScopeData() final; + ProducedPreparseData* GetChildData(Zone* zone, int child_index) final; + + private: + ZonePreparseData* data_; + ZoneVectorWrapper scope_data_wrapper_; +}; + +} // namespace internal +} // namespace v8 + +#endif // V8_PARSING_PREPARSE_DATA_IMPL_H_ |