1 // Copyright 2020 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 #ifndef V8_WASM_STRUCT_TYPES_H_ 6 #define V8_WASM_STRUCT_TYPES_H_ 7 8 #include "src/base/iterator.h" 9 #include "src/base/macros.h" 10 #include "src/common/globals.h" 11 #include "src/wasm/value-type.h" 12 #include "src/zone/zone.h" 13 14 namespace v8 { 15 namespace internal { 16 namespace wasm { 17 18 class StructType : public ZoneObject { 19 public: StructType(uint32_t field_count,uint32_t * field_offsets,const ValueType * reps,const bool * mutabilities)20 StructType(uint32_t field_count, uint32_t* field_offsets, 21 const ValueType* reps, const bool* mutabilities) 22 : field_count_(field_count), 23 field_offsets_(field_offsets), 24 reps_(reps), 25 mutabilities_(mutabilities) { 26 InitializeOffsets(); 27 } 28 field_count()29 uint32_t field_count() const { return field_count_; } 30 field(uint32_t index)31 ValueType field(uint32_t index) const { 32 DCHECK_LT(index, field_count_); 33 return reps_[index]; 34 } 35 mutability(uint32_t index)36 bool mutability(uint32_t index) const { 37 DCHECK_LT(index, field_count_); 38 return mutabilities_[index]; 39 } 40 41 // Iteration support. fields()42 base::iterator_range<const ValueType*> fields() const { 43 return {reps_, reps_ + field_count_}; 44 } mutabilities()45 base::iterator_range<const bool*> mutabilities() const { 46 return {mutabilities_, mutabilities_ + field_count_}; 47 } 48 49 bool operator==(const StructType& other) const { 50 if (this == &other) return true; 51 if (field_count() != other.field_count()) return false; 52 return std::equal(fields().begin(), fields().end(), 53 other.fields().begin()) && 54 std::equal(mutabilities().begin(), mutabilities().end(), 55 other.mutabilities().begin()); 56 } 57 bool operator!=(const StructType& other) const { return !(*this == other); } 58 field_offset(uint32_t index)59 uint32_t field_offset(uint32_t index) const { 60 DCHECK_LT(index, field_count()); 61 if (index == 0) return 0; 62 return field_offsets_[index - 1]; 63 } total_fields_size()64 uint32_t total_fields_size() const { 65 return field_count() == 0 ? 0 : field_offsets_[field_count() - 1]; 66 } 67 InitializeOffsets()68 void InitializeOffsets() { 69 if (field_count() == 0) return; 70 uint32_t offset = field(0).element_size_bytes(); 71 for (uint32_t i = 1; i < field_count(); i++) { 72 uint32_t field_size = field(i).element_size_bytes(); 73 offset = RoundUp(offset, field_size); 74 field_offsets_[i - 1] = offset; 75 offset += field_size; 76 } 77 offset = RoundUp(offset, kTaggedSize); 78 field_offsets_[field_count() - 1] = offset; 79 } 80 81 // For incrementally building StructTypes. 82 class Builder { 83 public: Builder(Zone * zone,uint32_t field_count)84 Builder(Zone* zone, uint32_t field_count) 85 : field_count_(field_count), 86 zone_(zone), 87 cursor_(0), 88 buffer_(zone->NewArray<ValueType>(static_cast<int>(field_count))), 89 mutabilities_(zone->NewArray<bool>(static_cast<int>(field_count))) {} 90 AddField(ValueType type,bool mutability)91 void AddField(ValueType type, bool mutability) { 92 DCHECK_LT(cursor_, field_count_); 93 mutabilities_[cursor_] = mutability; 94 buffer_[cursor_++] = type; 95 } 96 Build()97 StructType* Build() { 98 DCHECK_EQ(cursor_, field_count_); 99 uint32_t* offsets = zone_->NewArray<uint32_t>(field_count_); 100 return zone_->New<StructType>(field_count_, offsets, buffer_, 101 mutabilities_); 102 } 103 104 private: 105 const uint32_t field_count_; 106 Zone* const zone_; 107 uint32_t cursor_; 108 ValueType* const buffer_; 109 bool* const mutabilities_; 110 }; 111 112 private: 113 const uint32_t field_count_; 114 uint32_t* const field_offsets_; 115 const ValueType* const reps_; 116 const bool* const mutabilities_; 117 }; 118 119 class ArrayType : public ZoneObject { 120 public: ArrayType(ValueType rep,bool mutability)121 constexpr explicit ArrayType(ValueType rep, bool mutability) 122 : rep_(rep), mutability_(mutability) {} 123 element_type()124 ValueType element_type() const { return rep_; } mutability()125 bool mutability() const { return mutability_; } 126 127 bool operator==(const ArrayType& other) const { return rep_ == other.rep_; } 128 bool operator!=(const ArrayType& other) const { return rep_ != other.rep_; } 129 130 private: 131 const ValueType rep_; 132 const bool mutability_; 133 }; 134 135 } // namespace wasm 136 } // namespace internal 137 } // namespace v8 138 139 #endif // V8_WASM_STRUCT_TYPES_H_ 140