Label.java revision 23abc2fe89ec3713645d64bdb74415a9090084f4
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
17package com.google.dexmaker;
18
19import com.android.dx.rop.code.BasicBlock;
20import com.android.dx.rop.code.Insn;
21import com.android.dx.rop.code.InsnList;
22import com.android.dx.util.IntList;
23import java.util.ArrayList;
24import java.util.Collections;
25import java.util.List;
26
27/**
28 * A branch target in a list of instructions.
29 */
30public 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