summaryrefslogtreecommitdiff
path: root/deps/v8/src/parsing/preparse-data-impl.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/parsing/preparse-data-impl.h')
-rw-r--r--deps/v8/src/parsing/preparse-data-impl.h234
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_