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 9namespace v8 { 10namespace internal { 11namespace wasm { 12 13typedef Signature<LocalType> FunctionSig; 14 15const 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 28const 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 41std::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 56enum 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 64FOREACH_SIGNATURE(DECLARE_SIG) 65 66#define DECLARE_SIG_ENTRY(name, ...) &kSig_##name, 67 68static const FunctionSig* kSimpleExprSigs[] = { 69 nullptr, FOREACH_SIGNATURE(DECLARE_SIG_ENTRY)}; 70 71static byte kSimpleExprSigTable[256]; 72 73// Initialize the signature table. 74static 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 82class 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 94static base::LazyInstance<SigTable>::type sig_table = LAZY_INSTANCE_INITIALIZER; 95 96FunctionSig* 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 107int 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 119const char* WasmOpcodes::TrapReasonMessage(TrapReason reason) { 120 return MessageTemplate::TemplateString(TrapReasonToMessageId(reason)); 121} 122} // namespace wasm 123} // namespace internal 124} // namespace v8 125