LCOV - code coverage report
Current view: top level - src/wasm - wasm-opcodes.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 233 240 97.1 %
Date: 2019-04-17 Functions: 12 14 85.7 %

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

Generated by: LCOV version 1.10