summaryrefslogtreecommitdiff
path: root/dx/src/com/android/dx/merge/InstructionTransformer.java
diff options
context:
space:
mode:
Diffstat (limited to 'dx/src/com/android/dx/merge/InstructionTransformer.java')
-rw-r--r--dx/src/com/android/dx/merge/InstructionTransformer.java106
1 files changed, 106 insertions, 0 deletions
diff --git a/dx/src/com/android/dx/merge/InstructionTransformer.java b/dx/src/com/android/dx/merge/InstructionTransformer.java
new file mode 100644
index 0000000..62c3a49
--- /dev/null
+++ b/dx/src/com/android/dx/merge/InstructionTransformer.java
@@ -0,0 +1,106 @@
+/*
+ * 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.merge;
+
+import com.android.dx.io.CodeReader;
+import com.android.dx.io.instructions.DecodedInstruction;
+import com.android.dx.io.instructions.ShortArrayCodeOutput;
+import com.android.dx.util.DexException;
+
+final class InstructionTransformer {
+ private final IndexMap indexMap;
+ private final CodeReader reader;
+ private DecodedInstruction[] mappedInstructions;
+ private int mappedAt;
+
+ public InstructionTransformer(IndexMap indexMap) {
+ this.indexMap = indexMap;
+ this.reader = new CodeReader();
+ this.reader.setAllVisitors(new GenericVisitor());
+ this.reader.setStringVisitor(new StringVisitor());
+ this.reader.setTypeVisitor(new TypeVisitor());
+ this.reader.setFieldVisitor(new FieldVisitor());
+ this.reader.setMethodVisitor(new MethodVisitor());
+ }
+
+ public short[] transform(short[] encodedInstructions) throws DexException {
+ DecodedInstruction[] decodedInstructions =
+ DecodedInstruction.decodeAll(encodedInstructions);
+ int size = decodedInstructions.length;
+
+ mappedInstructions = new DecodedInstruction[size];
+ mappedAt = 0;
+ reader.visitAll(decodedInstructions);
+
+ ShortArrayCodeOutput out = new ShortArrayCodeOutput(size);
+ for (DecodedInstruction instruction : mappedInstructions) {
+ if (instruction != null) {
+ instruction.encode(out);
+ }
+ }
+
+ return out.getArray();
+ }
+
+ private class GenericVisitor implements CodeReader.Visitor {
+ public void visit(DecodedInstruction[] all, DecodedInstruction one) {
+ mappedInstructions[mappedAt++] = one;
+ }
+ }
+
+ private class StringVisitor implements CodeReader.Visitor {
+ public void visit(DecodedInstruction[] all, DecodedInstruction one) {
+ int stringId = one.getIndex();
+ int mappedId = indexMap.adjustString(stringId);
+ jumboCheck(stringId, mappedId);
+ mappedInstructions[mappedAt++] = one.withIndex(mappedId);
+ }
+ }
+
+ private class FieldVisitor implements CodeReader.Visitor {
+ public void visit(DecodedInstruction[] all, DecodedInstruction one) {
+ int fieldId = one.getIndex();
+ int mappedId = indexMap.adjustField(fieldId);
+ jumboCheck(fieldId, mappedId);
+ mappedInstructions[mappedAt++] = one.withIndex(mappedId);
+ }
+ }
+
+ private class TypeVisitor implements CodeReader.Visitor {
+ public void visit(DecodedInstruction[] all, DecodedInstruction one) {
+ int typeId = one.getIndex();
+ int mappedId = indexMap.adjustType(typeId);
+ jumboCheck(typeId, mappedId);
+ mappedInstructions[mappedAt++] = one.withIndex(mappedId);
+ }
+ }
+
+ private class MethodVisitor implements CodeReader.Visitor {
+ public void visit(DecodedInstruction[] all, DecodedInstruction one) {
+ int methodId = one.getIndex();
+ int mappedId = indexMap.adjustMethod(methodId);
+ jumboCheck(methodId, mappedId);
+ mappedInstructions[mappedAt++] = one.withIndex(mappedId);
+ }
+ }
+
+ private static void jumboCheck(int oldIndex, int newIndex) {
+ if ((oldIndex <= 0xffff) && (newIndex > 0xffff)) {
+ throw new DexException("Cannot handle conversion to jumbo index!");
+ }
+ }
+}