1 /*
2  * Copyright (C) 2007 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.android.dexgen.rop;
18 
19 import com.android.dexgen.util.Hex;
20 import com.android.dexgen.util.IntList;
21 import com.android.dexgen.util.LabeledItem;
22 
23 /**
24  * Representation of a basic block in a bytecode array.
25  */
26 public final class ByteBlock implements LabeledItem {
27     /** {@code >= 0;} label for this block */
28     private final int label;
29 
30     /** {@code >= 0;} bytecode offset (inclusive) of the start of the block */
31     private final int start;
32 
33     /** {@code > start;} bytecode offset (exclusive) of the end of the block */
34     private final int end;
35 
36     /** {@code non-null;} list of successors that this block may branch to */
37     private final IntList successors;
38 
39     /** {@code non-null;} list of exceptions caught and their handler targets */
40     private final ByteCatchList catches;
41 
42     /**
43      * Constructs an instance.
44      *
45      * @param label {@code >= 0;} target label for this block
46      * @param start {@code >= 0;} bytecode offset (inclusive) of the start
47      * of the block
48      * @param end {@code > start;} bytecode offset (exclusive) of the end
49      * of the block
50      * @param successors {@code non-null;} list of successors that this block may
51      * branch to
52      * @param catches {@code non-null;} list of exceptions caught and their
53      * handler targets
54      */
ByteBlock(int label, int start, int end, IntList successors, ByteCatchList catches)55     public ByteBlock(int label, int start, int end, IntList successors,
56                      ByteCatchList catches) {
57         if (label < 0) {
58             throw new IllegalArgumentException("label < 0");
59         }
60 
61         if (start < 0) {
62             throw new IllegalArgumentException("start < 0");
63         }
64 
65         if (end <= start) {
66             throw new IllegalArgumentException("end <= start");
67         }
68 
69         if (successors == null) {
70             throw new NullPointerException("targets == null");
71         }
72 
73         int sz = successors.size();
74         for (int i = 0; i < sz; i++) {
75             if (successors.get(i) < 0) {
76                 throw new IllegalArgumentException("successors[" + i +
77                                                    "] == " +
78                                                    successors.get(i));
79             }
80         }
81 
82         if (catches == null) {
83             throw new NullPointerException("catches == null");
84         }
85 
86         this.label = label;
87         this.start = start;
88         this.end = end;
89         this.successors = successors;
90         this.catches = catches;
91     }
92 
93     /** {@inheritDoc} */
94     @Override
toString()95     public String toString() {
96         return '{' + Hex.u2(label) + ": " + Hex.u2(start) + ".." +
97             Hex.u2(end) + '}';
98     }
99 
100     /**
101      * Gets the label of this block.
102      *
103      * @return {@code >= 0;} the label
104      */
getLabel()105     public int getLabel() {
106         return label;
107     }
108 
109     /**
110      * Gets the bytecode offset (inclusive) of the start of this block.
111      *
112      * @return {@code >= 0;} the start offset
113      */
getStart()114     public int getStart() {
115         return start;
116     }
117 
118     /**
119      * Gets the bytecode offset (exclusive) of the end of this block.
120      *
121      * @return {@code > getStart();} the end offset
122      */
getEnd()123     public int getEnd() {
124         return end;
125     }
126 
127     /**
128      * Gets the list of successors that this block may branch to
129      * non-exceptionally.
130      *
131      * @return {@code non-null;} the successor list
132      */
getSuccessors()133     public IntList getSuccessors() {
134         return successors;
135     }
136 
137     /**
138      * Gets the list of exceptions caught and their handler targets.
139      *
140      * @return {@code non-null;} the catch list
141      */
getCatches()142     public ByteCatchList getCatches() {
143         return catches;
144     }
145 }
146