ImmutableInstruction.java revision 22c3185bb7c8618437eabe6c597549e0989ec4e6
1e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver/* 2e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver * Copyright 2012, Google Inc. 3e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver * All rights reserved. 4e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver * 5e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver * Redistribution and use in source and binary forms, with or without 6e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver * modification, are permitted provided that the following conditions are 7e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver * met: 8e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver * 9e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver * * Redistributions of source code must retain the above copyright 10e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver * notice, this list of conditions and the following disclaimer. 11e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver * * Redistributions in binary form must reproduce the above 12e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver * copyright notice, this list of conditions and the following disclaimer 13e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver * in the documentation and/or other materials provided with the 14e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver * distribution. 15e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver * * Neither the name of Google Inc. nor the names of its 16e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver * contributors may be used to endorse or promote products derived from 17e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver * this software without specific prior written permission. 18e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver * 19e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver */ 31e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver 32e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruverpackage org.jf.dexlib2.immutable.instruction; 33e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver 34e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruverimport com.google.common.collect.ImmutableList; 35e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruverimport org.jf.dexlib2.Format; 36e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruverimport org.jf.dexlib2.Opcode; 37e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruverimport org.jf.dexlib2.iface.instruction.Instruction; 38e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruverimport org.jf.dexlib2.iface.instruction.formats.*; 39e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruverimport org.jf.dexlib2.util.Preconditions; 4022c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruverimport org.jf.util.ImmutableConverter; 41e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver 42e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruverimport javax.annotation.Nonnull; 43e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver 44e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruverpublic abstract class ImmutableInstruction implements Instruction { 4522c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruver @Nonnull protected final Opcode opcode; 46e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver 47e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver protected ImmutableInstruction(@Nonnull Opcode opcode) { 48e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver this.opcode = opcode; 49e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver //TODO: check performance. Move into subclasses if needed, where we can access the field directly 50e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver Preconditions.checkFormat(opcode, getFormat()); 51e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver } 52e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver 53c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver @Nonnull 54e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver public static ImmutableInstruction of(Instruction instruction) { 55e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver if (instruction instanceof ImmutableInstruction) { 56e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return (ImmutableInstruction)instruction; 57e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver } 58e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver 59e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver switch (instruction.getOpcode().format) { 60e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format10t: 61e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction10t.of((Instruction10t)instruction); 62e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format10x: 63e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction10x.of((Instruction10x)instruction); 64e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format11n: 65e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction11n.of((Instruction11n)instruction); 66e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format11x: 67e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction11x.of((Instruction11x)instruction); 68e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format12x: 69e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction12x.of((Instruction12x)instruction); 70e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format20t: 71e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction20t.of((Instruction20t)instruction); 72e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format21c: 73e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction21c.of((Instruction21c)instruction); 74e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format21ih: 75e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction21ih.of((Instruction21ih)instruction); 76e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format21lh: 77e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction21lh.of((Instruction21lh)instruction); 78e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format21s: 79e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction21s.of((Instruction21s)instruction); 80e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format21t: 81e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction21t.of((Instruction21t)instruction); 82e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format22b: 83e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction22b.of((Instruction22b)instruction); 84e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format22c: 85e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction22c.of((Instruction22c)instruction); 86e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format22s: 87e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction22s.of((Instruction22s)instruction); 88e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format22t: 89e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction22t.of((Instruction22t)instruction); 90e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format22x: 91e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction22x.of((Instruction22x)instruction); 92e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format23x: 93e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction23x.of((Instruction23x)instruction); 94e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format30t: 95e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction30t.of((Instruction30t)instruction); 96e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format31c: 97e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction31c.of((Instruction31c)instruction); 98e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format31i: 99e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction31i.of((Instruction31i)instruction); 100e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format31t: 101e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction31t.of((Instruction31t)instruction); 102e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format32x: 103e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction32x.of((Instruction32x)instruction); 104e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format35c: 105e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction35c.of((Instruction35c)instruction); 106e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format3rc: 107e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction3rc.of((Instruction3rc)instruction); 108e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format51l: 109e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction51l.of((Instruction51l)instruction); 110c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver case PackedSwitchPayload: 111c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver return ImmutablePackedSwitchPayload.of((PackedSwitchPayload) instruction); 112c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver case SparseSwitchPayload: 113c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver return ImmutableSparseSwitchPayload.of((SparseSwitchPayload) instruction); 114c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver case ArrayPayload: 115c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver return ImmutableArrayPayload.of((ArrayPayload) instruction); 116c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver //TODO: temporary, until we get all instructions implemented 117c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver default: 118c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver throw new RuntimeException("Unexpected instruction type"); 119e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver } 120e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver } 121e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver 122e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver public Opcode getOpcode() { 123e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return opcode; 124e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver } 125e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver 126e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver public abstract Format getFormat(); 127e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver 128c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver public int getCodeUnits() { 129eee0ff70fd7a92331472e3d9e6e584398aca378aBen Gruver return getFormat().size / 2; 130c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver } 131c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver 132e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver @Nonnull 133d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver public static ImmutableList<ImmutableInstruction> immutableListOf(Iterable<? extends Instruction> list) { 13422c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruver return CONVERTER.toList(list); 135e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver } 136e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver 13722c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruver private static final ImmutableConverter<ImmutableInstruction, Instruction> CONVERTER = 13822c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruver new ImmutableConverter<ImmutableInstruction, Instruction>() { 139e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver @Override 140ddf20219422e40a1e60268d8049093602d7bacf8Ben Gruver protected boolean isImmutable(@Nonnull Instruction item) { 141e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return item instanceof ImmutableInstruction; 142e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver } 143e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver 144c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver @Nonnull 145e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver @Override 146ddf20219422e40a1e60268d8049093602d7bacf8Ben Gruver protected ImmutableInstruction makeImmutable(@Nonnull Instruction item) { 147e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction.of(item); 148e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver } 149e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver }; 150e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver} 151