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