• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Javassist, a Java-bytecode translator toolkit.
3  * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved.
4  *
5  * The contents of this file are subject to the Mozilla Public License Version
6  * 1.1 (the "License"); you may not use this file except in compliance with
7  * the License.  Alternatively, the contents of this file may be used under
8  * the terms of the GNU Lesser General Public License Version 2.1 or later.
9  *
10  * Software distributed under the License is distributed on an "AS IS" basis,
11  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12  * for the specific language governing rights and limitations under the
13  * License.
14  */
15 
16 package javassist.bytecode;
17 
18 import java.io.DataInputStream;
19 import java.io.IOException;
20 import java.util.Map;
21 
22 /**
23  * <code>LineNumberTable_attribute</code>.
24  */
25 public class LineNumberAttribute extends AttributeInfo {
26     /**
27      * The name of this attribute <code>"LineNumberTable"</code>.
28      */
29     public static final String tag = "LineNumberTable";
30 
LineNumberAttribute(ConstPool cp, int n, DataInputStream in)31     LineNumberAttribute(ConstPool cp, int n, DataInputStream in)
32         throws IOException
33     {
34         super(cp, n, in);
35     }
36 
LineNumberAttribute(ConstPool cp, byte[] i)37     private LineNumberAttribute(ConstPool cp, byte[] i) {
38         super(cp, tag, i);
39     }
40 
41     /**
42      * Returns <code>line_number_table_length</code>.
43      * This represents the number of entries in the table.
44      */
tableLength()45     public int tableLength() {
46         return ByteArray.readU16bit(info, 0);
47     }
48 
49     /**
50      * Returns <code>line_number_table[i].start_pc</code>.
51      * This represents the index into the code array at which the code
52      * for a new line in the original source file begins.
53      *
54      * @param i         the i-th entry.
55      */
startPc(int i)56     public int startPc(int i) {
57         return ByteArray.readU16bit(info, i * 4 + 2);
58     }
59 
60     /**
61      * Returns <code>line_number_table[i].line_number</code>.
62      * This represents the corresponding line number in the original
63      * source file.
64      *
65      * @param i         the i-th entry.
66      */
lineNumber(int i)67     public int lineNumber(int i) {
68         return ByteArray.readU16bit(info, i * 4 + 4);
69     }
70 
71     /**
72      * Returns the line number corresponding to the specified bytecode.
73      *
74      * @param pc        the index into the code array.
75      */
toLineNumber(int pc)76     public int toLineNumber(int pc) {
77         int n = tableLength();
78         int i = 0;
79         for (; i < n; ++i)
80             if (pc < startPc(i))
81                 if (i == 0)
82                     return lineNumber(0);
83                 else
84                     break;
85 
86         return lineNumber(i - 1);
87     }
88 
89     /**
90      * Returns the index into the code array at which the code for
91      * the specified line begins.
92      *
93      * @param line      the line number.
94      * @return          -1 if the specified line is not found.
95      */
toStartPc(int line)96     public int toStartPc(int line) {
97         int n = tableLength();
98         for (int i = 0; i < n; ++i)
99             if (line == lineNumber(i))
100                 return startPc(i);
101 
102         return -1;
103     }
104 
105     /**
106      * Used as a return type of <code>toNearPc()</code>.
107      */
108     static public class Pc {
109         /**
110          * The index into the code array.
111          */
112         public int index;
113         /**
114          * The line number.
115          */
116         public int line;
117     }
118 
119     /**
120      * Returns the index into the code array at which the code for
121      * the specified line (or the nearest line after the specified one)
122      * begins.
123      *
124      * @param line      the line number.
125      * @return          a pair of the index and the line number of the
126      *                  bytecode at that index.
127      */
toNearPc(int line)128     public Pc toNearPc(int line) {
129         int n = tableLength();
130         int nearPc = 0;
131         int distance = 0;
132         if (n > 0) {
133             distance = lineNumber(0) - line;
134             nearPc = startPc(0);
135         }
136 
137         for (int i = 1; i < n; ++i) {
138             int d = lineNumber(i) - line;
139             if ((d < 0 && d > distance)
140                 || (d >= 0 && (d < distance || distance < 0))) {
141                     distance = d;
142                     nearPc = startPc(i);
143             }
144         }
145 
146         Pc res = new Pc();
147         res.index = nearPc;
148         res.line = line + distance;
149         return res;
150     }
151 
152     /**
153      * Makes a copy.
154      *
155      * @param newCp     the constant pool table used by the new copy.
156      * @param classnames        should be null.
157      */
copy(ConstPool newCp, Map classnames)158     public AttributeInfo copy(ConstPool newCp, Map classnames) {
159         byte[] src = info;
160         int num = src.length;
161         byte[] dest = new byte[num];
162         for (int i = 0; i < num; ++i)
163             dest[i] = src[i];
164 
165         LineNumberAttribute attr = new LineNumberAttribute(newCp, dest);
166         return attr;
167     }
168 
169     /**
170      * Adjusts start_pc if bytecode is inserted in a method body.
171      */
shiftPc(int where, int gapLength, boolean exclusive)172     void shiftPc(int where, int gapLength, boolean exclusive) {
173         int n = tableLength();
174         for (int i = 0; i < n; ++i) {
175             int pos = i * 4 + 2;
176             int pc = ByteArray.readU16bit(info, pos);
177             if (pc > where || (exclusive && pc == where))
178                 ByteArray.write16bit(pc + gapLength, info, pos);
179         }
180     }
181 }
182