1917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/* 2917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Copyright (C) 2007 The Android Open Source Project 3917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 4917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Licensed under the Apache License, Version 2.0 (the "License"); 5917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * you may not use this file except in compliance with the License. 6917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * You may obtain a copy of the License at 7917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 8917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * http://www.apache.org/licenses/LICENSE-2.0 9917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 10917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Unless required by applicable law or agreed to in writing, software 11917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * distributed under the License is distributed on an "AS IS" BASIS, 12917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * See the License for the specific language governing permissions and 14917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * limitations under the License. 15917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 16917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 17917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpackage com.android.dexgen.rop.code; 18917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 19917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.util.FixedSizeList; 20917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 21917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/** 22917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * List of {@link Insn} instances. 23917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 24917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpublic final class InsnList 25917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul extends FixedSizeList { 26917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 27917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Constructs an instance. All indices initially contain {@code null}. 28917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 29917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param size the size of the list 30917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 31917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public InsnList(int size) { 32917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul super(size); 33917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 34917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 35917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 36917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the element at the given index. It is an error to call 37917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * this with the index for an element which was never set; if you 38917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * do that, this will throw {@code NullPointerException}. 39917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 40917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param n {@code >= 0, < size();} which index 41917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} element at that index 42917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 43917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public Insn get(int n) { 44917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return (Insn) get0(n); 45917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 46917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 47917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 48917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Sets the instruction at the given index. 49917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 50917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param n {@code >= 0, < size();} which index 51917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param insn {@code non-null;} the instruction to set at {@code n} 52917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 53917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public void set(int n, Insn insn) { 54917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul set0(n, insn); 55917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 56917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 57917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 58917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the last instruction. This is just a convenient shorthand for 59917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code get(size() - 1)}. 60917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 61917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the last instruction 62917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 63917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public Insn getLast() { 64917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return get(size() - 1); 65917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 66917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 67917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 68917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Visits each instruction in the list, in order. 69917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 70917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param visitor {@code non-null;} visitor to use 71917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 72917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public void forEach(Insn.Visitor visitor) { 73917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int sz = size(); 74917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 75917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul for (int i = 0; i < sz; i++) { 76917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul get(i).accept(visitor); 77917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 78917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 79917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 80917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 81917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Compares the contents of this {@code InsnList} with another. 82917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * The blocks must have the same number of insns, and each Insn must 83917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * also return true to {@code Insn.contentEquals()}. 84917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 85917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param b to compare 86917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return true in the case described above. 87917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 88917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public boolean contentEquals(InsnList b) { 89917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (b == null) return false; 90917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 91917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int sz = size(); 92917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 93917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (sz != b.size()) return false; 94917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 95917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul for (int i = 0; i < sz; i++) { 96917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (!get(i).contentEquals(b.get(i))) { 97917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return false; 98917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 99917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 100917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 101917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return true; 102917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 103917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 104917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 105917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Returns an instance that is identical to this one, except that 106917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * the registers in each instruction are offset by the given 107917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * amount. Mutability of the result is inherited from the 108917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * original. 109917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 110917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param delta the amount to offset register numbers by 111917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} an appropriately-constructed instance 112917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 113917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public InsnList withRegisterOffset(int delta) { 114917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int sz = size(); 115917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul InsnList result = new InsnList(sz); 116917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 117917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul for (int i = 0; i < sz; i++) { 118917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul Insn one = (Insn) get0(i); 119917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (one != null) { 120917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul result.set0(i, one.withRegisterOffset(delta)); 121917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 122917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 123917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 124917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (isImmutable()) { 125917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul result.setImmutable(); 126917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 127917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 128917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return result; 129917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 130917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul} 131