ImmutableInstruction.java revision 2363e6e43ccd826a315b2f1feb1850a6ccd68f84
1c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell/*
2c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Copyright 2012, Google Inc.
3c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * All rights reserved.
4c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell *
5c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * Redistribution and use in source and binary forms, with or without
6c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * modification, are permitted provided that the following conditions are
7c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * met:
8c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell *
9c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell *     * Redistributions of source code must retain the above copyright
10c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * notice, this list of conditions and the following disclaimer.
11c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell *     * Redistributions in binary form must reproduce the above
12c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * copyright notice, this list of conditions and the following disclaimer
13c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * in the documentation and/or other materials provided with the
14c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * distribution.
15c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell *     * Neither the name of Google Inc. nor the names of its
16c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * contributors may be used to endorse or promote products derived from
17c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * this software without specific prior written permission.
18c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell *
19c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell */
31c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell
32c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwellpackage org.jf.dexlib2.immutable.instruction;
33c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell
34c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwellimport com.google.common.collect.ImmutableList;
35c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwellimport org.jf.dexlib2.Format;
367925274da323d5a896b557181d4016e0391f026fBrianimport org.jf.dexlib2.Opcode;
37ed6f41e2f467f5b9338320a96202c7dfd181422fBrianimport org.jf.dexlib2.iface.instruction.Instruction;
38492e61d94f68c3a4a515cab3cf227eed5b426bdfBrian Paulimport org.jf.dexlib2.iface.instruction.formats.*;
39c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwellimport org.jf.dexlib2.util.Preconditions;
4066ef96f6dc4cd898edb862e45965795fac46caedMichal Krolimport org.jf.util.ImmutableConverter;
41c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell
42c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwellimport javax.annotation.Nonnull;
439935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul
444f25420bdd834e81a3e22733304efc5261c2998aBrian Paulpublic abstract class ImmutableInstruction implements Instruction {
459935e3b7303da656e258d4bd5bc799ffbfbc737bBrian Paul    @Nonnull protected final Opcode opcode;
46c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell
47c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell    protected ImmutableInstruction(@Nonnull Opcode opcode) {
48c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell        this.opcode = opcode;
49c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell        //TODO: check performance. Move into subclasses if needed, where we can access the field directly
506756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul        Preconditions.checkFormat(opcode, getFormat());
51c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell    }
52c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell
53c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell    @Nonnull
54c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell    public static ImmutableInstruction of(Instruction instruction) {
55c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell        if (instruction instanceof ImmutableInstruction) {
56c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            return (ImmutableInstruction)instruction;
57c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell        }
58c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell
59c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell        switch (instruction.getOpcode().format) {
60c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            case Format10t:
61c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                return ImmutableInstruction10t.of((Instruction10t)instruction);
62ebe6160d7c9ccbddd8b1cc4b0e25b3d61c54293dMichal Krol            case Format10x:
63b806c3056f17685c8e6214ce946cd282c656107aBrian Paul                if (instruction instanceof UnknownInstruction) {
64b806c3056f17685c8e6214ce946cd282c656107aBrian Paul                    return ImmutableUnknownInstruction.of((UnknownInstruction)instruction);
65b806c3056f17685c8e6214ce946cd282c656107aBrian Paul                }
66b806c3056f17685c8e6214ce946cd282c656107aBrian Paul                return ImmutableInstruction10x.of((Instruction10x)instruction);
67b806c3056f17685c8e6214ce946cd282c656107aBrian Paul            case Format11n:
68a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell                return ImmutableInstruction11n.of((Instruction11n)instruction);
69a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell            case Format11x:
70c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                return ImmutableInstruction11x.of((Instruction11x)instruction);
71c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            case Format12x:
726756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul                return ImmutableInstruction12x.of((Instruction12x)instruction);
73c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            case Format20bc:
74c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                return ImmutableInstruction20bc.of((Instruction20bc)instruction);
75c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            case Format20t:
76c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                return ImmutableInstruction20t.of((Instruction20t)instruction);
77c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            case Format21c:
78c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                return ImmutableInstruction21c.of((Instruction21c)instruction);
79c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            case Format21ih:
80c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                return ImmutableInstruction21ih.of((Instruction21ih)instruction);
81c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            case Format21lh:
82c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                return ImmutableInstruction21lh.of((Instruction21lh)instruction);
83c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            case Format21s:
84c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                return ImmutableInstruction21s.of((Instruction21s)instruction);
85c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            case Format21t:
86c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                return ImmutableInstruction21t.of((Instruction21t)instruction);
87c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            case Format22b:
88c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                return ImmutableInstruction22b.of((Instruction22b)instruction);
89c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            case Format22c:
90c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                return ImmutableInstruction22c.of((Instruction22c)instruction);
91c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            case Format22cs:
92a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell                return ImmutableInstruction22cs.of((Instruction22cs)instruction);
93a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell            case Format22s:
94ca9c413647bf9efb5ed770e3a655bc758075aec7Michal Krol                return ImmutableInstruction22s.of((Instruction22s)instruction);
95ca9c413647bf9efb5ed770e3a655bc758075aec7Michal Krol            case Format22t:
96a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell                return ImmutableInstruction22t.of((Instruction22t)instruction);
97a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell            case Format22x:
98a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell                return ImmutableInstruction22x.of((Instruction22x)instruction);
99c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            case Format23x:
100c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                return ImmutableInstruction23x.of((Instruction23x)instruction);
101c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            case Format30t:
102c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                return ImmutableInstruction30t.of((Instruction30t)instruction);
103c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            case Format31c:
104c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                return ImmutableInstruction31c.of((Instruction31c)instruction);
105c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            case Format31i:
106c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                return ImmutableInstruction31i.of((Instruction31i)instruction);
107c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            case Format31t:
108c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                return ImmutableInstruction31t.of((Instruction31t)instruction);
109c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            case Format32x:
110c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                return ImmutableInstruction32x.of((Instruction32x)instruction);
111c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            case Format35c:
112c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                return ImmutableInstruction35c.of((Instruction35c)instruction);
1138e7326832a7420154fc0d526ac682494db1be160Keith Whitwell            case Format35mi:
1144ff1274e2312c7d9d8538dc443af500ec3b769cfKeith Whitwell                return ImmutableInstruction35mi.of((Instruction35mi)instruction);
115f36123323c9d696fec6e54882242cab15247ab0dBrian Paul            case Format35ms:
116c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                return ImmutableInstruction35ms.of((Instruction35ms)instruction);
117c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            case Format3rc:
118c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                return ImmutableInstruction3rc.of((Instruction3rc)instruction);
119c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            case Format3rmi:
120c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                return ImmutableInstruction3rmi.of((Instruction3rmi)instruction);
121c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            case Format3rms:
1228e7326832a7420154fc0d526ac682494db1be160Keith Whitwell                return ImmutableInstruction3rms.of((Instruction3rms)instruction);
1238e7326832a7420154fc0d526ac682494db1be160Keith Whitwell            case Format51l:
124c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                return ImmutableInstruction51l.of((Instruction51l)instruction);
125c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            case PackedSwitchPayload:
126c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                return ImmutablePackedSwitchPayload.of((PackedSwitchPayload) instruction);
127c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            case SparseSwitchPayload:
1286756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul                return ImmutableSparseSwitchPayload.of((SparseSwitchPayload) instruction);
129c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            case ArrayPayload:
130c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                return ImmutableArrayPayload.of((ArrayPayload) instruction);
131c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            //TODO: temporary, until we get all instructions implemented
132c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            default:
133c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                throw new RuntimeException("Unexpected instruction type");
134c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell        }
135c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell    }
13601f9e5120395f88bba8321e8639cac0bb9c85296Michal Krol
13701f9e5120395f88bba8321e8639cac0bb9c85296Michal Krol    @Nonnull public Opcode getOpcode() {
13801f9e5120395f88bba8321e8639cac0bb9c85296Michal Krol        return opcode;
13901f9e5120395f88bba8321e8639cac0bb9c85296Michal Krol    }
140c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell
14101f9e5120395f88bba8321e8639cac0bb9c85296Michal Krol    public abstract Format getFormat();
142c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell
143c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell    public int getCodeUnits() {
14401f9e5120395f88bba8321e8639cac0bb9c85296Michal Krol        return getFormat().size / 2;
14501f9e5120395f88bba8321e8639cac0bb9c85296Michal Krol    }
14601f9e5120395f88bba8321e8639cac0bb9c85296Michal Krol
14701f9e5120395f88bba8321e8639cac0bb9c85296Michal Krol    @Nonnull
14801f9e5120395f88bba8321e8639cac0bb9c85296Michal Krol    public static ImmutableList<ImmutableInstruction> immutableListOf(Iterable<? extends Instruction> list) {
14901f9e5120395f88bba8321e8639cac0bb9c85296Michal Krol        return CONVERTER.toList(list);
15001f9e5120395f88bba8321e8639cac0bb9c85296Michal Krol    }
15101f9e5120395f88bba8321e8639cac0bb9c85296Michal Krol
152c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell    private static final ImmutableConverter<ImmutableInstruction, Instruction> CONVERTER =
153c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            new ImmutableConverter<ImmutableInstruction, Instruction>() {
154c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                @Override
155c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                protected boolean isImmutable(@Nonnull Instruction item) {
156c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                    return item instanceof ImmutableInstruction;
157c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                }
158c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell
1596756c07b66164a2f8c769ad5725b95115eb7a6e6Brian Paul                @Nonnull
160c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell                @Override
161ebe6160d7c9ccbddd8b1cc4b0e25b3d61c54293dMichal Krol                protected ImmutableInstruction makeImmutable(@Nonnull Instruction item) {
1626153a1c28f118be1a74ffee0e19c16fb83b5cab7Keith Whitwell                    return ImmutableInstruction.of(item);
16301f9e5120395f88bba8321e8639cac0bb9c85296Michal Krol                }
164c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell            };
165ebe6160d7c9ccbddd8b1cc4b0e25b3d61c54293dMichal Krol}
166098aa5f9abcda3fff1a40666cc8f150f046d8867Brian Paul