001: // Copyright (c) 1997 Per M.A. Bothner.
002: // This is free software; for terms and warranty disclaimer see ./COPYING.
003:
004: package gnu.bytecode;
005:
006: import java.io.*;
007:
008: /**
009: * Represents the contents of a standard "LineNumberTable" attribute.
010: * @author Per Bothner
011: */
012:
013: public class LineNumbersAttr extends Attribute {
014: // The line number table. Each even entry (starting with index 0) is a PC,
015: // and the following odd entry is the linenumber. Each number is
016: // actually unsigned, so should be masked with 0xFFFF.
017: short[] linenumber_table;
018: // The number of linenumber (pairs) in linenumber_table.
019: int linenumber_count;
020:
021: /** Add a new LineNumbersAttr to a CodeAttr. */
022: public LineNumbersAttr(CodeAttr code) {
023: super ("LineNumberTable");
024: addToFrontOf(code);
025: code.lines = this ;
026: }
027:
028: public LineNumbersAttr(short[] numbers, CodeAttr code) {
029: this (code);
030: linenumber_table = numbers;
031: linenumber_count = numbers.length >> 1;
032: }
033:
034: /** Add a new line number entry.
035: * @param file the source file for this entry
036: * @param linenumber the number in the source file for this entry
037: * @param PC the byte code location for the code for this line number. */
038: void put(String file, int linenumber, int PC) {
039: Method method = ((CodeAttr) container).getMethod();
040: linenumber = method.classfile.getSourceMap().translate(file,
041: linenumber);
042: put(linenumber, PC);
043: }
044:
045: /** Add a new line number entry.
046: * @param linenumber the number in the source file for this entry
047: * @param PC the byte code location for the code for this line number.
048: * The line number is supposed to have already been translated by a source
049: * map.
050: */
051: public void put(int linenumber, int PC) {
052: if (linenumber_table == null)
053: linenumber_table = new short[32];
054: else if (2 * linenumber_count >= linenumber_table.length) {
055: short[] new_linenumbers = new short[2 * linenumber_table.length];
056: System.arraycopy(linenumber_table, 0, new_linenumbers, 0,
057: 2 * linenumber_count);
058: linenumber_table = new_linenumbers;
059: }
060: linenumber_table[2 * linenumber_count] = (short) PC;
061: linenumber_table[2 * linenumber_count + 1] = (short) linenumber;
062: linenumber_count++;
063: }
064:
065: /** Get the number of line number entries. */
066: public final int getLength() {
067: return 2 + 4 * linenumber_count;
068: }
069:
070: public int getLineCount() {
071: return linenumber_count;
072: }
073:
074: public short[] getLineNumberTable() {
075: return linenumber_table;
076: }
077:
078: public void write(DataOutputStream dstr) throws java.io.IOException {
079: dstr.writeShort(linenumber_count);
080: int count = 2 * linenumber_count;
081: for (int i = 0; i < count; i++) {
082: dstr.writeShort(linenumber_table[i]);
083: }
084: }
085:
086: public void print(ClassTypeWriter dst) {
087: dst.print("Attribute \"");
088: dst.print(getName());
089: dst.print("\", length:");
090: dst.print(getLength());
091: dst.print(", count: ");
092: dst.println(linenumber_count);
093: for (int i = 0; i < linenumber_count; i++) {
094: dst.print(" line: ");
095: dst.print(linenumber_table[2 * i + 1] & 0xFFFF); // line number
096: dst.print(" at pc: ");
097: dst.println(linenumber_table[2 * i] & 0xFFFF); // start_pc
098: }
099: }
100: }
|