Home | History | Annotate | Download | only in dex
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef ART_LIBDEXFILE_DEX_DEX_INSTRUCTION_H_
     18 #define ART_LIBDEXFILE_DEX_DEX_INSTRUCTION_H_
     19 
     20 #include <android-base/logging.h>
     21 
     22 #include "base/globals.h"
     23 #include "base/macros.h"
     24 
     25 typedef uint8_t uint4_t;
     26 typedef int8_t int4_t;
     27 
     28 namespace art {
     29 
     30 class DexFile;
     31 
     32 enum {
     33   kNumPackedOpcodes = 0x100
     34 };
     35 
     36 class Instruction {
     37  public:
     38   // NOP-encoded switch-statement signatures.
     39   enum Signatures {
     40     kPackedSwitchSignature = 0x0100,
     41     kSparseSwitchSignature = 0x0200,
     42     kArrayDataSignature = 0x0300,
     43   };
     44 
     45   struct PACKED(4) PackedSwitchPayload {
     46     const uint16_t ident;
     47     const uint16_t case_count;
     48     const int32_t first_key;
     49     const int32_t targets[];
     50 
     51    private:
     52     DISALLOW_COPY_AND_ASSIGN(PackedSwitchPayload);
     53   };
     54 
     55   struct PACKED(4) SparseSwitchPayload {
     56     const uint16_t ident;
     57     const uint16_t case_count;
     58     const int32_t keys_and_targets[];
     59 
     60    public:
     61     const int32_t* GetKeys() const {
     62       return keys_and_targets;
     63     }
     64 
     65     const int32_t* GetTargets() const {
     66       return keys_and_targets + case_count;
     67     }
     68 
     69    private:
     70     DISALLOW_COPY_AND_ASSIGN(SparseSwitchPayload);
     71   };
     72 
     73   struct PACKED(4) ArrayDataPayload {
     74     const uint16_t ident;
     75     const uint16_t element_width;
     76     const uint32_t element_count;
     77     const uint8_t data[];
     78 
     79    private:
     80     DISALLOW_COPY_AND_ASSIGN(ArrayDataPayload);
     81   };
     82 
     83   enum Code {  // private marker to avoid generate-operator-out.py from processing.
     84 #define INSTRUCTION_ENUM(opcode, cname, p, f, i, a, e, v) cname = (opcode),
     85 #include "dex_instruction_list.h"
     86     DEX_INSTRUCTION_LIST(INSTRUCTION_ENUM)
     87 #undef DEX_INSTRUCTION_LIST
     88 #undef INSTRUCTION_ENUM
     89     RSUB_INT_LIT16 = RSUB_INT,
     90   };
     91 
     92   enum Format : uint8_t {
     93     k10x,  // op
     94     k12x,  // op vA, vB
     95     k11n,  // op vA, #+B
     96     k11x,  // op vAA
     97     k10t,  // op +AA
     98     k20t,  // op +AAAA
     99     k22x,  // op vAA, vBBBB
    100     k21t,  // op vAA, +BBBB
    101     k21s,  // op vAA, #+BBBB
    102     k21h,  // op vAA, #+BBBB00000[00000000]
    103     k21c,  // op vAA, thing@BBBB
    104     k23x,  // op vAA, vBB, vCC
    105     k22b,  // op vAA, vBB, #+CC
    106     k22t,  // op vA, vB, +CCCC
    107     k22s,  // op vA, vB, #+CCCC
    108     k22c,  // op vA, vB, thing@CCCC
    109     k32x,  // op vAAAA, vBBBB
    110     k30t,  // op +AAAAAAAA
    111     k31t,  // op vAA, +BBBBBBBB
    112     k31i,  // op vAA, #+BBBBBBBB
    113     k31c,  // op vAA, thing@BBBBBBBB
    114     k35c,  // op {vC, vD, vE, vF, vG}, thing@BBBB (B: count, A: vG)
    115     k3rc,  // op {vCCCC .. v(CCCC+AA-1)}, meth@BBBB
    116 
    117     // op {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH (A: count)
    118     // format: AG op BBBB FEDC HHHH
    119     k45cc,
    120 
    121     // op {VCCCC .. v(CCCC+AA-1)}, meth@BBBB, proto@HHHH (AA: count)
    122     // format: AA op BBBB CCCC HHHH
    123     k4rcc,  // op {VCCCC .. v(CCCC+AA-1)}, meth@BBBB, proto@HHHH (AA: count)
    124 
    125     k51l,  // op vAA, #+BBBBBBBBBBBBBBBB
    126   };
    127 
    128   enum IndexType : uint8_t {
    129     kIndexUnknown = 0,
    130     kIndexNone,               // has no index
    131     kIndexTypeRef,            // type reference index
    132     kIndexStringRef,          // string reference index
    133     kIndexMethodRef,          // method reference index
    134     kIndexFieldRef,           // field reference index
    135     kIndexFieldOffset,        // field offset (for static linked fields)
    136     kIndexVtableOffset,       // vtable offset (for static linked methods)
    137     kIndexMethodAndProtoRef,  // method and a proto reference index (for invoke-polymorphic)
    138     kIndexCallSiteRef,        // call site reference index
    139     kIndexMethodHandleRef,    // constant method handle reference index
    140     kIndexProtoRef,           // prototype reference index
    141   };
    142 
    143   enum Flags : uint8_t {
    144     kBranch              = 0x01,  // conditional or unconditional branch
    145     kContinue            = 0x02,  // flow can continue to next statement
    146     kSwitch              = 0x04,  // switch statement
    147     kThrow               = 0x08,  // could cause an exception to be thrown
    148     kReturn              = 0x10,  // returns, no additional statements
    149     kInvoke              = 0x20,  // a flavor of invoke
    150     kUnconditional       = 0x40,  // unconditional branch
    151     kExperimental        = 0x80,  // is an experimental opcode
    152   };
    153 
    154   // Old flags. Keeping them around in case we might need them again some day.
    155   enum ExtendedFlags : uint32_t {
    156     kAdd                 = 0x0000080,  // addition
    157     kSubtract            = 0x0000100,  // subtract
    158     kMultiply            = 0x0000200,  // multiply
    159     kDivide              = 0x0000400,  // division
    160     kRemainder           = 0x0000800,  // remainder
    161     kAnd                 = 0x0001000,  // and
    162     kOr                  = 0x0002000,  // or
    163     kXor                 = 0x0004000,  // xor
    164     kShl                 = 0x0008000,  // shl
    165     kShr                 = 0x0010000,  // shr
    166     kUshr                = 0x0020000,  // ushr
    167     kCast                = 0x0040000,  // cast
    168     kStore               = 0x0080000,  // store opcode
    169     kLoad                = 0x0100000,  // load opcode
    170     kClobber             = 0x0200000,  // clobbers memory in a big way (not just a write)
    171     kRegCFieldOrConstant = 0x0400000,  // is the third virtual register a field or literal constant (vC)
    172     kRegBFieldOrConstant = 0x0800000,  // is the second virtual register a field or literal constant (vB)
    173   };
    174 
    175   enum VerifyFlag : uint32_t {
    176     kVerifyNone               = 0x0000000,
    177     kVerifyRegA               = 0x0000001,
    178     kVerifyRegAWide           = 0x0000002,
    179     kVerifyRegB               = 0x0000004,
    180     kVerifyRegBField          = 0x0000008,
    181     kVerifyRegBMethod         = 0x0000010,
    182     kVerifyRegBNewInstance    = 0x0000020,
    183     kVerifyRegBString         = 0x0000040,
    184     kVerifyRegBType           = 0x0000080,
    185     kVerifyRegBWide           = 0x0000100,
    186     kVerifyRegC               = 0x0000200,
    187     kVerifyRegCField          = 0x0000400,
    188     kVerifyRegCNewArray       = 0x0000800,
    189     kVerifyRegCType           = 0x0001000,
    190     kVerifyRegCWide           = 0x0002000,
    191     kVerifyArrayData          = 0x0004000,
    192     kVerifyBranchTarget       = 0x0008000,
    193     kVerifySwitchTargets      = 0x0010000,
    194     kVerifyVarArg             = 0x0020000,
    195     kVerifyVarArgNonZero      = 0x0040000,
    196     kVerifyVarArgRange        = 0x0080000,
    197     kVerifyVarArgRangeNonZero = 0x0100000,
    198     kVerifyRuntimeOnly        = 0x0200000,
    199     kVerifyError              = 0x0400000,
    200     kVerifyRegHPrototype      = 0x0800000,
    201     kVerifyRegBCallSite       = 0x1000000,
    202     kVerifyRegBMethodHandle   = 0x2000000,
    203     kVerifyRegBPrototype      = 0x4000000,
    204   };
    205 
    206   // Collect the enums in a struct for better locality.
    207   struct InstructionDescriptor {
    208     uint32_t verify_flags;         // Set of VerifyFlag.
    209     Format format;
    210     IndexType index_type;
    211     uint8_t flags;                 // Set of Flags.
    212     int8_t size_in_code_units;
    213   };
    214 
    215   static constexpr uint32_t kMaxVarArgRegs = 5;
    216 
    217   static constexpr bool kHaveExperimentalInstructions = false;
    218 
    219   // Returns the size (in 2 byte code units) of this instruction.
    220   size_t SizeInCodeUnits() const {
    221     int8_t result = kInstructionDescriptors[Opcode()].size_in_code_units;
    222     if (UNLIKELY(result < 0)) {
    223       return SizeInCodeUnitsComplexOpcode();
    224     } else {
    225       return static_cast<size_t>(result);
    226     }
    227   }
    228 
    229   // Code units required to calculate the size of the instruction.
    230   size_t CodeUnitsRequiredForSizeComputation() const {
    231     const int8_t result = kInstructionDescriptors[Opcode()].size_in_code_units;
    232     return UNLIKELY(result < 0) ? CodeUnitsRequiredForSizeOfComplexOpcode() : 1;
    233   }
    234 
    235   // Reads an instruction out of the stream at the specified address.
    236   static const Instruction* At(const uint16_t* code) {
    237     DCHECK(code != nullptr);
    238     return reinterpret_cast<const Instruction*>(code);
    239   }
    240 
    241   // Reads an instruction out of the stream from the current address plus an offset.
    242   const Instruction* RelativeAt(int32_t offset) const WARN_UNUSED {
    243     return At(reinterpret_cast<const uint16_t*>(this) + offset);
    244   }
    245 
    246   // Returns a pointer to the next instruction in the stream.
    247   const Instruction* Next() const {
    248     return RelativeAt(SizeInCodeUnits());
    249   }
    250 
    251   // Returns a pointer to the instruction after this 1xx instruction in the stream.
    252   const Instruction* Next_1xx() const {
    253     DCHECK(FormatOf(Opcode()) >= k10x && FormatOf(Opcode()) <= k10t);
    254     return RelativeAt(1);
    255   }
    256 
    257   // Returns a pointer to the instruction after this 2xx instruction in the stream.
    258   const Instruction* Next_2xx() const {
    259     DCHECK(FormatOf(Opcode()) >= k20t && FormatOf(Opcode()) <= k22c);
    260     return RelativeAt(2);
    261   }
    262 
    263   // Returns a pointer to the instruction after this 3xx instruction in the stream.
    264   const Instruction* Next_3xx() const {
    265     DCHECK(FormatOf(Opcode()) >= k32x && FormatOf(Opcode()) <= k3rc);
    266     return RelativeAt(3);
    267   }
    268 
    269   // Returns a pointer to the instruction after this 4xx instruction in the stream.
    270   const Instruction* Next_4xx() const {
    271     DCHECK(FormatOf(Opcode()) >= k45cc && FormatOf(Opcode()) <= k4rcc);
    272     return RelativeAt(4);
    273   }
    274 
    275   // Returns a pointer to the instruction after this 51l instruction in the stream.
    276   const Instruction* Next_51l() const {
    277     DCHECK(FormatOf(Opcode()) == k51l);
    278     return RelativeAt(5);
    279   }
    280 
    281   // Returns the name of this instruction's opcode.
    282   const char* Name() const {
    283     return Instruction::Name(Opcode());
    284   }
    285 
    286   // Returns the name of the given opcode.
    287   static const char* Name(Code opcode) {
    288     return kInstructionNames[opcode];
    289   }
    290 
    291   // VRegA
    292   bool HasVRegA() const;
    293   ALWAYS_INLINE int32_t VRegA() const;
    294 
    295   int8_t VRegA_10t() const {
    296     return VRegA_10t(Fetch16(0));
    297   }
    298   uint8_t VRegA_10x() const {
    299     return VRegA_10x(Fetch16(0));
    300   }
    301   uint4_t VRegA_11n() const {
    302     return VRegA_11n(Fetch16(0));
    303   }
    304   uint8_t VRegA_11x() const {
    305     return VRegA_11x(Fetch16(0));
    306   }
    307   uint4_t VRegA_12x() const {
    308     return VRegA_12x(Fetch16(0));
    309   }
    310   int16_t VRegA_20t() const;
    311   uint8_t VRegA_21c() const {
    312     return VRegA_21c(Fetch16(0));
    313   }
    314   uint8_t VRegA_21h() const {
    315     return VRegA_21h(Fetch16(0));
    316   }
    317   uint8_t VRegA_21s() const {
    318     return VRegA_21s(Fetch16(0));
    319   }
    320   uint8_t VRegA_21t() const {
    321     return VRegA_21t(Fetch16(0));
    322   }
    323   uint8_t VRegA_22b() const {
    324     return VRegA_22b(Fetch16(0));
    325   }
    326   uint4_t VRegA_22c() const {
    327     return VRegA_22c(Fetch16(0));
    328   }
    329   uint4_t VRegA_22s() const {
    330     return VRegA_22s(Fetch16(0));
    331   }
    332   uint4_t VRegA_22t() const {
    333     return VRegA_22t(Fetch16(0));
    334   }
    335   uint8_t VRegA_22x() const {
    336     return VRegA_22x(Fetch16(0));
    337   }
    338   uint8_t VRegA_23x() const {
    339     return VRegA_23x(Fetch16(0));
    340   }
    341   int32_t VRegA_30t() const;
    342   uint8_t VRegA_31c() const {
    343     return VRegA_31c(Fetch16(0));
    344   }
    345   uint8_t VRegA_31i() const {
    346     return VRegA_31i(Fetch16(0));
    347   }
    348   uint8_t VRegA_31t() const {
    349     return VRegA_31t(Fetch16(0));
    350   }
    351   uint16_t VRegA_32x() const;
    352   uint4_t VRegA_35c() const {
    353     return VRegA_35c(Fetch16(0));
    354   }
    355   uint8_t VRegA_3rc() const {
    356     return VRegA_3rc(Fetch16(0));
    357   }
    358   uint8_t VRegA_51l() const {
    359     return VRegA_51l(Fetch16(0));
    360   }
    361   uint4_t VRegA_45cc() const {
    362     return VRegA_45cc(Fetch16(0));
    363   }
    364   uint8_t VRegA_4rcc() const {
    365     return VRegA_4rcc(Fetch16(0));
    366   }
    367 
    368   // The following methods return the vA operand for various instruction formats. The "inst_data"
    369   // parameter holds the first 16 bits of instruction which the returned value is decoded from.
    370   int8_t VRegA_10t(uint16_t inst_data) const;
    371   uint8_t VRegA_10x(uint16_t inst_data) const;
    372   uint4_t VRegA_11n(uint16_t inst_data) const;
    373   uint8_t VRegA_11x(uint16_t inst_data) const;
    374   uint4_t VRegA_12x(uint16_t inst_data) const;
    375   uint8_t VRegA_21c(uint16_t inst_data) const;
    376   uint8_t VRegA_21h(uint16_t inst_data) const;
    377   uint8_t VRegA_21s(uint16_t inst_data) const;
    378   uint8_t VRegA_21t(uint16_t inst_data) const;
    379   uint8_t VRegA_22b(uint16_t inst_data) const;
    380   uint4_t VRegA_22c(uint16_t inst_data) const;
    381   uint4_t VRegA_22s(uint16_t inst_data) const;
    382   uint4_t VRegA_22t(uint16_t inst_data) const;
    383   uint8_t VRegA_22x(uint16_t inst_data) const;
    384   uint8_t VRegA_23x(uint16_t inst_data) const;
    385   uint8_t VRegA_31c(uint16_t inst_data) const;
    386   uint8_t VRegA_31i(uint16_t inst_data) const;
    387   uint8_t VRegA_31t(uint16_t inst_data) const;
    388   uint4_t VRegA_35c(uint16_t inst_data) const;
    389   uint8_t VRegA_3rc(uint16_t inst_data) const;
    390   uint8_t VRegA_51l(uint16_t inst_data) const;
    391   uint4_t VRegA_45cc(uint16_t inst_data) const;
    392   uint8_t VRegA_4rcc(uint16_t inst_data) const;
    393 
    394   // VRegB
    395   bool HasVRegB() const;
    396   int32_t VRegB() const;
    397 
    398   bool HasWideVRegB() const;
    399   uint64_t WideVRegB() const;
    400 
    401   int4_t VRegB_11n() const {
    402     return VRegB_11n(Fetch16(0));
    403   }
    404   uint4_t VRegB_12x() const {
    405     return VRegB_12x(Fetch16(0));
    406   }
    407   uint16_t VRegB_21c() const;
    408   uint16_t VRegB_21h() const;
    409   int16_t VRegB_21s() const;
    410   int16_t VRegB_21t() const;
    411   uint8_t VRegB_22b() const;
    412   uint4_t VRegB_22c() const {
    413     return VRegB_22c(Fetch16(0));
    414   }
    415   uint4_t VRegB_22s() const {
    416     return VRegB_22s(Fetch16(0));
    417   }
    418   uint4_t VRegB_22t() const {
    419     return VRegB_22t(Fetch16(0));
    420   }
    421   uint16_t VRegB_22x() const;
    422   uint8_t VRegB_23x() const;
    423   uint32_t VRegB_31c() const;
    424   int32_t VRegB_31i() const;
    425   int32_t VRegB_31t() const;
    426   uint16_t VRegB_32x() const;
    427   uint16_t VRegB_35c() const;
    428   uint16_t VRegB_3rc() const;
    429   uint64_t VRegB_51l() const;  // vB_wide
    430   uint16_t VRegB_45cc() const;
    431   uint16_t VRegB_4rcc() const;
    432 
    433   // The following methods return the vB operand for all instruction formats where it is encoded in
    434   // the first 16 bits of instruction. The "inst_data" parameter holds these 16 bits. The returned
    435   // value is decoded from it.
    436   int4_t VRegB_11n(uint16_t inst_data) const;
    437   uint4_t VRegB_12x(uint16_t inst_data) const;
    438   uint4_t VRegB_22c(uint16_t inst_data) const;
    439   uint4_t VRegB_22s(uint16_t inst_data) const;
    440   uint4_t VRegB_22t(uint16_t inst_data) const;
    441 
    442   // VRegC
    443   bool HasVRegC() const;
    444   int32_t VRegC() const;
    445 
    446   int8_t VRegC_22b() const;
    447   uint16_t VRegC_22c() const;
    448   int16_t VRegC_22s() const;
    449   int16_t VRegC_22t() const;
    450   uint8_t VRegC_23x() const;
    451   uint4_t VRegC_35c() const;
    452   uint16_t VRegC_3rc() const;
    453   uint4_t VRegC_45cc() const;
    454   uint16_t VRegC_4rcc() const;
    455 
    456 
    457   // VRegH
    458   bool HasVRegH() const;
    459   int32_t VRegH() const;
    460   uint16_t VRegH_45cc() const;
    461   uint16_t VRegH_4rcc() const;
    462 
    463   // Fills the given array with the 'arg' array of the instruction.
    464   bool HasVarArgs() const;
    465   void GetVarArgs(uint32_t args[kMaxVarArgRegs], uint16_t inst_data) const;
    466   void GetVarArgs(uint32_t args[kMaxVarArgRegs]) const {
    467     return GetVarArgs(args, Fetch16(0));
    468   }
    469 
    470   // Returns the opcode field of the instruction. The given "inst_data" parameter must be the first
    471   // 16 bits of instruction.
    472   Code Opcode(uint16_t inst_data) const {
    473     DCHECK_EQ(inst_data, Fetch16(0));
    474     return static_cast<Code>(inst_data & 0xFF);
    475   }
    476 
    477   // Returns the opcode field of the instruction from the first 16 bits of instruction.
    478   Code Opcode() const {
    479     return Opcode(Fetch16(0));
    480   }
    481 
    482   void SetOpcode(Code opcode) {
    483     DCHECK_LT(static_cast<uint16_t>(opcode), 256u);
    484     uint16_t* insns = reinterpret_cast<uint16_t*>(this);
    485     insns[0] = (insns[0] & 0xff00) | static_cast<uint16_t>(opcode);
    486   }
    487 
    488   void SetVRegA_10x(uint8_t val) {
    489     DCHECK(FormatOf(Opcode()) == k10x);
    490     uint16_t* insns = reinterpret_cast<uint16_t*>(this);
    491     insns[0] = (val << 8) | (insns[0] & 0x00ff);
    492   }
    493 
    494   void SetVRegB_3rc(uint16_t val) {
    495     DCHECK(FormatOf(Opcode()) == k3rc);
    496     uint16_t* insns = reinterpret_cast<uint16_t*>(this);
    497     insns[1] = val;
    498   }
    499 
    500   void SetVRegB_35c(uint16_t val) {
    501     DCHECK(FormatOf(Opcode()) == k35c);
    502     uint16_t* insns = reinterpret_cast<uint16_t*>(this);
    503     insns[1] = val;
    504   }
    505 
    506   void SetVRegC_22c(uint16_t val) {
    507     DCHECK(FormatOf(Opcode()) == k22c);
    508     uint16_t* insns = reinterpret_cast<uint16_t*>(this);
    509     insns[1] = val;
    510   }
    511 
    512   void SetVRegA_21c(uint8_t val) {
    513     DCHECK(FormatOf(Opcode()) == k21c);
    514     uint16_t* insns = reinterpret_cast<uint16_t*>(this);
    515     insns[0] = (val << 8) | (insns[0] & 0x00ff);
    516   }
    517 
    518   void SetVRegB_21c(uint16_t val) {
    519     DCHECK(FormatOf(Opcode()) == k21c);
    520     uint16_t* insns = reinterpret_cast<uint16_t*>(this);
    521     insns[1] = val;
    522   }
    523 
    524   // Returns the format of the given opcode.
    525   static Format FormatOf(Code opcode) {
    526     return kInstructionDescriptors[opcode].format;
    527   }
    528 
    529   // Returns the index type of the given opcode.
    530   static IndexType IndexTypeOf(Code opcode) {
    531     return kInstructionDescriptors[opcode].index_type;
    532   }
    533 
    534   // Returns the flags for the given opcode.
    535   static uint8_t FlagsOf(Code opcode) {
    536     return kInstructionDescriptors[opcode].flags;
    537   }
    538 
    539   // Return the verify flags for the given opcode.
    540   static uint32_t VerifyFlagsOf(Code opcode) {
    541     return kInstructionDescriptors[opcode].verify_flags;
    542   }
    543 
    544   // Returns true if this instruction is a branch.
    545   bool IsBranch() const {
    546     return (kInstructionDescriptors[Opcode()].flags & kBranch) != 0;
    547   }
    548 
    549   // Returns true if this instruction is a unconditional branch.
    550   bool IsUnconditional() const {
    551     return (kInstructionDescriptors[Opcode()].flags & kUnconditional) != 0;
    552   }
    553 
    554   // Returns the branch offset if this instruction is a branch.
    555   int32_t GetTargetOffset() const;
    556 
    557   // Returns true if the instruction allows control flow to go to the following instruction.
    558   bool CanFlowThrough() const;
    559 
    560   // Returns true if the instruction is a quickened instruction.
    561   bool IsQuickened() const {
    562     return (kInstructionDescriptors[Opcode()].index_type == kIndexFieldOffset) ||
    563         (kInstructionDescriptors[Opcode()].index_type == kIndexVtableOffset);
    564   }
    565 
    566   // Returns true if this instruction is a switch.
    567   bool IsSwitch() const {
    568     return (kInstructionDescriptors[Opcode()].flags & kSwitch) != 0;
    569   }
    570 
    571   // Returns true if this instruction can throw.
    572   bool IsThrow() const {
    573     return (kInstructionDescriptors[Opcode()].flags & kThrow) != 0;
    574   }
    575 
    576   // Determine if the instruction is any of 'return' instructions.
    577   bool IsReturn() const {
    578     return (kInstructionDescriptors[Opcode()].flags & kReturn) != 0;
    579   }
    580 
    581   // Determine if this instruction ends execution of its basic block.
    582   bool IsBasicBlockEnd() const {
    583     return IsBranch() || IsReturn() || Opcode() == THROW;
    584   }
    585 
    586   // Determine if this instruction is an invoke.
    587   bool IsInvoke() const {
    588     return (kInstructionDescriptors[Opcode()].flags & kInvoke) != 0;
    589   }
    590 
    591   // Determine if this instruction is experimental.
    592   bool IsExperimental() const {
    593     return (kInstructionDescriptors[Opcode()].flags & kExperimental) != 0;
    594   }
    595 
    596   int GetVerifyTypeArgumentA() const {
    597     return (kInstructionDescriptors[Opcode()].verify_flags & (kVerifyRegA | kVerifyRegAWide));
    598   }
    599 
    600   int GetVerifyTypeArgumentB() const {
    601     return (kInstructionDescriptors[Opcode()].verify_flags & (kVerifyRegB | kVerifyRegBField |
    602         kVerifyRegBMethod | kVerifyRegBNewInstance | kVerifyRegBString | kVerifyRegBType |
    603         kVerifyRegBWide));
    604   }
    605 
    606   int GetVerifyTypeArgumentC() const {
    607     return (kInstructionDescriptors[Opcode()].verify_flags & (kVerifyRegC | kVerifyRegCField |
    608         kVerifyRegCNewArray | kVerifyRegCType | kVerifyRegCWide));
    609   }
    610 
    611   int GetVerifyTypeArgumentH() const {
    612     return (kInstructionDescriptors[Opcode()].verify_flags & kVerifyRegHPrototype);
    613   }
    614 
    615   int GetVerifyExtraFlags() const {
    616     return (kInstructionDescriptors[Opcode()].verify_flags & (kVerifyArrayData |
    617         kVerifyBranchTarget | kVerifySwitchTargets | kVerifyVarArg | kVerifyVarArgNonZero |
    618         kVerifyVarArgRange | kVerifyVarArgRangeNonZero | kVerifyError));
    619   }
    620 
    621   bool GetVerifyIsRuntimeOnly() const {
    622     return (kInstructionDescriptors[Opcode()].verify_flags & kVerifyRuntimeOnly) != 0;
    623   }
    624 
    625   // Get the dex PC of this instruction as a offset in code units from the beginning of insns.
    626   uint32_t GetDexPc(const uint16_t* insns) const {
    627     return (reinterpret_cast<const uint16_t*>(this) - insns);
    628   }
    629 
    630   // Dump decoded version of instruction
    631   std::string DumpString(const DexFile*) const;
    632 
    633   // Dump code_units worth of this instruction, padding to code_units for shorter instructions
    634   std::string DumpHex(size_t code_units) const;
    635 
    636   // Little-endian dump code_units worth of this instruction, padding to code_units for
    637   // shorter instructions
    638   std::string DumpHexLE(size_t instr_code_units) const;
    639 
    640   uint16_t Fetch16(size_t offset) const {
    641     const uint16_t* insns = reinterpret_cast<const uint16_t*>(this);
    642     return insns[offset];
    643   }
    644 
    645  private:
    646   size_t SizeInCodeUnitsComplexOpcode() const;
    647 
    648   // Return how many code unit words are required to compute the size of the opcode.
    649   size_t CodeUnitsRequiredForSizeOfComplexOpcode() const;
    650 
    651   uint32_t Fetch32(size_t offset) const {
    652     return (Fetch16(offset) | ((uint32_t) Fetch16(offset + 1) << 16));
    653   }
    654 
    655   uint4_t InstA() const {
    656     return InstA(Fetch16(0));
    657   }
    658 
    659   uint4_t InstB() const {
    660     return InstB(Fetch16(0));
    661   }
    662 
    663   uint8_t InstAA() const {
    664     return InstAA(Fetch16(0));
    665   }
    666 
    667   uint4_t InstA(uint16_t inst_data) const {
    668     DCHECK_EQ(inst_data, Fetch16(0));
    669     return static_cast<uint4_t>((inst_data >> 8) & 0x0f);
    670   }
    671 
    672   uint4_t InstB(uint16_t inst_data) const {
    673     DCHECK_EQ(inst_data, Fetch16(0));
    674     return static_cast<uint4_t>(inst_data >> 12);
    675   }
    676 
    677   uint8_t InstAA(uint16_t inst_data) const {
    678     DCHECK_EQ(inst_data, Fetch16(0));
    679     return static_cast<uint8_t>(inst_data >> 8);
    680   }
    681 
    682   static const char* const kInstructionNames[];
    683 
    684   static const InstructionDescriptor kInstructionDescriptors[];
    685 
    686   DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction);
    687 };
    688 std::ostream& operator<<(std::ostream& os, const Instruction::Code& code);
    689 std::ostream& operator<<(std::ostream& os, const Instruction::Format& format);
    690 std::ostream& operator<<(std::ostream& os, const Instruction::Flags& flags);
    691 std::ostream& operator<<(std::ostream& os, const Instruction::VerifyFlag& vflags);
    692 
    693 // Base class for accessing instruction operands. Unifies operand
    694 // access for instructions that have range and varargs forms
    695 // (e.g. invoke-polymoprhic/range and invoke-polymorphic).
    696 class InstructionOperands {
    697  public:
    698   explicit InstructionOperands(size_t num_operands) : num_operands_(num_operands) {}
    699   virtual ~InstructionOperands() {}
    700   virtual uint32_t GetOperand(size_t index) const = 0;
    701   size_t GetNumberOfOperands() const { return num_operands_; }
    702 
    703  private:
    704   const size_t num_operands_;
    705 
    706   DISALLOW_IMPLICIT_CONSTRUCTORS(InstructionOperands);
    707 };
    708 
    709 // Class for accessing operands for instructions with a range format
    710 // (e.g. 3rc and 4rcc).
    711 class RangeInstructionOperands FINAL : public InstructionOperands {
    712  public:
    713   RangeInstructionOperands(uint32_t first_operand, size_t num_operands)
    714       : InstructionOperands(num_operands), first_operand_(first_operand) {}
    715   ~RangeInstructionOperands() {}
    716   uint32_t GetOperand(size_t operand_index) const OVERRIDE;
    717 
    718  private:
    719   const uint32_t first_operand_;
    720 
    721   DISALLOW_IMPLICIT_CONSTRUCTORS(RangeInstructionOperands);
    722 };
    723 
    724 // Class for accessing operands for instructions with a variable
    725 // number of arguments format (e.g. 35c and 45cc).
    726 class VarArgsInstructionOperands FINAL : public InstructionOperands {
    727  public:
    728   VarArgsInstructionOperands(const uint32_t (&operands)[Instruction::kMaxVarArgRegs],
    729                              size_t num_operands)
    730       : InstructionOperands(num_operands), operands_(operands) {}
    731   ~VarArgsInstructionOperands() {}
    732   uint32_t GetOperand(size_t operand_index) const OVERRIDE;
    733 
    734  private:
    735   const uint32_t (&operands_)[Instruction::kMaxVarArgRegs];
    736 
    737   DISALLOW_IMPLICIT_CONSTRUCTORS(VarArgsInstructionOperands);
    738 };
    739 
    740 // Class for accessing operands without the receiver by wrapping an
    741 // existing InstructionOperands instance.
    742 class NoReceiverInstructionOperands FINAL : public InstructionOperands {
    743  public:
    744   explicit NoReceiverInstructionOperands(const InstructionOperands* const inner)
    745       : InstructionOperands(inner->GetNumberOfOperands() - 1), inner_(inner) {}
    746   ~NoReceiverInstructionOperands() {}
    747   uint32_t GetOperand(size_t operand_index) const OVERRIDE;
    748 
    749  private:
    750   const InstructionOperands* const inner_;
    751 
    752   DISALLOW_IMPLICIT_CONSTRUCTORS(NoReceiverInstructionOperands);
    753 };
    754 
    755 }  // namespace art
    756 
    757 #endif  // ART_LIBDEXFILE_DEX_DEX_INSTRUCTION_H_
    758