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