Home | History | Annotate | Download | only in wasm
      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 #include "src/messages.h"
      7 #include "src/signature.h"
      8 
      9 namespace v8 {
     10 namespace internal {
     11 namespace wasm {
     12 
     13 typedef Signature<LocalType> FunctionSig;
     14 
     15 const char* WasmOpcodes::OpcodeName(WasmOpcode opcode) {
     16   switch (opcode) {
     17 #define DECLARE_NAME_CASE(name, opcode, sig) \
     18   case kExpr##name:                          \
     19     return "Expr" #name;
     20     FOREACH_OPCODE(DECLARE_NAME_CASE)
     21 #undef DECLARE_NAME_CASE
     22     default:
     23       break;
     24   }
     25   return "Unknown";
     26 }
     27 
     28 const char* WasmOpcodes::ShortOpcodeName(WasmOpcode opcode) {
     29   switch (opcode) {
     30 #define DECLARE_NAME_CASE(name, opcode, sig) \
     31   case kExpr##name:                          \
     32     return #name;
     33     FOREACH_OPCODE(DECLARE_NAME_CASE)
     34 #undef DECLARE_NAME_CASE
     35     default:
     36       break;
     37   }
     38   return "Unknown";
     39 }
     40 
     41 std::ostream& operator<<(std::ostream& os, const FunctionSig& sig) {
     42   if (sig.return_count() == 0) os << "v";
     43   for (size_t i = 0; i < sig.return_count(); ++i) {
     44     os << WasmOpcodes::ShortNameOf(sig.GetReturn(i));
     45   }
     46   os << "_";
     47   if (sig.parameter_count() == 0) os << "v";
     48   for (size_t i = 0; i < sig.parameter_count(); ++i) {
     49     os << WasmOpcodes::ShortNameOf(sig.GetParam(i));
     50   }
     51   return os;
     52 }
     53 
     54 #define DECLARE_SIG_ENUM(name, ...) kSigEnum_##name,
     55 
     56 enum WasmOpcodeSig { FOREACH_SIGNATURE(DECLARE_SIG_ENUM) };
     57 
     58 // TODO(titzer): not static-initializer safe. Wrap in LazyInstance.
     59 #define DECLARE_SIG(name, ...)                      \
     60   static LocalType kTypes_##name[] = {__VA_ARGS__}; \
     61   static const FunctionSig kSig_##name(             \
     62       1, static_cast<int>(arraysize(kTypes_##name)) - 1, kTypes_##name);
     63 
     64 FOREACH_SIGNATURE(DECLARE_SIG)
     65 
     66 #define DECLARE_SIG_ENTRY(name, ...) &kSig_##name,
     67 
     68 static const FunctionSig* kSimpleExprSigs[] = {
     69     nullptr, FOREACH_SIGNATURE(DECLARE_SIG_ENTRY)};
     70 
     71 static byte kSimpleExprSigTable[256];
     72 
     73 // Initialize the signature table.
     74 static void InitSigTable() {
     75 #define SET_SIG_TABLE(name, opcode, sig) \
     76   kSimpleExprSigTable[opcode] = static_cast<int>(kSigEnum_##sig) + 1;
     77   FOREACH_SIMPLE_OPCODE(SET_SIG_TABLE);
     78   FOREACH_ASMJS_COMPAT_OPCODE(SET_SIG_TABLE);
     79 #undef SET_SIG_TABLE
     80 }
     81 
     82 class SigTable {
     83  public:
     84   SigTable() {
     85     // TODO(ahaas): Move {InitSigTable} into the class.
     86     InitSigTable();
     87   }
     88   FunctionSig* Signature(WasmOpcode opcode) const {
     89     return const_cast<FunctionSig*>(
     90         kSimpleExprSigs[kSimpleExprSigTable[static_cast<byte>(opcode)]]);
     91   }
     92 };
     93 
     94 static base::LazyInstance<SigTable>::type sig_table = LAZY_INSTANCE_INITIALIZER;
     95 
     96 FunctionSig* WasmOpcodes::Signature(WasmOpcode opcode) {
     97   return sig_table.Get().Signature(opcode);
     98 }
     99 
    100 // TODO(titzer): pull WASM_64 up to a common header.
    101 #if !V8_TARGET_ARCH_32_BIT || V8_TARGET_ARCH_X64
    102 #define WASM_64 1
    103 #else
    104 #define WASM_64 0
    105 #endif
    106 
    107 int WasmOpcodes::TrapReasonToMessageId(TrapReason reason) {
    108   switch (reason) {
    109 #define TRAPREASON_TO_MESSAGE(name) \
    110   case k##name:                     \
    111     return MessageTemplate::kWasm##name;
    112     FOREACH_WASM_TRAPREASON(TRAPREASON_TO_MESSAGE)
    113 #undef TRAPREASON_TO_MESSAGE
    114     default:
    115       return MessageTemplate::kNone;
    116   }
    117 }
    118 
    119 const char* WasmOpcodes::TrapReasonMessage(TrapReason reason) {
    120   return MessageTemplate::TemplateString(TrapReasonToMessageId(reason));
    121 }
    122 }  // namespace wasm
    123 }  // namespace internal
    124 }  // namespace v8
    125