1 /* 2 * Copyright (C) 2011 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.google.dexmaker; 18 19 import com.android.dx.rop.code.BasicBlock; 20 import com.android.dx.rop.code.Insn; 21 import com.android.dx.rop.code.InsnList; 22 import com.android.dx.util.IntList; 23 import java.util.ArrayList; 24 import java.util.Collections; 25 import java.util.List; 26 27 /** 28 * A branch target in a list of instructions. 29 */ 30 public final class Label { 31 32 final List<Insn> instructions = new ArrayList<Insn>(); 33 34 Code code; 35 36 boolean marked = false; 37 38 /** an immutable list of labels corresponding to the types in the catch list */ 39 List<Label> catchLabels = Collections.emptyList(); 40 41 /** contains the next instruction if no branch occurs */ 42 Label primarySuccessor; 43 44 /** contains the instruction to jump to if the if is true */ 45 Label alternateSuccessor; 46 47 int id = -1; 48 49 public Label() {} 50 51 boolean isEmpty() { 52 return instructions.isEmpty(); 53 } 54 55 void compact() { 56 for (int i = 0; i < catchLabels.size(); i++) { 57 while (catchLabels.get(i).isEmpty()) { 58 catchLabels.set(i, catchLabels.get(i).primarySuccessor); 59 } 60 } 61 while (primarySuccessor != null && primarySuccessor.isEmpty()) { 62 primarySuccessor = primarySuccessor.primarySuccessor; 63 } 64 while (alternateSuccessor != null && alternateSuccessor.isEmpty()) { 65 alternateSuccessor = alternateSuccessor.primarySuccessor; 66 } 67 } 68 69 BasicBlock toBasicBlock() { 70 InsnList result = new InsnList(instructions.size()); 71 for (int i = 0; i < instructions.size(); i++) { 72 result.set(i, instructions.get(i)); 73 } 74 result.setImmutable(); 75 76 int primarySuccessorIndex = -1; 77 IntList successors = new IntList(); 78 for (Label catchLabel : catchLabels) { 79 successors.add(catchLabel.id); 80 } 81 if (primarySuccessor != null) { 82 primarySuccessorIndex = primarySuccessor.id; 83 successors.add(primarySuccessorIndex); 84 } 85 if (alternateSuccessor != null) { 86 successors.add(alternateSuccessor.id); 87 } 88 successors.setImmutable(); 89 90 return new BasicBlock(id, result, successors, primarySuccessorIndex); 91 } 92 } 93