--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java Tue Aug 08 22:52:41 2017 +0000
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java Sun Aug 13 21:10:40 2017 -0700
@@ -18,237 +18,197 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package com.sun.org.apache.bcel.internal.generic;
-
-import com.sun.org.apache.bcel.internal.Constants;
-import com.sun.org.apache.bcel.internal.classfile.*;
-import java.util.Objects;
+import com.sun.org.apache.bcel.internal.Const;
+import com.sun.org.apache.bcel.internal.classfile.LocalVariable;
/**
* This class represents a local variable within a method. It contains its
- * scope, name and type. The generated LocalVariable object can be obtained
- * with getLocalVariable which needs the instruction list and the constant
- * pool as parameters.
+ * scope, name and type. The generated LocalVariable object can be obtained with
+ * getLocalVariable which needs the instruction list and the constant pool as
+ * parameters.
*
- * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
- * @see LocalVariable
- * @see MethodGen
+ * @version $Id: LocalVariableGen.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @see LocalVariable
+ * @see MethodGen
*/
-public class LocalVariableGen
- implements InstructionTargeter, NamedAndTyped, Cloneable,
- java.io.Serializable
-{
- private final int index;
- private String name;
- private Type type;
- private InstructionHandle start, end;
+public class LocalVariableGen implements InstructionTargeter, NamedAndTyped, Cloneable {
- /**
- * Generate a local variable that with index `index'. Note that double and long
- * variables need two indexs. Index indices have to be provided by the user.
- *
- * @param index index of local variable
- * @param name its name
- * @param type its type
- * @param start from where the instruction is valid (null means from the start)
- * @param end until where the instruction is valid (null means to the end)
- */
- public LocalVariableGen(int index, String name, Type type,
- InstructionHandle start, InstructionHandle end) {
- if((index < 0) || (index > Constants.MAX_SHORT))
- throw new ClassGenException("Invalid index index: " + index);
-
- this.name = name;
- this.type = type;
- this.index = index;
- setStart(start);
- setEnd(end);
- }
+ private int index;
+ private String name;
+ private Type type;
+ private InstructionHandle start;
+ private InstructionHandle end;
- /**
- * Get LocalVariable object.
- *
- * This relies on that the instruction list has already been dumped to byte code or
- * or that the `setPositions' methods has been called for the instruction list.
- *
- * Note that for local variables whose scope end at the last
- * instruction of the method's code, the JVM specification is ambiguous:
- * both a start_pc+length ending at the last instruction and
- * start_pc+length ending at first index beyond the end of the code are
- * valid.
- *
- * @param il instruction list (byte code) which this variable belongs to
- * @param cp constant pool
- */
- public LocalVariable getLocalVariable(ConstantPoolGen cp) {
- int start_pc = start.getPosition();
- int length = end.getPosition() - start_pc;
-
- if(length > 0)
- length += end.getInstruction().getLength();
-
- int name_index = cp.addUtf8(name);
- int signature_index = cp.addUtf8(type.getSignature());
-
- return new LocalVariable(start_pc, length, name_index,
- signature_index, index, cp.getConstantPool());
- }
-
- public int getIndex() { return index; }
- @Override
- public void setName(String name) { this.name = name; }
- @Override
- public String getName() { return name; }
- @Override
- public void setType(Type type) { this.type = type; }
- @Override
- public Type getType() { return type; }
-
- public InstructionHandle getStart() { return start; }
- public InstructionHandle getEnd() { return end; }
+ /**
+ * Generate a local variable that with index `index'. Note that double and
+ * long variables need two indexs. Index indices have to be provided by the
+ * user.
+ *
+ * @param index index of local variable
+ * @param name its name
+ * @param type its type
+ * @param start from where the instruction is valid (null means from the
+ * start)
+ * @param end until where the instruction is valid (null means to the end)
+ */
+ public LocalVariableGen(final int index, final String name, final Type type,
+ final InstructionHandle start, final InstructionHandle end) {
+ if ((index < 0) || (index > Const.MAX_SHORT)) {
+ throw new ClassGenException("Invalid index index: " + index);
+ }
+ this.name = name;
+ this.type = type;
+ this.index = index;
+ setStart(start);
+ setEnd(end);
+ }
- /**
- * Remove this from any known HashSet in which it might be registered.
- */
- void notifyTargetChanging() {
- // hashCode depends on 'index', 'start', and 'end'.
- // Therefore before changing any of these values we
- // need to unregister 'this' from any HashSet where
- // this is registered, and then we need to add it
- // back...
-
- // Unregister 'this' from the HashSet held by 'start'.
- BranchInstruction.notifyTargetChanging(this.start, this);
- if (this.end != this.start) {
- // Since hashCode() is going to change we need to unregister
- // 'this' both form 'start' and 'end'.
- // Unregister 'this' from the HashSet held by 'end'.
- BranchInstruction.notifyTargetChanging(this.end, this);
+ /**
+ * Get LocalVariable object.
+ *
+ * This relies on that the instruction list has already been dumped to byte
+ * code or or that the `setPositions' methods has been called for the
+ * instruction list.
+ *
+ * Note that for local variables whose scope end at the last instruction of
+ * the method's code, the JVM specification is ambiguous: both a
+ * start_pc+length ending at the last instruction and start_pc+length ending
+ * at first index beyond the end of the code are valid.
+ *
+ * @param cp constant pool
+ */
+ public LocalVariable getLocalVariable(final ConstantPoolGen cp) {
+ int start_pc = 0;
+ int length = 0;
+ if ((start != null) && (end != null)) {
+ start_pc = start.getPosition();
+ length = end.getPosition() - start_pc;
+ if (end.getNext() == null) {
+ length += end.getInstruction().getLength();
+ }
+ }
+ final int name_index = cp.addUtf8(name);
+ final int signature_index = cp.addUtf8(type.getSignature());
+ return new LocalVariable(start_pc, length, name_index, signature_index, index, cp
+ .getConstantPool());
}
- }
-
- /**
- * Add back 'this' in all HashSet in which it should be registered.
- **/
- void notifyTargetChanged() {
- // hashCode depends on 'index', 'start', and 'end'.
- // Therefore before changing any of these values we
- // need to unregister 'this' from any HashSet where
- // this is registered, and then we need to add it
- // back...
-
- // Register 'this' in the HashSet held by start.
- BranchInstruction.notifyTargetChanged(this.start, this);
- if (this.end != this.start) {
- // Since hashCode() has changed we need to register
- // 'this' again in 'end'.
- // Add back 'this' in the HashSet held by 'end'.
- BranchInstruction.notifyTargetChanged(this.end, this);
- }
- }
-
- public final void setStart(InstructionHandle start) {
- // Call notifyTargetChanging *before* modifying this,
- // as the code triggered by notifyTargetChanging
- // depends on this pointing to the 'old' start.
- notifyTargetChanging();
-
- this.start = start;
+ public void setIndex(final int index) {
+ this.index = index;
+ }
- // call notifyTargetChanged *after* modifying this,
- // as the code triggered by notifyTargetChanged
- // depends on this pointing to the 'new' start.
- notifyTargetChanged();
- }
-
- public final void setEnd(InstructionHandle end) {
- // call notifyTargetChanging *before* modifying this,
- // as the code triggered by notifyTargetChanging
- // depends on this pointing to the 'old' end.
- // Unregister 'this' from the HashSet held by the 'old' end.
- notifyTargetChanging();
+ public int getIndex() {
+ return index;
+ }
- this.end = end;
-
- // call notifyTargetChanged *after* modifying this,
- // as the code triggered by notifyTargetChanged
- // depends on this pointing to the 'new' end.
- // Register 'this' in the HashSet held by the 'new' end.
- notifyTargetChanged();
-
- }
+ @Override
+ public void setName(final String name) {
+ this.name = name;
+ }
- /**
- * @param old_ih old target, either start or end
- * @param new_ih new target
- */
- @Override
- public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) {
- boolean targeted = false;
+ @Override
+ public String getName() {
+ return name;
+ }
- if(start == old_ih) {
- targeted = true;
- setStart(new_ih);
+ @Override
+ public void setType(final Type type) {
+ this.type = type;
}
- if(end == old_ih) {
- targeted = true;
- setEnd(new_ih);
+ @Override
+ public Type getType() {
+ return type;
+ }
+
+ public InstructionHandle getStart() {
+ return start;
+ }
+
+ public InstructionHandle getEnd() {
+ return end;
+ }
+
+ public void setStart(final InstructionHandle start) { // TODO could be package-protected?
+ BranchInstruction.notifyTarget(this.start, start, this);
+ this.start = start;
+ }
+
+ public void setEnd(final InstructionHandle end) { // TODO could be package-protected?
+ BranchInstruction.notifyTarget(this.end, end, this);
+ this.end = end;
+ }
+
+ /**
+ * @param old_ih old target, either start or end
+ * @param new_ih new target
+ */
+ @Override
+ public void updateTarget(final InstructionHandle old_ih, final InstructionHandle new_ih) {
+ boolean targeted = false;
+ if (start == old_ih) {
+ targeted = true;
+ setStart(new_ih);
+ }
+ if (end == old_ih) {
+ targeted = true;
+ setEnd(new_ih);
+ }
+ if (!targeted) {
+ throw new ClassGenException("Not targeting " + old_ih + ", but {" + start + ", " + end
+ + "}");
+ }
}
- if(!targeted)
- throw new ClassGenException("Not targeting " + old_ih + ", but {" + start + ", " +
- end + "}");
- }
+ /**
+ * Clear the references from and to this variable when it's removed.
+ */
+ void dispose() {
+ setStart(null);
+ setEnd(null);
+ }
- /**
- * @return true, if ih is target of this variable
- */
- @Override
- public boolean containsTarget(InstructionHandle ih) {
- return (start == ih) || (end == ih);
- }
+ /**
+ * @return true, if ih is target of this variable
+ */
+ @Override
+ public boolean containsTarget(final InstructionHandle ih) {
+ return (start == ih) || (end == ih);
+ }
- /**
- * We consider two local variables to be equal, if they use the same index and
- * are valid in the same range.
- */
- @Override
- public boolean equals(Object o) {
- if (o==this)
- return true;
-
- if(!(o instanceof LocalVariableGen))
- return false;
+ @Override
+ public int hashCode() {
+ // If the user changes the name or type, problems with the targeter hashmap will occur.
+ // Note: index cannot be part of hash as it may be changed by the user.
+ return name.hashCode() ^ type.hashCode();
+ }
- LocalVariableGen l = (LocalVariableGen)o;
- return (l.index == index) && (l.start == start) && (l.end == end);
- }
-
- @Override
- public int hashCode() {
- int hash = 7;
- hash = 59 * hash + this.index;
- hash = 59 * hash + Objects.hashCode(this.start);
- hash = 59 * hash + Objects.hashCode(this.end);
- return hash;
- }
+ /**
+ * We consider to local variables to be equal, if the use the same index and
+ * are valid in the same range.
+ */
+ @Override
+ public boolean equals(final Object o) {
+ if (!(o instanceof LocalVariableGen)) {
+ return false;
+ }
+ final LocalVariableGen l = (LocalVariableGen) o;
+ return (l.index == index) && (l.start == start) && (l.end == end);
+ }
- @Override
- public String toString() {
- return "LocalVariableGen(" + name + ", " + type + ", " + start + ", " + end + ")";
- }
+ @Override
+ public String toString() {
+ return "LocalVariableGen(" + name + ", " + type + ", " + start + ", " + end + ")";
+ }
- @Override
- public Object clone() {
- try {
- return super.clone();
- } catch(CloneNotSupportedException e) {
- System.err.println(e);
- return null;
+ @Override
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (final CloneNotSupportedException e) {
+ throw new Error("Clone Not Supported"); // never happens
+ }
}
- }
}