v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
wasm-init-expr.h
Go to the documentation of this file.
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#ifndef V8_WASM_WASM_INIT_EXPR_H_
6#define V8_WASM_WASM_INIT_EXPR_H_
7
8#if !V8_ENABLE_WEBASSEMBLY
9#error This header should only be included if WebAssembly is enabled.
10#endif // !V8_ENABLE_WEBASSEMBLY
11
12#include <memory>
13
14#include "src/wasm/value-type.h"
16
17namespace v8 {
18namespace internal {
19namespace wasm {
20
21struct WasmModule;
22
23// Representation of an constant expression. Unlike {ConstantExpression}, this
24// does not use {WireBytesRef}, i.e., it does not depend on a wasm module's
25// bytecode representation.
26class WasmInitExpr : public ZoneObject {
27 public:
53
54 union Immediate {
55 int32_t i32_const;
56 int64_t i64_const;
57 float f32_const;
58 double f64_const;
59 std::array<uint8_t, kSimd128Size> s128_const;
60 uint32_t index;
61 uint32_t heap_type_; // Read with {heap_type()}.
62 };
63
64 explicit WasmInitExpr(int32_t v) : kind_(kI32Const), operands_(nullptr) {
66 }
67 explicit WasmInitExpr(int64_t v) : kind_(kI64Const), operands_(nullptr) {
69 }
70 explicit WasmInitExpr(float v) : kind_(kF32Const), operands_(nullptr) {
72 }
73 explicit WasmInitExpr(double v) : kind_(kF64Const), operands_(nullptr) {
75 }
76 explicit WasmInitExpr(uint8_t v[kSimd128Size])
77 : kind_(kS128Const), operands_(nullptr) {
78 memcpy(immediate_.s128_const.data(), v, kSimd128Size);
79 }
80
84
86 WasmInitExpr rhs) {
87 DCHECK(op == kI32Add || op == kI32Sub || op == kI32Mul || op == kI64Add ||
88 op == kI64Sub || op == kI64Mul);
89 return WasmInitExpr(zone, op, {lhs, rhs});
90 }
91
92 static WasmInitExpr GlobalGet(uint32_t index) {
94 expr.immediate_.index = index;
95 return expr;
96 }
97
98 static WasmInitExpr RefFuncConst(uint32_t index) {
100 expr.immediate_.index = index;
101 return expr;
102 }
103
109
111 ZoneVector<WasmInitExpr>* elements) {
112 WasmInitExpr expr(kStructNew, elements);
113 expr.immediate_.index = index.index;
114 return expr;
115 }
116
119 expr.immediate_.index = index.index;
120 return expr;
121 }
122
124 WasmInitExpr initial, WasmInitExpr length) {
125 WasmInitExpr expr(zone, kArrayNew, {initial, length});
126 expr.immediate_.index = index.index;
127 return expr;
128 }
129
131 WasmInitExpr length) {
132 WasmInitExpr expr(zone, kArrayNewDefault, {length});
133 expr.immediate_.index = index.index;
134 return expr;
135 }
136
138 ZoneVector<WasmInitExpr>* elements) {
139 WasmInitExpr expr(kArrayNewFixed, elements);
140 expr.immediate_.index = index.index;
141 return expr;
142 }
143
144 static WasmInitExpr RefI31(Zone* zone, WasmInitExpr value) {
145 WasmInitExpr expr(zone, kRefI31, {value});
146 return expr;
147 }
148
149 static WasmInitExpr StringConst(uint32_t index) {
151 expr.immediate_.index = index;
152 return expr;
153 }
154
156 return WasmInitExpr(zone, kAnyConvertExtern, {arg});
157 }
158
160 return WasmInitExpr(zone, kExternConvertAny, {arg});
161 }
162
163 Immediate immediate() const { return immediate_; }
164 Operator kind() const { return kind_; }
165 const ZoneVector<WasmInitExpr>* operands() const { return operands_; }
166
167 bool operator==(const WasmInitExpr& other) const {
168 if (kind() != other.kind()) return false;
169 switch (kind()) {
170 case kGlobalGet:
171 case kRefFuncConst:
172 case kStringConst:
173 return immediate().index == other.immediate().index;
174 case kI32Const:
175 return immediate().i32_const == other.immediate().i32_const;
176 case kI64Const:
177 return immediate().i64_const == other.immediate().i64_const;
178 case kF32Const:
179 return immediate().f32_const == other.immediate().f32_const;
180 case kF64Const:
181 return immediate().f64_const == other.immediate().f64_const;
182 case kI32Add:
183 case kI32Sub:
184 case kI32Mul:
185 case kI64Add:
186 case kI64Sub:
187 case kI64Mul:
188 return operands_[0] == other.operands_[0] &&
189 operands_[1] == other.operands_[1];
190 case kS128Const:
191 return immediate().s128_const == other.immediate().s128_const;
192 case kRefNullConst:
193 return heap_type() == other.heap_type();
194 case kStructNew:
196 case kArrayNew:
197 case kArrayNewDefault:
198 if (immediate().index != other.immediate().index) return false;
199 DCHECK_EQ(operands()->size(), other.operands()->size());
200 for (uint32_t i = 0; i < operands()->size(); i++) {
201 if (operands()[i] != other.operands()[i]) return false;
202 }
203 return true;
204 case kArrayNewFixed:
205 if (immediate().index != other.immediate().index) return false;
206 if (operands()->size() != other.operands()->size()) return false;
207 for (uint32_t i = 0; i < operands()->size(); i++) {
208 if (operands()[i] != other.operands()[i]) return false;
209 }
210 return true;
211 case kRefI31:
214 return operands_[0] == other.operands_[0];
215 }
216 }
217
219 // No initializer, emit a default value.
220 switch (type.kind()) {
221 case kI8:
222 case kI16:
223 case kI32:
224 return WasmInitExpr(int32_t{0});
225 case kI64:
226 return WasmInitExpr(int64_t{0});
227 case kF16:
228 case kF32:
229 return WasmInitExpr(0.0f);
230 case kF64:
231 return WasmInitExpr(0.0);
232 case kRefNull:
233 return WasmInitExpr::RefNullConst(type.heap_type());
234 case kS128: {
235 uint8_t value[kSimd128Size] = {0};
236 return WasmInitExpr(value);
237 }
238 case kVoid:
239 case kTop:
240 case kBottom:
241 case kRef:
242 UNREACHABLE();
243 }
244 }
245
246 private:
249 explicit WasmInitExpr(Operator kind) : kind_(kind), operands_(nullptr) {}
251 std::initializer_list<WasmInitExpr> operands)
252 : kind_(kind),
253 operands_(zone->New<ZoneVector<WasmInitExpr>>(operands, zone)) {}
257};
258
260
261} // namespace wasm
262} // namespace internal
263} // namespace v8
264
265#endif // V8_WASM_WASM_INIT_EXPR_H_
static constexpr HeapType FromBits(uint32_t bits)
Definition value-type.h:721
constexpr uint32_t raw_bit_field() const
Definition value-type.h:594
static WasmInitExpr RefI31(Zone *zone, WasmInitExpr value)
WasmInitExpr(Zone *zone, Operator kind, std::initializer_list< WasmInitExpr > operands)
const ZoneVector< WasmInitExpr > * operands_
static WasmInitExpr AnyConvertExtern(Zone *zone, WasmInitExpr arg)
static WasmInitExpr GlobalGet(uint32_t index)
bool operator==(const WasmInitExpr &other) const
static WasmInitExpr ExternConvertAny(Zone *zone, WasmInitExpr arg)
static WasmInitExpr RefNullConst(HeapType heap_type)
WasmInitExpr(uint8_t v[kSimd128Size])
WasmInitExpr(Operator kind, const ZoneVector< WasmInitExpr > *operands)
static WasmInitExpr StringConst(uint32_t index)
static WasmInitExpr StructNewDefault(ModuleTypeIndex index)
static WasmInitExpr ArrayNewDefault(Zone *zone, ModuleTypeIndex index, WasmInitExpr length)
const ZoneVector< WasmInitExpr > * operands() const
static WasmInitExpr ArrayNewFixed(ModuleTypeIndex index, ZoneVector< WasmInitExpr > *elements)
static WasmInitExpr DefaultValue(ValueType type)
static WasmInitExpr ArrayNew(Zone *zone, ModuleTypeIndex index, WasmInitExpr initial, WasmInitExpr length)
static WasmInitExpr Binop(Zone *zone, Operator op, WasmInitExpr lhs, WasmInitExpr rhs)
static WasmInitExpr StructNew(ModuleTypeIndex index, ZoneVector< WasmInitExpr > *elements)
static WasmInitExpr RefFuncConst(uint32_t index)
constexpr int kSimd128Size
Definition globals.h:706
wasm::WasmModule WasmModule
Definition c-api.cc:87
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
#define ASSERT_TRIVIALLY_COPYABLE(T)
Definition macros.h:267
std::array< uint8_t, kSimd128Size > s128_const