wasm-opcodes.cc 17.4 KB
Newer Older
1 2 3 4 5
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/wasm/wasm-opcodes.h"
6 7 8 9

#include <array>

#include "src/base/template-utils.h"
10
#include "src/messages.h"
11
#include "src/runtime/runtime.h"
12 13 14 15 16 17
#include "src/signature.h"

namespace v8 {
namespace internal {
namespace wasm {

18 19 20 21 22 23 24
#define CASE_OP(name, str) \
  case kExpr##name:        \
    return str;
#define CASE_I32_OP(name, str) CASE_OP(I32##name, "i32." str)
#define CASE_I64_OP(name, str) CASE_OP(I64##name, "i64." str)
#define CASE_F32_OP(name, str) CASE_OP(F32##name, "f32." str)
#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 27 28 29
#define CASE_F32x4_OP(name, str) CASE_OP(F32x4##name, "f32x4." str)
#define CASE_I32x4_OP(name, str) CASE_OP(I32x4##name, "i32x4." str)
#define CASE_I16x8_OP(name, str) CASE_OP(I16x8##name, "i16x8." str)
#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 33
#define CASE_S16x8_OP(name, str) CASE_OP(S16x8##name, "s16x8." str)
#define CASE_S8x16_OP(name, str) CASE_OP(S8x16##name, "s8x16." str)
34 35 36
#define CASE_S1x4_OP(name, str) CASE_OP(S1x4##name, "s1x4." str)
#define CASE_S1x8_OP(name, str) CASE_OP(S1x8##name, "s1x8." str)
#define CASE_S1x16_OP(name, str) CASE_OP(S1x16##name, "s1x16." str)
37 38 39 40 41 42 43 44 45 46
#define CASE_INT_OP(name, str) CASE_I32_OP(name, str) CASE_I64_OP(name, str)
#define CASE_FLOAT_OP(name, str) CASE_F32_OP(name, str) CASE_F64_OP(name, str)
#define CASE_ALL_OP(name, str) CASE_FLOAT_OP(name, str) CASE_INT_OP(name, str)
#define CASE_SIMD_OP(name, str)                                              \
  CASE_F32x4_OP(name, str) CASE_I32x4_OP(name, str) CASE_I16x8_OP(name, str) \
      CASE_I8x16_OP(name, str)
#define CASE_SIMDI_OP(name, str) \
  CASE_I32x4_OP(name, str) CASE_I16x8_OP(name, str) CASE_I8x16_OP(name, str)
#define CASE_SIGN_OP(TYPE, name, str) \
  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 49 50 51 52
#define CASE_ALL_SIGN_OP(name, str) \
  CASE_FLOAT_OP(name, str) CASE_SIGN_OP(INT, name, str)
#define CASE_CONVERT_OP(name, RES, SRC, src_suffix, str) \
  CASE_##RES##_OP(U##name##SRC, str "_u/" src_suffix)    \
      CASE_##RES##_OP(S##name##SRC, str "_s/" src_suffix)
53 54 55
#define CASE_CONVERT_SAT_OP(name, RES, SRC, src_suffix, str)   \
  CASE_##RES##_OP(U##name##Sat##SRC, str "_u:sat/" src_suffix) \
      CASE_##RES##_OP(S##name##Sat##SRC, str "_s:sat/" src_suffix)
56 57 58 59
#define CASE_L32_OP(name, str)          \
  CASE_SIGN_OP(I32, name##8, str "8")   \
  CASE_SIGN_OP(I32, name##16, str "16") \
  CASE_I32_OP(name, str "32")
60 61 62 63
#define CASE_U32_OP(name, str)            \
  CASE_I32_OP(name, str "32")             \
  CASE_UNSIGNED_OP(I32, name##8, str "8") \
  CASE_UNSIGNED_OP(I32, name##16, str "16")
64 65 66 67 68 69
#define CASE_UNSIGNED_ALL_OP(name, str)     \
  CASE_U32_OP(name, str)                    \
  CASE_I64_OP(name, str "64")               \
  CASE_UNSIGNED_OP(I64, name##8, str "8")   \
  CASE_UNSIGNED_OP(I64, name##16, str "16") \
  CASE_UNSIGNED_OP(I64, name##32, str "32")
70

71 72
const char* WasmOpcodes::OpcodeName(WasmOpcode opcode) {
  switch (opcode) {
73
    // clang-format off
74

75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
    // Standard opcodes
    CASE_INT_OP(Eqz, "eqz")
    CASE_ALL_OP(Eq, "eq")
    CASE_ALL_OP(Ne, "ne")
    CASE_ALL_OP(Add, "add")
    CASE_ALL_OP(Sub, "sub")
    CASE_ALL_OP(Mul, "mul")
    CASE_ALL_SIGN_OP(Lt, "lt")
    CASE_ALL_SIGN_OP(Gt, "gt")
    CASE_ALL_SIGN_OP(Le, "le")
    CASE_ALL_SIGN_OP(Ge, "ge")
    CASE_INT_OP(Clz, "clz")
    CASE_INT_OP(Ctz, "ctz")
    CASE_INT_OP(Popcnt, "popcnt")
    CASE_ALL_SIGN_OP(Div, "div")
    CASE_SIGN_OP(INT, Rem, "rem")
    CASE_INT_OP(And, "and")
    CASE_INT_OP(Ior, "or")
    CASE_INT_OP(Xor, "xor")
    CASE_INT_OP(Shl, "shl")
    CASE_SIGN_OP(INT, Shr, "shr")
    CASE_INT_OP(Rol, "rol")
    CASE_INT_OP(Ror, "ror")
    CASE_FLOAT_OP(Abs, "abs")
    CASE_FLOAT_OP(Neg, "neg")
    CASE_FLOAT_OP(Ceil, "ceil")
    CASE_FLOAT_OP(Floor, "floor")
    CASE_FLOAT_OP(Trunc, "trunc")
    CASE_FLOAT_OP(NearestInt, "nearest")
    CASE_FLOAT_OP(Sqrt, "sqrt")
    CASE_FLOAT_OP(Min, "min")
    CASE_FLOAT_OP(Max, "max")
    CASE_FLOAT_OP(CopySign, "copysign")
108 109 110
    CASE_REF_OP(Null, "null")
    CASE_REF_OP(IsNull, "is_null")
    CASE_REF_OP(Eq, "eq")
111 112 113
    CASE_I32_OP(ConvertI64, "wrap/i64")
    CASE_CONVERT_OP(Convert, INT, F32, "f32", "trunc")
    CASE_CONVERT_OP(Convert, INT, F64, "f64", "trunc")
114
    // TODO(kschimpf): Simplify after filling in other saturating operations.
115 116
    CASE_CONVERT_SAT_OP(Convert, I32, F32, "f32", "trunc")
    CASE_CONVERT_SAT_OP(Convert, I32, F64, "f64", "trunc")
117 118
    CASE_CONVERT_SAT_OP(Convert, I64, F32, "f32", "trunc")
    CASE_CONVERT_SAT_OP(Convert, I64, F64, "f64", "trunc")
119

120 121 122 123 124 125 126 127 128 129 130
    CASE_CONVERT_OP(Convert, I64, I32, "i32", "extend")
    CASE_CONVERT_OP(Convert, F32, I32, "i32", "convert")
    CASE_CONVERT_OP(Convert, F32, I64, "i64", "convert")
    CASE_F32_OP(ConvertF64, "demote/f64")
    CASE_CONVERT_OP(Convert, F64, I32, "i32", "convert")
    CASE_CONVERT_OP(Convert, F64, I64, "i64", "convert")
    CASE_F64_OP(ConvertF32, "promote/f32")
    CASE_I32_OP(ReinterpretF32, "reinterpret/f32")
    CASE_I64_OP(ReinterpretF64, "reinterpret/f64")
    CASE_F32_OP(ReinterpretI32, "reinterpret/i32")
    CASE_F64_OP(ReinterpretI64, "reinterpret/i64")
131 132 133
    CASE_INT_OP(SExtendI8, "sign_extend8")
    CASE_INT_OP(SExtendI16, "sign_extend16")
    CASE_I64_OP(SExtendI32, "sign_extend32")
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
    CASE_OP(Unreachable, "unreachable")
    CASE_OP(Nop, "nop")
    CASE_OP(Block, "block")
    CASE_OP(Loop, "loop")
    CASE_OP(If, "if")
    CASE_OP(Else, "else")
    CASE_OP(End, "end")
    CASE_OP(Br, "br")
    CASE_OP(BrIf, "br_if")
    CASE_OP(BrTable, "br_table")
    CASE_OP(Return, "return")
    CASE_OP(CallFunction, "call")
    CASE_OP(CallIndirect, "call_indirect")
    CASE_OP(Drop, "drop")
    CASE_OP(Select, "select")
    CASE_OP(GetLocal, "get_local")
    CASE_OP(SetLocal, "set_local")
    CASE_OP(TeeLocal, "tee_local")
    CASE_OP(GetGlobal, "get_global")
    CASE_OP(SetGlobal, "set_global")
    CASE_ALL_OP(Const, "const")
    CASE_OP(MemorySize, "current_memory")
    CASE_OP(GrowMemory, "grow_memory")
    CASE_ALL_OP(LoadMem, "load")
    CASE_SIGN_OP(INT, LoadMem8, "load8")
    CASE_SIGN_OP(INT, LoadMem16, "load16")
    CASE_SIGN_OP(I64, LoadMem32, "load32")
161
    CASE_S128_OP(LoadMem, "load128")
162 163 164 165
    CASE_ALL_OP(StoreMem, "store")
    CASE_INT_OP(StoreMem8, "store8")
    CASE_INT_OP(StoreMem16, "store16")
    CASE_I64_OP(StoreMem32, "store32")
166
    CASE_S128_OP(StoreMem, "store128")
167 168 169 170

    // Non-standard opcodes.
    CASE_OP(Try, "try")
    CASE_OP(Throw, "throw")
171
    CASE_OP(Rethrow, "rethrow")
172
    CASE_OP(Catch, "catch")
173
    CASE_OP(CatchAll, "catch_all")
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210

    // asm.js-only opcodes.
    CASE_F64_OP(Acos, "acos")
    CASE_F64_OP(Asin, "asin")
    CASE_F64_OP(Atan, "atan")
    CASE_F64_OP(Cos, "cos")
    CASE_F64_OP(Sin, "sin")
    CASE_F64_OP(Tan, "tan")
    CASE_F64_OP(Exp, "exp")
    CASE_F64_OP(Log, "log")
    CASE_F64_OP(Atan2, "atan2")
    CASE_F64_OP(Pow, "pow")
    CASE_F64_OP(Mod, "mod")
    CASE_F32_OP(AsmjsLoadMem, "asmjs_load")
    CASE_F64_OP(AsmjsLoadMem, "asmjs_load")
    CASE_L32_OP(AsmjsLoadMem, "asmjs_load")
    CASE_I32_OP(AsmjsStoreMem, "asmjs_store")
    CASE_F32_OP(AsmjsStoreMem, "asmjs_store")
    CASE_F64_OP(AsmjsStoreMem, "asmjs_store")
    CASE_I32_OP(AsmjsStoreMem8, "asmjs_store8")
    CASE_I32_OP(AsmjsStoreMem16, "asmjs_store16")
    CASE_SIGN_OP(I32, AsmjsDiv, "asmjs_div")
    CASE_SIGN_OP(I32, AsmjsRem, "asmjs_rem")
    CASE_I32_OP(AsmjsSConvertF32, "asmjs_convert_s/f32")
    CASE_I32_OP(AsmjsUConvertF32, "asmjs_convert_u/f32")
    CASE_I32_OP(AsmjsSConvertF64, "asmjs_convert_s/f64")
    CASE_I32_OP(AsmjsUConvertF64, "asmjs_convert_u/f64")

    // SIMD opcodes.
    CASE_SIMD_OP(Splat, "splat")
    CASE_SIMD_OP(Neg, "neg")
    CASE_SIMD_OP(Eq, "eq")
    CASE_SIMD_OP(Ne, "ne")
    CASE_SIMD_OP(Add, "add")
    CASE_SIMD_OP(Sub, "sub")
    CASE_SIMD_OP(Mul, "mul")
    CASE_F32x4_OP(Abs, "abs")
211
    CASE_F32x4_OP(AddHoriz, "add_horizontal")
212
    CASE_F32x4_OP(RecipApprox, "recip_approx")
213
    CASE_F32x4_OP(RecipSqrtApprox, "recip_sqrt_approx")
214 215 216 217 218 219 220
    CASE_F32x4_OP(Min, "min")
    CASE_F32x4_OP(Max, "max")
    CASE_F32x4_OP(Lt, "lt")
    CASE_F32x4_OP(Le, "le")
    CASE_F32x4_OP(Gt, "gt")
    CASE_F32x4_OP(Ge, "ge")
    CASE_CONVERT_OP(Convert, F32x4, I32x4, "i32", "convert")
221
    CASE_CONVERT_OP(Convert, I32x4, F32x4, "f32", "convert")
222 223 224 225 226 227
    CASE_CONVERT_OP(Convert, I32x4, I16x8Low, "i32", "convert")
    CASE_CONVERT_OP(Convert, I32x4, I16x8High, "i32", "convert")
    CASE_CONVERT_OP(Convert, I16x8, I32x4, "i32", "convert")
    CASE_CONVERT_OP(Convert, I16x8, I8x16Low, "i32", "convert")
    CASE_CONVERT_OP(Convert, I16x8, I8x16High, "i32", "convert")
    CASE_CONVERT_OP(Convert, I8x16, I16x8, "i32", "convert")
228 229 230 231 232 233 234 235 236 237 238 239
    CASE_F32x4_OP(ExtractLane, "extract_lane")
    CASE_F32x4_OP(ReplaceLane, "replace_lane")
    CASE_SIMDI_OP(ExtractLane, "extract_lane")
    CASE_SIMDI_OP(ReplaceLane, "replace_lane")
    CASE_SIGN_OP(SIMDI, Min, "min")
    CASE_SIGN_OP(SIMDI, Max, "max")
    CASE_SIGN_OP(SIMDI, Lt, "lt")
    CASE_SIGN_OP(SIMDI, Le, "le")
    CASE_SIGN_OP(SIMDI, Gt, "gt")
    CASE_SIGN_OP(SIMDI, Ge, "ge")
    CASE_SIGN_OP(SIMDI, Shr, "shr")
    CASE_SIMDI_OP(Shl, "shl")
240 241
    CASE_I32x4_OP(AddHoriz, "add_horizontal")
    CASE_I16x8_OP(AddHoriz, "add_horizontal")
242 243 244 245
    CASE_SIGN_OP(I16x8, AddSaturate, "add_saturate")
    CASE_SIGN_OP(I8x16, AddSaturate, "add_saturate")
    CASE_SIGN_OP(I16x8, SubSaturate, "sub_saturate")
    CASE_SIGN_OP(I8x16, SubSaturate, "sub_saturate")
246
    CASE_S128_OP(And, "and")
247
    CASE_S128_OP(Or, "or")
248 249
    CASE_S128_OP(Xor, "xor")
    CASE_S128_OP(Not, "not")
250
    CASE_S128_OP(Select, "select")
251
    CASE_S8x16_OP(Shuffle, "shuffle")
252 253 254 255 256 257
    CASE_S1x4_OP(AnyTrue, "any_true")
    CASE_S1x4_OP(AllTrue, "all_true")
    CASE_S1x8_OP(AnyTrue, "any_true")
    CASE_S1x8_OP(AllTrue, "all_true")
    CASE_S1x16_OP(AnyTrue, "any_true")
    CASE_S1x16_OP(AllTrue, "all_true")
258 259

    // Atomic operations.
260 261 262 263 264 265 266
    CASE_UNSIGNED_ALL_OP(AtomicLoad, "atomic_load")
    CASE_UNSIGNED_ALL_OP(AtomicStore, "atomic_store")
    CASE_UNSIGNED_ALL_OP(AtomicAdd, "atomic_add")
    CASE_UNSIGNED_ALL_OP(AtomicSub, "atomic_sub")
    CASE_UNSIGNED_ALL_OP(AtomicAnd, "atomic_and")
    CASE_UNSIGNED_ALL_OP(AtomicOr, "atomic_or")
    CASE_UNSIGNED_ALL_OP(AtomicXor, "atomic_xor")
267 268
    CASE_UNSIGNED_ALL_OP(AtomicExchange, "atomic_xchng")
    CASE_UNSIGNED_ALL_OP(AtomicCompareExchange, "atomic_cmpxchng")
269 270 271

    default : return "unknown";
    // clang-format on
272 273
  }
}
274

275 276 277 278 279
#undef CASE_OP
#undef CASE_I32_OP
#undef CASE_I64_OP
#undef CASE_F32_OP
#undef CASE_F64_OP
280
#undef CASE_REF_OP
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298
#undef CASE_F32x4_OP
#undef CASE_I32x4_OP
#undef CASE_I16x8_OP
#undef CASE_I8x16_OP
#undef CASE_S128_OP
#undef CASE_S32x4_OP
#undef CASE_S16x8_OP
#undef CASE_S8x16_OP
#undef CASE_S1x4_OP
#undef CASE_S1x8_OP
#undef CASE_S1x16_OP
#undef CASE_INT_OP
#undef CASE_FLOAT_OP
#undef CASE_ALL_OP
#undef CASE_SIMD_OP
#undef CASE_SIMDI_OP
#undef CASE_SIGN_OP
#undef CASE_UNSIGNED_OP
299
#undef CASE_UNSIGNED_ALL_OP
300 301
#undef CASE_ALL_SIGN_OP
#undef CASE_CONVERT_OP
302
#undef CASE_CONVERT_SAT_OP
303 304 305
#undef CASE_L32_OP
#undef CASE_U32_OP

306 307
bool WasmOpcodes::IsPrefixOpcode(WasmOpcode opcode) {
  switch (opcode) {
308
#define CHECK_PREFIX(name, opcode) case k##name##Prefix:
309 310
    FOREACH_PREFIX(CHECK_PREFIX)
#undef CHECK_PREFIX
311
    return true;
312 313 314 315
    default:
      return false;
  }
}
316

317 318
bool WasmOpcodes::IsControlOpcode(WasmOpcode opcode) {
  switch (opcode) {
319
#define CHECK_OPCODE(name, opcode, _) case kExpr##name:
320 321
    FOREACH_CONTROL_OPCODE(CHECK_OPCODE)
#undef CHECK_OPCODE
322
    return true;
323 324 325 326
    default:
      return false;
  }
}
327

328 329 330 331 332 333 334 335 336 337 338 339
bool WasmOpcodes::IsUnconditionalJump(WasmOpcode opcode) {
  switch (opcode) {
    case kExprUnreachable:
    case kExprBr:
    case kExprBrTable:
    case kExprReturn:
      return true;
    default:
      return false;
  }
}

340 341 342 343 344 345 346 347 348 349 350 351 352
bool WasmOpcodes::IsSignExtensionOpcode(WasmOpcode opcode) {
  switch (opcode) {
    case kExprI32SExtendI8:
    case kExprI32SExtendI16:
    case kExprI64SExtendI8:
    case kExprI64SExtendI16:
    case kExprI64SExtendI32:
      return true;
    default:
      return false;
  }
}

353 354 355 356 357 358 359 360 361 362
bool WasmOpcodes::IsAnyRefOpcode(WasmOpcode opcode) {
  switch (opcode) {
    case kExprRefNull:
    case kExprRefIsNull:
    case kExprRefEq:
      return true;
    default:
      return false;
  }
}
363 364
std::ostream& operator<<(std::ostream& os, const FunctionSig& sig) {
  if (sig.return_count() == 0) os << "v";
365
  for (auto ret : sig.returns()) {
366
    os << ValueTypes::ShortNameOf(ret);
367 368 369
  }
  os << "_";
  if (sig.parameter_count() == 0) os << "v";
370
  for (auto param : sig.parameters()) {
371
    os << ValueTypes::ShortNameOf(param);
372 373 374 375
  }
  return os;
}

376 377 378 379
bool IsJSCompatibleSignature(const FunctionSig* sig) {
  for (auto type : sig->all()) {
    if (type == wasm::kWasmI64 || type == wasm::kWasmS128) return false;
  }
380
  return sig->return_count() <= 1;
381 382
}

383 384
namespace {

385
#define DECLARE_SIG_ENUM(name, ...) kSigEnum_##name,
386 387 388 389
enum WasmOpcodeSig : byte {
  kSigEnum_None,
  FOREACH_SIGNATURE(DECLARE_SIG_ENUM)
};
390
#undef DECLARE_SIG_ENUM
391 392 393 394 395 396
#define DECLARE_SIG(name, ...)                                                \
  constexpr ValueType kTypes_##name[] = {__VA_ARGS__};                        \
  constexpr int kReturnsCount_##name = kTypes_##name[0] == kWasmStmt ? 0 : 1; \
  constexpr FunctionSig kSig_##name(                                          \
      kReturnsCount_##name, static_cast<int>(arraysize(kTypes_##name)) - 1,   \
      kTypes_##name + (1 - kReturnsCount_##name));
397
FOREACH_SIGNATURE(DECLARE_SIG)
398
#undef DECLARE_SIG
399 400

#define DECLARE_SIG_ENTRY(name, ...) &kSig_##name,
401
constexpr const FunctionSig* kSimpleExprSigs[] = {
402
    nullptr, FOREACH_SIGNATURE(DECLARE_SIG_ENTRY)};
403
#undef DECLARE_SIG_ENTRY
404

405 406 407 408 409 410 411
// gcc 4.7 - 4.9 has a bug which causes the constexpr attribute to get lost when
// passing functions (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52892). Hence
// encapsulate these constexpr functions in functors.
// TODO(clemensh): Remove this once we require gcc >= 5.0.

struct GetOpcodeSigIndex {
  constexpr WasmOpcodeSig operator()(byte opcode) const {
412
#define CASE(name, opc, sig) opcode == opc ? kSigEnum_##sig:
413
    return FOREACH_SIMPLE_OPCODE(CASE) kSigEnum_None;
414
#undef CASE
415 416
  }
};
417

418 419
struct GetAsmJsOpcodeSigIndex {
  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 427
struct GetSimdOpcodeSigIndex {
  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) kSigEnum_None;
430
#undef CASE
431 432
  }
};
433

434 435
struct GetAtomicOpcodeSigIndex {
  constexpr WasmOpcodeSig operator()(byte opcode) const {
436
#define CASE(name, opc, sig) opcode == (opc & 0xFF) ? kSigEnum_##sig:
437
    return FOREACH_ATOMIC_OPCODE(CASE) kSigEnum_None;
438 439
#undef CASE
}
440
};
441

442 443 444 445 446 447 448 449
struct GetNumericOpcodeSigIndex {
  constexpr WasmOpcodeSig operator()(byte opcode) const {
#define CASE(name, opc, sig) opcode == (opc & 0xFF) ? kSigEnum_##sig:
    return FOREACH_NUMERIC_OPCODE(CASE) kSigEnum_None;
#undef CASE
  }
};

450 451 452 453 454 455 456 457
constexpr std::array<WasmOpcodeSig, 256> kSimpleExprSigTable =
    base::make_array<256>(GetOpcodeSigIndex{});
constexpr std::array<WasmOpcodeSig, 256> kSimpleAsmjsExprSigTable =
    base::make_array<256>(GetAsmJsOpcodeSigIndex{});
constexpr std::array<WasmOpcodeSig, 256> kSimdExprSigTable =
    base::make_array<256>(GetSimdOpcodeSigIndex{});
constexpr std::array<WasmOpcodeSig, 256> kAtomicExprSigTable =
    base::make_array<256>(GetAtomicOpcodeSigIndex{});
458 459
constexpr std::array<WasmOpcodeSig, 256> kNumericExprSigTable =
    base::make_array<256>(GetNumericOpcodeSigIndex{});
460

461
}  // namespace
462

463
FunctionSig* WasmOpcodes::Signature(WasmOpcode opcode) {
464 465 466 467 468 469 470 471 472 473 474 475 476 477
  switch (opcode >> 8) {
    case kSimdPrefix:
      return const_cast<FunctionSig*>(
          kSimpleExprSigs[kSimdExprSigTable[opcode & 0xFF]]);
    case kAtomicPrefix:
      return const_cast<FunctionSig*>(
          kSimpleExprSigs[kAtomicExprSigTable[opcode & 0xFF]]);
    case kNumericPrefix:
      return const_cast<FunctionSig*>(
          kSimpleExprSigs[kNumericExprSigTable[opcode & 0xFF]]);
    default:
      DCHECK_GT(kSimpleExprSigTable.size(), opcode);
      return const_cast<FunctionSig*>(
          kSimpleExprSigs[kSimpleExprSigTable[opcode]]);
478
  }
479 480
}

481
FunctionSig* WasmOpcodes::AsmjsSignature(WasmOpcode opcode) {
482
  DCHECK_GT(kSimpleAsmjsExprSigTable.size(), opcode);
483 484
  return const_cast<FunctionSig*>(
      kSimpleExprSigs[kSimpleAsmjsExprSigTable[opcode]]);
485 486
}

487 488 489 490 491 492 493 494
// Define constexpr arrays.
constexpr uint8_t LoadType::kLoadSizeLog2[];
constexpr ValueType LoadType::kValueType[];
constexpr MachineType LoadType::kMemType[];
constexpr uint8_t StoreType::kStoreSizeLog2[];
constexpr ValueType StoreType::kValueType[];
constexpr MachineRepresentation StoreType::kMemRep[];

495 496 497 498 499 500 501 502 503 504 505 506 507 508 509
int WasmOpcodes::TrapReasonToMessageId(TrapReason reason) {
  switch (reason) {
#define TRAPREASON_TO_MESSAGE(name) \
  case k##name:                     \
    return MessageTemplate::kWasm##name;
    FOREACH_WASM_TRAPREASON(TRAPREASON_TO_MESSAGE)
#undef TRAPREASON_TO_MESSAGE
    default:
      return MessageTemplate::kNone;
  }
}

const char* WasmOpcodes::TrapReasonMessage(TrapReason reason) {
  return MessageTemplate::TemplateString(TrapReasonToMessageId(reason));
}
510 511 512
}  // namespace wasm
}  // namespace internal
}  // namespace v8