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