ImmutableInstruction.java revision eee0ff70fd7a92331472e3d9e6e584398aca378a
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; 40e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruverimport org.jf.util.ImmutableListConverter; 41e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver 42e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruverimport javax.annotation.Nonnull; 43e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruverimport java.util.List; 44e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver 45e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruverpublic abstract class ImmutableInstruction implements Instruction { 46c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver @Nonnull public final Opcode opcode; 47e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver 48e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver protected ImmutableInstruction(@Nonnull Opcode opcode) { 49e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver this.opcode = opcode; 50e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver //TODO: check performance. Move into subclasses if needed, where we can access the field directly 51e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver Preconditions.checkFormat(opcode, getFormat()); 52e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver } 53e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver 54c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver @Nonnull 55e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver public static ImmutableInstruction of(Instruction instruction) { 56e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver if (instruction instanceof ImmutableInstruction) { 57e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return (ImmutableInstruction)instruction; 58e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver } 59e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver 60e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver switch (instruction.getOpcode().format) { 61e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format10t: 62e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction10t.of((Instruction10t)instruction); 63e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format10x: 64e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction10x.of((Instruction10x)instruction); 65e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format11n: 66e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction11n.of((Instruction11n)instruction); 67e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format11x: 68e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction11x.of((Instruction11x)instruction); 69e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format12x: 70e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction12x.of((Instruction12x)instruction); 71e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format20t: 72e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction20t.of((Instruction20t)instruction); 73e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format21c: 74e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction21c.of((Instruction21c)instruction); 75e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format21ih: 76e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction21ih.of((Instruction21ih)instruction); 77e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format21lh: 78e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction21lh.of((Instruction21lh)instruction); 79e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format21s: 80e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction21s.of((Instruction21s)instruction); 81e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format21t: 82e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction21t.of((Instruction21t)instruction); 83e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format22b: 84e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction22b.of((Instruction22b)instruction); 85e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format22c: 86e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction22c.of((Instruction22c)instruction); 87e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format22s: 88e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction22s.of((Instruction22s)instruction); 89e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format22t: 90e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction22t.of((Instruction22t)instruction); 91e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format22x: 92e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction22x.of((Instruction22x)instruction); 93e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format23x: 94e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction23x.of((Instruction23x)instruction); 95e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format30t: 96e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction30t.of((Instruction30t)instruction); 97e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format31c: 98e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction31c.of((Instruction31c)instruction); 99e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format31i: 100e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction31i.of((Instruction31i)instruction); 101e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format31t: 102e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction31t.of((Instruction31t)instruction); 103e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format32x: 104e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction32x.of((Instruction32x)instruction); 105e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format35c: 106e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction35c.of((Instruction35c)instruction); 107e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format3rc: 108e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction3rc.of((Instruction3rc)instruction); 109e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver case Format51l: 110e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction51l.of((Instruction51l)instruction); 111c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver case PackedSwitchPayload: 112c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver return ImmutablePackedSwitchPayload.of((PackedSwitchPayload) instruction); 113c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver case SparseSwitchPayload: 114c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver return ImmutableSparseSwitchPayload.of((SparseSwitchPayload) instruction); 115c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver case ArrayPayload: 116c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver return ImmutableArrayPayload.of((ArrayPayload) instruction); 117c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver //TODO: temporary, until we get all instructions implemented 118c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver default: 119c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver throw new RuntimeException("Unexpected instruction type"); 120e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver } 121e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver } 122e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver 123e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver public Opcode getOpcode() { 124e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return opcode; 125e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver } 126e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver 127e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver public abstract Format getFormat(); 128e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver 129c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver public int getCodeUnits() { 130eee0ff70fd7a92331472e3d9e6e584398aca378aBen Gruver return getFormat().size / 2; 131c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver } 132c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver 133e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver @Nonnull 134e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver public static ImmutableList<ImmutableInstruction> immutableListOf(List<? extends Instruction> list) { 135e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return CONVERTER.convert(list); 136e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver } 137e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver 138e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver private static final ImmutableListConverter<ImmutableInstruction, Instruction> CONVERTER = 139e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver new ImmutableListConverter<ImmutableInstruction, Instruction>() { 140e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver @Override 141e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver protected boolean isImmutable(Instruction item) { 142e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return item instanceof ImmutableInstruction; 143e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver } 144e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver 145c307c1887d0c57e2213d5146cedec2307251e9faBen Gruver @Nonnull 146e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver @Override 147e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver protected ImmutableInstruction makeImmutable(Instruction item) { 148e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver return ImmutableInstruction.of(item); 149e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver } 150e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver }; 151e2f00f0eba79723388f2152db7b68c64872d7eb3Ben Gruver} 152