• 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 #ifndef V8_WASM_WASM_OPCODES_INL_H_
6 #define V8_WASM_WASM_OPCODES_INL_H_
7 
8 #include <array>
9 
10 #include "src/base/template-utils.h"
11 #include "src/codegen/signature.h"
12 #include "src/execution/messages.h"
13 #include "src/runtime/runtime.h"
14 #include "src/wasm/wasm-opcodes.h"
15 
16 namespace v8 {
17 namespace internal {
18 namespace wasm {
19 
20 #define CASE_OP(name, str) \
21   case kExpr##name:        \
22     return str;
23 #define CASE_I32_OP(name, str) CASE_OP(I32##name, "i32." str)
24 #define CASE_I64_OP(name, str) CASE_OP(I64##name, "i64." str)
25 #define CASE_F32_OP(name, str) CASE_OP(F32##name, "f32." str)
26 #define CASE_F64_OP(name, str) CASE_OP(F64##name, "f64." str)
27 #define CASE_REF_OP(name, str) CASE_OP(Ref##name, "ref." str)
28 #define CASE_F64x2_OP(name, str) CASE_OP(F64x2##name, "f64x2." str)
29 #define CASE_F32x4_OP(name, str) CASE_OP(F32x4##name, "f32x4." str)
30 #define CASE_I64x2_OP(name, str) CASE_OP(I64x2##name, "i64x2." str)
31 #define CASE_I32x4_OP(name, str) CASE_OP(I32x4##name, "i32x4." str)
32 #define CASE_I16x8_OP(name, str) CASE_OP(I16x8##name, "i16x8." str)
33 #define CASE_I8x16_OP(name, str) CASE_OP(I8x16##name, "i8x16." str)
34 #define CASE_S128_OP(name, str) CASE_OP(S128##name, "s128." str)
35 #define CASE_S64x2_OP(name, str) CASE_OP(S64x2##name, "s64x2." str)
36 #define CASE_S32x4_OP(name, str) CASE_OP(S32x4##name, "s32x4." str)
37 #define CASE_S16x8_OP(name, str) CASE_OP(S16x8##name, "s16x8." str)
38 #define CASE_V32x4_OP(name, str) CASE_OP(V32x4##name, "v32x4." str)
39 #define CASE_V16x8_OP(name, str) CASE_OP(V16x8##name, "v16x8." str)
40 #define CASE_V8x16_OP(name, str) CASE_OP(V8x16##name, "v8x16." str)
41 #define CASE_INT_OP(name, str) CASE_I32_OP(name, str) CASE_I64_OP(name, str)
42 #define CASE_FLOAT_OP(name, str) CASE_F32_OP(name, str) CASE_F64_OP(name, str)
43 #define CASE_ALL_OP(name, str) CASE_FLOAT_OP(name, str) CASE_INT_OP(name, str)
44 #define CASE_SIMD_OP(name, str)                                              \
45   CASE_F64x2_OP(name, str) CASE_I64x2_OP(name, str) CASE_F32x4_OP(name, str) \
46       CASE_I32x4_OP(name, str) CASE_I16x8_OP(name, str)                      \
47           CASE_I8x16_OP(name, str)
48 #define CASE_SIMDF_OP(name, str) \
49   CASE_F32x4_OP(name, str) CASE_F64x2_OP(name, str)
50 #define CASE_SIMDI_OP(name, str) \
51   CASE_I32x4_OP(name, str) CASE_I16x8_OP(name, str) CASE_I8x16_OP(name, str)
52 #define CASE_SIMDV_OP(name, str) \
53   CASE_V32x4_OP(name, str) CASE_V16x8_OP(name, str) CASE_V8x16_OP(name, str)
54 #define CASE_SIGN_OP(TYPE, name, str) \
55   CASE_##TYPE##_OP(name##S, str "_s") CASE_##TYPE##_OP(name##U, str "_u")
56 #define CASE_UNSIGNED_OP(TYPE, name, str) CASE_##TYPE##_OP(name##U, str "_u")
57 #define CASE_ALL_SIGN_OP(name, str) \
58   CASE_FLOAT_OP(name, str) CASE_SIGN_OP(INT, name, str)
59 #define CASE_CONVERT_OP(name, RES, SRC, src_suffix, str) \
60   CASE_##RES##_OP(U##name##SRC, str "_" src_suffix "_u") \
61       CASE_##RES##_OP(S##name##SRC, str "_" src_suffix "_s")
62 #define CASE_CONVERT_SAT_OP(name, RES, SRC, src_suffix, str)      \
63   CASE_##RES##_OP(U##name##Sat##SRC, str "_sat_" src_suffix "_u") \
64       CASE_##RES##_OP(S##name##Sat##SRC, str "_sat_" src_suffix "_s")
65 #define CASE_L32_OP(name, str)          \
66   CASE_SIGN_OP(I32, name##8, str "8")   \
67   CASE_SIGN_OP(I32, name##16, str "16") \
68   CASE_I32_OP(name, str "32")
69 #define CASE_U32_OP(name, str)            \
70   CASE_I32_OP(name, str "32")             \
71   CASE_UNSIGNED_OP(I32, name##8, str "8") \
72   CASE_UNSIGNED_OP(I32, name##16, str "16")
73 #define CASE_UNSIGNED_ALL_OP(name, str)     \
74   CASE_U32_OP(name, str)                    \
75   CASE_I64_OP(name, str "64")               \
76   CASE_UNSIGNED_OP(I64, name##8, str "8")   \
77   CASE_UNSIGNED_OP(I64, name##16, str "16") \
78   CASE_UNSIGNED_OP(I64, name##32, str "32")
79 
80 // static
OpcodeName(WasmOpcode opcode)81 constexpr const char* WasmOpcodes::OpcodeName(WasmOpcode opcode) {
82   switch (opcode) {
83     // clang-format off
84 
85     // Standard opcodes
86     CASE_INT_OP(Eqz, "eqz")
87     CASE_ALL_OP(Eq, "eq")
88     CASE_ALL_OP(Ne, "ne")
89     CASE_ALL_OP(Add, "add")
90     CASE_ALL_OP(Sub, "sub")
91     CASE_ALL_OP(Mul, "mul")
92     CASE_ALL_SIGN_OP(Lt, "lt")
93     CASE_ALL_SIGN_OP(Gt, "gt")
94     CASE_ALL_SIGN_OP(Le, "le")
95     CASE_ALL_SIGN_OP(Ge, "ge")
96     CASE_INT_OP(Clz, "clz")
97     CASE_INT_OP(Ctz, "ctz")
98     CASE_INT_OP(Popcnt, "popcnt")
99     CASE_ALL_SIGN_OP(Div, "div")
100     CASE_SIGN_OP(INT, Rem, "rem")
101     CASE_INT_OP(And, "and")
102     CASE_INT_OP(Ior, "or")
103     CASE_INT_OP(Xor, "xor")
104     CASE_INT_OP(Shl, "shl")
105     CASE_SIGN_OP(INT, Shr, "shr")
106     CASE_INT_OP(Rol, "rol")
107     CASE_INT_OP(Ror, "ror")
108     CASE_FLOAT_OP(Abs, "abs")
109     CASE_FLOAT_OP(Neg, "neg")
110     CASE_FLOAT_OP(Ceil, "ceil")
111     CASE_FLOAT_OP(Floor, "floor")
112     CASE_FLOAT_OP(Trunc, "trunc")
113     CASE_FLOAT_OP(NearestInt, "nearest")
114     CASE_FLOAT_OP(Sqrt, "sqrt")
115     CASE_FLOAT_OP(Min, "min")
116     CASE_FLOAT_OP(Max, "max")
117     CASE_FLOAT_OP(CopySign, "copysign")
118     CASE_REF_OP(Null, "null")
119     CASE_REF_OP(IsNull, "is_null")
120     CASE_REF_OP(Func, "func")
121     CASE_REF_OP(AsNonNull, "as_non_null")
122     CASE_I32_OP(ConvertI64, "wrap_i64")
123     CASE_CONVERT_OP(Convert, INT, F32, "f32", "trunc")
124     CASE_CONVERT_OP(Convert, INT, F64, "f64", "trunc")
125     CASE_CONVERT_OP(Convert, I64, I32, "i32", "extend")
126     CASE_CONVERT_OP(Convert, F32, I32, "i32", "convert")
127     CASE_CONVERT_OP(Convert, F32, I64, "i64", "convert")
128     CASE_F32_OP(ConvertF64, "demote_f64")
129     CASE_CONVERT_OP(Convert, F64, I32, "i32", "convert")
130     CASE_CONVERT_OP(Convert, F64, I64, "i64", "convert")
131     CASE_F64_OP(ConvertF32, "promote_f32")
132     CASE_I32_OP(ReinterpretF32, "reinterpret_f32")
133     CASE_I64_OP(ReinterpretF64, "reinterpret_f64")
134     CASE_F32_OP(ReinterpretI32, "reinterpret_i32")
135     CASE_F64_OP(ReinterpretI64, "reinterpret_i64")
136     CASE_INT_OP(SExtendI8, "extend8_s")
137     CASE_INT_OP(SExtendI16, "extend16_s")
138     CASE_I64_OP(SExtendI32, "extend32_s")
139     CASE_OP(Unreachable, "unreachable")
140     CASE_OP(Nop, "nop")
141     CASE_OP(Block, "block")
142     CASE_OP(Loop, "loop")
143     CASE_OP(If, "if")
144     CASE_OP(Else, "else")
145     CASE_OP(End, "end")
146     CASE_OP(Br, "br")
147     CASE_OP(BrIf, "br_if")
148     CASE_OP(BrTable, "br_table")
149     CASE_OP(Return, "return")
150     CASE_OP(CallFunction, "call")
151     CASE_OP(CallIndirect, "call_indirect")
152     CASE_OP(ReturnCall, "return_call")
153     CASE_OP(ReturnCallIndirect, "return_call_indirect")
154     CASE_OP(CallRef, "call_ref")
155     CASE_OP(ReturnCallRef, "return_call_ref")
156     CASE_OP(BrOnNull, "br_on_null")
157     CASE_OP(Drop, "drop")
158     CASE_OP(Select, "select")
159     CASE_OP(SelectWithType, "select")
160     CASE_OP(LocalGet, "local.get")
161     CASE_OP(LocalSet, "local.set")
162     CASE_OP(LocalTee, "local.tee")
163     CASE_OP(GlobalGet, "global.get")
164     CASE_OP(GlobalSet, "global.set")
165     CASE_OP(TableGet, "table.get")
166     CASE_OP(TableSet, "table.set")
167     CASE_ALL_OP(Const, "const")
168     CASE_OP(MemorySize, "memory.size")
169     CASE_OP(MemoryGrow, "memory.grow")
170     CASE_ALL_OP(LoadMem, "load")
171     CASE_SIGN_OP(INT, LoadMem8, "load8")
172     CASE_SIGN_OP(INT, LoadMem16, "load16")
173     CASE_SIGN_OP(I64, LoadMem32, "load32")
174     CASE_S128_OP(LoadMem, "load128")
175     CASE_S128_OP(Const, "const")
176     CASE_ALL_OP(StoreMem, "store")
177     CASE_INT_OP(StoreMem8, "store8")
178     CASE_INT_OP(StoreMem16, "store16")
179     CASE_I64_OP(StoreMem32, "store32")
180     CASE_S128_OP(StoreMem, "store128")
181 
182     // Exception handling opcodes.
183     CASE_OP(Try, "try")
184     CASE_OP(Catch, "catch")
185     CASE_OP(Throw, "throw")
186     CASE_OP(Rethrow, "rethrow")
187     CASE_OP(BrOnExn, "br_on_exn")
188 
189     // asm.js-only opcodes.
190     CASE_F64_OP(Acos, "acos")
191     CASE_F64_OP(Asin, "asin")
192     CASE_F64_OP(Atan, "atan")
193     CASE_F64_OP(Cos, "cos")
194     CASE_F64_OP(Sin, "sin")
195     CASE_F64_OP(Tan, "tan")
196     CASE_F64_OP(Exp, "exp")
197     CASE_F64_OP(Log, "log")
198     CASE_F64_OP(Atan2, "atan2")
199     CASE_F64_OP(Pow, "pow")
200     CASE_F64_OP(Mod, "mod")
201     CASE_F32_OP(AsmjsLoadMem, "asmjs_load")
202     CASE_F64_OP(AsmjsLoadMem, "asmjs_load")
203     CASE_L32_OP(AsmjsLoadMem, "asmjs_load")
204     CASE_I32_OP(AsmjsStoreMem, "asmjs_store")
205     CASE_F32_OP(AsmjsStoreMem, "asmjs_store")
206     CASE_F64_OP(AsmjsStoreMem, "asmjs_store")
207     CASE_I32_OP(AsmjsStoreMem8, "asmjs_store8")
208     CASE_I32_OP(AsmjsStoreMem16, "asmjs_store16")
209     CASE_SIGN_OP(I32, AsmjsDiv, "asmjs_div")
210     CASE_SIGN_OP(I32, AsmjsRem, "asmjs_rem")
211     CASE_I32_OP(AsmjsSConvertF32, "asmjs_convert_f32_s")
212     CASE_I32_OP(AsmjsUConvertF32, "asmjs_convert_f32_u")
213     CASE_I32_OP(AsmjsSConvertF64, "asmjs_convert_f64_s")
214     CASE_I32_OP(AsmjsUConvertF64, "asmjs_convert_f64_u")
215 
216     // Numeric Opcodes.
217     CASE_CONVERT_SAT_OP(Convert, I32, F32, "f32", "trunc")
218     CASE_CONVERT_SAT_OP(Convert, I32, F64, "f64", "trunc")
219     CASE_CONVERT_SAT_OP(Convert, I64, F32, "f32", "trunc")
220     CASE_CONVERT_SAT_OP(Convert, I64, F64, "f64", "trunc")
221     CASE_OP(MemoryInit, "memory.init")
222     CASE_OP(DataDrop, "data.drop")
223     CASE_OP(MemoryCopy, "memory.copy")
224     CASE_OP(MemoryFill, "memory.fill")
225     CASE_OP(TableInit, "table.init")
226     CASE_OP(ElemDrop, "elem.drop")
227     CASE_OP(TableCopy, "table.copy")
228     CASE_OP(TableGrow, "table.grow")
229     CASE_OP(TableSize, "table.size")
230     CASE_OP(TableFill, "table.fill")
231 
232     // SIMD opcodes.
233     CASE_SIMD_OP(Splat, "splat")
234     CASE_SIMD_OP(Neg, "neg")
235     CASE_SIMDF_OP(Sqrt, "sqrt")
236     CASE_SIMD_OP(Eq, "eq")
237     CASE_SIMDF_OP(Ne, "ne")
238     CASE_SIMDI_OP(Ne, "ne")
239     CASE_SIMD_OP(Add, "add")
240     CASE_SIMD_OP(Sub, "sub")
241     CASE_SIMD_OP(Mul, "mul")
242     CASE_SIMDF_OP(Div, "div")
243     CASE_SIMDF_OP(Lt, "lt")
244     CASE_SIMDF_OP(Le, "le")
245     CASE_SIMDF_OP(Gt, "gt")
246     CASE_SIMDF_OP(Ge, "ge")
247     CASE_SIMDF_OP(Abs, "abs")
248     CASE_F32x4_OP(AddHoriz, "add_horizontal")
249     CASE_F32x4_OP(RecipApprox, "recip_approx")
250     CASE_F32x4_OP(RecipSqrtApprox, "recip_sqrt_approx")
251     CASE_SIMDF_OP(Min, "min")
252     CASE_SIMDF_OP(Max, "max")
253     CASE_CONVERT_OP(Convert, F32x4, I32x4, "i32", "convert")
254     CASE_CONVERT_OP(Convert, I32x4, F32x4, "f32", "convert")
255     CASE_CONVERT_OP(Convert, I32x4, I16x8Low, "i32", "convert")
256     CASE_CONVERT_OP(Convert, I32x4, I16x8High, "i32", "convert")
257     CASE_CONVERT_OP(Convert, I16x8, I32x4, "i32", "convert")
258     CASE_CONVERT_OP(Convert, I16x8, I8x16Low, "i32", "convert")
259     CASE_CONVERT_OP(Convert, I16x8, I8x16High, "i32", "convert")
260     CASE_CONVERT_OP(Convert, I8x16, I16x8, "i32", "convert")
261     CASE_SIMDF_OP(ExtractLane, "extract_lane")
262     CASE_SIMDF_OP(ReplaceLane, "replace_lane")
263     CASE_I64x2_OP(ExtractLane, "extract_lane")
264     CASE_I64x2_OP(ReplaceLane, "replace_lane")
265     CASE_I32x4_OP(ExtractLane, "extract_lane")
266     CASE_SIGN_OP(I16x8, ExtractLane, "extract_lane")
267     CASE_SIGN_OP(I8x16, ExtractLane, "extract_lane")
268     CASE_SIMDI_OP(ReplaceLane, "replace_lane")
269     CASE_SIGN_OP(SIMDI, Min, "min")
270     CASE_SIGN_OP(SIMDI, Max, "max")
271     CASE_SIGN_OP(SIMDI, Lt, "lt")
272     CASE_SIGN_OP(SIMDI, Le, "le")
273     CASE_SIGN_OP(SIMDI, Gt, "gt")
274     CASE_SIGN_OP(SIMDI, Ge, "ge")
275     CASE_CONVERT_OP(Convert, I64x2, I32x4Low, "i32", "convert")
276     CASE_CONVERT_OP(Convert, I64x2, I32x4High, "i32", "convert")
277     CASE_SIGN_OP(SIMDI, Shr, "shr")
278     CASE_SIGN_OP(I64x2, Shr, "shr")
279     CASE_SIMDI_OP(Shl, "shl")
280     CASE_I64x2_OP(Shl, "shl")
281     CASE_I32x4_OP(AddHoriz, "add_horizontal")
282     CASE_I16x8_OP(AddHoriz, "add_horizontal")
283     CASE_SIGN_OP(I16x8, AddSat, "add_sat")
284     CASE_SIGN_OP(I8x16, AddSat, "add_sat")
285     CASE_SIGN_OP(I16x8, SubSat, "sub_sat")
286     CASE_SIGN_OP(I8x16, SubSat, "sub_sat")
287     CASE_S128_OP(And, "and")
288     CASE_S128_OP(Or, "or")
289     CASE_S128_OP(Xor, "xor")
290     CASE_S128_OP(Not, "not")
291     CASE_S128_OP(Select, "select")
292     CASE_S128_OP(AndNot, "andnot")
293     CASE_I8x16_OP(Swizzle, "swizzle")
294     CASE_I8x16_OP(Shuffle, "shuffle")
295     CASE_SIMDV_OP(AnyTrue, "any_true")
296     CASE_SIMDV_OP(AllTrue, "all_true")
297     CASE_SIMDF_OP(Qfma, "qfma")
298     CASE_SIMDF_OP(Qfms, "qfms")
299 
300     CASE_S128_OP(Load32Zero, "load32_zero")
301     CASE_S128_OP(Load64Zero, "load64_zero")
302     CASE_S128_OP(Load8Splat, "load8_splat")
303     CASE_S128_OP(Load16Splat, "load16_splat")
304     CASE_S128_OP(Load32Splat, "load32_splat")
305     CASE_S128_OP(Load64Splat, "load64_splat")
306     CASE_S128_OP(Load8x8S, "load8x8_s")
307     CASE_S128_OP(Load8x8U, "load8x8_u")
308     CASE_S128_OP(Load16x4S, "load16x4_s")
309     CASE_S128_OP(Load16x4U, "load16x4_u")
310     CASE_S128_OP(Load32x2S, "load32x2_s")
311     CASE_S128_OP(Load32x2U, "load32x2_u")
312     CASE_S128_OP(Load8Lane, "load8_lane")
313     CASE_S128_OP(Load16Lane, "load16_lane")
314     CASE_S128_OP(Load32Lane, "load32_lane")
315     CASE_S128_OP(Load64Lane, "load64_lane")
316     CASE_S128_OP(Store8Lane, "store8_lane")
317     CASE_S128_OP(Store16Lane, "store16_lane")
318     CASE_S128_OP(Store32Lane, "store32_lane")
319     CASE_S128_OP(Store64Lane, "store64_lane")
320 
321     CASE_I8x16_OP(RoundingAverageU, "avgr_u")
322     CASE_I16x8_OP(RoundingAverageU, "avgr_u")
323     CASE_I16x8_OP(Q15MulRSatS, "q15mulr_sat_s")
324 
325     CASE_I8x16_OP(Abs, "abs")
326     CASE_I8x16_OP(Popcnt, "popcnt")
327     CASE_I16x8_OP(Abs, "abs")
328     CASE_I32x4_OP(Abs, "abs")
329 
330     CASE_I8x16_OP(BitMask, "bitmask")
331     CASE_I16x8_OP(BitMask, "bitmask")
332     CASE_I32x4_OP(BitMask, "bitmask")
333     CASE_I64x2_OP(BitMask, "bitmask")
334 
335     CASE_F32x4_OP(Pmin, "pmin")
336     CASE_F32x4_OP(Pmax, "pmax")
337     CASE_F64x2_OP(Pmin, "pmin")
338     CASE_F64x2_OP(Pmax, "pmax")
339 
340     CASE_F32x4_OP(Ceil, "ceil")
341     CASE_F32x4_OP(Floor, "floor")
342     CASE_F32x4_OP(Trunc, "trunc")
343     CASE_F32x4_OP(NearestInt, "nearest")
344     CASE_F64x2_OP(Ceil, "ceil")
345     CASE_F64x2_OP(Floor, "floor")
346     CASE_F64x2_OP(Trunc, "trunc")
347     CASE_F64x2_OP(NearestInt, "nearest")
348 
349     CASE_I32x4_OP(DotI16x8S, "dot_i16x8_s")
350 
351     CASE_SIGN_OP(I16x8, ExtMulLowI8x16, "extmul_low_i8x16")
352     CASE_SIGN_OP(I16x8, ExtMulHighI8x16, "extmul_high_i8x16")
353     CASE_SIGN_OP(I32x4, ExtMulLowI16x8, "extmul_low_i16x8")
354     CASE_SIGN_OP(I32x4, ExtMulHighI16x8, "extmul_high_i16x8")
355     CASE_SIGN_OP(I64x2, ExtMulLowI32x4, "extmul_low_i32x4")
356     CASE_SIGN_OP(I64x2, ExtMulHighI32x4, "extmul_high_i32x4")
357     CASE_SIMDI_OP(SignSelect, "signselect")
358     CASE_I64x2_OP(SignSelect, "signselect")
359 
360     CASE_SIGN_OP(I32x4, ExtAddPairwiseI16x8, "extadd_pairwise_i16x8")
361     CASE_SIGN_OP(I16x8, ExtAddPairwiseI8x16, "extadd_pairwise_i8x6")
362 
363     // Atomic operations.
364     CASE_OP(AtomicNotify, "atomic.notify")
365     CASE_INT_OP(AtomicWait, "atomic.wait")
366     CASE_OP(AtomicFence, "atomic.fence")
367     CASE_UNSIGNED_ALL_OP(AtomicLoad, "atomic.load")
368     CASE_UNSIGNED_ALL_OP(AtomicStore, "atomic.store")
369     CASE_UNSIGNED_ALL_OP(AtomicAdd, "atomic.add")
370     CASE_UNSIGNED_ALL_OP(AtomicSub, "atomic.sub")
371     CASE_UNSIGNED_ALL_OP(AtomicAnd, "atomic.and")
372     CASE_UNSIGNED_ALL_OP(AtomicOr, "atomic.or")
373     CASE_UNSIGNED_ALL_OP(AtomicXor, "atomic.xor")
374     CASE_UNSIGNED_ALL_OP(AtomicExchange, "atomic.xchng")
375     CASE_UNSIGNED_ALL_OP(AtomicCompareExchange, "atomic.cmpxchng")
376 
377     // GC operations.
378     CASE_OP(StructNewWithRtt, "struct.new_with_rtt")
379     CASE_OP(StructNewDefault, "struct.new_default")
380     CASE_OP(StructGet, "struct.get")
381     CASE_OP(StructGetS, "struct.get_s")
382     CASE_OP(StructGetU, "struct.get_u")
383     CASE_OP(StructSet, "struct.set")
384     CASE_OP(ArrayNewWithRtt, "array.new_with_rtt")
385     CASE_OP(ArrayNewDefault, "array.new_default")
386     CASE_OP(ArrayGet, "array.get")
387     CASE_OP(ArrayGetS, "array.get_s")
388     CASE_OP(ArrayGetU, "array.get_u")
389     CASE_OP(ArrayLen, "array.len")
390     CASE_OP(ArraySet, "array.set")
391     CASE_OP(I31New, "i31.new")
392     CASE_OP(I31GetS, "i31.get_s")
393     CASE_OP(I31GetU, "i31.get_u")
394     CASE_OP(RttCanon, "rtt.canon")
395     CASE_OP(RttSub, "rtt.sub")
396     CASE_OP(RefTest, "ref.test")
397     CASE_OP(RefCast, "ref.cast")
398     CASE_OP(BrOnCast, "br_on_cast")
399     CASE_OP(RefEq, "ref.eq")
400     CASE_OP(Let, "let")
401 
402 
403     case kNumericPrefix:
404     case kSimdPrefix:
405     case kAtomicPrefix:
406     case kGCPrefix:
407       return "unknown";
408     // clang-format on
409   }
410   // Even though the switch above handles all well-defined enum values,
411   // random modules (e.g. fuzzer generated) can call this function with
412   // random (invalid) opcodes. Handle those here:
413   return "invalid opcode";
414 }
415 
416 #undef CASE_OP
417 #undef CASE_I32_OP
418 #undef CASE_I64_OP
419 #undef CASE_F32_OP
420 #undef CASE_F64_OP
421 #undef CASE_REF_OP
422 #undef CASE_F64x2_OP
423 #undef CASE_F32x4_OP
424 #undef CASE_I64x2_OP
425 #undef CASE_I32x4_OP
426 #undef CASE_I16x8_OP
427 #undef CASE_I8x16_OP
428 #undef CASE_S128_OP
429 #undef CASE_S64x2_OP
430 #undef CASE_S32x4_OP
431 #undef CASE_S16x8_OP
432 #undef CASE_INT_OP
433 #undef CASE_FLOAT_OP
434 #undef CASE_ALL_OP
435 #undef CASE_SIMD_OP
436 #undef CASE_SIMDI_OP
437 #undef CASE_SIGN_OP
438 #undef CASE_UNSIGNED_OP
439 #undef CASE_UNSIGNED_ALL_OP
440 #undef CASE_ALL_SIGN_OP
441 #undef CASE_CONVERT_OP
442 #undef CASE_CONVERT_SAT_OP
443 #undef CASE_L32_OP
444 #undef CASE_U32_OP
445 
446 // static
IsPrefixOpcode(WasmOpcode opcode)447 constexpr bool WasmOpcodes::IsPrefixOpcode(WasmOpcode opcode) {
448   switch (opcode) {
449 #define CHECK_PREFIX(name, opcode) case k##name##Prefix:
450     FOREACH_PREFIX(CHECK_PREFIX)
451 #undef CHECK_PREFIX
452     return true;
453     default:
454       return false;
455   }
456 }
457 
458 // static
IsControlOpcode(WasmOpcode opcode)459 constexpr bool WasmOpcodes::IsControlOpcode(WasmOpcode opcode) {
460   switch (opcode) {
461 #define CHECK_OPCODE(name, opcode, _) case kExpr##name:
462     FOREACH_CONTROL_OPCODE(CHECK_OPCODE)
463 #undef CHECK_OPCODE
464     return true;
465     default:
466       return false;
467   }
468 }
469 
470 // static
IsUnconditionalJump(WasmOpcode opcode)471 constexpr bool WasmOpcodes::IsUnconditionalJump(WasmOpcode opcode) {
472   switch (opcode) {
473     case kExprUnreachable:
474     case kExprBr:
475     case kExprBrTable:
476     case kExprReturn:
477     case kExprReturnCall:
478     case kExprReturnCallIndirect:
479       return true;
480     default:
481       return false;
482   }
483 }
484 
485 // static
IsBreakable(WasmOpcode opcode)486 constexpr bool WasmOpcodes::IsBreakable(WasmOpcode opcode) {
487   switch (opcode) {
488     case kExprBlock:
489     case kExprTry:
490     case kExprCatch:
491     case kExprLoop:
492     case kExprElse:
493       return false;
494     default:
495       return true;
496   }
497 }
498 
499 // static
IsExternRefOpcode(WasmOpcode opcode)500 constexpr bool WasmOpcodes::IsExternRefOpcode(WasmOpcode opcode) {
501   switch (opcode) {
502     case kExprRefNull:
503     case kExprRefIsNull:
504     case kExprRefFunc:
505     case kExprRefAsNonNull:
506       return true;
507     default:
508       return false;
509   }
510 }
511 
512 // static
IsThrowingOpcode(WasmOpcode opcode)513 constexpr bool WasmOpcodes::IsThrowingOpcode(WasmOpcode opcode) {
514   // TODO(8729): Trapping opcodes are not yet considered to be throwing.
515   switch (opcode) {
516     case kExprThrow:
517     case kExprRethrow:
518     case kExprCallFunction:
519     case kExprCallIndirect:
520       return true;
521     default:
522       return false;
523   }
524 }
525 
526 // static
IsSimdPostMvpOpcode(WasmOpcode opcode)527 constexpr bool WasmOpcodes::IsSimdPostMvpOpcode(WasmOpcode opcode) {
528   switch (opcode) {
529 #define CHECK_OPCODE(name, opcode, _) case kExpr##name:
530     FOREACH_SIMD_POST_MVP_OPCODE(CHECK_OPCODE)
531     FOREACH_SIMD_POST_MVP_MEM_OPCODE(CHECK_OPCODE)
532 #undef CHECK_OPCODE
533     return true;
534     default:
535       return false;
536   }
537 }
538 
539 namespace impl {
540 
541 #define DECLARE_SIG_ENUM(name, ...) kSigEnum_##name,
542 enum WasmOpcodeSig : byte {
543   kSigEnum_None,
544   FOREACH_SIGNATURE(DECLARE_SIG_ENUM)
545 };
546 #undef DECLARE_SIG_ENUM
547 #define DECLARE_SIG(name, ...)                                                \
548   constexpr ValueType kTypes_##name[] = {__VA_ARGS__};                        \
549   constexpr int kReturnsCount_##name = kTypes_##name[0] == kWasmStmt ? 0 : 1; \
550   constexpr FunctionSig kSig_##name(                                          \
551       kReturnsCount_##name, static_cast<int>(arraysize(kTypes_##name)) - 1,   \
552       kTypes_##name + (1 - kReturnsCount_##name));
553 FOREACH_SIGNATURE(DECLARE_SIG)
554 #undef DECLARE_SIG
555 
556 #define DECLARE_SIG_ENTRY(name, ...) &kSig_##name,
557 constexpr const FunctionSig* kCachedSigs[] = {
558     nullptr, FOREACH_SIGNATURE(DECLARE_SIG_ENTRY)};
559 #undef DECLARE_SIG_ENTRY
560 
GetShortOpcodeSigIndex(byte opcode)561 constexpr WasmOpcodeSig GetShortOpcodeSigIndex(byte opcode) {
562 #define CASE(name, opc, sig) opcode == opc ? kSigEnum_##sig:
563   return FOREACH_SIMPLE_OPCODE(CASE) FOREACH_SIMPLE_PROTOTYPE_OPCODE(CASE)
564       kSigEnum_None;
565 #undef CASE
566 }
567 
GetAsmJsOpcodeSigIndex(byte opcode)568 constexpr WasmOpcodeSig GetAsmJsOpcodeSigIndex(byte opcode) {
569 #define CASE(name, opc, sig) opcode == opc ? kSigEnum_##sig:
570   return FOREACH_ASMJS_COMPAT_OPCODE(CASE) kSigEnum_None;
571 #undef CASE
572 }
573 
GetSimdOpcodeSigIndex(byte opcode)574 constexpr WasmOpcodeSig GetSimdOpcodeSigIndex(byte opcode) {
575 #define CASE(name, opc, sig) opcode == (opc & 0xFF) ? kSigEnum_##sig:
576   return FOREACH_SIMD_0_OPERAND_OPCODE(CASE) FOREACH_SIMD_MEM_OPCODE(CASE)
577       FOREACH_SIMD_POST_MVP_MEM_OPCODE(CASE) kSigEnum_None;
578 #undef CASE
579 }
580 
GetAtomicOpcodeSigIndex(byte opcode)581 constexpr WasmOpcodeSig GetAtomicOpcodeSigIndex(byte opcode) {
582 #define CASE(name, opc, sig) opcode == (opc & 0xFF) ? kSigEnum_##sig:
583   return FOREACH_ATOMIC_OPCODE(CASE) FOREACH_ATOMIC_0_OPERAND_OPCODE(CASE)
584       kSigEnum_None;
585 #undef CASE
586 }
587 
GetNumericOpcodeSigIndex(byte opcode)588 constexpr WasmOpcodeSig GetNumericOpcodeSigIndex(byte opcode) {
589 #define CASE(name, opc, sig) opcode == (opc & 0xFF) ? kSigEnum_##sig:
590   return FOREACH_NUMERIC_OPCODE(CASE) kSigEnum_None;
591 #undef CASE
592 }
593 
594 constexpr std::array<WasmOpcodeSig, 256> kShortSigTable =
595     base::make_array<256>(GetShortOpcodeSigIndex);
596 constexpr std::array<WasmOpcodeSig, 256> kSimpleAsmjsExprSigTable =
597     base::make_array<256>(GetAsmJsOpcodeSigIndex);
598 constexpr std::array<WasmOpcodeSig, 256> kSimdExprSigTable =
599     base::make_array<256>(GetSimdOpcodeSigIndex);
600 constexpr std::array<WasmOpcodeSig, 256> kAtomicExprSigTable =
601     base::make_array<256>(GetAtomicOpcodeSigIndex);
602 constexpr std::array<WasmOpcodeSig, 256> kNumericExprSigTable =
603     base::make_array<256>(GetNumericOpcodeSigIndex);
604 
605 }  // namespace impl
606 
Signature(WasmOpcode opcode)607 constexpr const FunctionSig* WasmOpcodes::Signature(WasmOpcode opcode) {
608   switch (opcode >> 8) {
609     case 0:
610       return impl::kCachedSigs[impl::kShortSigTable[opcode]];
611     case kSimdPrefix:
612       return impl::kCachedSigs[impl::kSimdExprSigTable[opcode & 0xFF]];
613     case kAtomicPrefix:
614       return impl::kCachedSigs[impl::kAtomicExprSigTable[opcode & 0xFF]];
615     case kNumericPrefix:
616       return impl::kCachedSigs[impl::kNumericExprSigTable[opcode & 0xFF]];
617     default:
618 #if V8_HAS_CXX14_CONSTEXPR
619       UNREACHABLE();  // invalid prefix.
620 #else
621       return nullptr;
622 #endif
623   }
624 }
625 
AsmjsSignature(WasmOpcode opcode)626 constexpr const FunctionSig* WasmOpcodes::AsmjsSignature(WasmOpcode opcode) {
627   CONSTEXPR_DCHECK(opcode < impl::kSimpleAsmjsExprSigTable.size());
628   return impl::kCachedSigs[impl::kSimpleAsmjsExprSigTable[opcode]];
629 }
630 
TrapReasonToMessageId(TrapReason reason)631 constexpr MessageTemplate WasmOpcodes::TrapReasonToMessageId(
632     TrapReason reason) {
633   switch (reason) {
634 #define TRAPREASON_TO_MESSAGE(name) \
635   case k##name:                     \
636     return MessageTemplate::kWasm##name;
637     FOREACH_WASM_TRAPREASON(TRAPREASON_TO_MESSAGE)
638 #undef TRAPREASON_TO_MESSAGE
639     default:
640       return MessageTemplate::kNone;
641   }
642 }
643 
TrapReasonMessage(TrapReason reason)644 const char* WasmOpcodes::TrapReasonMessage(TrapReason reason) {
645   return MessageFormatter::TemplateString(TrapReasonToMessageId(reason));
646 }
647 
648 }  // namespace wasm
649 }  // namespace internal
650 }  // namespace v8
651 
652 #endif  // V8_WASM_WASM_OPCODES_INL_H_
653