| Index: src/interpreter/bytecode-traits.h
|
| diff --git a/src/interpreter/bytecode-traits.h b/src/interpreter/bytecode-traits.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..fd778d7c927880428797ad62fa0a7ee6f728e6e2
|
| --- /dev/null
|
| +++ b/src/interpreter/bytecode-traits.h
|
| @@ -0,0 +1,180 @@
|
| +// 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.
|
| +
|
| +#ifndef V8_INTERPRETER_BYTECODE_TRAITS_H_
|
| +#define V8_INTERPRETER_BYTECODE_TRAITS_H_
|
| +
|
| +#include "src/interpreter/bytecodes.h"
|
| +
|
| +namespace v8 {
|
| +namespace internal {
|
| +namespace interpreter {
|
| +
|
| +// TODO(rmcilroy): consider simplifying this to avoid the template magic.
|
| +
|
| +// Template helpers to deduce the number of operands each bytecode has.
|
| +#define OPERAND_TERM OperandType::kNone, OperandType::kNone, OperandType::kNone
|
| +
|
| +template <OperandType>
|
| +struct OperandTraits {};
|
| +
|
| +#define DECLARE_OPERAND_SIZE(Name, Size) \
|
| + template <> \
|
| + struct OperandTraits<OperandType::k##Name> { \
|
| + static const OperandSize kSizeType = Size; \
|
| + static const int kSize = static_cast<int>(Size); \
|
| + };
|
| +OPERAND_TYPE_LIST(DECLARE_OPERAND_SIZE)
|
| +#undef DECLARE_OPERAND_SIZE
|
| +
|
| +
|
| +template <OperandType... Args>
|
| +struct BytecodeTraits {};
|
| +
|
| +template <OperandType operand_0, OperandType operand_1, OperandType operand_2,
|
| + OperandType operand_3>
|
| +struct BytecodeTraits<operand_0, operand_1, operand_2, operand_3,
|
| + OPERAND_TERM> {
|
| + static OperandType GetOperandType(int i) {
|
| + DCHECK(0 <= i && i < kOperandCount);
|
| + const OperandType kOperands[] = {operand_0, operand_1, operand_2,
|
| + operand_3};
|
| + return kOperands[i];
|
| + }
|
| +
|
| + static inline OperandSize GetOperandSize(int i) {
|
| + DCHECK(0 <= i && i < kOperandCount);
|
| + const OperandSize kOperandSizes[] =
|
| + {OperandTraits<operand_0>::kSizeType,
|
| + OperandTraits<operand_1>::kSizeType,
|
| + OperandTraits<operand_2>::kSizeType,
|
| + OperandTraits<operand_3>::kSizeType};
|
| + return kOperandSizes[i];
|
| + }
|
| +
|
| + static inline int GetOperandOffset(int i) {
|
| + DCHECK(0 <= i && i < kOperandCount);
|
| + const int kOffset0 = 1;
|
| + const int kOffset1 = kOffset0 + OperandTraits<operand_0>::kSize;
|
| + const int kOffset2 = kOffset1 + OperandTraits<operand_1>::kSize;
|
| + const int kOffset3 = kOffset2 + OperandTraits<operand_2>::kSize;
|
| + const int kOperandOffsets[] = {kOffset0, kOffset1, kOffset2, kOffset3};
|
| + return kOperandOffsets[i];
|
| + }
|
| +
|
| + static const int kOperandCount = 4;
|
| + static const int kSize =
|
| + 1 + OperandTraits<operand_0>::kSize + OperandTraits<operand_1>::kSize +
|
| + OperandTraits<operand_2>::kSize + OperandTraits<operand_3>::kSize;
|
| +};
|
| +
|
| +
|
| +template <OperandType operand_0, OperandType operand_1, OperandType operand_2>
|
| +struct BytecodeTraits<operand_0, operand_1, operand_2, OPERAND_TERM> {
|
| + static inline OperandType GetOperandType(int i) {
|
| + DCHECK(0 <= i && i <= 2);
|
| + const OperandType kOperands[] = {operand_0, operand_1, operand_2};
|
| + return kOperands[i];
|
| + }
|
| +
|
| + static inline OperandSize GetOperandSize(int i) {
|
| + DCHECK(0 <= i && i < kOperandCount);
|
| + const OperandSize kOperandSizes[] =
|
| + {OperandTraits<operand_0>::kSizeType,
|
| + OperandTraits<operand_1>::kSizeType,
|
| + OperandTraits<operand_2>::kSizeType};
|
| + return kOperandSizes[i];
|
| + }
|
| +
|
| + static inline int GetOperandOffset(int i) {
|
| + DCHECK(0 <= i && i < kOperandCount);
|
| + const int kOffset0 = 1;
|
| + const int kOffset1 = kOffset0 + OperandTraits<operand_0>::kSize;
|
| + const int kOffset2 = kOffset1 + OperandTraits<operand_1>::kSize;
|
| + const int kOperandOffsets[] = {kOffset0, kOffset1, kOffset2};
|
| + return kOperandOffsets[i];
|
| + }
|
| +
|
| + static const int kOperandCount = 3;
|
| + static const int kSize =
|
| + 1 + OperandTraits<operand_0>::kSize + OperandTraits<operand_1>::kSize +
|
| + OperandTraits<operand_2>::kSize;
|
| +};
|
| +
|
| +template <OperandType operand_0, OperandType operand_1>
|
| +struct BytecodeTraits<operand_0, operand_1, OPERAND_TERM> {
|
| + static inline OperandType GetOperandType(int i) {
|
| + DCHECK(0 <= i && i < kOperandCount);
|
| + const OperandType kOperands[] = {operand_0, operand_1};
|
| + return kOperands[i];
|
| + }
|
| +
|
| + static inline OperandSize GetOperandSize(int i) {
|
| + DCHECK(0 <= i && i < kOperandCount);
|
| + const OperandSize kOperandSizes[] =
|
| + {OperandTraits<operand_0>::kSizeType,
|
| + OperandTraits<operand_1>::kSizeType};
|
| + return kOperandSizes[i];
|
| + }
|
| +
|
| + static inline int GetOperandOffset(int i) {
|
| + DCHECK(0 <= i && i < kOperandCount);
|
| + const int kOffset0 = 1;
|
| + const int kOffset1 = kOffset0 + OperandTraits<operand_0>::kSize;
|
| + const int kOperandOffsets[] = {kOffset0, kOffset1};
|
| + return kOperandOffsets[i];
|
| + }
|
| +
|
| + static const int kOperandCount = 2;
|
| + static const int kSize =
|
| + 1 + OperandTraits<operand_0>::kSize + OperandTraits<operand_1>::kSize;
|
| +};
|
| +
|
| +template <OperandType operand_0>
|
| +struct BytecodeTraits<operand_0, OPERAND_TERM> {
|
| + static inline OperandType GetOperandType(int i) {
|
| + DCHECK(i == 0);
|
| + return operand_0;
|
| + }
|
| +
|
| + static inline OperandSize GetOperandSize(int i) {
|
| + DCHECK(i == 0);
|
| + return OperandTraits<operand_0>::kSizeType;
|
| + }
|
| +
|
| + static inline int GetOperandOffset(int i) {
|
| + DCHECK(i == 0);
|
| + return 1;
|
| + }
|
| +
|
| + static const int kOperandCount = 1;
|
| + static const int kSize = 1 + OperandTraits<operand_0>::kSize;
|
| +};
|
| +
|
| +template <>
|
| +struct BytecodeTraits<OperandType::kNone, OPERAND_TERM> {
|
| + static inline OperandType GetOperandType(int i) {
|
| + UNREACHABLE();
|
| + return OperandType::kNone;
|
| + }
|
| +
|
| + static inline OperandSize GetOperandSize(int i) {
|
| + UNREACHABLE();
|
| + return OperandSize::kNone;
|
| + }
|
| +
|
| + static inline int GetOperandOffset(int i) {
|
| + UNREACHABLE();
|
| + return 1;
|
| + }
|
| +
|
| + static const int kOperandCount = 0;
|
| + static const int kSize = 1 + OperandTraits<OperandType::kNone>::kSize;
|
| +};
|
| +
|
| +} // namespace interpreter
|
| +} // namespace internal
|
| +} // namespace v8
|
| +
|
| +#endif // V8_INTERPRETER_BYTECODE_TRAITS_H_
|
|
|