Home | History | Annotate | Download | only in instruction
      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 
     32 package org.jf.dexlib2.immutable.instruction;
     33 
     34 import com.google.common.collect.ImmutableList;
     35 import org.jf.dexlib2.Format;
     36 import org.jf.dexlib2.Opcode;
     37 import org.jf.dexlib2.iface.instruction.Instruction;
     38 import org.jf.dexlib2.iface.instruction.formats.*;
     39 import org.jf.dexlib2.util.Preconditions;
     40 import org.jf.util.ImmutableConverter;
     41 
     42 import javax.annotation.Nonnull;
     43 
     44 public abstract class ImmutableInstruction implements Instruction {
     45     @Nonnull protected final Opcode opcode;
     46 
     47     protected ImmutableInstruction(@Nonnull Opcode opcode) {
     48         Preconditions.checkFormat(opcode, getFormat());
     49         this.opcode = opcode;
     50     }
     51 
     52     @Nonnull
     53     public static ImmutableInstruction of(Instruction instruction) {
     54         if (instruction instanceof ImmutableInstruction) {
     55             return (ImmutableInstruction)instruction;
     56         }
     57 
     58         switch (instruction.getOpcode().format) {
     59             case Format10t:
     60                 return ImmutableInstruction10t.of((Instruction10t)instruction);
     61             case Format10x:
     62                 if (instruction instanceof UnknownInstruction) {
     63                     return ImmutableUnknownInstruction.of((UnknownInstruction)instruction);
     64                 }
     65                 return ImmutableInstruction10x.of((Instruction10x)instruction);
     66             case Format11n:
     67                 return ImmutableInstruction11n.of((Instruction11n)instruction);
     68             case Format11x:
     69                 return ImmutableInstruction11x.of((Instruction11x)instruction);
     70             case Format12x:
     71                 return ImmutableInstruction12x.of((Instruction12x)instruction);
     72             case Format20bc:
     73                 return ImmutableInstruction20bc.of((Instruction20bc)instruction);
     74             case Format20t:
     75                 return ImmutableInstruction20t.of((Instruction20t)instruction);
     76             case Format21c:
     77                 return ImmutableInstruction21c.of((Instruction21c)instruction);
     78             case Format21ih:
     79                 return ImmutableInstruction21ih.of((Instruction21ih)instruction);
     80             case Format21lh:
     81                 return ImmutableInstruction21lh.of((Instruction21lh)instruction);
     82             case Format21s:
     83                 return ImmutableInstruction21s.of((Instruction21s)instruction);
     84             case Format21t:
     85                 return ImmutableInstruction21t.of((Instruction21t)instruction);
     86             case Format22b:
     87                 return ImmutableInstruction22b.of((Instruction22b)instruction);
     88             case Format22c:
     89                 return ImmutableInstruction22c.of((Instruction22c)instruction);
     90             case Format22cs:
     91                 return ImmutableInstruction22cs.of((Instruction22cs)instruction);
     92             case Format22s:
     93                 return ImmutableInstruction22s.of((Instruction22s)instruction);
     94             case Format22t:
     95                 return ImmutableInstruction22t.of((Instruction22t)instruction);
     96             case Format22x:
     97                 return ImmutableInstruction22x.of((Instruction22x)instruction);
     98             case Format23x:
     99                 return ImmutableInstruction23x.of((Instruction23x)instruction);
    100             case Format25x:
    101                 return ImmutableInstruction25x.of((Instruction25x) instruction);
    102             case Format30t:
    103                 return ImmutableInstruction30t.of((Instruction30t)instruction);
    104             case Format31c:
    105                 return ImmutableInstruction31c.of((Instruction31c)instruction);
    106             case Format31i:
    107                 return ImmutableInstruction31i.of((Instruction31i)instruction);
    108             case Format31t:
    109                 return ImmutableInstruction31t.of((Instruction31t)instruction);
    110             case Format32x:
    111                 return ImmutableInstruction32x.of((Instruction32x)instruction);
    112             case Format35c:
    113                 return ImmutableInstruction35c.of((Instruction35c)instruction);
    114             case Format35mi:
    115                 return ImmutableInstruction35mi.of((Instruction35mi)instruction);
    116             case Format35ms:
    117                 return ImmutableInstruction35ms.of((Instruction35ms)instruction);
    118             case Format3rc:
    119                 return ImmutableInstruction3rc.of((Instruction3rc)instruction);
    120             case Format3rmi:
    121                 return ImmutableInstruction3rmi.of((Instruction3rmi)instruction);
    122             case Format3rms:
    123                 return ImmutableInstruction3rms.of((Instruction3rms)instruction);
    124             case Format51l:
    125                 return ImmutableInstruction51l.of((Instruction51l)instruction);
    126             case PackedSwitchPayload:
    127                 return ImmutablePackedSwitchPayload.of((PackedSwitchPayload) instruction);
    128             case SparseSwitchPayload:
    129                 return ImmutableSparseSwitchPayload.of((SparseSwitchPayload) instruction);
    130             case ArrayPayload:
    131                 return ImmutableArrayPayload.of((ArrayPayload) instruction);
    132             default:
    133                 throw new RuntimeException("Unexpected instruction type");
    134         }
    135     }
    136 
    137     @Nonnull public Opcode getOpcode() {
    138         return opcode;
    139     }
    140 
    141     public abstract Format getFormat();
    142 
    143     public int getCodeUnits() {
    144         return getFormat().size / 2;
    145     }
    146 
    147     @Nonnull
    148     public static ImmutableList<ImmutableInstruction> immutableListOf(Iterable<? extends Instruction> list) {
    149         return CONVERTER.toList(list);
    150     }
    151 
    152     private static final ImmutableConverter<ImmutableInstruction, Instruction> CONVERTER =
    153             new ImmutableConverter<ImmutableInstruction, Instruction>() {
    154                 @Override
    155                 protected boolean isImmutable(@Nonnull Instruction item) {
    156                     return item instanceof ImmutableInstruction;
    157                 }
    158 
    159                 @Nonnull
    160                 @Override
    161                 protected ImmutableInstruction makeImmutable(@Nonnull Instruction item) {
    162                     return ImmutableInstruction.of(item);
    163                 }
    164             };
    165 }
    166