diff options
Diffstat (limited to 'dx/src/com/android/dx/dex/code/InsnFormat.java')
-rw-r--r-- | dx/src/com/android/dx/dex/code/InsnFormat.java | 578 |
1 files changed, 0 insertions, 578 deletions
diff --git a/dx/src/com/android/dx/dex/code/InsnFormat.java b/dx/src/com/android/dx/dex/code/InsnFormat.java deleted file mode 100644 index ed4137b3f..000000000 --- a/dx/src/com/android/dx/dex/code/InsnFormat.java +++ /dev/null @@ -1,578 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dx.dex.code; - -import com.android.dx.rop.code.RegisterSpecList; -import com.android.dx.rop.cst.Constant; -import com.android.dx.rop.cst.CstInteger; -import com.android.dx.rop.cst.CstKnownNull; -import com.android.dx.rop.cst.CstLiteral64; -import com.android.dx.rop.cst.CstLiteralBits; -import com.android.dx.util.AnnotatedOutput; -import com.android.dx.util.Hex; - -/** - * Base class for all instruction format handlers. Instruction format - * handlers know how to translate {@link DalvInsn} instances into - * streams of code words, as well as human-oriented listing strings - * representing such translations. - */ -public abstract class InsnFormat { - /** - * Returns the string form, suitable for inclusion in a listing - * dump, of the given instruction. The instruction must be of this - * instance's format for proper operation. - * - * @param insn non-null; the instruction - * @param noteIndices whether to include an explicit notation of - * constant pool indices - * @return non-null; the string form - */ - public final String listingString(DalvInsn insn, boolean noteIndices) { - String op = insn.getOpcode().getName(); - String arg = insnArgString(insn); - String comment = insnCommentString(insn, noteIndices); - StringBuilder sb = new StringBuilder(100); - - sb.append(op); - - if (arg.length() != 0) { - sb.append(' '); - sb.append(arg); - } - - if (comment.length() != 0) { - sb.append(" // "); - sb.append(comment); - } - - return sb.toString(); - } - - /** - * Returns the string form of the arguments to the given instruction. - * The instruction must be of this instance's format. If the instruction - * has no arguments, then the result should be <code>""</code>, not - * <code>null</code>. - * - * <p>Subclasses must override this method.</p> - * - * @param insn non-null; the instruction - * @return non-null; the string form - */ - public abstract String insnArgString(DalvInsn insn); - - /** - * Returns the associated comment for the given instruction, if any. - * The instruction must be of this instance's format. If the instruction - * has no comment, then the result should be <code>""</code>, not - * <code>null</code>. - * - * <p>Subclasses must override this method.</p> - * - * @param insn non-null; the instruction - * @param noteIndices whether to include an explicit notation of - * constant pool indices - * @return non-null; the string form - */ - public abstract String insnCommentString(DalvInsn insn, - boolean noteIndices); - - /** - * Gets the code size of instructions that use this format. The - * size is a number of 16-bit code units, not bytes. This should - * throw an exception if this format is of variable size. - * - * @return >= 0; the instruction length in 16-bit code units - */ - public abstract int codeSize(); - - /** - * Returns whether or not the given instruction's arguments will - * fit in this instance's format. This includes such things as - * counting register arguments, checking register ranges, and - * making sure that additional arguments are of appropriate types - * and are in-range. If this format has a branch target but the - * instruction's branch offset is unknown, this method will simply - * not check the offset. - * - * <p>Subclasses must override this method.</p> - * - * @param insn non-null; the instruction to check - * @return <code>true</code> iff the instruction's arguments are - * appropriate for this instance, or <code>false</code> if not - */ - public abstract boolean isCompatible(DalvInsn insn); - - /** - * Returns whether or not the given instruction's branch offset will - * fit in this instance's format. This always returns <code>false</code> - * for formats that don't include a branch offset. - * - * <p>The default implementation of this method always returns - * <code>false</code>. Subclasses must override this method if they - * include branch offsets.</p> - * - * @param insn non-null; the instruction to check - * @return <code>true</code> iff the instruction's branch offset is - * appropriate for this instance, or <code>false</code> if not - */ - public boolean branchFits(TargetInsn insn) { - return false; - } - - /** - * Returns the next instruction format to try to match an instruction - * with, presuming that this instance isn't compatible, if any. - * - * <p>Subclasses must override this method.</p> - * - * @return null-ok; the next format to try, or <code>null</code> if - * there are no suitable alternatives - */ - public abstract InsnFormat nextUp(); - - /** - * Writes the code units for the given instruction to the given - * output destination. The instruction must be of this instance's format. - * - * <p>Subclasses must override this method.</p> - * - * @param out non-null; the output destination to write to - * @param insn non-null; the instruction to write - */ - public abstract void writeTo(AnnotatedOutput out, DalvInsn insn); - - /** - * Helper method to return a register list string. - * - * @param list non-null; the list of registers - * @return non-null; the string form - */ - protected static String regListString(RegisterSpecList list) { - int sz = list.size(); - StringBuffer sb = new StringBuffer(sz * 5 + 2); - - sb.append('{'); - - for (int i = 0; i < sz; i++) { - if (i != 0) { - sb.append(", "); - } - sb.append(list.get(i).regString()); - } - - sb.append('}'); - - return sb.toString(); - } - - /** - * Helper method to return a literal bits argument string. - * - * @param value the value - * @return non-null; the string form - */ - protected static String literalBitsString(CstLiteralBits value) { - StringBuffer sb = new StringBuffer(100); - - sb.append('#'); - - if (value instanceof CstKnownNull) { - sb.append("null"); - } else { - sb.append(value.typeName()); - sb.append(' '); - sb.append(value.toHuman()); - } - - return sb.toString(); - } - - /** - * Helper method to return a literal bits comment string. - * - * @param value the value - * @param width the width of the constant, in bits (used for displaying - * the uninterpreted bits; one of: <code>4 8 16 32 64</code> - * @return non-null; the comment - */ - protected static String literalBitsComment(CstLiteralBits value, - int width) { - StringBuffer sb = new StringBuffer(20); - - sb.append("#"); - - long bits; - - if (value instanceof CstLiteral64) { - bits = ((CstLiteral64) value).getLongBits(); - } else { - bits = value.getIntBits(); - } - - switch (width) { - case 4: sb.append(Hex.uNibble((int) bits)); break; - case 8: sb.append(Hex.u1((int) bits)); break; - case 16: sb.append(Hex.u2((int) bits)); break; - case 32: sb.append(Hex.u4((int) bits)); break; - case 64: sb.append(Hex.u8(bits)); break; - default: { - throw new RuntimeException("shouldn't happen"); - } - } - - return sb.toString(); - } - - /** - * Helper method to return a branch address string. - * - * @param insn non-null; the instruction in question - * @return non-null; the string form of the instruction's branch target - */ - protected static String branchString(DalvInsn insn) { - TargetInsn ti = (TargetInsn) insn; - int address = ti.getTargetAddress(); - - return (address == (char) address) ? Hex.u2(address) : Hex.u4(address); - } - - /** - * Helper method to return the comment for a branch. - * - * @param insn non-null; the instruction in question - * @return non-null; the comment - */ - protected static String branchComment(DalvInsn insn) { - TargetInsn ti = (TargetInsn) insn; - int offset = ti.getTargetOffset(); - - return (offset == (short) offset) ? Hex.s2(offset) : Hex.s4(offset); - } - - /** - * Helper method to return a constant string. - * - * @param insn non-null; a constant-bearing instruction - * @return non-null; the string form of the contained constant - */ - protected static String cstString(DalvInsn insn) { - CstInsn ci = (CstInsn) insn; - Constant cst = ci.getConstant(); - - return cst.toHuman(); - } - - /** - * Helper method to return an instruction comment for a constant. - * - * @param insn non-null; a constant-bearing instruction - * @return non-null; comment string representing the constant - */ - protected static String cstComment(DalvInsn insn) { - CstInsn ci = (CstInsn) insn; - - if (! ci.hasIndex()) { - return ""; - } - - StringBuilder sb = new StringBuilder(20); - int index = ci.getIndex(); - - sb.append(ci.getConstant().typeName()); - sb.append('@'); - - if (index < 65536) { - sb.append(Hex.u2(index)); - } else { - sb.append(Hex.u4(index)); - } - - return sb.toString(); - } - - /** - * Helper method to determine if a signed int value fits in a nibble. - * - * @param value the value in question - * @return <code>true</code> iff it's in the range -8..+7 - */ - protected static boolean signedFitsInNibble(int value) { - return (value >= -8) && (value <= 7); - } - - /** - * Helper method to determine if an unsigned int value fits in a nibble. - * - * @param value the value in question - * @return <code>true</code> iff it's in the range 0..0xf - */ - protected static boolean unsignedFitsInNibble(int value) { - return value == (value & 0xf); - } - - /** - * Helper method to determine if a signed int value fits in a byte. - * - * @param value the value in question - * @return <code>true</code> iff it's in the range -0x80..+0x7f - */ - protected static boolean signedFitsInByte(int value) { - return (byte) value == value; - } - - /** - * Helper method to determine if an unsigned int value fits in a byte. - * - * @param value the value in question - * @return <code>true</code> iff it's in the range 0..0xff - */ - protected static boolean unsignedFitsInByte(int value) { - return value == (value & 0xff); - } - - /** - * Helper method to determine if a signed int value fits in a short. - * - * @param value the value in question - * @return <code>true</code> iff it's in the range -0x8000..+0x7fff - */ - protected static boolean signedFitsInShort(int value) { - return (short) value == value; - } - - /** - * Helper method to determine if an unsigned int value fits in a short. - * - * @param value the value in question - * @return <code>true</code> iff it's in the range 0..0xffff - */ - protected static boolean unsignedFitsInShort(int value) { - return value == (value & 0xffff); - } - - /** - * Helper method to determine if a signed int value fits in three bytes. - * - * @param value the value in question - * @return <code>true</code> iff it's in the range -0x800000..+0x7fffff - */ - protected static boolean signedFitsIn3Bytes(int value) { - return value == ((value << 8) >> 8); - } - - /** - * Helper method to extract the callout-argument index from an - * appropriate instruction. - * - * @param insn non-null; the instruction - * @return >= 0; the callout argument index - */ - protected static int argIndex(DalvInsn insn) { - int arg = ((CstInteger) ((CstInsn) insn).getConstant()).getValue(); - - if (arg < 0) { - throw new IllegalArgumentException("bogus insn"); - } - - return arg; - } - - /** - * Helper method to combine an opcode and a second byte of data into - * the appropriate form for emitting into a code buffer. - * - * @param insn non-null; the instruction containing the opcode - * @param arg 0..255; arbitrary other byte value - * @return combined value - */ - protected static short opcodeUnit(DalvInsn insn, int arg) { - if ((arg & 0xff) != arg) { - throw new IllegalArgumentException("arg out of range 0..255"); - } - - int opcode = insn.getOpcode().getOpcode(); - - if ((opcode & 0xff) != opcode) { - throw new IllegalArgumentException("opcode out of range 0..255"); - } - - return (short) (opcode | (arg << 8)); - } - - /** - * Helper method to combine two bytes into a code unit. - * - * @param low 0..255; low byte - * @param high 0..255; high byte - * @return combined value - */ - protected static short codeUnit(int low, int high) { - if ((low & 0xff) != low) { - throw new IllegalArgumentException("low out of range 0..255"); - } - - if ((high & 0xff) != high) { - throw new IllegalArgumentException("high out of range 0..255"); - } - - return (short) (low | (high << 8)); - } - - /** - * Helper method to combine four nibbles into a code unit. - * - * @param n0 0..15; low nibble - * @param n1 0..15; medium-low nibble - * @param n2 0..15; medium-high nibble - * @param n3 0..15; high nibble - * @return combined value - */ - protected static short codeUnit(int n0, int n1, int n2, int n3) { - if ((n0 & 0xf) != n0) { - throw new IllegalArgumentException("n0 out of range 0..15"); - } - - if ((n1 & 0xf) != n1) { - throw new IllegalArgumentException("n1 out of range 0..15"); - } - - if ((n2 & 0xf) != n2) { - throw new IllegalArgumentException("n2 out of range 0..15"); - } - - if ((n3 & 0xf) != n3) { - throw new IllegalArgumentException("n3 out of range 0..15"); - } - - return (short) (n0 | (n1 << 4) | (n2 << 8) | (n3 << 12)); - } - - /** - * Helper method to combine two nibbles into a byte. - * - * @param low 0..15; low nibble - * @param high 0..15; high nibble - * @return 0..255; combined value - */ - protected static int makeByte(int low, int high) { - if ((low & 0xf) != low) { - throw new IllegalArgumentException("low out of range 0..15"); - } - - if ((high & 0xf) != high) { - throw new IllegalArgumentException("high out of range 0..15"); - } - - return low | (high << 4); - } - - /** - * Writes one code unit to the given output destination. - * - * @param out non-null; where to write to - * @param c0 code unit to write - */ - protected static void write(AnnotatedOutput out, short c0) { - out.writeShort(c0); - } - - /** - * Writes two code units to the given output destination. - * - * @param out non-null; where to write to - * @param c0 code unit to write - * @param c1 code unit to write - */ - protected static void write(AnnotatedOutput out, short c0, short c1) { - out.writeShort(c0); - out.writeShort(c1); - } - - /** - * Writes three code units to the given output destination. - * - * @param out non-null; where to write to - * @param c0 code unit to write - * @param c1 code unit to write - * @param c2 code unit to write - */ - protected static void write(AnnotatedOutput out, short c0, short c1, - short c2) { - out.writeShort(c0); - out.writeShort(c1); - out.writeShort(c2); - } - - /** - * Writes four code units to the given output destination. - * - * @param out non-null; where to write to - * @param c0 code unit to write - * @param c1 code unit to write - * @param c2 code unit to write - * @param c3 code unit to write - */ - protected static void write(AnnotatedOutput out, short c0, short c1, - short c2, short c3) { - out.writeShort(c0); - out.writeShort(c1); - out.writeShort(c2); - out.writeShort(c3); - } - - /** - * Writes five code units to the given output destination. - * - * @param out non-null; where to write to - * @param c0 code unit to write - * @param c1 code unit to write - * @param c2 code unit to write - * @param c3 code unit to write - * @param c4 code unit to write - */ - protected static void write(AnnotatedOutput out, short c0, short c1, - short c2, short c3, short c4) { - out.writeShort(c0); - out.writeShort(c1); - out.writeShort(c2); - out.writeShort(c3); - out.writeShort(c4); - } - - /** - * Writes six code units to the given output destination. - * - * @param out non-null; where to write to - * @param c0 code unit to write - * @param c1 code unit to write - * @param c2 code unit to write - * @param c3 code unit to write - * @param c4 code unit to write - * @param c5 code unit to write - */ - protected static void write(AnnotatedOutput out, short c0, short c1, - short c2, short c3, short c4, short c5) { - out.writeShort(c0); - out.writeShort(c1); - out.writeShort(c2); - out.writeShort(c3); - out.writeShort(c4); - out.writeShort(c5); - } -} |