InstructionTransformer.java revision a754fbb1555f9ac2d14de0ffd0046c780732da5a
1081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson/*
2081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson * Copyright (C) 2011 The Android Open Source Project
3081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson *
4081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson * Licensed under the Apache License, Version 2.0 (the "License");
5081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson * you may not use this file except in compliance with the License.
6081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson * You may obtain a copy of the License at
7081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson *
8081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson *      http://www.apache.org/licenses/LICENSE-2.0
9081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson *
10081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson * Unless required by applicable law or agreed to in writing, software
11081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
12081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson * See the License for the specific language governing permissions and
14081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson * limitations under the License.
15081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson */
16081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson
17081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilsonpackage com.android.dx.merge;
18081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson
19081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilsonimport com.android.dx.dex.DexException;
20e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilsonimport com.android.dx.io.CodeReader;
2138b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornsteinimport com.android.dx.io.DecodedInstruction;
22a754fbb1555f9ac2d14de0ffd0046c780732da5aDan Bornsteinimport com.android.dx.io.OpcodeInfo;
2338b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornsteinimport com.android.dx.io.ShortArrayCodeOutput;
24081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson
25dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilsonfinal class InstructionTransformer {
26081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson    private final IndexMap indexMap;
27e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson    private final CodeReader reader;
2838b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    private DecodedInstruction[] mappedInstructions;
2938b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    private int mappedAt;
30081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson
31081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson    public InstructionTransformer(IndexMap indexMap) {
32081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson        this.indexMap = indexMap;
33e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson        this.reader = new CodeReader();
3438b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        this.reader.setAllVisitors(new GenericVisitor());
3538b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        this.reader.setJumboStringVisitor(new JumboStringVisitor());
3638b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        this.reader.setStringVisitor(new StringVisitor());
37e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson        this.reader.setTypeVisitor(new TypeVisitor());
38e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson        this.reader.setFieldVisitor(new FieldVisitor());
39e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson        this.reader.setMethodVisitor(new MethodVisitor());
40081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson    }
41081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson
4238b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    public short[] transform(short[] encodedInstructions) throws DexException {
4338b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        DecodedInstruction[] decodedInstructions =
4438b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein            DecodedInstruction.decodeAll(encodedInstructions);
4538b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        int size = decodedInstructions.length;
4638b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein
4738b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        mappedInstructions = new DecodedInstruction[size];
4838b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        mappedAt = 0;
4938b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        reader.visitAll(decodedInstructions);
5038b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein
5138b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        ShortArrayCodeOutput out = new ShortArrayCodeOutput(size);
5238b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        for (DecodedInstruction instruction : mappedInstructions) {
5338b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein            if (instruction != null) {
5438b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein                instruction.encode(out);
5538b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein            }
5638b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        }
5738b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein
5838b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        return out.getArray();
59081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson    }
60081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson
6138b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    private class GenericVisitor implements CodeReader.Visitor {
62a754fbb1555f9ac2d14de0ffd0046c780732da5aDan Bornstein        public void visit(DecodedInstruction[] all, DecodedInstruction one) {
6338b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein            mappedInstructions[mappedAt++] = one;
6438b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        }
6538b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    }
6638b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein
6738b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    private class StringVisitor implements CodeReader.Visitor {
68a754fbb1555f9ac2d14de0ffd0046c780732da5aDan Bornstein        public void visit(DecodedInstruction[] all, DecodedInstruction one) {
6938b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein            int stringId = one.getIndex();
7038b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein            int mappedId = indexMap.adjustString(stringId);
7138b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein            if (mappedId > 0xFFFF) {
72081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson                throw new DexException("Cannot convert string to jumbo string!");
73081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson            }
7438b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein
7538b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein            mappedInstructions[mappedAt++] = one.withIndex(mappedId);
76081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson        }
77081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson    }
78081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson
7938b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    private class JumboStringVisitor implements CodeReader.Visitor {
80a754fbb1555f9ac2d14de0ffd0046c780732da5aDan Bornstein        public void visit(DecodedInstruction[] all, DecodedInstruction one) {
81081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson            throw new UnsupportedOperationException("Jumbo strings not implemented. "
82081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson                    + "Due to a lack of dex files requiring jumbo strings, this class doesn't "
83081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson                    + "bother to support jumbo strings!");
84081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson        }
85081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson    }
86081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson
87e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson    private class FieldVisitor implements CodeReader.Visitor {
88a754fbb1555f9ac2d14de0ffd0046c780732da5aDan Bornstein        public void visit(DecodedInstruction[] all, DecodedInstruction one) {
8938b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein            int fieldId = one.getIndex();
9038b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein            int mappedId = indexMap.adjustField(fieldId);
9138b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein            mappedInstructions[mappedAt++] = one.withIndex(mappedId);
92081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson        }
93081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson    }
94081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson
95e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson    private class TypeVisitor implements CodeReader.Visitor {
96a754fbb1555f9ac2d14de0ffd0046c780732da5aDan Bornstein        public void visit(DecodedInstruction[] all, DecodedInstruction one) {
9738b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein            int typeId = one.getIndex();
9838b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein            int mappedId = indexMap.adjustType(typeId);
9938b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein            mappedInstructions[mappedAt++] = one.withIndex(mappedId);
100081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson        }
101081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson    }
102081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson
103e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson    private class MethodVisitor implements CodeReader.Visitor {
104a754fbb1555f9ac2d14de0ffd0046c780732da5aDan Bornstein        public void visit(DecodedInstruction[] all, DecodedInstruction one) {
10538b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein            int methodId = one.getIndex();
10638b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein            int mappedId = indexMap.adjustMethod(methodId);
10738b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein            mappedInstructions[mappedAt++] = one.withIndex(mappedId);
108081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson        }
109081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson    }
110081c7142b29ccd6e1744b26e097b6a4d7c12f2bdJesse Wilson}
111