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