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.rop.type.TypeList; 20579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.util.Hex; 21579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.util.IntList; 22579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.util.LabeledItem; 23579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 24579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/** 25579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Basic block of register-based instructions. 26579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 27579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpublic final class BasicBlock implements LabeledItem { 28579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code >= 0;} target label for this block */ 29579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private final int label; 30579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 31579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} list of instructions in this block */ 32579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private final InsnList insns; 33579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 34579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 35579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code non-null;} full list of successors that this block may 36579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * branch to 37579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 38579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private final IntList successors; 39579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 40579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 41579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code >= -1;} the primary / standard-flow / "default" successor, or 42579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code -1} if this block has no successors (that is, it 43579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * exits the function/method) 44579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 45579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private final int primarySuccessor; 46579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 47579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 48579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Constructs an instance. The predecessor set is set to {@code null}. 49579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 50579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param label {@code >= 0;} target label for this block 51579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param insns {@code non-null;} list of instructions in this block 52579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param successors {@code non-null;} full list of successors that this 53579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * block may branch to 54579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param primarySuccessor {@code >= -1;} the primary / standard-flow / 55579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * "default" successor, or {@code -1} if this block has no 56579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * successors (that is, it exits the function/method or is an 57579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * unconditional throw) 58579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 59579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public BasicBlock(int label, InsnList insns, IntList successors, 60579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int primarySuccessor) { 61579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (label < 0) { 62579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IllegalArgumentException("label < 0"); 63579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 64579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 65579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson try { 66579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson insns.throwIfMutable(); 67579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } catch (NullPointerException ex) { 68579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // Elucidate exception. 69579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new NullPointerException("insns == null"); 70579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 71579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 72579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int sz = insns.size(); 73579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 74579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (sz == 0) { 75579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IllegalArgumentException("insns.size() == 0"); 76579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 77579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 78579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (int i = sz - 2; i >= 0; i--) { 79579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Rop one = insns.get(i).getOpcode(); 80579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (one.getBranchingness() != Rop.BRANCH_NONE) { 81579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IllegalArgumentException("insns[" + i + "] is a " + 82579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson "branch or can throw"); 83579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 84579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 85579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 86579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Insn lastInsn = insns.get(sz - 1); 87579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (lastInsn.getOpcode().getBranchingness() == Rop.BRANCH_NONE) { 88579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IllegalArgumentException("insns does not end with " + 89579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson "a branch or throwing " + 90579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson "instruction"); 91579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 92579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 93579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson try { 94579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson successors.throwIfMutable(); 95579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } catch (NullPointerException ex) { 96579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // Elucidate exception. 97579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new NullPointerException("successors == null"); 98579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 99579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 100579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (primarySuccessor < -1) { 101579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IllegalArgumentException("primarySuccessor < -1"); 102579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 103579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 104579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (primarySuccessor >= 0 && !successors.contains(primarySuccessor)) { 105579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IllegalArgumentException( 106579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson "primarySuccessor " + primarySuccessor + " not in successors " + successors); 107579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 108579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 109579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.label = label; 110579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.insns = insns; 111579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.successors = successors; 112579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.primarySuccessor = primarySuccessor; 113579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 114579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 115579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 116579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@inheritDoc} 117579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 118579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Instances of this class compare by identity. That is, 119579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code x.equals(y)} is only true if {@code x == y}. 120579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 121579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 122579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public boolean equals(Object other) { 123579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return (this == other); 124579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 125579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 126579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 127579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@inheritDoc} 128579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 129579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Return the identity hashcode of this instance. This is proper, 130579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * since instances of this class compare by identity (see {@link #equals}). 131579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 132579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 133579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public int hashCode() { 134579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return System.identityHashCode(this); 135579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 136579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 137579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 138579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the target label of this block. 139579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 140579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code >= 0;} the label 141579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 142579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public int getLabel() { 143579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return label; 144579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 145579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 146579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 147579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the list of instructions inside this block. 148579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 149579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} the instruction list 150579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 151579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public InsnList getInsns() { 152579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return insns; 153579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 154579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 155579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 156579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the list of successors that this block may branch to. 157579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 158579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} the successors list 159579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 160579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public IntList getSuccessors() { 161579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return successors; 162579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 163579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 164579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 165579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the primary successor of this block. 166579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 167579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code >= -1;} the primary successor, or {@code -1} if this 168579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * block has no successors at all 169579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 170579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public int getPrimarySuccessor() { 171579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return primarySuccessor; 172579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 173579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 174579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 175579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the secondary successor of this block. It is only valid to call 176579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * this method on blocks that have exactly two successors. 177579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 178579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code >= 0;} the secondary successor 179579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 180579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public int getSecondarySuccessor() { 181579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (successors.size() != 2) { 182579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new UnsupportedOperationException( 183579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson "block doesn't have exactly two successors"); 184579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 185579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 186579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int succ = successors.get(0); 187579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (succ == primarySuccessor) { 188579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson succ = successors.get(1); 189579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 190579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 191579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return succ; 192579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 193579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 194579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 195579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the first instruction of this block. This is just a 196579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * convenient shorthand for {@code getInsns().get(0)}. 197579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 198579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} the first instruction 199579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 200579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Insn getFirstInsn() { 201579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return insns.get(0); 202579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 203579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 204579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 205579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the last instruction of this block. This is just a 206579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * convenient shorthand for {@code getInsns().getLast()}. 207579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 208579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} the last instruction 209579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 210579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Insn getLastInsn() { 211579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return insns.getLast(); 212579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 213579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 214579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 215579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Returns whether this block might throw an exception. This is 216579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * just a convenient shorthand for {@code getLastInsn().canThrow()}. 217579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 218579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code true} iff this block might throw an 219579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * exception 220579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 221579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public boolean canThrow() { 222579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return insns.getLast().canThrow(); 223579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 224579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 225579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 226579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Returns whether this block has any associated exception handlers. 227579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * This is just a shorthand for inspecting the last instruction in 228579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * the block to see if it could throw, and if so, whether it in fact 229579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * has any associated handlers. 230579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 231579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code true} iff this block has any associated 232579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * exception handlers 233579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 234579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public boolean hasExceptionHandlers() { 235579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Insn lastInsn = insns.getLast(); 236579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return lastInsn.getCatches().size() != 0; 237579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 238579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 239579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 240579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Returns the exception handler types associated with this block, 241579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * if any. This is just a shorthand for inspecting the last 242579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * instruction in the block to see if it could throw, and if so, 243579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * grabbing the catch list out of it. If not, this returns an 244579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * empty list (not {@code null}). 245579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 246579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} the exception handler types associated with 247579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * this block 248579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 249579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public TypeList getExceptionHandlerTypes() { 250579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Insn lastInsn = insns.getLast(); 251579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return lastInsn.getCatches(); 252579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 253579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 254579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 255579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Returns an instance that is identical to this one, except that 256579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * the registers in each instruction are offset by the given 257579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * amount. 258579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 259579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param delta the amount to offset register numbers by 260579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} an appropriately-constructed instance 261579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 262579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public BasicBlock withRegisterOffset(int delta) { 263579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return new BasicBlock(label, insns.withRegisterOffset(delta), 264579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson successors, primarySuccessor); 265579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 266579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 267579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public String toString() { 268579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return '{' + Hex.u2(label) + '}'; 269579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 270579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 271579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 272579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * BasicBlock visitor interface 273579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 274579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public interface Visitor { 275579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 276579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Visits a basic block 277579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param b block visited 278579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 279579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void visitBlock (BasicBlock b); 280579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 281579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson} 282