src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java
changeset 55496 8e0ae3830fca
parent 47216 71c04702a3d5
equal deleted inserted replaced
55495:badfa812b82a 55496:8e0ae3830fca
    23 import com.sun.org.apache.bcel.internal.Const;
    23 import com.sun.org.apache.bcel.internal.Const;
    24 import com.sun.org.apache.bcel.internal.classfile.LocalVariable;
    24 import com.sun.org.apache.bcel.internal.classfile.LocalVariable;
    25 
    25 
    26 /**
    26 /**
    27  * This class represents a local variable within a method. It contains its
    27  * This class represents a local variable within a method. It contains its
    28  * scope, name and type. The generated LocalVariable object can be obtained with
    28  * scope, name and type. The generated LocalVariable object can be obtained
    29  * getLocalVariable which needs the instruction list and the constant pool as
    29  * with getLocalVariable which needs the instruction list and the constant
    30  * parameters.
    30  * pool as parameters.
    31  *
    31  *
    32  * @version $Id: LocalVariableGen.java 1749603 2016-06-21 20:50:19Z ggregory $
    32  * @version $Id$
    33  * @see LocalVariable
    33  * @see     LocalVariable
    34  * @see MethodGen
    34  * @see     MethodGen
    35  */
    35  */
    36 public class LocalVariableGen implements InstructionTargeter, NamedAndTyped, Cloneable {
    36 public class LocalVariableGen implements InstructionTargeter, NamedAndTyped, Cloneable {
    37 
    37 
    38     private int index;
    38     private int index;
    39     private String name;
    39     private String name;
    40     private Type type;
    40     private Type type;
    41     private InstructionHandle start;
    41     private InstructionHandle start;
    42     private InstructionHandle end;
    42     private InstructionHandle end;
    43 
    43     private int orig_index; // never changes; used to match up with LocalVariableTypeTable entries
    44     /**
    44     private boolean live_to_end;
    45      * Generate a local variable that with index `index'. Note that double and
    45 
    46      * long variables need two indexs. Index indices have to be provided by the
    46 
    47      * user.
    47     /**
       
    48      * Generate a local variable that with index `index'. Note that double and long
       
    49      * variables need two indexs. Index indices have to be provided by the user.
    48      *
    50      *
    49      * @param index index of local variable
    51      * @param index index of local variable
    50      * @param name its name
    52      * @param name its name
    51      * @param type its type
    53      * @param type its type
    52      * @param start from where the instruction is valid (null means from the
    54      * @param start from where the instruction is valid (null means from the start)
    53      * start)
       
    54      * @param end until where the instruction is valid (null means to the end)
    55      * @param end until where the instruction is valid (null means to the end)
    55      */
    56      */
    56     public LocalVariableGen(final int index, final String name, final Type type,
    57     public LocalVariableGen(final int index, final String name, final Type type, final InstructionHandle start,
    57             final InstructionHandle start, final InstructionHandle end) {
    58             final InstructionHandle end) {
    58         if ((index < 0) || (index > Const.MAX_SHORT)) {
    59         if ((index < 0) || (index > Const.MAX_SHORT)) {
    59             throw new ClassGenException("Invalid index index: " + index);
    60             throw new ClassGenException("Invalid index index: " + index);
    60         }
    61         }
    61         this.name = name;
    62         this.name = name;
    62         this.type = type;
    63         this.type = type;
    63         this.index = index;
    64         this.index = index;
    64         setStart(start);
    65         setStart(start);
    65         setEnd(end);
    66         setEnd(end);
    66     }
    67         this.orig_index = index;
       
    68         this.live_to_end = end == null;
       
    69     }
       
    70 
       
    71 
       
    72     /**
       
    73      * Generate a local variable that with index `index'. Note that double and long
       
    74      * variables need two indexs. Index indices have to be provided by the user.
       
    75      *
       
    76      * @param index index of local variable
       
    77      * @param name its name
       
    78      * @param type its type
       
    79      * @param start from where the instruction is valid (null means from the start)
       
    80      * @param end until where the instruction is valid (null means to the end)
       
    81      * @param orig_index index of local variable prior to any changes to index
       
    82      */
       
    83     public LocalVariableGen(final int index, final String name, final Type type, final InstructionHandle start,
       
    84             final InstructionHandle end, final int orig_index) {
       
    85         this(index, name, type, start, end);
       
    86         this.orig_index = orig_index;
       
    87     }
       
    88 
    67 
    89 
    68     /**
    90     /**
    69      * Get LocalVariable object.
    91      * Get LocalVariable object.
    70      *
    92      *
    71      * This relies on that the instruction list has already been dumped to byte
    93      * This relies on that the instruction list has already been dumped to byte code or
    72      * code or or that the `setPositions' methods has been called for the
    94      * or that the `setPositions' methods has been called for the instruction list.
    73      * instruction list.
    95      *
    74      *
    96      * Note that due to the conversion from byte code offset to InstructionHandle,
    75      * Note that for local variables whose scope end at the last instruction of
    97      * it is impossible to tell the difference between a live range that ends BEFORE
    76      * the method's code, the JVM specification is ambiguous: both a
    98      * the last insturction of the method or a live range that ends AFTER the last
    77      * start_pc+length ending at the last instruction and start_pc+length ending
    99      * instruction of the method.  Hence the live_to_end flag to differentiate
    78      * at first index beyond the end of the code are valid.
   100      * between these two cases.
    79      *
   101      *
    80      * @param cp constant pool
   102      * @param cp constant pool
    81      */
   103      */
    82     public LocalVariable getLocalVariable(final ConstantPoolGen cp) {
   104     public LocalVariable getLocalVariable( final ConstantPoolGen cp ) {
    83         int start_pc = 0;
   105         int start_pc = 0;
    84         int length = 0;
   106         int length = 0;
    85         if ((start != null) && (end != null)) {
   107         if ((start != null) && (end != null)) {
    86             start_pc = start.getPosition();
   108             start_pc = start.getPosition();
    87             length = end.getPosition() - start_pc;
   109             length = end.getPosition() - start_pc;
    88             if (end.getNext() == null) {
   110             if ((end.getNext() == null) && live_to_end) {
    89                 length += end.getInstruction().getLength();
   111                 length += end.getInstruction().getLength();
    90             }
   112             }
    91         }
   113         }
    92         final int name_index = cp.addUtf8(name);
   114         final int name_index = cp.addUtf8(name);
    93         final int signature_index = cp.addUtf8(type.getSignature());
   115         final int signature_index = cp.addUtf8(type.getSignature());
    94         return new LocalVariable(start_pc, length, name_index, signature_index, index, cp
   116         return new LocalVariable(start_pc, length, name_index, signature_index, index, cp
    95                 .getConstantPool());
   117                 .getConstantPool(), orig_index);
    96     }
   118     }
    97 
   119 
    98     public void setIndex(final int index) {
   120 
       
   121     public void setIndex( final int index ) {
    99         this.index = index;
   122         this.index = index;
   100     }
   123     }
       
   124 
   101 
   125 
   102     public int getIndex() {
   126     public int getIndex() {
   103         return index;
   127         return index;
   104     }
   128     }
   105 
   129 
   106     @Override
   130 
   107     public void setName(final String name) {
   131     public int getOrigIndex() {
       
   132         return orig_index;
       
   133     }
       
   134 
       
   135 
       
   136     public void setLiveToEnd( final boolean live_to_end) {
       
   137         this.live_to_end = live_to_end;
       
   138     }
       
   139 
       
   140 
       
   141     public boolean getLiveToEnd() {
       
   142         return live_to_end;
       
   143     }
       
   144 
       
   145 
       
   146     @Override
       
   147     public void setName( final String name ) {
   108         this.name = name;
   148         this.name = name;
   109     }
   149     }
       
   150 
   110 
   151 
   111     @Override
   152     @Override
   112     public String getName() {
   153     public String getName() {
   113         return name;
   154         return name;
   114     }
   155     }
   115 
   156 
   116     @Override
   157 
   117     public void setType(final Type type) {
   158     @Override
       
   159     public void setType( final Type type ) {
   118         this.type = type;
   160         this.type = type;
   119     }
   161     }
       
   162 
   120 
   163 
   121     @Override
   164     @Override
   122     public Type getType() {
   165     public Type getType() {
   123         return type;
   166         return type;
   124     }
   167     }
   125 
   168 
       
   169 
   126     public InstructionHandle getStart() {
   170     public InstructionHandle getStart() {
   127         return start;
   171         return start;
   128     }
   172     }
   129 
   173 
       
   174 
   130     public InstructionHandle getEnd() {
   175     public InstructionHandle getEnd() {
   131         return end;
   176         return end;
   132     }
   177     }
   133 
   178 
   134     public void setStart(final InstructionHandle start) { // TODO could be package-protected?
   179 
       
   180     public void setStart( final InstructionHandle start ) { // TODO could be package-protected?
   135         BranchInstruction.notifyTarget(this.start, start, this);
   181         BranchInstruction.notifyTarget(this.start, start, this);
   136         this.start = start;
   182         this.start = start;
   137     }
   183     }
   138 
   184 
   139     public void setEnd(final InstructionHandle end) { // TODO could be package-protected?
   185 
       
   186     public void setEnd( final InstructionHandle end ) { // TODO could be package-protected?
   140         BranchInstruction.notifyTarget(this.end, end, this);
   187         BranchInstruction.notifyTarget(this.end, end, this);
   141         this.end = end;
   188         this.end = end;
   142     }
   189     }
   143 
   190 
       
   191 
   144     /**
   192     /**
   145      * @param old_ih old target, either start or end
   193      * @param old_ih old target, either start or end
   146      * @param new_ih new target
   194      * @param new_ih new target
   147      */
   195      */
   148     @Override
   196     @Override
   149     public void updateTarget(final InstructionHandle old_ih, final InstructionHandle new_ih) {
   197     public void updateTarget( final InstructionHandle old_ih, final InstructionHandle new_ih ) {
   150         boolean targeted = false;
   198         boolean targeted = false;
   151         if (start == old_ih) {
   199         if (start == old_ih) {
   152             targeted = true;
   200             targeted = true;
   153             setStart(new_ih);
   201             setStart(new_ih);
   154         }
   202         }
   172 
   220 
   173     /**
   221     /**
   174      * @return true, if ih is target of this variable
   222      * @return true, if ih is target of this variable
   175      */
   223      */
   176     @Override
   224     @Override
   177     public boolean containsTarget(final InstructionHandle ih) {
   225     public boolean containsTarget( final InstructionHandle ih ) {
   178         return (start == ih) || (end == ih);
   226         return (start == ih) || (end == ih);
   179     }
   227     }
       
   228 
   180 
   229 
   181     @Override
   230     @Override
   182     public int hashCode() {
   231     public int hashCode() {
   183         // If the user changes the name or type, problems with the targeter hashmap will occur.
   232         // If the user changes the name or type, problems with the targeter hashmap will occur.
   184         // Note: index cannot be part of hash as it may be changed by the user.
   233         // Note: index cannot be part of hash as it may be changed by the user.
   185         return name.hashCode() ^ type.hashCode();
   234         return name.hashCode() ^ type.hashCode();
   186     }
   235     }
   187 
   236 
       
   237 
   188     /**
   238     /**
   189      * We consider to local variables to be equal, if the use the same index and
   239      * We consider to local variables to be equal, if the use the same index and
   190      * are valid in the same range.
   240      * are valid in the same range.
   191      */
   241      */
   192     @Override
   242     @Override
   193     public boolean equals(final Object o) {
   243     public boolean equals( final Object o ) {
   194         if (!(o instanceof LocalVariableGen)) {
   244         if (!(o instanceof LocalVariableGen)) {
   195             return false;
   245             return false;
   196         }
   246         }
   197         final LocalVariableGen l = (LocalVariableGen) o;
   247         final LocalVariableGen l = (LocalVariableGen) o;
   198         return (l.index == index) && (l.start == start) && (l.end == end);
   248         return (l.index == index) && (l.start == start) && (l.end == end);
   199     }
   249     }
   200 
   250 
       
   251 
   201     @Override
   252     @Override
   202     public String toString() {
   253     public String toString() {
   203         return "LocalVariableGen(" + name + ", " + type + ", " + start + ", " + end + ")";
   254         return "LocalVariableGen(" + name + ", " + type + ", " + start + ", " + end + ")";
   204     }
   255     }
       
   256 
   205 
   257 
   206     @Override
   258     @Override
   207     public Object clone() {
   259     public Object clone() {
   208         try {
   260         try {
   209             return super.clone();
   261             return super.clone();