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