1b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/* 2b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ProGuard -- shrinking, optimization, obfuscation, and preverification 3b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * of Java bytecode. 4b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 5b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu) 6b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 7b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is free software; you can redistribute it and/or modify it 8b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * under the terms of the GNU General Public License as published by the Free 9b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Software Foundation; either version 2 of the License, or (at your option) 10b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * any later version. 11b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 12b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is distributed in the hope that it will be useful, but WITHOUT 13b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * more details. 16b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 17b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * You should have received a copy of the GNU General Public License along 18b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * with this program; if not, write to the Free Software Foundation, Inc., 19b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 21b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopackage proguard.classfile.attribute; 22b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 23b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.*; 24b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.attribute.visitor.*; 25b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 26b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/** 27b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This Attribute represents a line number table attribute. 28b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 29b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @author Eric Lafortune 30b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 31b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopublic class LineNumberTableAttribute extends Attribute 32b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato{ 33b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public int u2lineNumberTableLength; 34b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public LineNumberInfo[] lineNumberTable; 35b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 36b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 37b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 38b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Creates an uninitialized LineNumberTableAttribute. 39b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 40b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public LineNumberTableAttribute() 41b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 42b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 43b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 44b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 45b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 46b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Creates an initialized LineNumberTableAttribute. 47b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 48b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public LineNumberTableAttribute(int u2attributeNameIndex, 49b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato int u2lineNumberTableLength, 50b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato LineNumberInfo[] lineNumberTable) 51b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 52b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato super(u2attributeNameIndex); 53b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 54b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.u2lineNumberTableLength = u2lineNumberTableLength; 55b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.lineNumberTable = lineNumberTable; 56b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 57b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 58b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 59b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 60b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Returns the line number corresponding to the given byte code program 61b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * counter. 62b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 63b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public int getLineNumber(int pc) 64b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 65b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato for (int index = u2lineNumberTableLength-1 ; index >= 0 ; index--) 66b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 67b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato LineNumberInfo info = lineNumberTable[index]; 68b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (pc >= info.u2startPC) 69b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 70b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return info.u2lineNumber; 71b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 72b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 73b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 74b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return u2lineNumberTableLength > 0 ? 75b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato lineNumberTable[0].u2lineNumber : 76b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 0; 77b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 78b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 79b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 80b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang /** 81b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * Returns the lowest line number, or 0 if there aren't any line numbers. 82b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang */ 83b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang public int getLowestLineNumber() 84b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang { 85b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang if (u2lineNumberTableLength == 0) 86b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang { 87b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang return 0; 88b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang } 89b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 90b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang int lowestLineNumber = Integer.MAX_VALUE; 91b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 92b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang for (int index = 0; index < u2lineNumberTableLength; index++) 93b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang { 94b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang int lineNumber = lineNumberTable[index].u2lineNumber; 95b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang if (lineNumber < lowestLineNumber) 96b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang { 97b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang lowestLineNumber = lineNumber; 98b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang } 99b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang } 100b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 101b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang return lowestLineNumber; 102b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang } 103b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 104b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 105b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang /** 106b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * Returns the highest line number, or 0 if there aren't any line numbers. 107b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang */ 108b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang public int getHighestLineNumber() 109b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang { 110b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang if (u2lineNumberTableLength == 0) 111b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang { 112b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang return 0; 113b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang } 114b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 115b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang int highestLineNumber = Integer.MIN_VALUE; 116b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 117b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang for (int index = 0; index < u2lineNumberTableLength; index++) 118b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang { 119b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang int lineNumber = lineNumberTable[index].u2lineNumber; 120b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang if (lineNumber > highestLineNumber) 121b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang { 122b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang highestLineNumber = lineNumber; 123b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang } 124b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang } 125b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 126b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang return highestLineNumber; 127b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang } 128b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 129b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang 130b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Implementations for Attribute. 131b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 132b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, AttributeVisitor attributeVisitor) 133b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 134b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato attributeVisitor.visitLineNumberTableAttribute(clazz, method, codeAttribute, this); 135b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 136b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 137b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 138b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 139b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Applies the given visitor to all line numbers. 140b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 141b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void lineNumbersAccept(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberInfoVisitor lineNumberInfoVisitor) 142b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 143b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato for (int index = 0; index < u2lineNumberTableLength; index++) 144b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 145b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // We don't need double dispatching here, since there is only one 146b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // type of LineNumberInfo. 147b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato lineNumberInfoVisitor.visitLineNumberInfo(clazz, method, codeAttribute, lineNumberTable[index]); 148b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 149b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 150b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato} 151