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