1579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/* 2579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Copyright (C) 2007 The Android Open Source Project 3579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 4579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License"); 5579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * you may not use this file except in compliance with the License. 6579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * You may obtain a copy of the License at 7579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 8579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 9579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 10579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Unless required by applicable law or agreed to in writing, software 11579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 12579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * See the License for the specific language governing permissions and 14579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * limitations under the License. 15579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 16579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 17579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpackage com.android.dx.rop.code; 18579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 19579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.util.FixedSizeList; 20579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 21579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/** 22579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * List of {@link Insn} instances. 23579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 24579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpublic final class InsnList 25579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson extends FixedSizeList { 26579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 27579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Constructs an instance. All indices initially contain {@code null}. 28579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 29579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param size the size of the list 30579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 31579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public InsnList(int size) { 32579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson super(size); 33579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 34579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 35579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 36579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the element at the given index. It is an error to call 37579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * this with the index for an element which was never set; if you 38579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * do that, this will throw {@code NullPointerException}. 39579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 40579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param n {@code >= 0, < size();} which index 41579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} element at that index 42579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 43579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Insn get(int n) { 44579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return (Insn) get0(n); 45579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 46579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 47579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 48579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Sets the instruction at the given index. 49579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 50579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param n {@code >= 0, < size();} which index 51579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param insn {@code non-null;} the instruction to set at {@code n} 52579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 53579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void set(int n, Insn insn) { 54579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson set0(n, insn); 55579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 56579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 57579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 58579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the last instruction. This is just a convenient shorthand for 59579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code get(size() - 1)}. 60579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 61579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} the last instruction 62579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 63579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Insn getLast() { 64579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return get(size() - 1); 65579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 66579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 67579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 68579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Visits each instruction in the list, in order. 69579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 70579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param visitor {@code non-null;} visitor to use 71579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 72579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void forEach(Insn.Visitor visitor) { 73579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int sz = size(); 74579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 75579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (int i = 0; i < sz; i++) { 76579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson get(i).accept(visitor); 77579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 78579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 79579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 80579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 81579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Compares the contents of this {@code InsnList} with another. 82579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * The blocks must have the same number of insns, and each Insn must 83579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * also return true to {@code Insn.contentEquals()}. 84579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 85579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param b to compare 86579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return true in the case described above. 87579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 88579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public boolean contentEquals(InsnList b) { 89579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (b == null) return false; 90579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 91579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int sz = size(); 92579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 93579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (sz != b.size()) return false; 94579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 95579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (int i = 0; i < sz; i++) { 96579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (!get(i).contentEquals(b.get(i))) { 97579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return false; 98579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 99579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 100579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 101579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return true; 102579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 103579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 104579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 105579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Returns an instance that is identical to this one, except that 106579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * the registers in each instruction are offset by the given 107579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * amount. Mutability of the result is inherited from the 108579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * original. 109579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 110579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param delta the amount to offset register numbers by 111579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} an appropriately-constructed instance 112579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 113579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public InsnList withRegisterOffset(int delta) { 114579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int sz = size(); 115579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson InsnList result = new InsnList(sz); 116579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 117579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (int i = 0; i < sz; i++) { 118579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Insn one = (Insn) get0(i); 119579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (one != null) { 120579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.set0(i, one.withRegisterOffset(delta)); 121579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 122579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 123579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 124579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (isImmutable()) { 125579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result.setImmutable(); 126579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 127579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 128579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return result; 129579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 130579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson} 131