Java Code Examples for com.android.dx.rop.code.BasicBlock#getSuccessors()
The following examples show how to use
com.android.dx.rop.code.BasicBlock#getSuccessors() .
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: Ropper.java From Box with Apache License 2.0 | 6 votes |
/** * Helper for {@link #addOrReplaceBlock} which recursively removes * the given block and all blocks that are (direct and indirect) * successors of it whose labels indicate that they are not in the * normally-translated range. * * @param idx {@code non-null;} block to remove (etc.) */ private void removeBlockAndSpecialSuccessors(int idx) { int minLabel = getMinimumUnreservedLabel(); BasicBlock block = result.get(idx); IntList successors = block.getSuccessors(); int sz = successors.size(); result.remove(idx); resultSubroutines.remove(idx); for (int i = 0; i < sz; i++) { int label = successors.get(i); if (label >= minLabel) { idx = labelToResultIndex(label); if (idx < 0) { throw new RuntimeException("Invalid label " + Hex.u2(label)); } removeBlockAndSpecialSuccessors(idx); } } }
Example 2
Source File: Ropper.java From buck with Apache License 2.0 | 6 votes |
/** * Helper for {@link #addOrReplaceBlock} which recursively removes * the given block and all blocks that are (direct and indirect) * successors of it whose labels indicate that they are not in the * normally-translated range. * * @param idx {@code non-null;} block to remove (etc.) */ private void removeBlockAndSpecialSuccessors(int idx) { int minLabel = getMinimumUnreservedLabel(); BasicBlock block = result.get(idx); IntList successors = block.getSuccessors(); int sz = successors.size(); result.remove(idx); resultSubroutines.remove(idx); for (int i = 0; i < sz; i++) { int label = successors.get(i); if (label >= minLabel) { idx = labelToResultIndex(label); if (idx < 0) { throw new RuntimeException("Invalid label " + Hex.u2(label)); } removeBlockAndSpecialSuccessors(idx); } } }
Example 3
Source File: Ropper.java From J2ME-Loader with Apache License 2.0 | 6 votes |
/** * Helper for {@link #addOrReplaceBlock} which recursively removes * the given block and all blocks that are (direct and indirect) * successors of it whose labels indicate that they are not in the * normally-translated range. * * @param idx {@code non-null;} block to remove (etc.) */ private void removeBlockAndSpecialSuccessors(int idx) { int minLabel = getMinimumUnreservedLabel(); BasicBlock block = result.get(idx); IntList successors = block.getSuccessors(); int sz = successors.size(); result.remove(idx); resultSubroutines.remove(idx); for (int i = 0; i < sz; i++) { int label = successors.get(i); if (label >= minLabel) { idx = labelToResultIndex(label); if (idx < 0) { throw new RuntimeException("Invalid label " + Hex.u2(label)); } removeBlockAndSpecialSuccessors(idx); } } }
Example 4
Source File: Ropper.java From Box with Apache License 2.0 | 6 votes |
/** * Helper for {@link #addOrReplaceBlock} which recursively removes * the given block and all blocks that are (direct and indirect) * successors of it whose labels indicate that they are not in the * normally-translated range. * * @param idx {@code non-null;} block to remove (etc.) */ private void removeBlockAndSpecialSuccessors(int idx) { int minLabel = getMinimumUnreservedLabel(); BasicBlock block = result.get(idx); IntList successors = block.getSuccessors(); int sz = successors.size(); result.remove(idx); resultSubroutines.remove(idx); for (int i = 0; i < sz; i++) { int label = successors.get(i); if (label >= minLabel) { idx = labelToResultIndex(label); if (idx < 0) { throw new RuntimeException("Invalid label " + Hex.u2(label)); } removeBlockAndSpecialSuccessors(idx); } } }
Example 5
Source File: Ropper.java From buck with Apache License 2.0 | 5 votes |
/** * Visits each block once in depth-first successor order, ignoring * {@code jsr} targets. Worker for {@link #forEachNonSubBlockDepthFirst}. * * @param next next block to visit * @param v callback interface * @param visited set of blocks already visited */ private void forEachNonSubBlockDepthFirst0( BasicBlock next, BasicBlock.Visitor v, BitSet visited) { v.visitBlock(next); visited.set(next.getLabel()); IntList successors = next.getSuccessors(); int sz = successors.size(); for (int i = 0; i < sz; i++) { int succ = successors.get(i); if (visited.get(succ)) { continue; } if (isSubroutineCaller(next) && i > 0) { // ignore jsr targets continue; } /* * Ignore missing labels: they're successors of * subroutines that never invoke a ret. */ int idx = labelToResultIndex(succ); if (idx >= 0) { forEachNonSubBlockDepthFirst0(result.get(idx), v, visited); } } }
Example 6
Source File: Ropper.java From buck with Apache License 2.0 | 5 votes |
/** * Checks to see if the basic block is a subroutine caller block. * * @param bb {@code non-null;} the basic block in question * @return true if this block calls a subroutine */ private boolean isSubroutineCaller(BasicBlock bb) { IntList successors = bb.getSuccessors(); if (successors.size() < 2) return false; int subLabel = successors.get(1); return (subLabel < subroutines.length) && (subroutines[subLabel] != null); }
Example 7
Source File: Ropper.java From J2ME-Loader with Apache License 2.0 | 5 votes |
/** * Visits each block once in depth-first successor order, ignoring * {@code jsr} targets. Worker for {@link #forEachNonSubBlockDepthFirst}. * * @param next next block to visit * @param v callback interface * @param visited set of blocks already visited */ private void forEachNonSubBlockDepthFirst0( BasicBlock next, BasicBlock.Visitor v, BitSet visited) { v.visitBlock(next); visited.set(next.getLabel()); IntList successors = next.getSuccessors(); int sz = successors.size(); for (int i = 0; i < sz; i++) { int succ = successors.get(i); if (visited.get(succ)) { continue; } if (isSubroutineCaller(next) && i > 0) { // ignore jsr targets continue; } /* * Ignore missing labels: they're successors of * subroutines that never invoke a ret. */ int idx = labelToResultIndex(succ); if (idx >= 0) { forEachNonSubBlockDepthFirst0(result.get(idx), v, visited); } } }
Example 8
Source File: Ropper.java From J2ME-Loader with Apache License 2.0 | 5 votes |
/** * Checks to see if the basic block is a subroutine caller block. * * @param bb {@code non-null;} the basic block in question * @return true if this block calls a subroutine */ private boolean isSubroutineCaller(BasicBlock bb) { IntList successors = bb.getSuccessors(); if (successors.size() < 2) return false; int subLabel = successors.get(1); return (subLabel < subroutines.length) && (subroutines[subLabel] != null); }
Example 9
Source File: Ropper.java From Box with Apache License 2.0 | 5 votes |
/** * Visits each block once in depth-first successor order, ignoring * {@code jsr} targets. Worker for {@link #forEachNonSubBlockDepthFirst}. * * @param next next block to visit * @param v callback interface * @param visited set of blocks already visited */ private void forEachNonSubBlockDepthFirst0( BasicBlock next, BasicBlock.Visitor v, BitSet visited) { v.visitBlock(next); visited.set(next.getLabel()); IntList successors = next.getSuccessors(); int sz = successors.size(); for (int i = 0; i < sz; i++) { int succ = successors.get(i); if (visited.get(succ)) { continue; } if (isSubroutineCaller(next) && i > 0) { // ignore jsr targets continue; } /* * Ignore missing labels: they're successors of * subroutines that never invoke a ret. */ int idx = labelToResultIndex(succ); if (idx >= 0) { forEachNonSubBlockDepthFirst0(result.get(idx), v, visited); } } }
Example 10
Source File: Ropper.java From Box with Apache License 2.0 | 5 votes |
/** * Checks to see if the basic block is a subroutine caller block. * * @param bb {@code non-null;} the basic block in question * @return true if this block calls a subroutine */ private boolean isSubroutineCaller(BasicBlock bb) { IntList successors = bb.getSuccessors(); if (successors.size() < 2) return false; int subLabel = successors.get(1); return (subLabel < subroutines.length) && (subroutines[subLabel] != null); }
Example 11
Source File: Ropper.java From Box with Apache License 2.0 | 5 votes |
/** * Visits each block once in depth-first successor order, ignoring * {@code jsr} targets. Worker for {@link #forEachNonSubBlockDepthFirst}. * * @param next next block to visit * @param v callback interface * @param visited set of blocks already visited */ private void forEachNonSubBlockDepthFirst0( BasicBlock next, BasicBlock.Visitor v, BitSet visited) { v.visitBlock(next); visited.set(next.getLabel()); IntList successors = next.getSuccessors(); int sz = successors.size(); for (int i = 0; i < sz; i++) { int succ = successors.get(i); if (visited.get(succ)) { continue; } if (isSubroutineCaller(next) && i > 0) { // ignore jsr targets continue; } /* * Ignore missing labels: they're successors of * subroutines that never invoke a ret. */ int idx = labelToResultIndex(succ); if (idx >= 0) { forEachNonSubBlockDepthFirst0(result.get(idx), v, visited); } } }
Example 12
Source File: BlockDumper.java From Box with Apache License 2.0 | 4 votes |
/** * Does a registerizing dump. * * @param meth {@code non-null;} method data to dump */ private void ropDump(ConcreteMethod meth) { TranslationAdvice advice = DexTranslationAdvice.THE_ONE; BytecodeArray code = meth.getCode(); ByteArray bytes = code.getBytes(); RopMethod rmeth = Ropper.convert(meth, advice, classFile.getMethods(), dexOptions); StringBuilder sb = new StringBuilder(2000); if (optimize) { boolean isStatic = AccessFlags.isStatic(meth.getAccessFlags()); int paramWidth = computeParamWidth(meth, isStatic); rmeth = Optimizer.optimize(rmeth, paramWidth, isStatic, true, advice); } BasicBlockList blocks = rmeth.getBlocks(); int[] order = blocks.getLabelsInOrder(); sb.append("first " + Hex.u2(rmeth.getFirstLabel()) + "\n"); for (int label : order) { BasicBlock bb = blocks.get(blocks.indexOfLabel(label)); sb.append("block "); sb.append(Hex.u2(label)); sb.append("\n"); IntList preds = rmeth.labelToPredecessors(label); int psz = preds.size(); for (int i = 0; i < psz; i++) { sb.append(" pred "); sb.append(Hex.u2(preds.get(i))); sb.append("\n"); } InsnList il = bb.getInsns(); int ilsz = il.size(); for (int i = 0; i < ilsz; i++) { Insn one = il.get(i); sb.append(" "); sb.append(il.get(i).toHuman()); sb.append("\n"); } IntList successors = bb.getSuccessors(); int ssz = successors.size(); if (ssz == 0) { sb.append(" returns\n"); } else { int primary = bb.getPrimarySuccessor(); for (int i = 0; i < ssz; i++) { int succ = successors.get(i); sb.append(" next "); sb.append(Hex.u2(succ)); if ((ssz != 1) && (succ == primary)) { sb.append(" *"); } sb.append("\n"); } } } suppressDump = false; parsed(bytes, 0, bytes.size(), sb.toString()); suppressDump = true; }
Example 13
Source File: DotDumper.java From Box with Apache License 2.0 | 4 votes |
@Override public void endParsingMember(ByteArray bytes, int offset, String name, String descriptor, Member member) { if (!(member instanceof Method)) { return; } if (!shouldDumpMethod(name)) { return; } ConcreteMethod meth = new ConcreteMethod((Method) member, classFile, true, true); TranslationAdvice advice = DexTranslationAdvice.THE_ONE; RopMethod rmeth = Ropper.convert(meth, advice, classFile.getMethods(), dexOptions); if (optimize) { boolean isStatic = AccessFlags.isStatic(meth.getAccessFlags()); rmeth = Optimizer.optimize(rmeth, BaseDumper.computeParamWidth(meth, isStatic), isStatic, true, advice); } System.out.println("digraph " + name + "{"); System.out.println("\tfirst -> n" + Hex.u2(rmeth.getFirstLabel()) + ";"); BasicBlockList blocks = rmeth.getBlocks(); int sz = blocks.size(); for (int i = 0; i < sz; i++) { BasicBlock bb = blocks.get(i); int label = bb.getLabel(); IntList successors = bb.getSuccessors(); if (successors.size() == 0) { System.out.println("\tn" + Hex.u2(label) + " -> returns;"); } else if (successors.size() == 1) { System.out.println("\tn" + Hex.u2(label) + " -> n" + Hex.u2(successors.get(0)) + ";"); } else { System.out.print("\tn" + Hex.u2(label) + " -> {"); for (int j = 0; j < successors.size(); j++ ) { int successor = successors.get(j); if (successor != bb.getPrimarySuccessor()) { System.out.print(" n" + Hex.u2(successor) + " "); } } System.out.println("};"); System.out.println("\tn" + Hex.u2(label) + " -> n" + Hex.u2(bb.getPrimarySuccessor()) + " [label=\"primary\"];"); } } System.out.println("}"); }
Example 14
Source File: StdCatchBuilder.java From J2ME-Loader with Apache License 2.0 | 4 votes |
/** * Makes the {@link CatchHandlerList} for the given basic block. * * @param block {@code non-null;} block to get entries for * @param addresses {@code non-null;} address objects for each block * @return {@code non-null;} array of entries */ private static CatchHandlerList handlersFor(BasicBlock block, BlockAddresses addresses) { IntList successors = block.getSuccessors(); int succSize = successors.size(); int primary = block.getPrimarySuccessor(); TypeList catches = block.getLastInsn().getCatches(); int catchSize = catches.size(); if (catchSize == 0) { return CatchHandlerList.EMPTY; } if (((primary == -1) && (succSize != catchSize)) || ((primary != -1) && ((succSize != (catchSize + 1)) || (primary != successors.get(catchSize))))) { /* * Blocks that throw are supposed to list their primary * successor -- if any -- last in the successors list, but * that constraint appears to be violated here. */ throw new RuntimeException( "shouldn't happen: weird successors list"); } /* * Reduce the effective catchSize if we spot a catch-all that * isn't at the end. */ for (int i = 0; i < catchSize; i++) { Type type = catches.getType(i); if (type.equals(Type.OBJECT)) { catchSize = i + 1; break; } } CatchHandlerList result = new CatchHandlerList(catchSize); for (int i = 0; i < catchSize; i++) { CstType oneType = new CstType(catches.getType(i)); CodeAddress oneHandler = addresses.getStart(successors.get(i)); result.set(i, oneType, oneHandler.getAddress()); } result.setImmutable(); return result; }
Example 15
Source File: StdCatchBuilder.java From Box with Apache License 2.0 | 4 votes |
/** * Makes the {@link CatchHandlerList} for the given basic block. * * @param block {@code non-null;} block to get entries for * @param addresses {@code non-null;} address objects for each block * @return {@code non-null;} array of entries */ private static CatchHandlerList handlersFor(BasicBlock block, BlockAddresses addresses) { IntList successors = block.getSuccessors(); int succSize = successors.size(); int primary = block.getPrimarySuccessor(); TypeList catches = block.getLastInsn().getCatches(); int catchSize = catches.size(); if (catchSize == 0) { return CatchHandlerList.EMPTY; } if (((primary == -1) && (succSize != catchSize)) || ((primary != -1) && ((succSize != (catchSize + 1)) || (primary != successors.get(catchSize))))) { /* * Blocks that throw are supposed to list their primary * successor -- if any -- last in the successors list, but * that constraint appears to be violated here. */ throw new RuntimeException( "shouldn't happen: weird successors list"); } /* * Reduce the effective catchSize if we spot a catch-all that * isn't at the end. */ for (int i = 0; i < catchSize; i++) { Type type = catches.getType(i); if (type.equals(Type.OBJECT)) { catchSize = i + 1; break; } } CatchHandlerList result = new CatchHandlerList(catchSize); for (int i = 0; i < catchSize; i++) { CstType oneType = new CstType(catches.getType(i)); CodeAddress oneHandler = addresses.getStart(successors.get(i)); result.set(i, oneType, oneHandler.getAddress()); } result.setImmutable(); return result; }
Example 16
Source File: DotDumper.java From Box with Apache License 2.0 | 4 votes |
@Override public void endParsingMember(ByteArray bytes, int offset, String name, String descriptor, Member member) { if (!(member instanceof Method)) { return; } if (!shouldDumpMethod(name)) { return; } ConcreteMethod meth = new ConcreteMethod((Method) member, classFile, true, true); TranslationAdvice advice = DexTranslationAdvice.THE_ONE; RopMethod rmeth = Ropper.convert(meth, advice, classFile.getMethods(), dexOptions); if (optimize) { boolean isStatic = AccessFlags.isStatic(meth.getAccessFlags()); rmeth = Optimizer.optimize(rmeth, BaseDumper.computeParamWidth(meth, isStatic), isStatic, true, advice); } System.out.println("digraph " + name + "{"); System.out.println("\tfirst -> n" + Hex.u2(rmeth.getFirstLabel()) + ";"); BasicBlockList blocks = rmeth.getBlocks(); int sz = blocks.size(); for (int i = 0; i < sz; i++) { BasicBlock bb = blocks.get(i); int label = bb.getLabel(); IntList successors = bb.getSuccessors(); if (successors.size() == 0) { System.out.println("\tn" + Hex.u2(label) + " -> returns;"); } else if (successors.size() == 1) { System.out.println("\tn" + Hex.u2(label) + " -> n" + Hex.u2(successors.get(0)) + ";"); } else { System.out.print("\tn" + Hex.u2(label) + " -> {"); for (int j = 0; j < successors.size(); j++ ) { int successor = successors.get(j); if (successor != bb.getPrimarySuccessor()) { System.out.print(" n" + Hex.u2(successor) + " "); } } System.out.println("};"); System.out.println("\tn" + Hex.u2(label) + " -> n" + Hex.u2(bb.getPrimarySuccessor()) + " [label=\"primary\"];"); } } System.out.println("}"); }
Example 17
Source File: BlockDumper.java From Box with Apache License 2.0 | 4 votes |
/** * Does a registerizing dump. * * @param meth {@code non-null;} method data to dump */ private void ropDump(ConcreteMethod meth) { TranslationAdvice advice = DexTranslationAdvice.THE_ONE; BytecodeArray code = meth.getCode(); ByteArray bytes = code.getBytes(); RopMethod rmeth = Ropper.convert(meth, advice, classFile.getMethods(), dexOptions); StringBuilder sb = new StringBuilder(2000); if (optimize) { boolean isStatic = AccessFlags.isStatic(meth.getAccessFlags()); int paramWidth = computeParamWidth(meth, isStatic); rmeth = Optimizer.optimize(rmeth, paramWidth, isStatic, true, advice); } BasicBlockList blocks = rmeth.getBlocks(); int[] order = blocks.getLabelsInOrder(); sb.append("first " + Hex.u2(rmeth.getFirstLabel()) + "\n"); for (int label : order) { BasicBlock bb = blocks.get(blocks.indexOfLabel(label)); sb.append("block "); sb.append(Hex.u2(label)); sb.append("\n"); IntList preds = rmeth.labelToPredecessors(label); int psz = preds.size(); for (int i = 0; i < psz; i++) { sb.append(" pred "); sb.append(Hex.u2(preds.get(i))); sb.append("\n"); } InsnList il = bb.getInsns(); int ilsz = il.size(); for (int i = 0; i < ilsz; i++) { Insn one = il.get(i); sb.append(" "); sb.append(il.get(i).toHuman()); sb.append("\n"); } IntList successors = bb.getSuccessors(); int ssz = successors.size(); if (ssz == 0) { sb.append(" returns\n"); } else { int primary = bb.getPrimarySuccessor(); for (int i = 0; i < ssz; i++) { int succ = successors.get(i); sb.append(" next "); sb.append(Hex.u2(succ)); if ((ssz != 1) && (succ == primary)) { sb.append(" *"); } sb.append("\n"); } } } suppressDump = false; parsed(bytes, 0, bytes.size(), sb.toString()); suppressDump = true; }
Example 18
Source File: BlockDumper.java From buck with Apache License 2.0 | 4 votes |
/** * Does a registerizing dump. * * @param meth {@code non-null;} method data to dump */ private void ropDump(ConcreteMethod meth) { TranslationAdvice advice = DexTranslationAdvice.THE_ONE; BytecodeArray code = meth.getCode(); ByteArray bytes = code.getBytes(); RopMethod rmeth = Ropper.convert(meth, advice, classFile.getMethods()); StringBuffer sb = new StringBuffer(2000); if (optimize) { boolean isStatic = AccessFlags.isStatic(meth.getAccessFlags()); int paramWidth = computeParamWidth(meth, isStatic); rmeth = Optimizer.optimize(rmeth, paramWidth, isStatic, true, advice); } BasicBlockList blocks = rmeth.getBlocks(); int[] order = blocks.getLabelsInOrder(); sb.append("first " + Hex.u2(rmeth.getFirstLabel()) + "\n"); for (int label : order) { BasicBlock bb = blocks.get(blocks.indexOfLabel(label)); sb.append("block "); sb.append(Hex.u2(label)); sb.append("\n"); IntList preds = rmeth.labelToPredecessors(label); int psz = preds.size(); for (int i = 0; i < psz; i++) { sb.append(" pred "); sb.append(Hex.u2(preds.get(i))); sb.append("\n"); } InsnList il = bb.getInsns(); int ilsz = il.size(); for (int i = 0; i < ilsz; i++) { Insn one = il.get(i); sb.append(" "); sb.append(il.get(i).toHuman()); sb.append("\n"); } IntList successors = bb.getSuccessors(); int ssz = successors.size(); if (ssz == 0) { sb.append(" returns\n"); } else { int primary = bb.getPrimarySuccessor(); for (int i = 0; i < ssz; i++) { int succ = successors.get(i); sb.append(" next "); sb.append(Hex.u2(succ)); if ((ssz != 1) && (succ == primary)) { sb.append(" *"); } sb.append("\n"); } } } suppressDump = false; setAt(bytes, 0); parsed(bytes, 0, bytes.size(), sb.toString()); suppressDump = true; }
Example 19
Source File: DotDumper.java From buck with Apache License 2.0 | 4 votes |
public void endParsingMember(ByteArray bytes, int offset, String name, String descriptor, Member member) { if (!(member instanceof Method)) { return; } if (!shouldDumpMethod(name)) { return; } ConcreteMethod meth = new ConcreteMethod((Method) member, classFile, true, true); TranslationAdvice advice = DexTranslationAdvice.THE_ONE; RopMethod rmeth = Ropper.convert(meth, advice, classFile.getMethods()); if (optimize) { boolean isStatic = AccessFlags.isStatic(meth.getAccessFlags()); rmeth = Optimizer.optimize(rmeth, BaseDumper.computeParamWidth(meth, isStatic), isStatic, true, advice); } System.out.println("digraph " + name + "{"); System.out.println("\tfirst -> n" + Hex.u2(rmeth.getFirstLabel()) + ";"); BasicBlockList blocks = rmeth.getBlocks(); int sz = blocks.size(); for (int i = 0; i < sz; i++) { BasicBlock bb = blocks.get(i); int label = bb.getLabel(); IntList successors = bb.getSuccessors(); if (successors.size() == 0) { System.out.println("\tn" + Hex.u2(label) + " -> returns;"); } else if (successors.size() == 1) { System.out.println("\tn" + Hex.u2(label) + " -> n" + Hex.u2(successors.get(0)) + ";"); } else { System.out.print("\tn" + Hex.u2(label) + " -> {"); for (int j = 0; j < successors.size(); j++ ) { int successor = successors.get(j); if (successor != bb.getPrimarySuccessor()) { System.out.print(" n" + Hex.u2(successor) + " "); } } System.out.println("};"); System.out.println("\tn" + Hex.u2(label) + " -> n" + Hex.u2(bb.getPrimarySuccessor()) + " [label=\"primary\"];"); } } System.out.println("}"); }
Example 20
Source File: StdCatchBuilder.java From Box with Apache License 2.0 | 4 votes |
/** * Makes the {@link CatchHandlerList} for the given basic block. * * @param block {@code non-null;} block to get entries for * @param addresses {@code non-null;} address objects for each block * @return {@code non-null;} array of entries */ private static CatchHandlerList handlersFor(BasicBlock block, BlockAddresses addresses) { IntList successors = block.getSuccessors(); int succSize = successors.size(); int primary = block.getPrimarySuccessor(); TypeList catches = block.getLastInsn().getCatches(); int catchSize = catches.size(); if (catchSize == 0) { return CatchHandlerList.EMPTY; } if (((primary == -1) && (succSize != catchSize)) || ((primary != -1) && ((succSize != (catchSize + 1)) || (primary != successors.get(catchSize))))) { /* * Blocks that throw are supposed to list their primary * successor -- if any -- last in the successors list, but * that constraint appears to be violated here. */ throw new RuntimeException( "shouldn't happen: weird successors list"); } /* * Reduce the effective catchSize if we spot a catch-all that * isn't at the end. */ for (int i = 0; i < catchSize; i++) { Type type = catches.getType(i); if (type.equals(Type.OBJECT)) { catchSize = i + 1; break; } } CatchHandlerList result = new CatchHandlerList(catchSize); for (int i = 0; i < catchSize; i++) { CstType oneType = new CstType(catches.getType(i)); CodeAddress oneHandler = addresses.getStart(successors.get(i)); result.set(i, oneType, oneHandler.getAddress()); } result.setImmutable(); return result; }