< prev index next >

src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumberTable.java

Print this page


   1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * Licensed to the Apache Software Foundation (ASF) under one or more
   7  * contributor license agreements.  See the NOTICE file distributed with
   8  * this work for additional information regarding copyright ownership.
   9  * The ASF licenses this file to You under the Apache License, Version 2.0
  10  * (the "License"); you may not use this file except in compliance with
  11  * the License.  You may obtain a copy of the License at
  12  *
  13  *      http://www.apache.org/licenses/LICENSE-2.0
  14  *
  15  * Unless required by applicable law or agreed to in writing, software
  16  * distributed under the License is distributed on an "AS IS" BASIS,
  17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18  * See the License for the specific language governing permissions and
  19  * limitations under the License.
  20  */
  21 
  22 package com.sun.org.apache.bcel.internal.classfile;
  23 
  24 
  25 import  com.sun.org.apache.bcel.internal.Constants;
  26 import  java.io.*;


  27 
  28 /**
  29  * This class represents a table of line numbers for debugging
  30  * purposes. This attribute is used by the <em>Code</em> attribute. It
  31  * contains pairs of PCs and line numbers.
  32  *
  33  * @author  <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  34  * @see     Code
  35  * @see LineNumber
  36  */
  37 public final class LineNumberTable extends Attribute {
  38   private int          line_number_table_length;

  39   private LineNumber[] line_number_table; // Table of line/numbers pairs
  40 

  41   /*
  42    * Initialize from another object. Note that both objects use the same
  43    * references (shallow copy). Use copy() for a physical copy.
  44    */
  45   public LineNumberTable(LineNumberTable c) {
  46     this(c.getNameIndex(), c.getLength(), c.getLineNumberTable(),
  47          c.getConstantPool());
  48   }
  49 

  50   /*
  51    * @param name_index Index of name
  52    * @param length Content length in bytes
  53    * @param line_number_table Table of line/numbers pairs
  54    * @param constant_pool Array of constants
  55    */
  56   public LineNumberTable(int name_index, int length,
  57                          LineNumber[] line_number_table,
  58                          ConstantPool constant_pool)
  59   {
  60     super(Constants.ATTR_LINE_NUMBER_TABLE, name_index, length, constant_pool);
  61     setLineNumberTable(line_number_table);
  62   }
  63 
  64   /**
  65    * Construct object from file stream.

  66    * @param name_index Index of name
  67    * @param length Content length in bytes
  68    * @param file Input stream
  69    * @throws IOException
  70    * @param constant_pool Array of constants

  71    */
  72   LineNumberTable(int name_index, int length, DataInputStream file,
  73                   ConstantPool constant_pool) throws IOException
  74   {
  75     this(name_index, length, (LineNumber[])null, constant_pool);
  76     line_number_table_length = (file.readUnsignedShort());
  77     line_number_table = new LineNumber[line_number_table_length];
  78 
  79     for(int i=0; i < line_number_table_length; i++)
  80       line_number_table[i] = new LineNumber(file);
  81   }

  82   /**
  83    * Called by objects that are traversing the nodes of the tree implicitely
  84    * defined by the contents of a Java class. I.e., the hierarchy of methods,
  85    * fields, attributes, etc. spawns a tree of objects.
  86    *
  87    * @param v Visitor object
  88    */
  89   public void accept(Visitor v) {

  90     v.visitLineNumberTable(this);
  91   }

  92   /**
  93    * Dump line number table attribute to file stream in binary format.
  94    *
  95    * @param file Output file stream
  96    * @throws IOException
  97    */
  98   public final void dump(DataOutputStream file) throws IOException
  99   {
 100     super.dump(file);
 101     file.writeShort(line_number_table_length);
 102     for(int i=0; i < line_number_table_length; i++)
 103       line_number_table[i].dump(file);

 104   }
 105 
 106   /**
 107    * @return Array of (pc offset, line number) pairs.
 108    */
 109   public final LineNumber[] getLineNumberTable() { return line_number_table; }


 110 
 111   /**
 112    * @param line_number_table.
 113    */
 114   public final void setLineNumberTable(LineNumber[] line_number_table) {
 115     this.line_number_table = line_number_table;
 116 
 117     line_number_table_length = (line_number_table == null)? 0 :
 118       line_number_table.length;
 119   }
 120 
 121   /**
 122    * @return String representation.
 123    */

 124   public final String toString() {
 125     StringBuffer buf  = new StringBuffer();
 126     StringBuffer line = new StringBuffer();
 127 
 128     for(int i=0; i < line_number_table_length; i++) {
 129       line.append(line_number_table[i].toString());
 130 
 131       if(i < line_number_table_length - 1)
 132         line.append(", ");
 133 
 134       if(line.length() > 72) {
 135         line.append('\n');
 136         buf.append(line);
 137         line.setLength(0);
 138       }
 139     }
 140 
 141     buf.append(line);
 142 
 143     return buf.toString();
 144   }
 145 
 146   /**
 147    * Map byte code positions to source code lines.
 148    *
 149    * @param pos byte code offset
 150    * @return corresponding line in source code
 151    */
 152   public int getSourceLine(int pos) {
 153     int l = 0, r = line_number_table_length-1;
 154 
 155     if(r < 0) // array is empty
 156       return -1;
 157 
 158     int min_index = -1, min=-1;
 159 
 160     /* Do a binary search since the array is ordered.
 161      */
 162     do {
 163       int i = (l + r) / 2;
 164       int j = line_number_table[i].getStartPC();
 165 
 166       if(j == pos)
 167         return line_number_table[i].getLineNumber();
 168       else if(pos < j) // else constrain search area
 169         r = i - 1;
 170       else // pos > j
 171         l = i + 1;
 172 
 173       /* If exact match can't be found (which is the most common case)
 174        * return the line number that corresponds to the greatest index less
 175        * than pos.
 176        */
 177       if(j < pos && j > min) {
 178         min       = j;
 179         min_index = i;
 180       }
 181     } while(l <= r);
 182 
 183     /* It's possible that we did not find any valid entry for the bytecode
 184      * offset we were looking for.
 185      */
 186     if (min_index < 0)
 187       return -1;
 188 
 189     return line_number_table[min_index].getLineNumber();
 190   }
 191 
 192   /**
 193    * @return deep copy of this attribute
 194    */
 195   public Attribute copy(ConstantPool constant_pool) {
 196     LineNumberTable c = (LineNumberTable)clone();
 197 
 198     c.line_number_table = new LineNumber[line_number_table_length];
 199     for(int i=0; i < line_number_table_length; i++)


 200       c.line_number_table[i] = line_number_table[i].copy();
 201 
 202     c.constant_pool = constant_pool;
 203     return c;
 204   }
 205 
 206   public final int getTableLength() { return line_number_table_length; }


 207 }
   1 /*
   2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.

   3  */
   4 /*
   5  * Licensed to the Apache Software Foundation (ASF) under one or more
   6  * contributor license agreements.  See the NOTICE file distributed with
   7  * this work for additional information regarding copyright ownership.
   8  * The ASF licenses this file to You under the Apache License, Version 2.0
   9  * (the "License"); you may not use this file except in compliance with
  10  * the License.  You may obtain a copy of the License at
  11  *
  12  *      http://www.apache.org/licenses/LICENSE-2.0
  13  *
  14  * Unless required by applicable law or agreed to in writing, software
  15  * distributed under the License is distributed on an "AS IS" BASIS,
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17  * See the License for the specific language governing permissions and
  18  * limitations under the License.
  19  */

  20 package com.sun.org.apache.bcel.internal.classfile;
  21 
  22 import com.sun.org.apache.bcel.internal.Const;
  23 import java.io.DataInput;
  24 import java.io.DataOutputStream;
  25 import java.io.IOException;
  26 import jdk.xml.internal.SecuritySupport;
  27 
  28 /**
  29  * This class represents a table of line numbers for debugging purposes. This
  30  * attribute is used by the <em>Code</em> attribute. It contains pairs of PCs
  31  * and line numbers.
  32  *
  33  * @version $Id: LineNumberTable.java 1749603 2016-06-21 20:50:19Z ggregory $
  34  * @see Code
  35  * @see LineNumber
  36  */
  37 public final class LineNumberTable extends Attribute {
  38 
  39     private static final int MAX_LINE_LENGTH = 72;
  40     private LineNumber[] line_number_table; // Table of line/numbers pairs
  41 
  42 
  43     /*
  44      * Initialize from another object. Note that both objects use the same
  45      * references (shallow copy). Use copy() for a physical copy.
  46      */
  47     public LineNumberTable(final LineNumberTable c) {
  48         this(c.getNameIndex(), c.getLength(), c.getLineNumberTable(), c.getConstantPool());

  49     }
  50 
  51 
  52     /*
  53      * @param name_index Index of name
  54      * @param length Content length in bytes
  55      * @param line_number_table Table of line/numbers pairs
  56      * @param constant_pool Array of constants
  57      */
  58     public LineNumberTable(final int name_index, final int length, final LineNumber[] line_number_table,
  59             final ConstantPool constant_pool) {
  60         super(Const.ATTR_LINE_NUMBER_TABLE, name_index, length, constant_pool);
  61         this.line_number_table = line_number_table;


  62     }
  63 
  64     /**
  65      * Construct object from input stream.
  66      *
  67      * @param name_index Index of name
  68      * @param length Content length in bytes
  69      * @param input Input stream

  70      * @param constant_pool Array of constants
  71      * @throws IOEXception if an I/O Exception occurs in readUnsignedShort
  72      */
  73     LineNumberTable(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool)
  74             throws IOException {
  75         this(name_index, length, (LineNumber[]) null, constant_pool);
  76         final int line_number_table_length = input.readUnsignedShort();

  77         line_number_table = new LineNumber[line_number_table_length];
  78         for (int i = 0; i < line_number_table_length; i++) {
  79             line_number_table[i] = new LineNumber(input);
  80         }
  81     }
  82 
  83     /**
  84      * Called by objects that are traversing the nodes of the tree implicitely
  85      * defined by the contents of a Java class. I.e., the hierarchy of methods,
  86      * fields, attributes, etc. spawns a tree of objects.
  87      *
  88      * @param v Visitor object
  89      */
  90     @Override
  91     public void accept(final Visitor v) {
  92         v.visitLineNumberTable(this);
  93     }
  94 
  95     /**
  96      * Dump line number table attribute to file stream in binary format.
  97      *
  98      * @param file Output file stream
  99      * @throws IOEXception if an I/O Exception occurs in writeShort
 100      */
 101     @Override
 102     public final void dump(final DataOutputStream file) throws IOException {
 103         super.dump(file);
 104         file.writeShort(line_number_table.length);
 105         for (final LineNumber lineNumber : line_number_table) {
 106             lineNumber.dump(file);
 107         }
 108     }
 109 
 110     /**
 111      * @return Array of (pc offset, line number) pairs.
 112      */
 113     public final LineNumber[] getLineNumberTable() {
 114         return line_number_table;
 115     }
 116 
 117     /**
 118      * @param line_number_table the line number entries for this table
 119      */
 120     public final void setLineNumberTable(final LineNumber[] line_number_table) {
 121         this.line_number_table = line_number_table;



 122     }
 123 
 124     /**
 125      * @return String representation.
 126      */
 127     @Override
 128     public final String toString() {
 129         final StringBuilder buf = new StringBuilder();
 130         final StringBuilder line = new StringBuilder();
 131 
 132         for (int i = 0; i < line_number_table.length; i++) {
 133             line.append(line_number_table[i].toString());
 134             if (i < line_number_table.length - 1) {

 135                 line.append(", ");
 136             }
 137             if ((line.length() > MAX_LINE_LENGTH) && (i < line_number_table.length - 1)) {
 138                 line.append(SecuritySupport.NEWLINE);
 139                 buf.append(line);
 140                 line.setLength(0);
 141             }
 142         }

 143         buf.append(line);

 144         return buf.toString();
 145     }
 146 
 147     /**
 148      * Map byte code positions to source code lines.
 149      *
 150      * @param pos byte code offset
 151      * @return corresponding line in source code
 152      */
 153     public int getSourceLine(final int pos) {
 154         int l = 0;
 155         int r = line_number_table.length - 1;
 156         if (r < 0) {
 157             return -1;
 158         }
 159         int min_index = -1;
 160         int min = -1;
 161         /* Do a binary search since the array is ordered.
 162          */
 163         do {
 164             final int i = (l + r) / 2;
 165             final int j = line_number_table[i].getStartPC();
 166             if (j == pos) {

 167                 return line_number_table[i].getLineNumber();
 168             } else if (pos < j) {
 169                 r = i - 1;
 170             } else {
 171                 l = i + 1;
 172             }
 173             /* If exact match can't be found (which is the most common case)
 174              * return the line number that corresponds to the greatest index less
 175              * than pos.
 176              */
 177             if (j < pos && j > min) {
 178                 min = j;
 179                 min_index = i;
 180             }
 181         } while (l <= r);

 182         /* It's possible that we did not find any valid entry for the bytecode
 183          * offset we were looking for.
 184          */
 185         if (min_index < 0) {
 186             return -1;
 187         }
 188         return line_number_table[min_index].getLineNumber();
 189     }
 190 
 191     /**
 192      * @return deep copy of this attribute
 193      */
 194     @Override
 195     public Attribute copy(final ConstantPool _constant_pool) {
 196         // TODO could use the lower level constructor and thereby allow
 197         // line_number_table to be made final
 198         final LineNumberTable c = (LineNumberTable) clone();
 199         c.line_number_table = new LineNumber[line_number_table.length];
 200         for (int i = 0; i < line_number_table.length; i++) {
 201             c.line_number_table[i] = line_number_table[i].copy();
 202         }
 203         c.setConstantPool(_constant_pool);
 204         return c;
 205     }
 206 
 207     public final int getTableLength() {
 208         return line_number_table == null ? 0 : line_number_table.length;
 209     }
 210 }
< prev index next >