• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 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 #include "src/wasm/wasm-opcodes.h"
6 
7 #include <array>
8 
9 #include "src/base/template-utils.h"
10 #include "src/messages.h"
11 #include "src/runtime/runtime.h"
12 #include "src/signature.h"
13 
14 namespace v8 {
15 namespace internal {
16 namespace wasm {
17 
18 #define CASE_OP(name, str) \
19   case kExpr##name:        \
20     return str;
21 #define CASE_I32_OP(name, str) CASE_OP(I32##name, "i32." str)
22 #define CASE_I64_OP(name, str) CASE_OP(I64##name, "i64." str)
23 #define CASE_F32_OP(name, str) CASE_OP(F32##name, "f32." str)
24 #define CASE_F64_OP(name, str) CASE_OP(F64##name, "f64." str)
25 #define CASE_REF_OP(name, str) CASE_OP(Ref##name, "ref." str)
26 #define CASE_F32x4_OP(name, str) CASE_OP(F32x4##name, "f32x4." str)
27 #define CASE_I32x4_OP(name, str) CASE_OP(I32x4##name, "i32x4." str)
28 #define CASE_I16x8_OP(name, str) CASE_OP(I16x8##name, "i16x8." str)
29 #define CASE_I8x16_OP(name, str) CASE_OP(I8x16##name, "i8x16." str)
30 #define CASE_S128_OP(name, str) CASE_OP(S128##name, "s128." str)
31 #define CASE_S32x4_OP(name, str) CASE_OP(S32x4##name, "s32x4." str)
32 #define CASE_S16x8_OP(name, str) CASE_OP(S16x8##name, "s16x8." str)
33 #define CASE_S8x16_OP(name, str) CASE_OP(S8x16##name, "s8x16." str)
34 #define CASE_S1x4_OP(name, str) CASE_OP(S1x4##name, "s1x4." str)
35 #define CASE_S1x8_OP(name, str) CASE_OP(S1x8##name, "s1x8." str)
36 #define CASE_S1x16_OP(name, str) CASE_OP(S1x16##name, "s1x16." str)
37 #define CASE_INT_OP(name, str) CASE_I32_OP(name, str) CASE_I64_OP(name, str)
38 #define CASE_FLOAT_OP(name, str) CASE_F32_OP(name, str) CASE_F64_OP(name, str)
39 #define CASE_ALL_OP(name, str) CASE_FLOAT_OP(name, str) CASE_INT_OP(name, str)
40 #define CASE_SIMD_OP(name, str)                                              \
41   CASE_F32x4_OP(name, str) CASE_I32x4_OP(name, str) CASE_I16x8_OP(name, str) \
42       CASE_I8x16_OP(name, str)
43 #define CASE_SIMDI_OP(name, str) \
44   CASE_I32x4_OP(name, str) CASE_I16x8_OP(name, str) CASE_I8x16_OP(name, str)
45 #define CASE_SIGN_OP(TYPE, name, str) \
46   CASE_##TYPE##_OP(name##S, str "_s") CASE_##TYPE##_OP(name##U, str "_u")
47 #define CASE_UNSIGNED_OP(TYPE, name, str) CASE_##TYPE##_OP(name##U, str "_u")
48 #define CASE_ALL_SIGN_OP(name, str) \
49   CASE_FLOAT_OP(name, str) CASE_SIGN_OP(INT, name, str)
50 #define CASE_CONVERT_OP(name, RES, SRC, src_suffix, str) \
51   CASE_##RES##_OP(U##name##SRC, str "_u/" src_suffix)    \
52       CASE_##RES##_OP(S##name##SRC, str "_s/" src_suffix)
53 #define CASE_CONVERT_SAT_OP(name, RES, SRC, src_suffix, str)   \
54   CASE_##RES##_OP(U##name##Sat##SRC, str "_u:sat/" src_suffix) \
55       CASE_##RES##_OP(S##name##Sat##SRC, str "_s:sat/" src_suffix)
56 #define CASE_L32_OP(name, str)          \
57   CASE_SIGN_OP(I32, name##8, str "8")   \
58   CASE_SIGN_OP(I32, name##16, str "16") \
59   CASE_I32_OP(name, str "32")
60 #define CASE_U32_OP(name, str)            \
61   CASE_I32_OP(name, str "32")             \
62   CASE_UNSIGNED_OP(I32, name##8, str "8") \
63   CASE_UNSIGNED_OP(I32, name##16, str "16")
64 #define CASE_UNSIGNED_ALL_OP(name, str)     \
65   CASE_U32_OP(name, str)                    \
66   CASE_I64_OP(name, str "64")               \
67   CASE_UNSIGNED_OP(I64, name##8, str "8")   \
68   CASE_UNSIGNED_OP(I64, name##16, str "16") \
69   CASE_UNSIGNED_OP(I64, name##32, str "32")
70 
OpcodeName(WasmOpcode opcode)71 const char* WasmOpcodes::OpcodeName(WasmOpcode opcode) {
72   switch (opcode) {
73     // clang-format off
74 
75     // Standard opcodes
76     CASE_INT_OP(Eqz, "eqz")
77     CASE_ALL_OP(Eq, "eq")
78     CASE_ALL_OP(Ne, "ne")
79     CASE_ALL_OP(Add, "add")
80     CASE_ALL_OP(Sub, "sub")
81     CASE_ALL_OP(Mul, "mul")
82     CASE_ALL_SIGN_OP(Lt, "lt")
83     CASE_ALL_SIGN_OP(Gt, "gt")
84     CASE_ALL_SIGN_OP(Le, "le")
85     CASE_ALL_SIGN_OP(Ge, "ge")
86     CASE_INT_OP(Clz, "clz")
87     CASE_INT_OP(Ctz, "ctz")
88     CASE_INT_OP(Popcnt, "popcnt")
89     CASE_ALL_SIGN_OP(Div, "div")
90     CASE_SIGN_OP(INT, Rem, "rem")
91     CASE_INT_OP(And, "and")
92     CASE_INT_OP(Ior, "or")
93     CASE_INT_OP(Xor, "xor")
94     CASE_INT_OP(Shl, "shl")
95     CASE_SIGN_OP(INT, Shr, "shr")
96     CASE_INT_OP(Rol, "rol")
97     CASE_INT_OP(Ror, "ror")
98     CASE_FLOAT_OP(Abs, "abs")
99     CASE_FLOAT_OP(Neg, "neg")
100     CASE_FLOAT_OP(Ceil, "ceil")
101     CASE_FLOAT_OP(Floor, "floor")
102     CASE_FLOAT_OP(Trunc, "trunc")
103     CASE_FLOAT_OP(NearestInt, "nearest")
104     CASE_FLOAT_OP(Sqrt, "sqrt")
105     CASE_FLOAT_OP(Min, "min")
106     CASE_FLOAT_OP(Max, "max")
107     CASE_FLOAT_OP(CopySign, "copysign")
108     CASE_REF_OP(Null, "null")
109     CASE_REF_OP(IsNull, "is_null")
110     CASE_I32_OP(ConvertI64, "wrap/i64")
111     CASE_CONVERT_OP(Convert, INT, F32, "f32", "trunc")
112     CASE_CONVERT_OP(Convert, INT, F64, "f64", "trunc")
113     // TODO(kschimpf): Simplify after filling in other saturating operations.
114     CASE_CONVERT_SAT_OP(Convert, I32, F32, "f32", "trunc")
115     CASE_CONVERT_SAT_OP(Convert, I32, F64, "f64", "trunc")
116     CASE_CONVERT_SAT_OP(Convert, I64, F32, "f32", "trunc")
117     CASE_CONVERT_SAT_OP(Convert, I64, F64, "f64", "trunc")
118 
119     CASE_CONVERT_OP(Convert, I64, I32, "i32", "extend")
120     CASE_CONVERT_OP(Convert, F32, I32, "i32", "convert")
121     CASE_CONVERT_OP(Convert, F32, I64, "i64", "convert")
122     CASE_F32_OP(ConvertF64, "demote/f64")
123     CASE_CONVERT_OP(Convert, F64, I32, "i32", "convert")
124     CASE_CONVERT_OP(Convert, F64, I64, "i64", "convert")
125     CASE_F64_OP(ConvertF32, "promote/f32")
126     CASE_I32_OP(ReinterpretF32, "reinterpret/f32")
127     CASE_I64_OP(ReinterpretF64, "reinterpret/f64")
128     CASE_F32_OP(ReinterpretI32, "reinterpret/i32")
129     CASE_F64_OP(ReinterpretI64, "reinterpret/i64")
130     CASE_INT_OP(SExtendI8, "sign_extend8")
131     CASE_INT_OP(SExtendI16, "sign_extend16")
132     CASE_I64_OP(SExtendI32, "sign_extend32")
133     CASE_OP(Unreachable, "unreachable")
134     CASE_OP(Nop, "nop")
135     CASE_OP(Block, "block")
136     CASE_OP(Loop, "loop")
137     CASE_OP(If, "if")
138     CASE_OP(Else, "else")
139     CASE_OP(End, "end")
140     CASE_OP(Br, "br")
141     CASE_OP(BrIf, "br_if")
142     CASE_OP(BrTable, "br_table")
143     CASE_OP(Return, "return")
144     CASE_OP(CallFunction, "call")
145     CASE_OP(CallIndirect, "call_indirect")
146     CASE_OP(Drop, "drop")
147     CASE_OP(Select, "select")
148     CASE_OP(GetLocal, "get_local")
149     CASE_OP(SetLocal, "set_local")
150     CASE_OP(TeeLocal, "tee_local")
151     CASE_OP(GetGlobal, "get_global")
152     CASE_OP(SetGlobal, "set_global")
153     CASE_ALL_OP(Const, "const")
154     CASE_OP(MemorySize, "current_memory")
155     CASE_OP(GrowMemory, "grow_memory")
156     CASE_ALL_OP(LoadMem, "load")
157     CASE_SIGN_OP(INT, LoadMem8, "load8")
158     CASE_SIGN_OP(INT, LoadMem16, "load16")
159     CASE_SIGN_OP(I64, LoadMem32, "load32")
160     CASE_S128_OP(LoadMem, "load128")
161     CASE_ALL_OP(StoreMem, "store")
162     CASE_INT_OP(StoreMem8, "store8")
163     CASE_INT_OP(StoreMem16, "store16")
164     CASE_I64_OP(StoreMem32, "store32")
165     CASE_S128_OP(StoreMem, "store128")
166 
167     // Non-standard opcodes.
168     CASE_OP(Try, "try")
169     CASE_OP(Throw, "throw")
170     CASE_OP(Rethrow, "rethrow")
171     CASE_OP(Catch, "catch")
172     CASE_OP(CatchAll, "catch_all")
173 
174     // asm.js-only opcodes.
175     CASE_F64_OP(Acos, "acos")
176     CASE_F64_OP(Asin, "asin")
177     CASE_F64_OP(Atan, "atan")
178     CASE_F64_OP(Cos, "cos")
179     CASE_F64_OP(Sin, "sin")
180     CASE_F64_OP(Tan, "tan")
181     CASE_F64_OP(Exp, "exp")
182     CASE_F64_OP(Log, "log")
183     CASE_F64_OP(Atan2, "atan2")
184     CASE_F64_OP(Pow, "pow")
185     CASE_F64_OP(Mod, "mod")
186     CASE_F32_OP(AsmjsLoadMem, "asmjs_load")
187     CASE_F64_OP(AsmjsLoadMem, "asmjs_load")
188     CASE_L32_OP(AsmjsLoadMem, "asmjs_load")
189     CASE_I32_OP(AsmjsStoreMem, "asmjs_store")
190     CASE_F32_OP(AsmjsStoreMem, "asmjs_store")
191     CASE_F64_OP(AsmjsStoreMem, "asmjs_store")
192     CASE_I32_OP(AsmjsStoreMem8, "asmjs_store8")
193     CASE_I32_OP(AsmjsStoreMem16, "asmjs_store16")
194     CASE_SIGN_OP(I32, AsmjsDiv, "asmjs_div")
195     CASE_SIGN_OP(I32, AsmjsRem, "asmjs_rem")
196     CASE_I32_OP(AsmjsSConvertF32, "asmjs_convert_s/f32")
197     CASE_I32_OP(AsmjsUConvertF32, "asmjs_convert_u/f32")
198     CASE_I32_OP(AsmjsSConvertF64, "asmjs_convert_s/f64")
199     CASE_I32_OP(AsmjsUConvertF64, "asmjs_convert_u/f64")
200 
201     // SIMD opcodes.
202     CASE_SIMD_OP(Splat, "splat")
203     CASE_SIMD_OP(Neg, "neg")
204     CASE_SIMD_OP(Eq, "eq")
205     CASE_SIMD_OP(Ne, "ne")
206     CASE_SIMD_OP(Add, "add")
207     CASE_SIMD_OP(Sub, "sub")
208     CASE_SIMD_OP(Mul, "mul")
209     CASE_F32x4_OP(Abs, "abs")
210     CASE_F32x4_OP(AddHoriz, "add_horizontal")
211     CASE_F32x4_OP(RecipApprox, "recip_approx")
212     CASE_F32x4_OP(RecipSqrtApprox, "recip_sqrt_approx")
213     CASE_F32x4_OP(Min, "min")
214     CASE_F32x4_OP(Max, "max")
215     CASE_F32x4_OP(Lt, "lt")
216     CASE_F32x4_OP(Le, "le")
217     CASE_F32x4_OP(Gt, "gt")
218     CASE_F32x4_OP(Ge, "ge")
219     CASE_CONVERT_OP(Convert, F32x4, I32x4, "i32", "convert")
220     CASE_CONVERT_OP(Convert, I32x4, F32x4, "f32", "convert")
221     CASE_CONVERT_OP(Convert, I32x4, I16x8Low, "i32", "convert")
222     CASE_CONVERT_OP(Convert, I32x4, I16x8High, "i32", "convert")
223     CASE_CONVERT_OP(Convert, I16x8, I32x4, "i32", "convert")
224     CASE_CONVERT_OP(Convert, I16x8, I8x16Low, "i32", "convert")
225     CASE_CONVERT_OP(Convert, I16x8, I8x16High, "i32", "convert")
226     CASE_CONVERT_OP(Convert, I8x16, I16x8, "i32", "convert")
227     CASE_F32x4_OP(ExtractLane, "extract_lane")
228     CASE_F32x4_OP(ReplaceLane, "replace_lane")
229     CASE_SIMDI_OP(ExtractLane, "extract_lane")
230     CASE_SIMDI_OP(ReplaceLane, "replace_lane")
231     CASE_SIGN_OP(SIMDI, Min, "min")
232     CASE_SIGN_OP(SIMDI, Max, "max")
233     CASE_SIGN_OP(SIMDI, Lt, "lt")
234     CASE_SIGN_OP(SIMDI, Le, "le")
235     CASE_SIGN_OP(SIMDI, Gt, "gt")
236     CASE_SIGN_OP(SIMDI, Ge, "ge")
237     CASE_SIGN_OP(SIMDI, Shr, "shr")
238     CASE_SIMDI_OP(Shl, "shl")
239     CASE_I32x4_OP(AddHoriz, "add_horizontal")
240     CASE_I16x8_OP(AddHoriz, "add_horizontal")
241     CASE_SIGN_OP(I16x8, AddSaturate, "add_saturate")
242     CASE_SIGN_OP(I8x16, AddSaturate, "add_saturate")
243     CASE_SIGN_OP(I16x8, SubSaturate, "sub_saturate")
244     CASE_SIGN_OP(I8x16, SubSaturate, "sub_saturate")
245     CASE_S128_OP(And, "and")
246     CASE_S128_OP(Or, "or")
247     CASE_S128_OP(Xor, "xor")
248     CASE_S128_OP(Not, "not")
249     CASE_S128_OP(Select, "select")
250     CASE_S8x16_OP(Shuffle, "shuffle")
251     CASE_S1x4_OP(AnyTrue, "any_true")
252     CASE_S1x4_OP(AllTrue, "all_true")
253     CASE_S1x8_OP(AnyTrue, "any_true")
254     CASE_S1x8_OP(AllTrue, "all_true")
255     CASE_S1x16_OP(AnyTrue, "any_true")
256     CASE_S1x16_OP(AllTrue, "all_true")
257 
258     // Atomic operations.
259     CASE_UNSIGNED_ALL_OP(AtomicLoad, "atomic_load")
260     CASE_UNSIGNED_ALL_OP(AtomicStore, "atomic_store")
261     CASE_UNSIGNED_ALL_OP(AtomicAdd, "atomic_add")
262     CASE_UNSIGNED_ALL_OP(AtomicSub, "atomic_sub")
263     CASE_UNSIGNED_ALL_OP(AtomicAnd, "atomic_and")
264     CASE_UNSIGNED_ALL_OP(AtomicOr, "atomic_or")
265     CASE_UNSIGNED_ALL_OP(AtomicXor, "atomic_xor")
266     CASE_UNSIGNED_ALL_OP(AtomicExchange, "atomic_xchng")
267     CASE_UNSIGNED_ALL_OP(AtomicCompareExchange, "atomic_cmpxchng")
268 
269     default : return "unknown";
270     // clang-format on
271   }
272 }
273 
274 #undef CASE_OP
275 #undef CASE_I32_OP
276 #undef CASE_I64_OP
277 #undef CASE_F32_OP
278 #undef CASE_F64_OP
279 #undef CASE_REF_OP
280 #undef CASE_F32x4_OP
281 #undef CASE_I32x4_OP
282 #undef CASE_I16x8_OP
283 #undef CASE_I8x16_OP
284 #undef CASE_S128_OP
285 #undef CASE_S32x4_OP
286 #undef CASE_S16x8_OP
287 #undef CASE_S8x16_OP
288 #undef CASE_S1x4_OP
289 #undef CASE_S1x8_OP
290 #undef CASE_S1x16_OP
291 #undef CASE_INT_OP
292 #undef CASE_FLOAT_OP
293 #undef CASE_ALL_OP
294 #undef CASE_SIMD_OP
295 #undef CASE_SIMDI_OP
296 #undef CASE_SIGN_OP
297 #undef CASE_UNSIGNED_OP
298 #undef CASE_UNSIGNED_ALL_OP
299 #undef CASE_ALL_SIGN_OP
300 #undef CASE_CONVERT_OP
301 #undef CASE_CONVERT_SAT_OP
302 #undef CASE_L32_OP
303 #undef CASE_U32_OP
304 
IsPrefixOpcode(WasmOpcode opcode)305 bool WasmOpcodes::IsPrefixOpcode(WasmOpcode opcode) {
306   switch (opcode) {
307 #define CHECK_PREFIX(name, opcode) case k##name##Prefix:
308     FOREACH_PREFIX(CHECK_PREFIX)
309 #undef CHECK_PREFIX
310     return true;
311     default:
312       return false;
313   }
314 }
315 
IsControlOpcode(WasmOpcode opcode)316 bool WasmOpcodes::IsControlOpcode(WasmOpcode opcode) {
317   switch (opcode) {
318 #define CHECK_OPCODE(name, opcode, _) case kExpr##name:
319     FOREACH_CONTROL_OPCODE(CHECK_OPCODE)
320 #undef CHECK_OPCODE
321     return true;
322     default:
323       return false;
324   }
325 }
326 
IsUnconditionalJump(WasmOpcode opcode)327 bool WasmOpcodes::IsUnconditionalJump(WasmOpcode opcode) {
328   switch (opcode) {
329     case kExprUnreachable:
330     case kExprBr:
331     case kExprBrTable:
332     case kExprReturn:
333       return true;
334     default:
335       return false;
336   }
337 }
338 
IsSignExtensionOpcode(WasmOpcode opcode)339 bool WasmOpcodes::IsSignExtensionOpcode(WasmOpcode opcode) {
340   switch (opcode) {
341     case kExprI32SExtendI8:
342     case kExprI32SExtendI16:
343     case kExprI64SExtendI8:
344     case kExprI64SExtendI16:
345     case kExprI64SExtendI32:
346       return true;
347     default:
348       return false;
349   }
350 }
351 
IsAnyRefOpcode(WasmOpcode opcode)352 bool WasmOpcodes::IsAnyRefOpcode(WasmOpcode opcode) {
353   switch (opcode) {
354     case kExprRefNull:
355     case kExprRefIsNull:
356       return true;
357     default:
358       return false;
359   }
360 }
361 
operator <<(std::ostream & os,const FunctionSig & sig)362 std::ostream& operator<<(std::ostream& os, const FunctionSig& sig) {
363   if (sig.return_count() == 0) os << "v";
364   for (auto ret : sig.returns()) {
365     os << ValueTypes::ShortNameOf(ret);
366   }
367   os << "_";
368   if (sig.parameter_count() == 0) os << "v";
369   for (auto param : sig.parameters()) {
370     os << ValueTypes::ShortNameOf(param);
371   }
372   return os;
373 }
374 
IsJSCompatibleSignature(const FunctionSig * sig)375 bool IsJSCompatibleSignature(const FunctionSig* sig) {
376   for (auto type : sig->all()) {
377     if (type == kWasmI64 || type == kWasmS128) return false;
378   }
379   return sig->return_count() <= 1;
380 }
381 
382 namespace {
383 
384 #define DECLARE_SIG_ENUM(name, ...) kSigEnum_##name,
385 enum WasmOpcodeSig : byte {
386   kSigEnum_None,
387   FOREACH_SIGNATURE(DECLARE_SIG_ENUM)
388 };
389 #undef DECLARE_SIG_ENUM
390 #define DECLARE_SIG(name, ...)                                                \
391   constexpr ValueType kTypes_##name[] = {__VA_ARGS__};                        \
392   constexpr int kReturnsCount_##name = kTypes_##name[0] == kWasmStmt ? 0 : 1; \
393   constexpr FunctionSig kSig_##name(                                          \
394       kReturnsCount_##name, static_cast<int>(arraysize(kTypes_##name)) - 1,   \
395       kTypes_##name + (1 - kReturnsCount_##name));
396 FOREACH_SIGNATURE(DECLARE_SIG)
397 #undef DECLARE_SIG
398 
399 #define DECLARE_SIG_ENTRY(name, ...) &kSig_##name,
400 constexpr const FunctionSig* kCachedSigs[] = {
401     nullptr, FOREACH_SIGNATURE(DECLARE_SIG_ENTRY)};
402 #undef DECLARE_SIG_ENTRY
403 
404 // gcc 4.7 - 4.9 has a bug which causes the constexpr attribute to get lost when
405 // passing functions (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52892). Hence
406 // encapsulate these constexpr functions in functors.
407 // TODO(clemensh): Remove this once we require gcc >= 5.0.
408 
409 struct GetShortOpcodeSigIndex {
operator ()v8::internal::wasm::__anonaecad79b0111::GetShortOpcodeSigIndex410   constexpr WasmOpcodeSig operator()(byte opcode) const {
411 #define CASE(name, opc, sig) opcode == opc ? kSigEnum_##sig:
412     return FOREACH_SIMPLE_OPCODE(CASE) FOREACH_SIMPLE_PROTOTYPE_OPCODE(CASE)
413         kSigEnum_None;
414 #undef CASE
415   }
416 };
417 
418 struct GetAsmJsOpcodeSigIndex {
operator ()v8::internal::wasm::__anonaecad79b0111::GetAsmJsOpcodeSigIndex419   constexpr WasmOpcodeSig operator()(byte opcode) const {
420 #define CASE(name, opc, sig) opcode == opc ? kSigEnum_##sig:
421     return FOREACH_ASMJS_COMPAT_OPCODE(CASE) kSigEnum_None;
422 #undef CASE
423   }
424 };
425 
426 struct GetSimdOpcodeSigIndex {
operator ()v8::internal::wasm::__anonaecad79b0111::GetSimdOpcodeSigIndex427   constexpr WasmOpcodeSig operator()(byte opcode) const {
428 #define CASE(name, opc, sig) opcode == (opc & 0xFF) ? kSigEnum_##sig:
429     return FOREACH_SIMD_0_OPERAND_OPCODE(CASE) FOREACH_SIMD_MEM_OPCODE(CASE)
430         kSigEnum_None;
431 #undef CASE
432   }
433 };
434 
435 struct GetAtomicOpcodeSigIndex {
operator ()v8::internal::wasm::__anonaecad79b0111::GetAtomicOpcodeSigIndex436   constexpr WasmOpcodeSig operator()(byte opcode) const {
437 #define CASE(name, opc, sig) opcode == (opc & 0xFF) ? kSigEnum_##sig:
438     return FOREACH_ATOMIC_OPCODE(CASE) kSigEnum_None;
439 #undef CASE
440 }
441 };
442 
443 struct GetNumericOpcodeSigIndex {
operator ()v8::internal::wasm::__anonaecad79b0111::GetNumericOpcodeSigIndex444   constexpr WasmOpcodeSig operator()(byte opcode) const {
445 #define CASE(name, opc, sig) opcode == (opc & 0xFF) ? kSigEnum_##sig:
446     return FOREACH_NUMERIC_OPCODE(CASE) kSigEnum_None;
447 #undef CASE
448   }
449 };
450 
451 constexpr std::array<WasmOpcodeSig, 256> kShortSigTable =
452     base::make_array<256>(GetShortOpcodeSigIndex{});
453 constexpr std::array<WasmOpcodeSig, 256> kSimpleAsmjsExprSigTable =
454     base::make_array<256>(GetAsmJsOpcodeSigIndex{});
455 constexpr std::array<WasmOpcodeSig, 256> kSimdExprSigTable =
456     base::make_array<256>(GetSimdOpcodeSigIndex{});
457 constexpr std::array<WasmOpcodeSig, 256> kAtomicExprSigTable =
458     base::make_array<256>(GetAtomicOpcodeSigIndex{});
459 constexpr std::array<WasmOpcodeSig, 256> kNumericExprSigTable =
460     base::make_array<256>(GetNumericOpcodeSigIndex{});
461 
462 // Computes a direct pointer to a cached signature for a simple opcode.
463 struct GetSimpleOpcodeSig {
operator ()v8::internal::wasm::__anonaecad79b0111::GetSimpleOpcodeSig464   constexpr const FunctionSig* operator()(byte opcode) const {
465 #define CASE(name, opc, sig) opcode == opc ? &kSig_##sig:
466     return FOREACH_SIMPLE_OPCODE(CASE) nullptr;
467 #undef CASE
468   }
469 };
470 
471 }  // namespace
472 
473 const std::array<const FunctionSig*, 256> kSimpleOpcodeSigs =
474     base::make_array<256>(GetSimpleOpcodeSig{});
475 
Signature(WasmOpcode opcode)476 FunctionSig* WasmOpcodes::Signature(WasmOpcode opcode) {
477   switch (opcode >> 8) {
478     case 0:
479       return const_cast<FunctionSig*>(kCachedSigs[kShortSigTable[opcode]]);
480     case kSimdPrefix:
481       return const_cast<FunctionSig*>(
482           kCachedSigs[kSimdExprSigTable[opcode & 0xFF]]);
483     case kAtomicPrefix:
484       return const_cast<FunctionSig*>(
485           kCachedSigs[kAtomicExprSigTable[opcode & 0xFF]]);
486     case kNumericPrefix:
487       return const_cast<FunctionSig*>(
488           kCachedSigs[kNumericExprSigTable[opcode & 0xFF]]);
489     default:
490       UNREACHABLE();  // invalid prefix.
491       return nullptr;
492   }
493 }
494 
AsmjsSignature(WasmOpcode opcode)495 FunctionSig* WasmOpcodes::AsmjsSignature(WasmOpcode opcode) {
496   DCHECK_GT(kSimpleAsmjsExprSigTable.size(), opcode);
497   return const_cast<FunctionSig*>(
498       kCachedSigs[kSimpleAsmjsExprSigTable[opcode]]);
499 }
500 
501 // Define constexpr arrays.
502 constexpr uint8_t LoadType::kLoadSizeLog2[];
503 constexpr ValueType LoadType::kValueType[];
504 constexpr MachineType LoadType::kMemType[];
505 constexpr uint8_t StoreType::kStoreSizeLog2[];
506 constexpr ValueType StoreType::kValueType[];
507 constexpr MachineRepresentation StoreType::kMemRep[];
508 
TrapReasonToMessageId(TrapReason reason)509 int WasmOpcodes::TrapReasonToMessageId(TrapReason reason) {
510   switch (reason) {
511 #define TRAPREASON_TO_MESSAGE(name) \
512   case k##name:                     \
513     return MessageTemplate::kWasm##name;
514     FOREACH_WASM_TRAPREASON(TRAPREASON_TO_MESSAGE)
515 #undef TRAPREASON_TO_MESSAGE
516     default:
517       return MessageTemplate::kNone;
518   }
519 }
520 
TrapReasonMessage(TrapReason reason)521 const char* WasmOpcodes::TrapReasonMessage(TrapReason reason) {
522   return MessageTemplate::TemplateString(TrapReasonToMessageId(reason));
523 }
524 }  // namespace wasm
525 }  // namespace internal
526 }  // namespace v8
527