1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.dx.rop.code; 18 19 import com.android.dx.util.FixedSizeList; 20 21 /** 22 * List of {@link Insn} instances. 23 */ 24 public final class InsnList 25 extends FixedSizeList { 26 /** 27 * Constructs an instance. All indices initially contain {@code null}. 28 * 29 * @param size the size of the list 30 */ InsnList(int size)31 public InsnList(int size) { 32 super(size); 33 } 34 35 /** 36 * Gets the element at the given index. It is an error to call 37 * this with the index for an element which was never set; if you 38 * do that, this will throw {@code NullPointerException}. 39 * 40 * @param n {@code >= 0, < size();} which index 41 * @return {@code non-null;} element at that index 42 */ get(int n)43 public Insn get(int n) { 44 return (Insn) get0(n); 45 } 46 47 /** 48 * Sets the instruction at the given index. 49 * 50 * @param n {@code >= 0, < size();} which index 51 * @param insn {@code non-null;} the instruction to set at {@code n} 52 */ set(int n, Insn insn)53 public void set(int n, Insn insn) { 54 set0(n, insn); 55 } 56 57 /** 58 * Gets the last instruction. This is just a convenient shorthand for 59 * {@code get(size() - 1)}. 60 * 61 * @return {@code non-null;} the last instruction 62 */ getLast()63 public Insn getLast() { 64 return get(size() - 1); 65 } 66 67 /** 68 * Visits each instruction in the list, in order. 69 * 70 * @param visitor {@code non-null;} visitor to use 71 */ forEach(Insn.Visitor visitor)72 public void forEach(Insn.Visitor visitor) { 73 int sz = size(); 74 75 for (int i = 0; i < sz; i++) { 76 get(i).accept(visitor); 77 } 78 } 79 80 /** 81 * Compares the contents of this {@code InsnList} with another. 82 * The blocks must have the same number of insns, and each Insn must 83 * also return true to {@code Insn.contentEquals()}. 84 * 85 * @param b to compare 86 * @return true in the case described above. 87 */ contentEquals(InsnList b)88 public boolean contentEquals(InsnList b) { 89 if (b == null) return false; 90 91 int sz = size(); 92 93 if (sz != b.size()) return false; 94 95 for (int i = 0; i < sz; i++) { 96 if (!get(i).contentEquals(b.get(i))) { 97 return false; 98 } 99 } 100 101 return true; 102 } 103 104 /** 105 * Returns an instance that is identical to this one, except that 106 * the registers in each instruction are offset by the given 107 * amount. Mutability of the result is inherited from the 108 * original. 109 * 110 * @param delta the amount to offset register numbers by 111 * @return {@code non-null;} an appropriately-constructed instance 112 */ withRegisterOffset(int delta)113 public InsnList withRegisterOffset(int delta) { 114 int sz = size(); 115 InsnList result = new InsnList(sz); 116 117 for (int i = 0; i < sz; i++) { 118 Insn one = (Insn) get0(i); 119 if (one != null) { 120 result.set0(i, one.withRegisterOffset(delta)); 121 } 122 } 123 124 if (isImmutable()) { 125 result.setImmutable(); 126 } 127 128 return result; 129 } 130 } 131