• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 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_WASM_INIT_EXPR_H_
10 #define V8_WASM_WASM_INIT_EXPR_H_
11 
12 #include <memory>
13 
14 #include "src/wasm/value-type.h"
15 #include "src/zone/zone-containers.h"
16 
17 namespace v8 {
18 namespace internal {
19 namespace wasm {
20 
21 struct WasmModule;
22 class WasmFeatures;
23 
24 // Representation of an initializer expression. Unlike {ConstantExpression} in
25 // wasm-module.h, this does not use {WireBytesRef}, i.e., it does not depend on
26 // a wasm module's bytecode representation.
27 class WasmInitExpr : public ZoneObject {
28  public:
29   enum Operator {
30     kNone,
31     kGlobalGet,
32     kI32Const,
33     kI64Const,
34     kF32Const,
35     kF64Const,
36     kS128Const,
37     kRefNullConst,
38     kRefFuncConst,
39     kStructNewWithRtt,
40     kStructNew,
41     kStructNewDefaultWithRtt,
42     kStructNewDefault,
43     kArrayInit,
44     kArrayInitStatic,
45     kRttCanon,
46   };
47 
48   union Immediate {
49     int32_t i32_const;
50     int64_t i64_const;
51     float f32_const;
52     double f64_const;
53     std::array<uint8_t, kSimd128Size> s128_const;
54     uint32_t index;
55     HeapType::Representation heap_type;
56   };
57 
WasmInitExpr()58   WasmInitExpr() : kind_(kNone), operands_(nullptr) {
59     immediate_.i32_const = 0;
60   }
WasmInitExpr(int32_t v)61   explicit WasmInitExpr(int32_t v) : kind_(kI32Const), operands_(nullptr) {
62     immediate_.i32_const = v;
63   }
WasmInitExpr(int64_t v)64   explicit WasmInitExpr(int64_t v) : kind_(kI64Const), operands_(nullptr) {
65     immediate_.i64_const = v;
66   }
WasmInitExpr(float v)67   explicit WasmInitExpr(float v) : kind_(kF32Const), operands_(nullptr) {
68     immediate_.f32_const = v;
69   }
WasmInitExpr(double v)70   explicit WasmInitExpr(double v) : kind_(kF64Const), operands_(nullptr) {
71     immediate_.f64_const = v;
72   }
WasmInitExpr(uint8_t v[kSimd128Size])73   explicit WasmInitExpr(uint8_t v[kSimd128Size])
74       : kind_(kS128Const), operands_(nullptr) {
75     memcpy(immediate_.s128_const.data(), v, kSimd128Size);
76   }
77 
GlobalGet(uint32_t index)78   static WasmInitExpr GlobalGet(uint32_t index) {
79     WasmInitExpr expr;
80     expr.kind_ = kGlobalGet;
81     expr.immediate_.index = index;
82     return expr;
83   }
84 
RefFuncConst(uint32_t index)85   static WasmInitExpr RefFuncConst(uint32_t index) {
86     WasmInitExpr expr;
87     expr.kind_ = kRefFuncConst;
88     expr.immediate_.index = index;
89     return expr;
90   }
91 
RefNullConst(HeapType::Representation heap_type)92   static WasmInitExpr RefNullConst(HeapType::Representation heap_type) {
93     WasmInitExpr expr;
94     expr.kind_ = kRefNullConst;
95     expr.immediate_.heap_type = heap_type;
96     return expr;
97   }
98 
StructNewWithRtt(uint32_t index,ZoneVector<WasmInitExpr> * elements)99   static WasmInitExpr StructNewWithRtt(uint32_t index,
100                                        ZoneVector<WasmInitExpr>* elements) {
101     WasmInitExpr expr(kStructNewWithRtt, elements);
102     expr.immediate_.index = index;
103     return expr;
104   }
105 
StructNew(uint32_t index,ZoneVector<WasmInitExpr> * elements)106   static WasmInitExpr StructNew(uint32_t index,
107                                 ZoneVector<WasmInitExpr>* elements) {
108     WasmInitExpr expr(kStructNew, elements);
109     expr.immediate_.index = index;
110     return expr;
111   }
112 
StructNewDefaultWithRtt(Zone * zone,uint32_t index,WasmInitExpr rtt)113   static WasmInitExpr StructNewDefaultWithRtt(Zone* zone, uint32_t index,
114                                               WasmInitExpr rtt) {
115     WasmInitExpr expr(kStructNewDefaultWithRtt,
116                       zone->New<ZoneVector<WasmInitExpr>>(
117                           std::initializer_list<WasmInitExpr>{rtt}, zone));
118     expr.immediate_.index = index;
119     return expr;
120   }
121 
StructNewDefault(uint32_t index)122   static WasmInitExpr StructNewDefault(uint32_t index) {
123     WasmInitExpr expr;
124     expr.kind_ = kStructNewDefault;
125     expr.immediate_.index = index;
126     return expr;
127   }
128 
ArrayInit(uint32_t index,ZoneVector<WasmInitExpr> * elements)129   static WasmInitExpr ArrayInit(uint32_t index,
130                                 ZoneVector<WasmInitExpr>* elements) {
131     WasmInitExpr expr(kArrayInit, elements);
132     expr.immediate_.index = index;
133     return expr;
134   }
135 
ArrayInitStatic(uint32_t index,ZoneVector<WasmInitExpr> * elements)136   static WasmInitExpr ArrayInitStatic(uint32_t index,
137                                       ZoneVector<WasmInitExpr>* elements) {
138     WasmInitExpr expr(kArrayInitStatic, elements);
139     expr.immediate_.index = index;
140     return expr;
141   }
142 
RttCanon(uint32_t index)143   static WasmInitExpr RttCanon(uint32_t index) {
144     WasmInitExpr expr;
145     expr.kind_ = kRttCanon;
146     expr.immediate_.index = index;
147     return expr;
148   }
149 
immediate()150   Immediate immediate() const { return immediate_; }
kind()151   Operator kind() const { return kind_; }
operands()152   const ZoneVector<WasmInitExpr>* operands() const { return operands_; }
153 
154   bool operator==(const WasmInitExpr& other) const {
155     if (kind() != other.kind()) return false;
156     switch (kind()) {
157       case kNone:
158         return true;
159       case kGlobalGet:
160       case kRefFuncConst:
161       case kRttCanon:
162         return immediate().index == other.immediate().index;
163       case kI32Const:
164         return immediate().i32_const == other.immediate().i32_const;
165       case kI64Const:
166         return immediate().i64_const == other.immediate().i64_const;
167       case kF32Const:
168         return immediate().f32_const == other.immediate().f32_const;
169       case kF64Const:
170         return immediate().f64_const == other.immediate().f64_const;
171       case kS128Const:
172         return immediate().s128_const == other.immediate().s128_const;
173       case kRefNullConst:
174         return immediate().heap_type == other.immediate().heap_type;
175       case kStructNewWithRtt:
176       case kStructNew:
177       case kStructNewDefaultWithRtt:
178       case kStructNewDefault:
179         if (immediate().index != other.immediate().index) return false;
180         DCHECK_EQ(operands()->size(), other.operands()->size());
181         for (uint32_t i = 0; i < operands()->size(); i++) {
182           if (operands()[i] != other.operands()[i]) return false;
183         }
184         return true;
185       case kArrayInit:
186       case kArrayInitStatic:
187         if (immediate().index != other.immediate().index) return false;
188         if (operands()->size() != other.operands()->size()) return false;
189         for (uint32_t i = 0; i < operands()->size(); i++) {
190           if (operands()[i] != other.operands()[i]) return false;
191         }
192         return true;
193     }
194   }
195 
196   V8_INLINE bool operator!=(const WasmInitExpr& other) const {
197     return !(*this == other);
198   }
199 
200   ValueType type(const WasmModule* module,
201                  const WasmFeatures& enabled_features) const;
202 
203  private:
WasmInitExpr(Operator kind,const ZoneVector<WasmInitExpr> * operands)204   WasmInitExpr(Operator kind, const ZoneVector<WasmInitExpr>* operands)
205       : kind_(kind), operands_(operands) {}
206   Immediate immediate_;
207   Operator kind_;
208   const ZoneVector<WasmInitExpr>* operands_;
209 };
210 
211 ASSERT_TRIVIALLY_COPYABLE(WasmInitExpr);
212 
213 }  // namespace wasm
214 }  // namespace internal
215 }  // namespace v8
216 
217 #endif  // V8_WASM_WASM_INIT_EXPR_H_
218