* - this enum
* - the switch inside dexDecodeInstruction() in InstrUtils.c
* - the switch inside dumpInstruction() in DexDump.c
+ * - the switch inside dvmCompilerMIR2LIR() in CodegenDriver.c
*/
typedef unsigned char InstructionFormat;
enum InstructionFormat {
kFmt11n, // op vA, #+B
kFmt11x, // op vAA
kFmt10t, // op +AA
- kFmt20bc, // op AA, thing@BBBB
+ kFmt20bc, // [opt] op AA, thing@BBBB
kFmt20t, // op +AAAA
kFmt22x, // op vAA, vBBBB
kFmt21t, // op vAA, +BBBB
kFmt22s, // op vA, vB, #+CCCC
kFmt22c, // op vA, vB, thing@CCCC
kFmt22cs, // [opt] op vA, vB, field offset CCCC
- kFmt32x, // op vAAAA, vBBBB
kFmt30t, // op +AAAAAAAA
- kFmt31t, // op vAA, +BBBBBBBB
+ kFmt32x, // op vAAAA, vBBBB
kFmt31i, // op vAA, #+BBBBBBBB
- kFmt31c, // op vAA, thing@BBBBBBBB
- kFmt35c, // op {vC, vD, vE, vF, vG}, thing@BBBB (B: count, A: vG)
+ kFmt31t, // op vAA, +BBBBBBBB
+ kFmt31c, // op vAA, string@BBBBBBBB
+ kFmt35c, // op {vC,vD,vE,vF,vG}, thing@BBBB
kFmt35ms, // [opt] invoke-virtual+super
- kFmt35fs, // [opt] invoke-interface
- kFmt3rc, // op {vCCCC .. v(CCCC+AA-1)}, meth@BBBB
+ kFmt3rc, // op {vCCCC .. v(CCCC+AA-1)}, thing@BBBB
kFmt3rms, // [opt] invoke-virtual+super/range
- kFmt3rfs, // [opt] invoke-interface/range
- kFmt3inline, // [opt] inline invoke
- kFmt3rinline, // [opt] inline invoke/range
kFmt51l, // op vAA, #+BBBBBBBBBBBBBBBB
+ kFmt35mi, // [opt] inline invoke
+ kFmt3rmi, // [opt] inline invoke/range
+ kFmt33x, // exop vAA, vBB, vCCCC
+ kFmt32s, // exop vAA, vBB, #+CCCC
+ kFmt41c, // exop vAAAA, thing@BBBBBBBB
+ kFmt52c, // exop vAAAA, vBBBB, thing@CCCCCCCC
+ kFmt5rc, // exop {vCCCC .. v(CCCC+AAAA-1)}, thing@BBBBBBBB
+};
+
+/*
+ * Different kinds of indexed reference, for formats that include such an
+ * indexed reference (e.g., 21c and 35c)
+ */
+typedef unsigned char InstructionIndexType;
+enum InstructionIndexType {
+ kIndexUnknown = 0,
+ kIndexNone, // has no index
+ kIndexVaries, // "It depends." Used for throw-verification-error
+ kIndexTypeRef, // type reference index
+ kIndexStringRef, // string reference index
+ kIndexMethodRef, // method reference index
+ kIndexFieldRef, // field reference index
+ kIndexInlineMethod, // inline method index (for inline linked methods)
+ kIndexVtableOffset, // vtable offset (for static linked methods)
+ kIndexFieldOffset // field offset (for static linked fields)
};
/*
u4 vC;
u4 arg[5]; /* vC/D/E/F/G in invoke or filled-new-array */
OpCode opCode;
+ InstructionIndexType indexType;
} DecodedInstruction;
/*
- * Instruction width, a value in the range -3 to 5.
+ * Instruction width, a value in the range 0 to 5.
*/
-typedef signed char InstructionWidth;
+typedef unsigned char InstructionWidth;
/*
* Instruction flags, used by the verifier and JIT to determine where
kInstrUnconditional = 1 << 6, // unconditional branch
};
+/*
+ * Struct that includes a pointer to each of the instruction information
+ * tables.
+ */
+typedef struct InstructionInfoTables {
+ InstructionFormat* formats;
+ InstructionIndexType* indexTypes;
+ InstructionFlags* flags;
+ InstructionWidth* widths;
+} InstructionInfoTables;
/*
* Allocate and populate a 256-element array with instruction widths. A
*/
InstructionWidth* dexCreateInstrWidthTable(void);
-#if 0 // no longer used
-/*
- * Returns the width of the specified instruction, or 0 if not defined.
- * Optimized instructions use negative values.
- */
-DEX_INLINE int dexGetInstrWidth(const InstructionWidth* widths, OpCode opCode)
-{
- // assert(/*opCode >= 0 &&*/ opCode < kNumDalvikInstructions);
- return widths[opCode];
-}
-#endif
-
/*
* Return the width of the specified instruction, or 0 if not defined.
*/
-DEX_INLINE size_t dexGetInstrWidthAbs(const InstructionWidth* widths,
+DEX_INLINE size_t dexGetInstrWidth(const InstructionWidth* widths,
OpCode opCode)
{
//assert(/*opCode >= 0 &&*/ opCode < kNumDalvikInstructions);
-
- int val = widths[opCode];
- if (val < 0)
- val = -val;
- /* XXX - the no-compare trick may be a cycle slower on ARM */
- return val;
+ return widths[opCode];
}
/*
* works for special OP_NOP entries, including switch statement data tables
* and array data.
*/
-size_t dexGetInstrOrTableWidthAbs(const InstructionWidth* widths,
+size_t dexGetInstrOrTableWidth(const InstructionWidth* widths,
const u2* insns);
-
/*
* Allocate and populate a 256-element array with instruction flags.
*/
return flags[opCode];
}
-
/*
* Allocate and populate a 256-element array with instruction formats.
*/
}
/*
+ * Allocate and populate an array with index types for all instructions.
+ * Used in conjunction with dexDecodeInstruction.
+ */
+InstructionIndexType* dexCreateInstrIndexTypeTable(void);
+
+/*
+ * Return the instruction index type for the specified opcode.
+ */
+DEX_INLINE InstructionIndexType dexGetInstrIndexType(
+ const InstructionIndexType* types, OpCode opCode)
+{
+ //assert(/*opCode >= 0 &&*/ opCode < kNumDalvikInstructions);
+ return types[opCode];
+}
+
+/*
+ * Construct all of the instruction info tables, storing references to
+ * them into the given struct. This returns 0 on success or non-zero on
+ * failure. If this fails, then no net allocation will have occurred.
+ */
+int dexCreateInstructionInfoTables(InstructionInfoTables* info);
+
+/*
+ * Free up the tables referred to by the given instruction info struct.
+ */
+void dexFreeInstructionInfoTables(InstructionInfoTables* info);
+
+/*
* Decode the instruction pointed to by "insns".
*/
-void dexDecodeInstruction(const InstructionFormat* fmts, const u2* insns,
+void dexDecodeInstruction(const InstructionInfoTables* info, const u2* insns,
DecodedInstruction* pDec);
#endif /*_LIBDEX_INSTRUTILS*/