4156d940e4
R=titzer@chromium.org,binji@chromium.org BUG=v8:4614 Review-Url: https://codereview.chromium.org/2423883003 Cr-Commit-Position: refs/heads/master@{#40606}
184 lines
5.4 KiB
C++
184 lines
5.4 KiB
C++
// 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"
|
|
#include "src/messages.h"
|
|
#include "src/signature.h"
|
|
|
|
namespace v8 {
|
|
namespace internal {
|
|
namespace wasm {
|
|
|
|
typedef Signature<LocalType> FunctionSig;
|
|
|
|
const char* WasmOpcodes::OpcodeName(WasmOpcode opcode) {
|
|
switch (opcode) {
|
|
#define DECLARE_NAME_CASE(name, opcode, sig) \
|
|
case kExpr##name: \
|
|
return "Expr" #name;
|
|
FOREACH_OPCODE(DECLARE_NAME_CASE)
|
|
#undef DECLARE_NAME_CASE
|
|
default:
|
|
break;
|
|
}
|
|
return "Unknown";
|
|
}
|
|
|
|
const char* WasmOpcodes::ShortOpcodeName(WasmOpcode opcode) {
|
|
switch (opcode) {
|
|
#define DECLARE_NAME_CASE(name, opcode, sig) \
|
|
case kExpr##name: \
|
|
return #name;
|
|
FOREACH_OPCODE(DECLARE_NAME_CASE)
|
|
#undef DECLARE_NAME_CASE
|
|
default:
|
|
break;
|
|
}
|
|
return "Unknown";
|
|
}
|
|
|
|
bool WasmOpcodes::IsPrefixOpcode(WasmOpcode opcode) {
|
|
switch (opcode) {
|
|
#define CHECK_PREFIX(name, opcode) \
|
|
case k##name##Prefix: \
|
|
return true;
|
|
FOREACH_PREFIX(CHECK_PREFIX)
|
|
#undef CHECK_PREFIX
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
std::ostream& operator<<(std::ostream& os, const FunctionSig& sig) {
|
|
if (sig.return_count() == 0) os << "v";
|
|
for (size_t i = 0; i < sig.return_count(); ++i) {
|
|
os << WasmOpcodes::ShortNameOf(sig.GetReturn(i));
|
|
}
|
|
os << "_";
|
|
if (sig.parameter_count() == 0) os << "v";
|
|
for (size_t i = 0; i < sig.parameter_count(); ++i) {
|
|
os << WasmOpcodes::ShortNameOf(sig.GetParam(i));
|
|
}
|
|
return os;
|
|
}
|
|
|
|
#define DECLARE_SIG_ENUM(name, ...) kSigEnum_##name,
|
|
|
|
enum WasmOpcodeSig { FOREACH_SIGNATURE(DECLARE_SIG_ENUM) };
|
|
|
|
// TODO(titzer): not static-initializer safe. Wrap in LazyInstance.
|
|
#define DECLARE_SIG(name, ...) \
|
|
static LocalType kTypes_##name[] = {__VA_ARGS__}; \
|
|
static const FunctionSig kSig_##name( \
|
|
1, static_cast<int>(arraysize(kTypes_##name)) - 1, kTypes_##name);
|
|
|
|
FOREACH_SIGNATURE(DECLARE_SIG)
|
|
|
|
#define DECLARE_SIG_ENTRY(name, ...) &kSig_##name,
|
|
|
|
static const FunctionSig* kSimpleExprSigs[] = {
|
|
nullptr, FOREACH_SIGNATURE(DECLARE_SIG_ENTRY)};
|
|
|
|
#define DECLARE_SIMD_SIG_ENTRY(name, ...) &kSig_##name,
|
|
|
|
static const FunctionSig* kSimdExprSigs[] = {
|
|
nullptr, FOREACH_SIMD_SIGNATURE(DECLARE_SIMD_SIG_ENTRY)};
|
|
|
|
static byte kSimpleExprSigTable[256];
|
|
static byte kSimpleAsmjsExprSigTable[256];
|
|
static byte kSimdExprSigTable[256];
|
|
static byte kAtomicExprSigTable[256];
|
|
|
|
// Initialize the signature table.
|
|
static void InitSigTables() {
|
|
#define SET_SIG_TABLE(name, opcode, sig) \
|
|
kSimpleExprSigTable[opcode] = static_cast<int>(kSigEnum_##sig) + 1;
|
|
FOREACH_SIMPLE_OPCODE(SET_SIG_TABLE);
|
|
#undef SET_SIG_TABLE
|
|
#define SET_ASMJS_SIG_TABLE(name, opcode, sig) \
|
|
kSimpleAsmjsExprSigTable[opcode] = static_cast<int>(kSigEnum_##sig) + 1;
|
|
FOREACH_ASMJS_COMPAT_OPCODE(SET_ASMJS_SIG_TABLE);
|
|
#undef SET_ASMJS_SIG_TABLE
|
|
byte simd_index;
|
|
#define SET_SIG_TABLE(name, opcode, sig) \
|
|
simd_index = opcode & 0xff; \
|
|
kSimdExprSigTable[simd_index] = static_cast<int>(kSigEnum_##sig) + 1;
|
|
FOREACH_SIMD_0_OPERAND_OPCODE(SET_SIG_TABLE)
|
|
#undef SET_SIG_TABLE
|
|
byte atomic_index;
|
|
#define SET_ATOMIC_SIG_TABLE(name, opcode, sig) \
|
|
atomic_index = opcode & 0xff; \
|
|
kAtomicExprSigTable[atomic_index] = static_cast<int>(kSigEnum_##sig) + 1;
|
|
FOREACH_ATOMIC_OPCODE(SET_ATOMIC_SIG_TABLE)
|
|
#undef SET_ATOMIC_SIG_TABLE
|
|
}
|
|
|
|
class SigTable {
|
|
public:
|
|
SigTable() {
|
|
// TODO(ahaas): Move {InitSigTable} into the class.
|
|
InitSigTables();
|
|
}
|
|
FunctionSig* Signature(WasmOpcode opcode) const {
|
|
return const_cast<FunctionSig*>(
|
|
kSimpleExprSigs[kSimpleExprSigTable[static_cast<byte>(opcode)]]);
|
|
}
|
|
FunctionSig* AsmjsSignature(WasmOpcode opcode) const {
|
|
return const_cast<FunctionSig*>(
|
|
kSimpleExprSigs[kSimpleAsmjsExprSigTable[static_cast<byte>(opcode)]]);
|
|
}
|
|
FunctionSig* SimdSignature(WasmOpcode opcode) const {
|
|
return const_cast<FunctionSig*>(
|
|
kSimdExprSigs[kSimdExprSigTable[static_cast<byte>(opcode & 0xff)]]);
|
|
}
|
|
FunctionSig* AtomicSignature(WasmOpcode opcode) const {
|
|
return const_cast<FunctionSig*>(
|
|
kSimpleExprSigs[kAtomicExprSigTable[static_cast<byte>(opcode & 0xff)]]);
|
|
}
|
|
};
|
|
|
|
static base::LazyInstance<SigTable>::type sig_table = LAZY_INSTANCE_INITIALIZER;
|
|
|
|
FunctionSig* WasmOpcodes::Signature(WasmOpcode opcode) {
|
|
if (opcode >> 8 == kSimdPrefix) {
|
|
return sig_table.Get().SimdSignature(opcode);
|
|
} else {
|
|
return sig_table.Get().Signature(opcode);
|
|
}
|
|
}
|
|
|
|
FunctionSig* WasmOpcodes::AsmjsSignature(WasmOpcode opcode) {
|
|
return sig_table.Get().AsmjsSignature(opcode);
|
|
}
|
|
|
|
FunctionSig* WasmOpcodes::AtomicSignature(WasmOpcode opcode) {
|
|
return sig_table.Get().AtomicSignature(opcode);
|
|
}
|
|
|
|
// TODO(titzer): pull WASM_64 up to a common header.
|
|
#if !V8_TARGET_ARCH_32_BIT || V8_TARGET_ARCH_X64
|
|
#define WASM_64 1
|
|
#else
|
|
#define WASM_64 0
|
|
#endif
|
|
|
|
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));
|
|
}
|
|
} // namespace wasm
|
|
} // namespace internal
|
|
} // namespace v8
|