diff options
author | Dan Bornstein <danfuzz@android.com> | 2011-02-01 17:01:27 -0800 |
---|---|---|
committer | Dan Bornstein <danfuzz@android.com> | 2011-02-02 10:26:32 -0800 |
commit | 38b861bc63b91114d52ba01e74d31fbf316a5784 (patch) | |
tree | aa5c501da71388c5c408aa2e42db00275650f426 /dx/src/com/android/dx/io | |
parent | 0c6b7eb528615d1bf92cc1e83a70c52718efa417 (diff) | |
download | android_dalvik-38b861bc63b91114d52ba01e74d31fbf316a5784.tar.gz android_dalvik-38b861bc63b91114d52ba01e74d31fbf316a5784.tar.bz2 android_dalvik-38b861bc63b91114d52ba01e74d31fbf316a5784.zip |
Hook up CodeReader.
This involved tweaking a lot of interfaces and a few bits of the
implementation, and it could use at least one cleanup pass, but I think
the basic structure is pretty reasonable.
Change-Id: Ic49410aca479d54ceb837ee7e04bedd2ca0bcda9
Diffstat (limited to 'dx/src/com/android/dx/io')
-rw-r--r-- | dx/src/com/android/dx/io/CodeInput.java | 6 | ||||
-rw-r--r-- | dx/src/com/android/dx/io/CodeReader.java | 544 | ||||
-rw-r--r-- | dx/src/com/android/dx/io/DecodedInstruction.java | 21 | ||||
-rw-r--r-- | dx/src/com/android/dx/io/ShortArrayCodeInput.java | 7 | ||||
-rw-r--r-- | dx/src/com/android/dx/io/ShortArrayCodeOutput.java | 96 |
5 files changed, 378 insertions, 296 deletions
diff --git a/dx/src/com/android/dx/io/CodeInput.java b/dx/src/com/android/dx/io/CodeInput.java index c1dd5506b..e8c7081f3 100644 --- a/dx/src/com/android/dx/io/CodeInput.java +++ b/dx/src/com/android/dx/io/CodeInput.java @@ -30,6 +30,12 @@ public interface CodeInput { public int cursor(); /** + * Returns whether there are any more code units to read. This + * is analogous to {@code hasNext()} on an interator. + */ + public boolean hasMore(); + + /** * Reads a code unit. */ public int read() throws EOFException; diff --git a/dx/src/com/android/dx/io/CodeReader.java b/dx/src/com/android/dx/io/CodeReader.java index a25cb7c9a..21bec7e0d 100644 --- a/dx/src/com/android/dx/io/CodeReader.java +++ b/dx/src/com/android/dx/io/CodeReader.java @@ -17,7 +17,7 @@ package com.android.dx.io; import com.android.dx.dex.DexException; -import java.util.BitSet; +import com.android.dx.util.Hex; /** * Walks through a block of code and calls visitor call backs. @@ -26,74 +26,74 @@ public final class CodeReader { private final Instruction[] instructions = new Instruction[] { // 0x00...0x0f - new Instruction(1, "nop"), - new Instruction(1, "move vA, vB"), - new Instruction(2, "move/from vAA, vBBBB"), - new Instruction(3, "move/16 vAAAA, vBBBB"), - new Instruction(1, "move-wide, vA, vB"), - new Instruction(2, "move-wide/from16 vAA, vBBBB"), - new Instruction(3, "move-wide/from16 vAAAA, vBBBB"), - new Instruction(1, "move-object vA, vB"), - new Instruction(2, "move-object/from16 vAA, vBBBB"), - new Instruction(3, "move-object/16 vAAAA, vBBBB"), - new Instruction(1, "move-result vAA"), - new Instruction(1, "move-result-wide vAA"), - new Instruction(1, "move-result-object vAA"), - new Instruction(1, "move-exception vAA"), - new Instruction(1, "return void"), - new Instruction(1, "return vAA"), + new Instruction("nop"), + new Instruction("move vA, vB"), + new Instruction("move/from vAA, vBBBB"), + new Instruction("move/16 vAAAA, vBBBB"), + new Instruction("move-wide, vA, vB"), + new Instruction("move-wide/from16 vAA, vBBBB"), + new Instruction("move-wide/from16 vAAAA, vBBBB"), + new Instruction("move-object vA, vB"), + new Instruction("move-object/from16 vAA, vBBBB"), + new Instruction("move-object/16 vAAAA, vBBBB"), + new Instruction("move-result vAA"), + new Instruction("move-result-wide vAA"), + new Instruction("move-result-object vAA"), + new Instruction("move-exception vAA"), + new Instruction("return void"), + new Instruction("return vAA"), // 0x10...0x1f - new Instruction(1, "return-wide vAA"), - new Instruction(1, "return-object vAA"), - new Instruction(1, "const/4 vA, #+B"), - new Instruction(2, "const/16 vAA, #+BBBB"), - new Instruction(3, "const vAA, #+BBBBBBBB"), - new Instruction(2, "const/high16 vAA, #+BBBB0000"), - new Instruction(2, "const-wide/16 vAA, #+BBBB"), - new Instruction(3, "const-wide/32 vAA, #+BBBBBBBB"), - new Instruction(5, "const-wide vAA, #+BBBBBBBBBBBBBBBB"), - new Instruction(2, "const-wide/high16 vAA, #+BBBB000000000000"), - new Instruction(2, "const-string vAA, string@BBBB"), - new Instruction(3, "const-string/jumbo vAA, string@BBBBBBBB"), - new Instruction(2, "const-class vAA, type@BBBB"), - new Instruction(1, "monitor-enter vAA"), - new Instruction(1, "monitor-exit vAA"), - new Instruction(2, "check-cast vAA type@BBBB"), + new Instruction("return-wide vAA"), + new Instruction("return-object vAA"), + new Instruction("const/4 vA, #+B"), + new Instruction("const/16 vAA, #+BBBB"), + new Instruction("const vAA, #+BBBBBBBB"), + new Instruction("const/high16 vAA, #+BBBB0000"), + new Instruction("const-wide/16 vAA, #+BBBB"), + new Instruction("const-wide/32 vAA, #+BBBBBBBB"), + new Instruction("const-wide vAA, #+BBBBBBBBBBBBBBBB"), + new Instruction("const-wide/high16 vAA, #+BBBB000000000000"), + new Instruction("const-string vAA, string@BBBB"), + new Instruction("const-string/jumbo vAA, string@BBBBBBBB"), + new Instruction("const-class vAA, type@BBBB"), + new Instruction("monitor-enter vAA"), + new Instruction("monitor-exit vAA"), + new Instruction("check-cast vAA type@BBBB"), // 0x20...0x2f - new Instruction(2, "instance-of vA, vB, type@CCCC"), - new Instruction(1, "array-length vA, vB"), - new Instruction(2, "new-instance vAA, type@BBBB"), - new Instruction(2, "new-array vA, vB, type@CCCC"), - new Instruction(3, "filled-new-array {vD, vE, vF, vG, vA}, type@CCCC"), - new Instruction(3, "filled-new-array/range {vCCCC..vNNNN}, type@BBBB"), - new FillArrayInstruction(3, "fill-array-data vAA, +BBBBBBBB"), - new Instruction(1, "throw vAA"), - new Instruction(1, "goto +AA"), - new Instruction(2, "goto/16 +AAAA"), - new Instruction(3, "goto/32 +AAAAAAAA"), - new PackedSwitchInstruction(3, "packed-switch vAA, +BBBBBBBB"), - new SparseSwitchInstruction(3, "sparse-switch vAA, +BBBBBBBB"), - new Instruction(2, "cmpl-float vAA, vBB, vCC"), - new Instruction(2, "cmpg-float vAA, vBB, vCC"), - new Instruction(2, "cmpl-double vAA, vBB, vCC"), + new Instruction("instance-of vA, vB, type@CCCC"), + new Instruction("array-length vA, vB"), + new Instruction("new-instance vAA, type@BBBB"), + new Instruction("new-array vA, vB, type@CCCC"), + new Instruction("filled-new-array {vD, vE, vF, vG, vA}, type@CCCC"), + new Instruction("filled-new-array/range {vCCCC..vNNNN}, type@BBBB"), + new Instruction("fill-array-data vAA, +BBBBBBBB"), + new Instruction("throw vAA"), + new Instruction("goto +AA"), + new Instruction("goto/16 +AAAA"), + new Instruction("goto/32 +AAAAAAAA"), + new Instruction("packed-switch vAA, +BBBBBBBB"), + new Instruction("sparse-switch vAA, +BBBBBBBB"), + new Instruction("cmpl-float vAA, vBB, vCC"), + new Instruction("cmpg-float vAA, vBB, vCC"), + new Instruction("cmpl-double vAA, vBB, vCC"), // 0x30...0x3f - new Instruction(2, "cmpg-double vAA, vBB, vCC"), - new Instruction(2, "cmp-long vAA, vBB, vCC"), - new Instruction(2, "if-eq vA, vB, +CCCC"), - new Instruction(2, "if-ne vA, vB, +CCCC"), - new Instruction(2, "if-lt vA, vB, +CCCC"), - new Instruction(2, "if-ge vA, vB, +CCCC"), - new Instruction(2, "if-gt vA, vB, +CCCC"), - new Instruction(2, "if-le vA, vB, +CCCC"), - new Instruction(2, "if-eqz vAA, +BBBB"), - new Instruction(2, "if-nez vAA, +BBBB"), - new Instruction(2, "if-ltz vAA, +BBBB"), - new Instruction(2, "if-gez vAA, +BBBB"), - new Instruction(2, "if-gtz vAA, +BBBB"), - new Instruction(2, "if-lez vAA, +BBBB"), + new Instruction("cmpg-double vAA, vBB, vCC"), + new Instruction("cmp-long vAA, vBB, vCC"), + new Instruction("if-eq vA, vB, +CCCC"), + new Instruction("if-ne vA, vB, +CCCC"), + new Instruction("if-lt vA, vB, +CCCC"), + new Instruction("if-ge vA, vB, +CCCC"), + new Instruction("if-gt vA, vB, +CCCC"), + new Instruction("if-le vA, vB, +CCCC"), + new Instruction("if-eqz vAA, +BBBB"), + new Instruction("if-nez vAA, +BBBB"), + new Instruction("if-ltz vAA, +BBBB"), + new Instruction("if-gez vAA, +BBBB"), + new Instruction("if-gtz vAA, +BBBB"), + new Instruction("if-lez vAA, +BBBB"), new UnusedInstruction(), new UnusedInstruction(), @@ -102,188 +102,197 @@ public final class CodeReader { new UnusedInstruction(), new UnusedInstruction(), new UnusedInstruction(), - new Instruction(2, "aget vAA, vBB, vCC"), - new Instruction(2, "aget-wide vAA, vBB, vCC"), - new Instruction(2, "aget-object vAA, vBB, vCC"), - new Instruction(2, "aget-boolean vAA, vBB, vCC"), - new Instruction(2, "aget-byte vAA, vBB, vCC"), - new Instruction(2, "aget-char vAA, vBB, vCC"), - new Instruction(2, "aget-short vAA, vBB, vCC"), - new Instruction(2, "aput vAA, vBB, vCC"), - new Instruction(2, "aput-wide vAA, vBB, vCC"), - new Instruction(2, "aput-object vAA, vBB, vCC"), - new Instruction(2, "aput-boolean vAA, vBB, vCC"), - new Instruction(2, "aput-byte vAA, vBB, vCC"), + new Instruction("aget vAA, vBB, vCC"), + new Instruction("aget-wide vAA, vBB, vCC"), + new Instruction("aget-object vAA, vBB, vCC"), + new Instruction("aget-boolean vAA, vBB, vCC"), + new Instruction("aget-byte vAA, vBB, vCC"), + new Instruction("aget-char vAA, vBB, vCC"), + new Instruction("aget-short vAA, vBB, vCC"), + new Instruction("aput vAA, vBB, vCC"), + new Instruction("aput-wide vAA, vBB, vCC"), + new Instruction("aput-object vAA, vBB, vCC"), + new Instruction("aput-boolean vAA, vBB, vCC"), + new Instruction("aput-byte vAA, vBB, vCC"), // 0x50...0x5f - new Instruction(2, "aput-char vAA, vBB, vCC"), - new Instruction(2, "aput-short vAA, vBB, vCC"), - new Instruction(2, "iget vA, vB, field@CCCC"), - new Instruction(2, "iget-wide vA, vB, field@CCCC"), - new Instruction(2, "iget-object vA, vB, field@CCCC"), - new Instruction(2, "iget-boolean vA, vB, field@CCCC"), - new Instruction(2, "iget-byte vA, vB, field@CCCC"), - new Instruction(2, "iget-char vA, vB, field@CCCC"), - new Instruction(2, "iget-short vA, vB, field@CCCC"), - new Instruction(2, "iput vA, vB, field@CCCC"), - new Instruction(2, "iput-wide vA, vB, field@CCCC"), - new Instruction(2, "iput-object vA, vB, field@CCCC"), - new Instruction(2, "iput-boolean vA, vB, field@CCCC"), - new Instruction(2, "iput-byte vA, vB, field@CCCC"), - new Instruction(2, "iput-char vA, vB, field@CCCC"), - new Instruction(2, "iput-short vA, vB, field@CCCC"), + new Instruction("aput-char vAA, vBB, vCC"), + new Instruction("aput-short vAA, vBB, vCC"), + new Instruction("iget vA, vB, field@CCCC"), + new Instruction("iget-wide vA, vB, field@CCCC"), + new Instruction("iget-object vA, vB, field@CCCC"), + new Instruction("iget-boolean vA, vB, field@CCCC"), + new Instruction("iget-byte vA, vB, field@CCCC"), + new Instruction("iget-char vA, vB, field@CCCC"), + new Instruction("iget-short vA, vB, field@CCCC"), + new Instruction("iput vA, vB, field@CCCC"), + new Instruction("iput-wide vA, vB, field@CCCC"), + new Instruction("iput-object vA, vB, field@CCCC"), + new Instruction("iput-boolean vA, vB, field@CCCC"), + new Instruction("iput-byte vA, vB, field@CCCC"), + new Instruction("iput-char vA, vB, field@CCCC"), + new Instruction("iput-short vA, vB, field@CCCC"), // 0x60...0x6f - new Instruction(2, "sget vAA, field@BBBB"), - new Instruction(2, "sget-wide vAA, field@BBBB"), - new Instruction(2, "sget-object vAA, field@BBBB"), - new Instruction(2, "sget-boolean vAA, field@BBBB"), - new Instruction(2, "sget-byte vAA, field@BBBB"), - new Instruction(2, "sget-char vAA, field@BBBB"), - new Instruction(2, "sget-short vAA, field@BBBB"), - new Instruction(2, "sput vAA, field@BBBB"), - new Instruction(2, "sput-wide vAA, field@BBBB"), - new Instruction(2, "sput-object vAA, field@BBBB"), - new Instruction(2, "sput-boolean vAA, field@BBBB"), - new Instruction(2, "sput-byte vAA, field@BBBB"), - new Instruction(2, "sput-char vAA, field@BBBB"), - new Instruction(2, "sput-short vAA, field@BBBB"), - new Instruction(3, "invoke-virtual {vD, vE, vF, vG, vA}, meth@CCCC"), - new Instruction(3, "invoke-super {vD, vE, vF, vG, vA}, meth@CCCC"), + new Instruction("sget vAA, field@BBBB"), + new Instruction("sget-wide vAA, field@BBBB"), + new Instruction("sget-object vAA, field@BBBB"), + new Instruction("sget-boolean vAA, field@BBBB"), + new Instruction("sget-byte vAA, field@BBBB"), + new Instruction("sget-char vAA, field@BBBB"), + new Instruction("sget-short vAA, field@BBBB"), + new Instruction("sput vAA, field@BBBB"), + new Instruction("sput-wide vAA, field@BBBB"), + new Instruction("sput-object vAA, field@BBBB"), + new Instruction("sput-boolean vAA, field@BBBB"), + new Instruction("sput-byte vAA, field@BBBB"), + new Instruction("sput-char vAA, field@BBBB"), + new Instruction("sput-short vAA, field@BBBB"), + new Instruction("invoke-virtual {vD, vE, vF, vG, vA}, meth@CCCC"), + new Instruction("invoke-super {vD, vE, vF, vG, vA}, meth@CCCC"), // 0x70...0x7f - new Instruction(3, "invoke-direct {vD, vE, vF, vG, vA}, meth@CCCC"), - new Instruction(3, "invoke-static {vD, vE, vF, vG, vA}, meth@CCCC"), - new Instruction(3, "invoke-interface {vD, vE, vF, vG, vA}, meth@CCCC"), + new Instruction("invoke-direct {vD, vE, vF, vG, vA}, meth@CCCC"), + new Instruction("invoke-static {vD, vE, vF, vG, vA}, meth@CCCC"), + new Instruction("invoke-interface {vD, vE, vF, vG, vA}, meth@CCCC"), new UnusedInstruction(), - new Instruction(3, "invoke-virtual/range {vCCCC..vNNNN}, meth@BBBB"), - new Instruction(3, "invoke-super/range {vCCCC..vNNNN}, meth@BBBB"), - new Instruction(3, "invoke-direct/range {vCCCC..vNNNN}, meth@BBBB"), - new Instruction(3, "invoke-static/range {vCCCC..vNNNN}, meth@BBBB"), - new Instruction(3, "invoke-interface/range {vCCCC..vNNNN}, meth@BBBB"), + new Instruction("invoke-virtual/range {vCCCC..vNNNN}, meth@BBBB"), + new Instruction("invoke-super/range {vCCCC..vNNNN}, meth@BBBB"), + new Instruction("invoke-direct/range {vCCCC..vNNNN}, meth@BBBB"), + new Instruction("invoke-static/range {vCCCC..vNNNN}, meth@BBBB"), + new Instruction("invoke-interface/range {vCCCC..vNNNN}, meth@BBBB"), new UnusedInstruction(), new UnusedInstruction(), - new Instruction(1, "neg-int vA, vB"), - new Instruction(1, "not-int vA, vB"), - new Instruction(1, "neg-long vA, vB"), - new Instruction(1, "not-long vA, vB"), - new Instruction(1, "neg-float vA, vB"), + new Instruction("neg-int vA, vB"), + new Instruction("not-int vA, vB"), + new Instruction("neg-long vA, vB"), + new Instruction("not-long vA, vB"), + new Instruction("neg-float vA, vB"), // 0x80...0x8f - new Instruction(1, "neg-double vA, vB"), - new Instruction(1, "int-to-long vA, vB"), - new Instruction(1, "int-to-float vA, vB"), - new Instruction(1, "int-to-double vA, vB"), - new Instruction(1, "long-to-int vA, vB"), - new Instruction(1, "long-to-float vA, vB"), - new Instruction(1, "long-to-double vA, vB"), - new Instruction(1, "float-to-int vA, vB"), - new Instruction(1, "float-to-long vA, vB"), - new Instruction(1, "float-to-double vA, vB"), - new Instruction(1, "double-to-int vA, vB"), - new Instruction(1, "double-to-long vA, vB"), - new Instruction(1, "double-to-float vA, vB"), - new Instruction(1, "int-to-byte vA, vB"), - new Instruction(1, "int-to-char vA, vB"), - new Instruction(1, "int-to-short vA, vB"), + new Instruction("neg-double vA, vB"), + new Instruction("int-to-long vA, vB"), + new Instruction("int-to-float vA, vB"), + new Instruction("int-to-double vA, vB"), + new Instruction("long-to-int vA, vB"), + new Instruction("long-to-float vA, vB"), + new Instruction("long-to-double vA, vB"), + new Instruction("float-to-int vA, vB"), + new Instruction("float-to-long vA, vB"), + new Instruction("float-to-double vA, vB"), + new Instruction("double-to-int vA, vB"), + new Instruction("double-to-long vA, vB"), + new Instruction("double-to-float vA, vB"), + new Instruction("int-to-byte vA, vB"), + new Instruction("int-to-char vA, vB"), + new Instruction("int-to-short vA, vB"), // 0x90...0x9f - new Instruction(2, "add-int vAA, vBB, vCC"), - new Instruction(2, "sub-int vAA, vBB, vCC"), - new Instruction(2, "mul-int vAA, vBB, vCC"), - new Instruction(2, "div-int vAA, vBB, vCC"), - new Instruction(2, "rem-int vAA, vBB, vCC"), - new Instruction(2, "and-int vAA, vBB, vCC"), - new Instruction(2, "or-int vAA, vBB, vCC"), - new Instruction(2, "xor-int vAA, vBB, vCC"), - new Instruction(2, "shl-int vAA, vBB, vCC"), - new Instruction(2, "shr-int vAA, vBB, vCC"), - new Instruction(2, "ushr-int vAA, vBB, vCC"), - new Instruction(2, "add-long vAA, vBB, vCC"), - new Instruction(2, "sub-long vAA, vBB, vCC"), - new Instruction(2, "mul-long vAA, vBB, vCC"), - new Instruction(2, "div-long vAA, vBB, vCC"), - new Instruction(2, "rem-long vAA, vBB, vCC"), + new Instruction("add-int vAA, vBB, vCC"), + new Instruction("sub-int vAA, vBB, vCC"), + new Instruction("mul-int vAA, vBB, vCC"), + new Instruction("div-int vAA, vBB, vCC"), + new Instruction("rem-int vAA, vBB, vCC"), + new Instruction("and-int vAA, vBB, vCC"), + new Instruction("or-int vAA, vBB, vCC"), + new Instruction("xor-int vAA, vBB, vCC"), + new Instruction("shl-int vAA, vBB, vCC"), + new Instruction("shr-int vAA, vBB, vCC"), + new Instruction("ushr-int vAA, vBB, vCC"), + new Instruction("add-long vAA, vBB, vCC"), + new Instruction("sub-long vAA, vBB, vCC"), + new Instruction("mul-long vAA, vBB, vCC"), + new Instruction("div-long vAA, vBB, vCC"), + new Instruction("rem-long vAA, vBB, vCC"), // 0xa0...0xaf - new Instruction(2, "and-long vAA, vBB, vCC"), - new Instruction(2, "or-long vAA, vBB, vCC"), - new Instruction(2, "xor-long vAA, vBB, vCC"), - new Instruction(2, "shl-long vAA, vBB, vCC"), - new Instruction(2, "shr-long vAA, vBB, vCC"), - new Instruction(2, "ushr-long vAA, vBB, vCC"), - new Instruction(2, "add-float vAA, vBB, vCC"), - new Instruction(2, "sub-float vAA, vBB, vCC"), - new Instruction(2, "mul-float vAA, vBB, vCC"), - new Instruction(2, "div-float vAA, vBB, vCC"), - new Instruction(2, "rem-float vAA, vBB, vCC"), - new Instruction(2, "add-double vAA, vBB, vCC"), - new Instruction(2, "sub-double vAA, vBB, vCC"), - new Instruction(2, "mul-double vAA, vBB, vCC"), - new Instruction(2, "div-double vAA, vBB, vCC"), - new Instruction(2, "rem-double vAA, vBB, vCC"), + new Instruction("and-long vAA, vBB, vCC"), + new Instruction("or-long vAA, vBB, vCC"), + new Instruction("xor-long vAA, vBB, vCC"), + new Instruction("shl-long vAA, vBB, vCC"), + new Instruction("shr-long vAA, vBB, vCC"), + new Instruction("ushr-long vAA, vBB, vCC"), + new Instruction("add-float vAA, vBB, vCC"), + new Instruction("sub-float vAA, vBB, vCC"), + new Instruction("mul-float vAA, vBB, vCC"), + new Instruction("div-float vAA, vBB, vCC"), + new Instruction("rem-float vAA, vBB, vCC"), + new Instruction("add-double vAA, vBB, vCC"), + new Instruction("sub-double vAA, vBB, vCC"), + new Instruction("mul-double vAA, vBB, vCC"), + new Instruction("div-double vAA, vBB, vCC"), + new Instruction("rem-double vAA, vBB, vCC"), // 0xb0..0xbf - new Instruction(1, "add-int/2addr vA, vB"), - new Instruction(1, "sub-int/2addr vA, vB"), - new Instruction(1, "mul-int/2addr vA, vB"), - new Instruction(1, "div-int/2addr vA, vB"), - new Instruction(1, "rem-int/2addr vA, vB"), - new Instruction(1, "and-int/2addr vA, vB"), - new Instruction(1, "or-int/2addr vA, vB"), - new Instruction(1, "xor-int/2addr vA, vB"), - new Instruction(1, "shl-int/2addr vA, vB"), - new Instruction(1, "shr-int/2addr vA, vB"), - new Instruction(1, "ushr-int/2addr vA, vB"), - new Instruction(1, "add-long/2addr vA, vB"), - new Instruction(1, "sub-long/2addr vA, vB"), - new Instruction(1, "mul-long/2addr vA, vB"), - new Instruction(1, "div-long/2addr vA, vB"), - new Instruction(1, "rem-long/2addr vA, vB"), + new Instruction("add-int/2addr vA, vB"), + new Instruction("sub-int/2addr vA, vB"), + new Instruction("mul-int/2addr vA, vB"), + new Instruction("div-int/2addr vA, vB"), + new Instruction("rem-int/2addr vA, vB"), + new Instruction("and-int/2addr vA, vB"), + new Instruction("or-int/2addr vA, vB"), + new Instruction("xor-int/2addr vA, vB"), + new Instruction("shl-int/2addr vA, vB"), + new Instruction("shr-int/2addr vA, vB"), + new Instruction("ushr-int/2addr vA, vB"), + new Instruction("add-long/2addr vA, vB"), + new Instruction("sub-long/2addr vA, vB"), + new Instruction("mul-long/2addr vA, vB"), + new Instruction("div-long/2addr vA, vB"), + new Instruction("rem-long/2addr vA, vB"), // 0xc0...0xcf - new Instruction(1, "and-long/2addr vA, vB"), - new Instruction(1, "or-long/2addr vA, vB"), - new Instruction(1, "xor-long/2addr vA, vB"), - new Instruction(1, "shl-long/2addr vA, vB"), - new Instruction(1, "shr-long/2addr vA, vB"), - new Instruction(1, "ushr-long/2addr vA, vB"), - new Instruction(1, "add-float/2addr vA, vB"), - new Instruction(1, "sub-float/2addr vA, vB"), - new Instruction(1, "mul-float/2addr vA, vB"), - new Instruction(1, "div-float/2addr vA, vB"), - new Instruction(1, "rem-float/2addr vA, vB"), - new Instruction(1, "add-double/2addr vA, vB"), - new Instruction(1, "sub-double/2addr vA, vB"), - new Instruction(1, "mul-double/2addr vA, vB"), - new Instruction(1, "div-double/2addr vA, vB"), - new Instruction(1, "rem-double/2addr vA, vB"), + new Instruction("and-long/2addr vA, vB"), + new Instruction("or-long/2addr vA, vB"), + new Instruction("xor-long/2addr vA, vB"), + new Instruction("shl-long/2addr vA, vB"), + new Instruction("shr-long/2addr vA, vB"), + new Instruction("ushr-long/2addr vA, vB"), + new Instruction("add-float/2addr vA, vB"), + new Instruction("sub-float/2addr vA, vB"), + new Instruction("mul-float/2addr vA, vB"), + new Instruction("div-float/2addr vA, vB"), + new Instruction("rem-float/2addr vA, vB"), + new Instruction("add-double/2addr vA, vB"), + new Instruction("sub-double/2addr vA, vB"), + new Instruction("mul-double/2addr vA, vB"), + new Instruction("div-double/2addr vA, vB"), + new Instruction("rem-double/2addr vA, vB"), // 0xd0...0xdf - new Instruction(2, "add-int/lit16 vA, vB, #+CCCC"), - new Instruction(2, "rsub-int (reverse subtract) vA, vB, #+CCCC"), - new Instruction(2, "mul-int/lit16 vA, vB, #+CCCC"), - new Instruction(2, "div-int/lit16 vA, vB, #+CCCC"), - new Instruction(2, "rem-int/lit16 vA, vB, #+CCCC"), - new Instruction(2, "and-int/lit16 vA, vB, #+CCCC"), - new Instruction(2, "or-int/lit16 vA, vB, #+CCCC"), - new Instruction(2, "xor-int/lit16 vA, vB, #+CCCC"), - new Instruction(2, "add-int/lit8 vAA, vBB, #+CC"), - new Instruction(2, "rsub-int/lit8 vAA, vBB, #+CC"), - new Instruction(2, "mul-int/lit8 vAA, vBB, #+CC"), - new Instruction(2, "div-int/lit8 vAA, vBB, #+CC"), - new Instruction(2, "rem-int/lit8 vAA, vBB, #+CC"), - new Instruction(2, "and-int/lit8 vAA, vBB, #+CC"), - new Instruction(2, "or-int/lit8 vAA, vBB, #+CC"), - new Instruction(2, "xor-int/lit8 vAA, vBB, #+CC"), + new Instruction("add-int/lit16 vA, vB, #+CCCC"), + new Instruction("rsub-int (reverse subtract) vA, vB, #+CCCC"), + new Instruction("mul-int/lit16 vA, vB, #+CCCC"), + new Instruction("div-int/lit16 vA, vB, #+CCCC"), + new Instruction("rem-int/lit16 vA, vB, #+CCCC"), + new Instruction("and-int/lit16 vA, vB, #+CCCC"), + new Instruction("or-int/lit16 vA, vB, #+CCCC"), + new Instruction("xor-int/lit16 vA, vB, #+CCCC"), + new Instruction("add-int/lit8 vAA, vBB, #+CC"), + new Instruction("rsub-int/lit8 vAA, vBB, #+CC"), + new Instruction("mul-int/lit8 vAA, vBB, #+CC"), + new Instruction("div-int/lit8 vAA, vBB, #+CC"), + new Instruction("rem-int/lit8 vAA, vBB, #+CC"), + new Instruction("and-int/lit8 vAA, vBB, #+CC"), + new Instruction("or-int/lit8 vAA, vBB, #+CC"), + new Instruction("xor-int/lit8 vAA, vBB, #+CC"), // 0xe0...0xef - new Instruction(2, "shl-int/lit8 vAA, vBB, #+CC"), - new Instruction(2, "shr-int/lit8 vAA, vBB, #+CC"), - new Instruction(2, "ushr-int/lit8 vAA, vBB, #+CC"), + new Instruction("shl-int/lit8 vAA, vBB, #+CC"), + new Instruction("shr-int/lit8 vAA, vBB, #+CC"), + new Instruction("ushr-int/lit8 vAA, vBB, #+CC"), }; /** + * Sets {@code visitor} as the visitor for all instructions. + */ + public void setAllVisitors(Visitor visitor) { + for (Instruction instruction : instructions) { + instruction.setVisitor(null, visitor); + } + } + + /** * Sets {@code visitor} as the visitor for all string instructions. */ public void setStringVisitor(Visitor visitor) { @@ -360,38 +369,36 @@ public final class CodeReader { instructions[0x78].setVisitor("invoke-interface/range {vCCCC..vNNNN}, meth@BBBB", visitor); } - public void visitAll(short[] instructions) throws DexException { - BitSet skippedInstructions = new BitSet(); + public void visitAll(DecodedInstruction[] decodedInstructions) + throws DexException { + int size = decodedInstructions.length; - for (int i = 0; i < instructions.length; ) { - if (skippedInstructions.get(i)) { - i++; + for (int i = 0; i < size; i++) { + DecodedInstruction di = decodedInstructions[i]; + if (di == null) { continue; } - int index = instructions[i] & 0xFF; - if (index < 0 || index >= this.instructions.length) { - throw new DexException("Unhandled instruction at " + i - + ": " + Integer.toHexString(index)); - } - - Instruction instruction = this.instructions[index]; - instruction.mask(instructions, i, skippedInstructions); - if (instruction.visitor != null) { - instruction.visitor.visit(instruction, instructions, i); + Instruction instruction = instructions[di.getOpcode()]; + Visitor visitor = instruction.visitor; + if (visitor != null) { + visitor.visit(instruction, decodedInstructions, di); } - i += instruction.codeUnits; } } + public void visitAll(short[] encodedInstructions) throws DexException { + DecodedInstruction[] decodedInstructions = + DecodedInstruction.decodeAll(encodedInstructions); + visitAll(decodedInstructions); + } + public static class Instruction { private final String name; - private final int codeUnits; private Visitor visitor; - private Instruction(int codeUnits, String name) { + private Instruction(String name) { this.name = name; - this.codeUnits = codeUnits; } public String getName() { @@ -403,78 +410,25 @@ public final class CodeReader { * or null if this instruction has no visitor. */ public void setVisitor(String name, Visitor visitor) { - if (!this.name.equals(name)) { + if ((name != null) && !this.name.equals(name)) { throw new IllegalArgumentException("Expected " + this.name + " but was " + name); } this.visitor = visitor; } - protected void mask(short[] instructions, int offset, BitSet skippedInstructions) {} - @Override public String toString() { return name; } } public interface Visitor { - void visit(Instruction instruction, short[] instructions, int offset); + void visit(Instruction instruction, DecodedInstruction[] all, + DecodedInstruction one); } private static class UnusedInstruction extends Instruction { UnusedInstruction() { - super(1, "unused"); - } - } - - private static class PackedSwitchInstruction extends Instruction { - public PackedSwitchInstruction(int codeUnits, String name) { - super(codeUnits, name); - } - @Override protected void mask(short[] instructions, int i, BitSet skippedInstructions) { - int offset = (instructions[i + 1] & 0xFFFF) - + ((instructions[i + 2] & 0xFFFF) << 16); - if (instructions[i + offset] != 0x100) { - throw new DexException("Expected packed-switch-payload opcode but was 0x" - + Integer.toHexString(instructions[i + offset])); - } - short size = instructions[i + offset + 1]; - skippedInstructions.set(i + offset, i + offset + 4 + (size * 2)); - } - } - - private static class SparseSwitchInstruction extends Instruction { - public SparseSwitchInstruction(int codeUnits, String name) { - super(codeUnits, name); - } - @Override protected void mask(short[] instructions, int i, BitSet skippedInstructions) { - int offset = (instructions[i + 1] & 0xFFFF) - + ((instructions[i + 2] & 0xFFFF) << 16); - if (instructions[i + offset] != 0x200) { - throw new DexException("Expected sparse-switch-payload opcode but was 0x" - + Integer.toHexString(instructions[i + offset])); - } - short size = instructions[i + offset + 1]; - skippedInstructions.set(i + offset, i + offset + 2 + (size * 4)); - } - } - - private static class FillArrayInstruction extends Instruction { - public FillArrayInstruction(int codeUnits, String name) { - super(codeUnits, name); - } - @Override protected void mask(short[] instructions, int i, BitSet skippedInstructions) { - int offset = (instructions[i + 1] & 0xFFFF) - + ((instructions[i + 2] & 0xFFFF) << 16); - if (instructions[i + offset] != 0x300) { - throw new DexException("Expected fill-array-data-payload opcode but was 0x" - + Integer.toHexString(instructions[i + offset])); - } - int bytesPerElement = instructions[i + offset + 1]; - int size = (instructions[i + offset + 2] & 0xFFFF) - + ((instructions[i + offset + 3] & 0xFFFF) << 4); - int totalBytes = size * bytesPerElement; - int totalShorts = (totalBytes + 1) / 2; // round up! - skippedInstructions.set(i + offset, i + offset + 4 + totalShorts); + super("unused"); } } } diff --git a/dx/src/com/android/dx/io/DecodedInstruction.java b/dx/src/com/android/dx/io/DecodedInstruction.java index 24ea919cd..a1b636abb 100644 --- a/dx/src/com/android/dx/io/DecodedInstruction.java +++ b/dx/src/com/android/dx/io/DecodedInstruction.java @@ -90,6 +90,27 @@ public final class DecodedInstruction { } /** + * Decodes an array of instructions. The result has non-null + * elements at each offset that represents the start of an + * instruction. + */ + public static DecodedInstruction[] decodeAll(short[] encodedInstructions) { + int size = encodedInstructions.length; + DecodedInstruction[] decoded = new DecodedInstruction[size]; + ShortArrayCodeInput in = new ShortArrayCodeInput(encodedInstructions); + + try { + while (in.hasMore()) { + decoded[in.cursor()] = DecodedInstruction.decode(in); + } + } catch (EOFException ex) { + throw new AssertionError("shouldn't happen"); + } + + return decoded; + } + + /** * Constructs an instance. This is the base constructor that takes * all arguments. */ diff --git a/dx/src/com/android/dx/io/ShortArrayCodeInput.java b/dx/src/com/android/dx/io/ShortArrayCodeInput.java index da80df60c..20542c581 100644 --- a/dx/src/com/android/dx/io/ShortArrayCodeInput.java +++ b/dx/src/com/android/dx/io/ShortArrayCodeInput.java @@ -21,7 +21,7 @@ import java.io.EOFException; /** * Implementation of {@code CodeInput} that reads from a {@code short[]}. */ -public final class ShortArrayCodeInput { +public final class ShortArrayCodeInput implements CodeInput { /** source array to read from */ private final short[] array; @@ -46,6 +46,11 @@ public final class ShortArrayCodeInput { } /** @inheritDoc */ + public boolean hasMore() { + return cursor < array.length; + } + + /** @inheritDoc */ public int read() throws EOFException { try { return array[cursor++]; diff --git a/dx/src/com/android/dx/io/ShortArrayCodeOutput.java b/dx/src/com/android/dx/io/ShortArrayCodeOutput.java new file mode 100644 index 000000000..d469237b9 --- /dev/null +++ b/dx/src/com/android/dx/io/ShortArrayCodeOutput.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2011 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.io; + +/** + * Implementation of {@code CodeOutput} that writes to a {@code short[]}. + */ +public final class ShortArrayCodeOutput implements CodeOutput { + /** array to write to */ + private final short[] array; + + /** next index within {@link #array} to write */ + private int cursor; + + /** + * Constructs an instance. + */ + public ShortArrayCodeOutput(int maxSize) { + if (maxSize < 0) { + throw new IllegalArgumentException("maxSize < 0"); + } + + this.array = new short[maxSize]; + this.cursor = 0; + } + + /** + * Gets the array. The returned array contains exactly the data + * written (e.g. no leftover space at the end). + */ + public short[] getArray() { + if (cursor == array.length) { + return array; + } + + short[] result = new short[cursor]; + System.arraycopy(array, 0, result, 0, cursor); + return result; + } + + /** @inheritDoc */ + public void write(short codeUnit) { + array[cursor++] = codeUnit; + } + + /** @inheritDoc */ + public void write(short u0, short u1) { + write(u0); + write(u1); + } + + /** @inheritDoc */ + public void write(short u0, short u1, short u2) { + write(u0); + write(u1); + write(u2); + } + + /** @inheritDoc */ + public void write(short u0, short u1, short u2, short u3) { + write(u0); + write(u1); + write(u2); + write(u3); + } + + /** @inheritDoc */ + public void write(short u0, short u1, short u2, short u3, short u4) { + write(u0); + write(u1); + write(u2); + write(u3); + write(u4); + } + + /** @inheritDoc */ + public void write(short[] data) { + for (short unit : data) { + write(unit); + } + } +} |