| // Copyright 2020 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_WASM_STRUCT_TYPES_H_ |
| #define V8_WASM_STRUCT_TYPES_H_ |
| |
| #include "src/base/iterator.h" |
| #include "src/base/macros.h" |
| #include "src/common/globals.h" |
| #include "src/wasm/value-type.h" |
| #include "src/zone/zone.h" |
| |
| namespace v8 { |
| namespace internal { |
| namespace wasm { |
| |
| class StructType : public ZoneObject { |
| public: |
| StructType(uint32_t field_count, uint32_t* field_offsets, |
| const ValueType* reps, const bool* mutabilities) |
| : field_count_(field_count), |
| field_offsets_(field_offsets), |
| reps_(reps), |
| mutabilities_(mutabilities) { |
| InitializeOffsets(); |
| } |
| |
| uint32_t field_count() const { return field_count_; } |
| |
| ValueType field(uint32_t index) const { |
| DCHECK_LT(index, field_count_); |
| return reps_[index]; |
| } |
| |
| bool mutability(uint32_t index) const { |
| DCHECK_LT(index, field_count_); |
| return mutabilities_[index]; |
| } |
| |
| // Iteration support. |
| base::iterator_range<const ValueType*> fields() const { |
| return {reps_, reps_ + field_count_}; |
| } |
| base::iterator_range<const bool*> mutabilities() const { |
| return {mutabilities_, mutabilities_ + field_count_}; |
| } |
| |
| bool operator==(const StructType& other) const { |
| if (this == &other) return true; |
| if (field_count() != other.field_count()) return false; |
| return std::equal(fields().begin(), fields().end(), |
| other.fields().begin()) && |
| std::equal(mutabilities().begin(), mutabilities().end(), |
| other.mutabilities().begin()); |
| } |
| bool operator!=(const StructType& other) const { return !(*this == other); } |
| |
| uint32_t field_offset(uint32_t index) const { |
| DCHECK_LT(index, field_count()); |
| if (index == 0) return 0; |
| return field_offsets_[index - 1]; |
| } |
| uint32_t total_fields_size() const { |
| return field_count() == 0 ? 0 : field_offsets_[field_count() - 1]; |
| } |
| |
| void InitializeOffsets() { |
| if (field_count() == 0) return; |
| uint32_t offset = field(0).element_size_bytes(); |
| for (uint32_t i = 1; i < field_count(); i++) { |
| uint32_t field_size = field(i).element_size_bytes(); |
| offset = RoundUp(offset, field_size); |
| field_offsets_[i - 1] = offset; |
| offset += field_size; |
| } |
| offset = RoundUp(offset, kTaggedSize); |
| field_offsets_[field_count() - 1] = offset; |
| } |
| |
| // For incrementally building StructTypes. |
| class Builder { |
| public: |
| Builder(Zone* zone, uint32_t field_count) |
| : field_count_(field_count), |
| zone_(zone), |
| cursor_(0), |
| buffer_(zone->NewArray<ValueType>(static_cast<int>(field_count))), |
| mutabilities_(zone->NewArray<bool>(static_cast<int>(field_count))) {} |
| |
| void AddField(ValueType type, bool mutability) { |
| DCHECK_LT(cursor_, field_count_); |
| mutabilities_[cursor_] = mutability; |
| buffer_[cursor_++] = type; |
| } |
| |
| StructType* Build() { |
| DCHECK_EQ(cursor_, field_count_); |
| uint32_t* offsets = zone_->NewArray<uint32_t>(field_count_); |
| return zone_->New<StructType>(field_count_, offsets, buffer_, |
| mutabilities_); |
| } |
| |
| private: |
| const uint32_t field_count_; |
| Zone* const zone_; |
| uint32_t cursor_; |
| ValueType* const buffer_; |
| bool* const mutabilities_; |
| }; |
| |
| private: |
| const uint32_t field_count_; |
| uint32_t* const field_offsets_; |
| const ValueType* const reps_; |
| const bool* const mutabilities_; |
| }; |
| |
| class ArrayType : public ZoneObject { |
| public: |
| constexpr explicit ArrayType(ValueType rep, bool mutability) |
| : rep_(rep), mutability_(mutability) {} |
| |
| ValueType element_type() const { return rep_; } |
| bool mutability() const { return mutability_; } |
| |
| bool operator==(const ArrayType& other) const { return rep_ == other.rep_; } |
| bool operator!=(const ArrayType& other) const { return rep_ != other.rep_; } |
| |
| private: |
| const ValueType rep_; |
| const bool mutability_; |
| }; |
| |
| } // namespace wasm |
| } // namespace internal |
| } // namespace v8 |
| |
| #endif // V8_WASM_STRUCT_TYPES_H_ |