diff options
| author | Davor Bertovic <davor@losinj.com> | 2014-03-30 06:01:48 -0400 |
|---|---|---|
| committer | Gerrit Code Review <gerrit@doa.deadnet.net> | 2014-03-30 06:01:48 -0400 |
| commit | 41f02c2cea84d1f3cb8742240e8cb705e1297e30 (patch) | |
| tree | 40cdc580690a4f27bd507abbe361cdb6868ddd86 | |
| parent | 63542eeb167b7b5375f96ddf72d7f92bf19a5ec9 (diff) | |
| parent | 241e089ede168a1d89b2ba0cebae4d4b9a3d8586 (diff) | |
Merge "Revert "Remove code related to extended-opcode."" into kitkat
| -rw-r--r-- | dx/src/com/android/dx/command/dexer/Main.java | 4 | ||||
| -rw-r--r-- | dx/src/com/android/dx/dex/DexOptions.java | 8 | ||||
| -rw-r--r-- | dx/src/com/android/dx/dex/code/Dops.java | 26 | ||||
| -rw-r--r-- | dx/src/com/android/dx/io/Opcodes.java | 17 |
4 files changed, 49 insertions, 6 deletions
diff --git a/dx/src/com/android/dx/command/dexer/Main.java b/dx/src/com/android/dx/command/dexer/Main.java index d4c396903..ab6d2f788 100644 --- a/dx/src/com/android/dx/command/dexer/Main.java +++ b/dx/src/com/android/dx/command/dexer/Main.java @@ -1192,6 +1192,9 @@ public class Main { */ public boolean keepClassesInJar = false; + /** what API level to target */ + public int targetApiLevel = DexFormat.API_NO_EXTENDED_OPCODES; + /** how much source position info to preserve */ public int positionInfo = PositionList.LINES; @@ -1513,6 +1516,7 @@ public class Main { cfOptions.warn = DxConsole.err; dexOptions = new DexOptions(); + dexOptions.targetApiLevel = targetApiLevel; dexOptions.forceJumbo = forceJumbo; } } diff --git a/dx/src/com/android/dx/dex/DexOptions.java b/dx/src/com/android/dx/dex/DexOptions.java index 60d83a84e..db0c7a2c5 100644 --- a/dx/src/com/android/dx/dex/DexOptions.java +++ b/dx/src/com/android/dx/dex/DexOptions.java @@ -34,4 +34,12 @@ public class DexOptions { public String getMagic() { return DexFormat.apiToMagic(targetApiLevel); } + + /** + * Returns whether extended opcodes are allowed. This became + * allowed as of Ice Cream Sandwich. + */ + public boolean canUseExtendedOpcodes() { + return targetApiLevel >= DexFormat.API_CURRENT; + } } diff --git a/dx/src/com/android/dx/dex/code/Dops.java b/dx/src/com/android/dx/dex/code/Dops.java index a84ddc098..cc5c173ed 100644 --- a/dx/src/com/android/dx/dex/code/Dops.java +++ b/dx/src/com/android/dx/dex/code/Dops.java @@ -1206,15 +1206,29 @@ public final class Dops { * the last in its chain */ public static Dop getNextOrNull(Dop opcode, DexOptions options) { - int nextOpcode = opcode.getNextOpcode(); + boolean suppressExtendedOpcodes = !options.canUseExtendedOpcodes(); - if (nextOpcode == Opcodes.NO_NEXT) { - return null; - } + for (;;) { + int nextOpcode = opcode.getNextOpcode(); - opcode = get(nextOpcode); + if (nextOpcode == Opcodes.NO_NEXT) { + return null; + } + + opcode = get(nextOpcode); - return opcode; + if (suppressExtendedOpcodes && Opcodes.isExtended(nextOpcode)) { + /* + * Continuing rather than just returning null here + * protects against the possibility that an + * instruction fitting chain might list non-extended + * opcodes after extended ones. + */ + continue; + } + + return opcode; + } } /** diff --git a/dx/src/com/android/dx/io/Opcodes.java b/dx/src/com/android/dx/io/Opcodes.java index 611dbda43..6dba49d9e 100644 --- a/dx/src/com/android/dx/io/Opcodes.java +++ b/dx/src/com/android/dx/io/Opcodes.java @@ -327,6 +327,23 @@ public final class Opcodes { } /** + * Gets whether ({@code true}) or not ({@code false}) the given + * opcode value is an "extended" opcode (not counting the nop-like + * payload opcodes). Extended opcodes require a full 16-bit code + * unit to represent, without leaving space for an argument byte. + * + * @param opcode the opcode value + * @return {@code true} iff the opcode is an "extended" opcode + */ + public static boolean isExtended(int opcode) { + /* + * Note: Extended opcodes all have the form ((byteValue << 8) + * | 0xff). + */ + return (opcode >= 0x00ff); + } + + /** * Gets the opcode out of an opcode unit, the latter of which may also * include one or more argument values. * |
