• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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