diff options
Diffstat (limited to 'runtime/dex_instruction.cc')
| -rw-r--r-- | runtime/dex_instruction.cc | 83 |
1 files changed, 40 insertions, 43 deletions
diff --git a/runtime/dex_instruction.cc b/runtime/dex_instruction.cc index 9f34c12d9a..b2267e5573 100644 --- a/runtime/dex_instruction.cc +++ b/runtime/dex_instruction.cc @@ -31,57 +31,46 @@ namespace art { using android::base::StringPrintf; const char* const Instruction::kInstructionNames[] = { -#define INSTRUCTION_NAME(o, c, pname, f, i, a, v) pname, +#define INSTRUCTION_NAME(o, c, pname, f, i, a, e, v) pname, #include "dex_instruction_list.h" DEX_INSTRUCTION_LIST(INSTRUCTION_NAME) #undef DEX_INSTRUCTION_LIST #undef INSTRUCTION_NAME }; -Instruction::Format const Instruction::kInstructionFormats[] = { -#define INSTRUCTION_FORMAT(o, c, p, format, i, a, v) format, -#include "dex_instruction_list.h" - DEX_INSTRUCTION_LIST(INSTRUCTION_FORMAT) -#undef DEX_INSTRUCTION_LIST -#undef INSTRUCTION_FORMAT -}; - -Instruction::IndexType const Instruction::kInstructionIndexTypes[] = { -#define INSTRUCTION_INDEX_TYPE(o, c, p, f, index, a, v) index, -#include "dex_instruction_list.h" - DEX_INSTRUCTION_LIST(INSTRUCTION_INDEX_TYPE) -#undef DEX_INSTRUCTION_LIST -#undef INSTRUCTION_FLAGS -}; - -int const Instruction::kInstructionFlags[] = { -#define INSTRUCTION_FLAGS(o, c, p, f, i, flags, v) flags, -#include "dex_instruction_list.h" - DEX_INSTRUCTION_LIST(INSTRUCTION_FLAGS) -#undef DEX_INSTRUCTION_LIST -#undef INSTRUCTION_FLAGS -}; +static_assert(sizeof(Instruction::InstructionDescriptor) == 8u, "Unexpected descriptor size"); -int const Instruction::kInstructionVerifyFlags[] = { -#define INSTRUCTION_VERIFY_FLAGS(o, c, p, f, i, a, vflags) vflags, -#include "dex_instruction_list.h" - DEX_INSTRUCTION_LIST(INSTRUCTION_VERIFY_FLAGS) -#undef DEX_INSTRUCTION_LIST -#undef INSTRUCTION_VERIFY_FLAGS -}; +static constexpr int8_t InstructionSizeInCodeUnitsByOpcode(Instruction::Code opcode, + Instruction::Format format) { + if (opcode == Instruction::Code::NOP) { + return -1; + } else if ((format >= Instruction::Format::k10x) && (format <= Instruction::Format::k10t)) { + return 1; + } else if ((format >= Instruction::Format::k20t) && (format <= Instruction::Format::k22c)) { + return 2; + } else if ((format >= Instruction::Format::k32x) && (format <= Instruction::Format::k3rc)) { + return 3; + } else if ((format >= Instruction::Format::k45cc) && (format <= Instruction::Format::k4rcc)) { + return 4; + } else if (format == Instruction::Format::k51l) { + return 5; + } else { + return -1; + } +} -int const Instruction::kInstructionSizeInCodeUnits[] = { -#define INSTRUCTION_SIZE(opcode, c, p, format, i, a, v) \ - (((opcode) == NOP) ? -1 : \ - (((format) >= k10x) && ((format) <= k10t)) ? 1 : \ - (((format) >= k20t) && ((format) <= k22c)) ? 2 : \ - (((format) >= k32x) && ((format) <= k3rc)) ? 3 : \ - (((format) >= k45cc) && ((format) <= k4rcc)) ? 4 : \ - ((format) == k51l) ? 5 : -1), +Instruction::InstructionDescriptor const Instruction::kInstructionDescriptors[] = { +#define INSTRUCTION_DESCR(opcode, c, p, format, index, flags, eflags, vflags) \ + { vflags, \ + format, \ + index, \ + flags, \ + InstructionSizeInCodeUnitsByOpcode((c), (format)), \ + }, #include "dex_instruction_list.h" - DEX_INSTRUCTION_LIST(INSTRUCTION_SIZE) + DEX_INSTRUCTION_LIST(INSTRUCTION_DESCR) #undef DEX_INSTRUCTION_LIST -#undef INSTRUCTION_SIZE +#undef INSTRUCTION_DESCR }; int32_t Instruction::GetTargetOffset() const { @@ -520,7 +509,7 @@ std::string Instruction::DumpString(const DexFile* file) const { struct InstructionStaticAsserts : private Instruction { #define IMPLIES(a, b) (!(a) || (b)) - #define VAR_ARGS_CHECK(o, c, pname, f, i, a, v) \ + #define VAR_ARGS_CHECK(o, c, pname, f, i, a, e, v) \ static_assert(IMPLIES((f) == k35c || (f) == k45cc, \ ((v) & (kVerifyVarArg | kVerifyVarArgNonZero)) != 0), \ "Missing var-arg verification"); @@ -529,7 +518,7 @@ struct InstructionStaticAsserts : private Instruction { #undef DEX_INSTRUCTION_LIST #undef VAR_ARGS_CHECK - #define VAR_ARGS_RANGE_CHECK(o, c, pname, f, i, a, v) \ + #define VAR_ARGS_RANGE_CHECK(o, c, pname, f, i, a, e, v) \ static_assert(IMPLIES((f) == k3rc || (f) == k4rcc, \ ((v) & (kVerifyVarArgRange | kVerifyVarArgRangeNonZero)) != 0), \ "Missing var-arg verification"); @@ -537,6 +526,14 @@ struct InstructionStaticAsserts : private Instruction { DEX_INSTRUCTION_LIST(VAR_ARGS_RANGE_CHECK) #undef DEX_INSTRUCTION_LIST #undef VAR_ARGS_RANGE_CHECK + + #define EXPERIMENTAL_CHECK(o, c, pname, f, i, a, e, v) \ + static_assert(kHaveExperimentalInstructions || (((a) & kExperimental) == 0), \ + "Unexpected experimental instruction."); + #include "dex_instruction_list.h" + DEX_INSTRUCTION_LIST(EXPERIMENTAL_CHECK) + #undef DEX_INSTRUCTION_LIST + #undef EXPERIMENTAL_CHECK }; std::ostream& operator<<(std::ostream& os, const Instruction::Code& code) { |