aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavor Bertovic <davor@losinj.com>2014-03-30 06:01:44 -0400
committerDavor Bertovic <davor@losinj.com>2014-03-30 06:01:44 -0400
commit241e089ede168a1d89b2ba0cebae4d4b9a3d8586 (patch)
tree1e8225f9b588b632750cee62c5ce5a9cf445b112
parent6527b83f7327af4a3919f07054129130e44fdef3 (diff)
Revert "Remove code related to extended-opcode."
This reverts commit 6527b83f7327af4a3919f07054129130e44fdef3. Change-Id: I782de6800999ce57af8caa50c9900a225ed1fe35
-rw-r--r--dx/src/com/android/dx/command/dexer/Main.java4
-rw-r--r--dx/src/com/android/dx/dex/DexOptions.java8
-rw-r--r--dx/src/com/android/dx/dex/code/Dops.java26
-rw-r--r--dx/src/com/android/dx/io/Opcodes.java17
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.
*