]> source.dussan.org Git - aspectj.git/commitdiff
optimization
authoraclement <aclement>
Mon, 5 Oct 2009 17:35:36 +0000 (17:35 +0000)
committeraclement <aclement>
Mon, 5 Oct 2009 17:35:36 +0000 (17:35 +0000)
21 files changed:
bcel-builder/src/org/aspectj/apache/bcel/classfile/Code.java
bcel-builder/src/org/aspectj/apache/bcel/generic/BranchHandle.java
bcel-builder/src/org/aspectj/apache/bcel/generic/FieldInstruction.java
bcel-builder/src/org/aspectj/apache/bcel/generic/FieldOrMethod.java
bcel-builder/src/org/aspectj/apache/bcel/generic/IINC.java
bcel-builder/src/org/aspectj/apache/bcel/generic/INVOKEINTERFACE.java
bcel-builder/src/org/aspectj/apache/bcel/generic/Instruction.java
bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionBranch.java
bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionByte.java
bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionCP.java
bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionHandle.java
bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionLV.java
bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionList.java
bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionSelect.java
bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionShort.java
bcel-builder/src/org/aspectj/apache/bcel/generic/InvokeInstruction.java
bcel-builder/src/org/aspectj/apache/bcel/generic/LocalVariableTag.java
bcel-builder/src/org/aspectj/apache/bcel/generic/MULTIANEWARRAY.java
bcel-builder/src/org/aspectj/apache/bcel/generic/MethodGen.java
bcel-builder/src/org/aspectj/apache/bcel/generic/RET.java
bcel-builder/src/org/aspectj/apache/bcel/generic/Type.java

index fb96fbe5fa6b279b985ac9d9bce101c1294f1118..b714e6cabe220bb25b54c86cbeae055c12a6d936 100644 (file)
@@ -68,7 +68,7 @@ import org.aspectj.apache.bcel.Constants;
  * This attribute has attributes itself, namely <em>LineNumberTable</em> which is used for debugging purposes and
  * <em>LocalVariableTable</em> which contains information about the local variables.
  * 
- * @version $Id: Code.java,v 1.8 2009/09/15 19:40:12 aclement Exp $
+ * @version $Id: Code.java,v 1.9 2009/10/05 17:35:36 aclement Exp $
  * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  * @see Attribute
  * @see CodeException
@@ -109,8 +109,9 @@ public final class Code extends Attribute {
                        exceptionTable = NO_EXCEPTIONS;
                } else {
                        exceptionTable = new CodeException[len];
-                       for (int i = 0; i < len; i++)
+                       for (int i = 0; i < len; i++) {
                                exceptionTable[i] = new CodeException(file);
+                       }
                }
 
                // Read all attributes, eg: LineNumberTable, LocalVariableTable
@@ -172,12 +173,14 @@ public final class Code extends Attribute {
                file.write(code, 0, code.length);
 
                file.writeShort(exceptionTable.length);
-               for (int i = 0; i < exceptionTable.length; i++)
+               for (int i = 0; i < exceptionTable.length; i++) {
                        exceptionTable[i].dump(file);
+               }
 
                file.writeShort(attributes.length);
-               for (int i = 0; i < attributes.length; i++)
+               for (int i = 0; i < attributes.length; i++) {
                        attributes[i].dump(file);
+               }
        }
 
        /**
@@ -192,9 +195,11 @@ public final class Code extends Attribute {
         * @return LineNumberTable of Code, if it has one
         */
        public LineNumberTable getLineNumberTable() {
-               for (int i = 0; i < attributes.length; i++)
-                       if (attributes[i].tag == Constants.ATTR_LINE_NUMBER_TABLE)
+               for (int i = 0; i < attributes.length; i++) {
+                       if (attributes[i].tag == Constants.ATTR_LINE_NUMBER_TABLE) {
                                return (LineNumberTable) attributes[i];
+                       }
+               }
                return null;
        }
 
@@ -202,9 +207,11 @@ public final class Code extends Attribute {
         * @return LocalVariableTable of Code, if it has one
         */
        public LocalVariableTable getLocalVariableTable() {
-               for (int i = 0; i < attributes.length; i++)
-                       if (attributes[i].tag == Constants.ATTR_LOCAL_VARIABLE_TABLE)
+               for (int i = 0; i < attributes.length; i++) {
+                       if (attributes[i].tag == Constants.ATTR_LOCAL_VARIABLE_TABLE) {
                                return (LocalVariableTable) attributes[i];
+                       }
+               }
                return null;
        }
 
@@ -255,8 +262,9 @@ public final class Code extends Attribute {
        private final int calculateLength() {
                int len = 0;
                if (attributes != null) {
-                       for (int i = 0; i < attributes.length; i++)
+                       for (int i = 0; i < attributes.length; i++) {
                                len += attributes[i].length + 6 /* attribute header size */;
+                       }
                }
                return len + getInternalLength();
        }
@@ -309,15 +317,17 @@ public final class Code extends Attribute {
                if (exceptionTable.length > 0) {
                        buf.append("\nException handler(s) = \n" + "From\tTo\tHandler\tType\n");
 
-                       for (int i = 0; i < exceptionTable.length; i++)
+                       for (int i = 0; i < exceptionTable.length; i++) {
                                buf.append(exceptionTable[i].toString(cpool, verbose) + "\n");
+                       }
                }
 
                if (attributes.length > 0) {
                        buf.append("\nAttribute(s) = \n");
 
-                       for (int i = 0; i < attributes.length; i++)
+                       for (int i = 0; i < attributes.length; i++) {
                                buf.append(attributes[i].toString() + "\n");
+                       }
                }
 
                return buf.toString();
@@ -366,8 +376,9 @@ public final class Code extends Attribute {
                                CodeException exc = exceptionTable[i];
                                int type = exc.getCatchType();
                                String name = "finally";
-                               if (type != 0)
+                               if (type != 0) {
                                        name = this.cpool.getConstantString(type, Constants.CONSTANT_Class);
+                               }
                                codeString.append(name).append("[");
                                codeString.append(exc.getStartPC()).append(">").append(exc.getEndPC()).append("]\n");
                        }
index c735075a49e46e0b8f8af38afc158662087344f3..35d9528b87cebb8faba501da53e1dfe0cd89012d 100644 (file)
@@ -55,77 +55,80 @@ package org.aspectj.apache.bcel.generic;
  */
 
 /**
- * BranchHandle is returned by specialized InstructionList.append() whenever a
- * BranchInstruction is appended. This is useful when the target of this
- * instruction is not known at time of creation and must be set later
- * via setTarget().
- *
+ * BranchHandle is returned by specialized InstructionList.append() whenever a BranchInstruction is appended. This is useful when
+ * the target of this instruction is not known at time of creation and must be set later via setTarget().
+ * 
  * @see InstructionHandle
  * @see Instruction
  * @see InstructionList
- * @version $Id: BranchHandle.java,v 1.4 2008/05/28 23:52:55 aclement Exp $
- * @author  <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @version $Id: BranchHandle.java,v 1.5 2009/10/05 17:35:36 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  */
 public final class BranchHandle extends InstructionHandle {
-  private InstructionBranch bi; // An alias in fact, but saves lots of casts
-
-  private BranchHandle(InstructionBranch i) {
-    super(i);
-    bi = i;
-  }
+       private InstructionBranch bi; // An alias in fact, but saves lots of casts
 
-  static final BranchHandle getBranchHandle(InstructionBranch i) {
-      return new BranchHandle(i);
-  }
+       private BranchHandle(InstructionBranch i) {
+               super(i);
+               bi = i;
+       }
 
-  /* Override InstructionHandle methods: delegate to branch instruction.
-   * Through this overriding all access to the private i_position field should
-   * be prevented.
-   */
-  public int getPosition() { return bi.positionOfThisInstruction; }
+       static final BranchHandle getBranchHandle(InstructionBranch i) {
+               return new BranchHandle(i);
+       }
 
-  void setPosition(int pos) {
-    i_position = bi.positionOfThisInstruction = pos;
-  }
+       /*
+        * Override InstructionHandle methods: delegate to branch instruction. Through this overriding all access to the private
+        * i_position field should be prevented.
+        */
+       public int getPosition() {
+               return bi.positionOfThisInstruction;
+       }
 
-  protected int updatePosition(int offset, int max_offset) {
-    int x = bi.updatePosition(offset, max_offset);
-    i_position = bi.positionOfThisInstruction;
-    return x;
-  }
+       void setPosition(int pos) {
+               this.pos = bi.positionOfThisInstruction = pos;
+       }
 
-  /**
-   * Pass new target to instruction.
-   */
-  public void setTarget(InstructionHandle ih) {
-    bi.setTarget(ih);
-  }
+       /**
+        * Called by InstructionList.setPositions when setting the position for every instruction. In the presence of variable length
+        * instructions 'setPositions()' performs multiple passes over the instruction list to calculate the correct (byte) positions
+        * and offsets by calling this function.
+        * 
+        * @param offset additional offset caused by preceding (variable length) instructions
+        * @param max_offset the maximum offset that may be caused by these instructions
+        * @return additional offset caused by possible change of this instruction's length
+        */
+       protected int updatePosition(int offset, int max_offset) {
+               int x = bi.updatePosition(offset, max_offset);
+               pos = bi.positionOfThisInstruction;
+               return x;
+       }
 
-  /**
-   * Update target of instruction.
-   */
-  public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) {
-    bi.updateTarget(old_ih, new_ih);
-  }
+       /**
+        * Pass new target to instruction.
+        */
+       public void setTarget(InstructionHandle ih) {
+               bi.setTarget(ih);
+       }
 
-  /**
-   * @return target of instruction.
-   */
-  public InstructionHandle getTarget() {
-    return bi.getTarget();
-  }
+       /**
+        * Update target of instruction.
+        */
+       public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) {
+               bi.updateTarget(old_ih, new_ih);
+       }
 
-  /** 
-   * Set new contents. Old instruction is disposed and may not be used anymore.
-   */
-  public void setInstruction(Instruction i) {
-    super.setInstruction(i);
+       /**
+        * @return target of instruction.
+        */
+       public InstructionHandle getTarget() {
+               return bi.getTarget();
+       }
 
-    if(!(i instanceof InstructionBranch))
-      throw new ClassGenException("Assigning " + i +
-                                 " to branch handle which is not a branch instruction");
-
-    bi = (InstructionBranch)i;
-  }
+       /**
+        * Set new contents. Old instruction is disposed and may not be used anymore.
+        */
+       public void setInstruction(Instruction i) {
+               super.setInstruction(i);
+               bi = (InstructionBranch) i;
+       }
 }
-
index e7c67d2efef31a23270225f786cfe67e16ae9fde..54983e7c9cb912437f84253b63f598e1d5932131 100644 (file)
@@ -58,50 +58,55 @@ import org.aspectj.apache.bcel.classfile.ConstantPool;
 
 /**
  * Super class for the GET/PUTxxx family of instructions.
- *
- * @version $Id: FieldInstruction.java,v 1.6 2008/05/28 23:52:56 aclement Exp $
- * @author  <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * 
+ * @version $Id: FieldInstruction.java,v 1.7 2009/10/05 17:35:36 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  */
 public class FieldInstruction extends FieldOrMethod {
 
-  public FieldInstruction(short opcode, int index) {
-    super(opcode, index);
-  }
+       public FieldInstruction(short opcode, int index) {
+               super(opcode, index);
+       }
 
-  public String toString(ConstantPool cp) {
-    return org.aspectj.apache.bcel.Constants.OPCODE_NAMES[opcode] + " " +
-      cp.constantToString(index, org.aspectj.apache.bcel.Constants.CONSTANT_Fieldref);
-  }
-  
-  /** @return size of field (1 or 2)
-   */
-  protected int getFieldSize(ConstantPool cpg) {
-    return Type.getTypeSize(getSignature(cpg));
-  }
+       public String toString(ConstantPool cp) {
+               return org.aspectj.apache.bcel.Constants.OPCODE_NAMES[opcode] + " "
+                               + cp.constantToString(index, org.aspectj.apache.bcel.Constants.CONSTANT_Fieldref);
+       }
 
-  public Type getType(ConstantPool cpg) {
-    return getFieldType(cpg);
-  }
+       /**
+        * @return size of field (1 or 2)
+        */
+       protected int getFieldSize(ConstantPool cpg) {
+               return Type.getTypeSize(getSignature(cpg));
+       }
 
-  public Type getFieldType(ConstantPool cpg) {
-    return Type.getType(getSignature(cpg));
-  }
+       public Type getType(ConstantPool cpg) {
+               return getFieldType(cpg);
+       }
 
+       public Type getFieldType(ConstantPool cpg) {
+               return Type.getType(getSignature(cpg));
+       }
 
-  public String getFieldName(ConstantPool cpg) {
-    return getName(cpg);
-  }
-  
-  public int produceStack(ConstantPool cpg) {
-      if (!isStackProducer()) return 0;
-         
-         return getFieldSize(cpg); // SAME FOR GETFIELD/GETSTATIC
-  }
-  
-  public int consumeStack(ConstantPool cpg) {
-         if (!isStackConsumer()) return 0;
-         if (opcode==GETFIELD) return 1;
-         return getFieldSize(cpg)+(opcode==PUTFIELD?1:0);
-  }
-}
+       public String getFieldName(ConstantPool cpg) {
+               return getName(cpg);
+       }
+
+       public int produceStack(ConstantPool cpg) {
+               if (!isStackProducer()) {
+                       return 0;
+               }
 
+               return getFieldSize(cpg); // SAME FOR GETFIELD/GETSTATIC
+       }
+
+       public int consumeStack(ConstantPool cpg) {
+               if (!isStackConsumer()) {
+                       return 0;
+               }
+               if (opcode == GETFIELD) {
+                       return 1;
+               }
+               return getFieldSize(cpg) + (opcode == PUTFIELD ? 1 : 0);
+       }
+}
index 71f8157cd77d049249becc77c1037c69076a5f93..bf2c73299dd7d61a01df38c008ec3dc16153c887 100644 (file)
@@ -61,23 +61,15 @@ import org.aspectj.apache.bcel.classfile.ConstantUtf8;
 /**
  * Super class for InvokeInstruction and FieldInstruction, since they have some methods in common!
  * 
- * @version $Id: FieldOrMethod.java,v 1.7 2009/09/10 15:35:06 aclement Exp $
+ * @version $Id: FieldOrMethod.java,v 1.8 2009/10/05 17:35:36 aclement Exp $
  * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  */
 public abstract class FieldOrMethod extends InstructionCP {
 
-       // private boolean dontKnowSignature=true;
        private String signature;
-
-       // private boolean dontKnowName =true;
        private String name;
-
-       // private boolean dontKnowClassname =true;
        private String classname;
 
-       /**
-        * @param index to constant pool
-        */
        protected FieldOrMethod(short opcode, int index) {
                super(opcode, index);
        }
@@ -89,9 +81,7 @@ public abstract class FieldOrMethod extends InstructionCP {
                if (signature == null) {
                        ConstantCP cmr = (ConstantCP) cp.getConstant(index);
                        ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex());
-
                        signature = ((ConstantUtf8) cp.getConstant(cnat.getSignatureIndex())).getValue();
-                       // dontKnowSignature=false;
                }
                return signature;
        }
@@ -104,7 +94,6 @@ public abstract class FieldOrMethod extends InstructionCP {
                        ConstantCP cmr = (ConstantCP) cp.getConstant(index);
                        ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex());
                        name = ((ConstantUtf8) cp.getConstant(cnat.getNameIndex())).getValue();
-                       // dontKnowName = false;
                }
                return name;
        }
@@ -116,11 +105,11 @@ public abstract class FieldOrMethod extends InstructionCP {
                if (classname == null) {
                        ConstantCP cmr = (ConstantCP) cp.getConstant(index);
                        String str = cp.getConstantString(cmr.getClassIndex(), CONSTANT_Class);
-                       if (str.charAt(0) == '[')
+                       if (str.charAt(0) == '[') {
                                classname = str;
-                       else
+                       } else {
                                classname = str.replace('/', '.');
-                       // dontKnowClassname = false;
+                       }
                }
                return classname;
        }
index 6df506e44f055045bcace11e335d4a852e067b37..d70e2030835804bdd18611c78919a02959c6cb36 100644 (file)
@@ -53,56 +53,69 @@ package org.aspectj.apache.bcel.generic;
  * information on the Apache Software Foundation, please see
  * <http://www.apache.org/>.
  */
-import java.io.*;
+import java.io.DataOutputStream;
+import java.io.IOException;
 
 import org.aspectj.apache.bcel.Constants;
 
 /**
  * IINC - Increment local variable by constant
- *
- * @version $Id: IINC.java,v 1.4 2008/05/28 23:52:57 aclement Exp $
- * @author  <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * 
+ * @version $Id: IINC.java,v 1.5 2009/10/05 17:35:36 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  */
 public class IINC extends InstructionLV {
-  private int     c;
+       private int c;
+
+       public IINC(int n, int c, boolean w) {
+               super(Constants.IINC, n);
+               this.c = c;
+               // this.wide = w;//((n > org.aspectj.apache.bcel.Constants.MAX_BYTE) || (Math.abs(c) > Byte.MAX_VALUE));
+       }
+
+       private boolean wide() {
+               return ((lvar > org.aspectj.apache.bcel.Constants.MAX_BYTE) || (Math.abs(c) > Byte.MAX_VALUE));
+       }
 
-  public IINC(int n, int c,boolean w) {
-    super(Constants.IINC,n);
-    this.c=c;
-//    this.wide = w;//((n > org.aspectj.apache.bcel.Constants.MAX_BYTE) || (Math.abs(c) > Byte.MAX_VALUE));
-  }
+       public void dump(DataOutputStream out) throws IOException {
+               if (wide()) {
+                       out.writeByte(WIDE);
+                       out.writeByte(opcode);
+                       out.writeShort(lvar);
+                       out.writeShort(c);
+               } else {
+                       out.writeByte(opcode);
+                       out.writeByte(lvar);
+                       out.writeByte(c);
+               }
+       }
 
-  private boolean wide() {
-         return ((lvar > org.aspectj.apache.bcel.Constants.MAX_BYTE) || (Math.abs(c) > Byte.MAX_VALUE));
-  }
+       public int getLength() {
+               if (wide()) {
+                       return 6;
+               } else {
+                       return 3; // includes wide byte
+               }
+       }
 
-  public void dump(DataOutputStream out) throws IOException {
-         if (wide()) {
-                 out.writeByte(WIDE);
-             out.writeByte(opcode);
-             out.writeShort(lvar);
-             out.writeShort(c);
-         } else {
-             out.writeByte(opcode);
-          out.writeByte(lvar);
-          out.writeByte(c);
-      }
-  }
-  
-  
-  public int getLength() {
-         if (wide()) return 6; else return 3; // includes wide byte
-  }
+       public String toString(boolean verbose) {
+               return super.toString(verbose) + " " + c;
+       }
 
-  public String toString(boolean verbose) {
-    return super.toString(verbose) + " " + c;
-  }  
+       public final int getIncrement() {
+               return c;
+       }
 
-  public final int getIncrement() { return c; }
+       public boolean equals(Object other) {
+               if (!(other instanceof IINC)) {
+                       return false;
+               }
+               IINC o = (IINC) other;
+               return /* o.opcode == opcode && */o.lvar == lvar && o.c == c;
+       }
 
-//  //fixme promote or stick in a table
-//  public Type getType(ConstantPoolGen cp) {
-//    return Type.INT;
-//  }
+       public int hashCode() {
+               return opcode * 37 + lvar * (c + 17);
+       }
 
 }
index 6f60afdac24c912786ea883ba8492543bd01b3b0..b545f4d37a0ed05812e2452359f86a372a1611ef 100644 (file)
@@ -53,58 +53,75 @@ package org.aspectj.apache.bcel.generic;
  * information on the Apache Software Foundation, please see
  * <http://www.apache.org/>.
  */
-import org.aspectj.apache.bcel.classfile.ConstantPool;
-import org.aspectj.apache.bcel.Constants;
+import java.io.DataOutputStream;
+import java.io.IOException;
 
-import java.io.*;
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
 
-/** 
+/**
  * INVOKEINTERFACE - Invoke interface method
- * <PRE>Stack: ..., objectref, [arg1, [arg2 ...]] -&gt; ...</PRE>
- *
- * @version $Id: INVOKEINTERFACE.java,v 1.3 2008/05/28 23:52:58 aclement Exp $
- * @author  <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * 
+ * <PRE>
+ * Stack: ..., objectref, [arg1, [arg2 ...]] -&gt; ...
+ * </PRE>
+ * 
+ * @version $Id: INVOKEINTERFACE.java,v 1.4 2009/10/05 17:35:36 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  */
 public final class INVOKEINTERFACE extends InvokeInstruction {
-  private int nargs; // Number of arguments on stack (number of stack slots), called "count" in vmspec2
+       private int nargs; // Number of arguments on stack (number of stack slots), called "count" in vmspec2
 
+       public INVOKEINTERFACE(int index, int nargs, int zerobyte) {
+               super(Constants.INVOKEINTERFACE, index);
 
-  public INVOKEINTERFACE(int index, int nargs,int zerobyte) {
-    super(Constants.INVOKEINTERFACE, index);
+               if (nargs < 1) {
+                       throw new ClassGenException("Number of arguments must be > 0 " + nargs);
+               }
 
-    if(nargs < 1)
-      throw new ClassGenException("Number of arguments must be > 0 " + nargs);
+               this.nargs = nargs;
+       }
 
-    this.nargs = nargs;
-  }
+       /**
+        * Dump instruction as byte code to stream out.
+        * 
+        * @param out Output stream
+        */
+       public void dump(DataOutputStream out) throws IOException {
+               out.writeByte(opcode);
+               out.writeShort(index);
+               out.writeByte(nargs);
+               out.writeByte(0);
+       }
 
-  /**
-   * Dump instruction as byte code to stream out.
-   * @param out Output stream
-   */
-  public void dump(DataOutputStream out) throws IOException {
-    out.writeByte(opcode);
-    out.writeShort(index);
-    out.writeByte(nargs);
-    out.writeByte(0);
-  }
+       /**
+        * The <B>count</B> argument according to the Java Language Specification, Second Edition.
+        */
+       public int getCount() {
+               return nargs;
+       }
 
-  /**
-   * The <B>count</B> argument according to the Java Language Specification,
-   * Second Edition.
-   */
-  public int getCount() { return nargs; }
+       /**
+        * @return mnemonic for instruction with symbolic references resolved
+        */
+       public String toString(ConstantPool cp) {
+               return super.toString(cp) + " " + nargs;
+       }
 
+       public int consumeStack(ConstantPool cpg) { // nargs is given in byte-code
+               return nargs; // nargs includes this reference
+       }
 
-  /**
-   * @return mnemonic for instruction with symbolic references resolved
-   */
-  public String toString(ConstantPool cp) {
-    return super.toString(cp) + " " + nargs;
-  }
+       public boolean equals(Object other) {
+               if (!(other instanceof INVOKEINTERFACE)) {
+                       return false;
+               }
+               INVOKEINTERFACE o = (INVOKEINTERFACE) other;
+               return o.opcode == opcode && o.index == index && o.nargs == nargs;
+       }
 
-  public int consumeStack(ConstantPool cpg) { // nargs is given in byte-code
-    return nargs;  // nargs includes this reference
-  }
+       public int hashCode() {
+               return opcode * 37 + index * (nargs + 17);
+       }
 
 }
index ae85e06a0109ca9aac6c2ef70658b2c172c42c81..ffdf6305119ecb99b3b56b5e697c44aa85acde6f 100644 (file)
@@ -67,7 +67,7 @@ import com.sun.org.apache.bcel.internal.generic.BranchInstruction;
 /**
  * Abstract super class for all Java byte codes.
  * 
- * @version $Id: Instruction.java,v 1.8 2009/09/14 20:29:10 aclement Exp $
+ * @version $Id: Instruction.java,v 1.9 2009/10/05 17:35:36 aclement Exp $
  * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  */
 public class Instruction implements Cloneable, Serializable, Constants {
@@ -92,7 +92,9 @@ public class Instruction implements Cloneable, Serializable, Constants {
         * @see BranchInstruction
         * @return (shallow) copy of an instruction
         */
+       // GET RID OF THIS - make it throw an exception and track the callers
        final public Instruction copy() {
+               // if overridden correctly can just return 'this' here
                if (InstructionConstants.INSTRUCTIONS[opcode] != null) { // immutable instructions do not need copying
                        return this;
                } else {
@@ -107,7 +109,7 @@ public class Instruction implements Cloneable, Serializable, Constants {
        }
 
        /**
-        * Read an instruction from (byte code) input stream and return the appropiate object.
+        * Read an instruction bytecode from an input stream and return the appropriate object.
         * 
         * @param file file to read from
         * @return instruction object being read
@@ -115,7 +117,6 @@ public class Instruction implements Cloneable, Serializable, Constants {
        public static final Instruction readInstruction(ByteSequence bytes) throws IOException {
                boolean wide = false;
                short opcode = (short) bytes.readUnsignedByte();
-               Instruction obj = null;
 
                if (opcode == Constants.WIDE) {
                        wide = true;
@@ -128,6 +129,7 @@ public class Instruction implements Cloneable, Serializable, Constants {
                        return constantInstruction;
                }
 
+               Instruction obj = null;
                try {
                        switch (opcode) {
                        case Constants.BIPUSH:
@@ -257,9 +259,10 @@ public class Instruction implements Cloneable, Serializable, Constants {
        public int getLength() {
                // if it is zero, it should have been provided by an overriding implementation of getLength()
                int len = Constants.iLen[opcode];
-               if (len == 0) {
-                       throw new IllegalStateException("Length not right for " + getName().toUpperCase());
-               }
+               assert len != 0;
+               // if (len == 0) {
+               // throw new IllegalStateException("Length not right for " + getName().toUpperCase());
+               // }
                return len;
        }
 
@@ -268,38 +271,49 @@ public class Instruction implements Cloneable, Serializable, Constants {
        }
 
        @Override
-       public boolean equals(Object that) {
-               if (!(that instanceof Instruction)) {
-                       return false;
+       public boolean equals(Object other) {
+               if (this.getClass() != Instruction.class) {
+                       throw new RuntimeException("NO WAY " + this.getClass());
                }
-               Instruction i1 = this;
-               Instruction i2 = (Instruction) that;
-               if (i1.opcode == i2.opcode) {
-                       if (i1.isConstantInstruction()) {
-                               return i1.getValue().equals(i2.getValue());
-                       } else if (i1.isIndexedInstruction()) {
-                               return i1.getIndex() == i2.getIndex();
-                       } else if (i1.opcode == Constants.NEWARRAY) {
-                               return ((InstructionByte) i1).getTypecode() == ((InstructionByte) i2).getTypecode();
-                       } else {
-                               return true;
-                       }
+               if (!(other instanceof Instruction)) {
+                       return false;
                }
-
-               return false;
+               return ((Instruction) other).opcode == opcode;
+
+               // IMPLEMENT EQUALS AND HASHCODE IN THE SUBTYPES!
+
+               // Instruction i1 = this;
+               // Instruction i2 = (Instruction) that;
+               // if (i1.opcode == i2.opcode) {
+               // if (i1.isConstantInstruction()) {
+               // return i1.getValue().equals(i2.getValue());
+               // } else if (i1.isIndexedInstruction()) {
+               // return i1.getIndex() == i2.getIndex();
+               // } else if (i1.opcode == Constants.NEWARRAY) {
+               // return ((InstructionByte) i1).getTypecode() == ((InstructionByte) i2).getTypecode();
+               // } else {
+               // return true;
+               // }
+               // }
+               //
+               // return false;
        }
 
        @Override
        public int hashCode() {
-               int result = 17 + opcode * 37;
-               if (isConstantInstruction()) {
-                       result = 37 * getValue().hashCode() + result;
-               } else if (isIndexedInstruction()) {
-                       result = 37 * getIndex() + result;
-               } else if (opcode == Constants.NEWARRAY) {
-                       result = 37 * ((InstructionByte) this).getTypecode() + result;
+               if (this.getClass() != Instruction.class) {
+                       throw new RuntimeException("NO WAY " + this.getClass());
                }
-               return result;
+               return opcode * 37;
+               // int result = 17 + opcode * 37;
+               // if (isConstantInstruction()) {
+               // result = 37 * getValue().hashCode() + result;
+               // } else if (isIndexedInstruction()) {
+               // result = 37 * getIndex() + result;
+               // } else if (opcode == Constants.NEWARRAY) {
+               // result = 37 * ((InstructionByte) this).getTypecode() + result;
+               // }
+               // return result;
        }
 
        public Type getType() {
@@ -316,9 +330,10 @@ public class Instruction implements Cloneable, Serializable, Constants {
        }
 
        public Number getValue() {
-               if ((instFlags[opcode] & CONSTANT_INST) == 0) {
-                       throw new RuntimeException(getName() + " is not a constant instruction");
-               }
+               assert (instFlags[opcode] & CONSTANT_INST) == 0;
+               // if ((instFlags[opcode] & CONSTANT_INST) == 0) {
+               // throw new RuntimeException(getName() + " is not a constant instruction");
+               // }
                switch (opcode) {
                case ICONST_M1:
                case ICONST_0:
@@ -349,6 +364,11 @@ public class Instruction implements Cloneable, Serializable, Constants {
                return (Constants.instFlags[opcode] & LOAD_INST) != 0;
        }
 
+       // remove these from here, leave them in the InstructionLV
+       public boolean isASTORE() {
+               return false;
+       }
+
        public boolean isALOAD() {
                return false;
        }
@@ -357,13 +377,9 @@ public class Instruction implements Cloneable, Serializable, Constants {
                return (Constants.instFlags[opcode] & STORE_INST) != 0;
        }
 
-       public boolean isASTORE() {
-               return false;
-       }
-
-       public boolean containsTarget(InstructionHandle ih) {
-               throw new IllegalStateException("Dont ask!!");
-       }
+       // public boolean containsTarget(InstructionHandle ih) {
+       // throw new IllegalStateException("Dont ask!!");
+       // }
 
        public boolean isJsrInstruction() {
                return (Constants.instFlags[opcode] & JSR_INSTRUCTION) != 0;
@@ -394,10 +410,11 @@ public class Instruction implements Cloneable, Serializable, Constants {
        }
 
        public ObjectType getLoadClassType(ConstantPool cpg) {
-               if ((Constants.instFlags[opcode] & Constants.LOADCLASS_INST) == 0) {
-                       throw new IllegalStateException("This opcode " + opcode + " does not have the property "
-                                       + Long.toHexString(Constants.LOADCLASS_INST));
-               }
+               assert (Constants.instFlags[opcode] & Constants.LOADCLASS_INST) == 0;
+               // if ((Constants.instFlags[opcode] & Constants.LOADCLASS_INST) == 0) {
+               // throw new IllegalStateException("This opcode " + opcode + " does not have the property "
+               // + Long.toHexString(Constants.LOADCLASS_INST));
+               // }
                Type t = getType(cpg);
                if (t instanceof ArrayType) {
                        t = ((ArrayType) t).getBasicType();
@@ -409,9 +426,9 @@ public class Instruction implements Cloneable, Serializable, Constants {
                return (Constants.instFlags[opcode] & RET_INST) != 0;
        }
 
-       public boolean isGoto() {
-               return opcode == GOTO || opcode == GOTO_W;
-       }
+       // public boolean isGoto() {
+       // return opcode == GOTO || opcode == GOTO_W;
+       // }
 
        public boolean isLocalVariableInstruction() {
                return (Constants.instFlags[opcode] & LV_INST) != 0;
index 0a59122478d9a82c1d4e2463a32035461b159c1b..53fed8e5276effdf4b861e6f6db4422f1357f192 100644 (file)
@@ -65,7 +65,7 @@ import org.aspectj.apache.bcel.classfile.ConstantPool;
  * about an instruction it doesnt yet know the position if (targetInstruction). targetInstruction (if set) overrides targetIndex
  * 
  * @see InstructionList
- * @version $Id: InstructionBranch.java,v 1.5 2008/08/28 00:03:03 aclement Exp $
+ * @version $Id: InstructionBranch.java,v 1.6 2009/10/05 17:35:36 aclement Exp $
  * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  */
 public class InstructionBranch extends Instruction implements InstructionTargeter {
@@ -171,7 +171,7 @@ public class InstructionBranch extends Instruction implements InstructionTargete
                                } else {
                                        opcode = GOTO_W;
                                }
-                               return 2;
+                               return 2; // instruction jump destination grows from a short to a long
                        } else {
                                throw new IllegalStateException("Unable to pack method, jump (with opcode=" + opcode + ") is too far: "
                                                + Math.abs(i));
index fcd46dc9f272aaeb6bdb0503bab304890e365770..5ba8a9abedb98e185265945bde408e9079bdd621 100644 (file)
@@ -93,4 +93,16 @@ public class InstructionByte extends Instruction {
        public final Type getType() {
                return new ArrayType(BasicType.getType(theByte), 1);
        }
+
+       public boolean equals(Object other) {
+               if (!(other instanceof InstructionByte)) {
+                       return false;
+               }
+               InstructionByte o = (InstructionByte) other;
+               return o.opcode == opcode && o.theByte == theByte;
+       }
+
+       public int hashCode() {
+               return opcode * 37 + theByte;
+       }
 }
\ No newline at end of file
index e2b4f9c683a9dedd65346f9fda643af17d527fa8..09222d6a479ffb8a7326a4f79536b67419cb241c 100644 (file)
@@ -60,24 +60,22 @@ import java.io.IOException;
 import org.aspectj.apache.bcel.Constants;
 import org.aspectj.apache.bcel.classfile.Constant;
 import org.aspectj.apache.bcel.classfile.ConstantClass;
+import org.aspectj.apache.bcel.classfile.ConstantDouble;
+import org.aspectj.apache.bcel.classfile.ConstantFloat;
+import org.aspectj.apache.bcel.classfile.ConstantInteger;
+import org.aspectj.apache.bcel.classfile.ConstantLong;
 import org.aspectj.apache.bcel.classfile.ConstantPool;
-
-import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
-import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL;
-import com.sun.org.apache.bcel.internal.generic.LDC;
+import org.aspectj.apache.bcel.classfile.ConstantString;
+import org.aspectj.apache.bcel.classfile.ConstantUtf8;
 
 /**
- * Slass for instructions that use an index into the constant pool such as LDC, INVOKEVIRTUAL, etc.
- * 
- * @see ConstantPoolGen
- * @see LDC
- * @see INVOKEVIRTUAL
+ * Class for instructions that use an index into the constant pool such as LDC, INVOKEVIRTUAL, etc.
  * 
- * @version $Id: InstructionCP.java,v 1.5 2009/09/14 20:29:10 aclement Exp $
+ * @version $Id: InstructionCP.java,v 1.6 2009/10/05 17:35:36 aclement Exp $
  * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  */
 public class InstructionCP extends Instruction {
-       protected int index; // index to constant pool
+       protected int index;
 
        public InstructionCP(short opcode, int index) {
                super(opcode);
@@ -180,36 +178,47 @@ public class InstructionCP extends Instruction {
                        } else {
                                return Type.getType(name);
                        }
-               default: // Never reached
+               default:
                        throw new RuntimeException("Unknown or invalid constant type at " + index);
                }
        }
 
        @Override
-       public Object getValue(ConstantPool cpg) {
-               org.aspectj.apache.bcel.classfile.Constant c = cpg.getConstant(index);
+       public Object getValue(ConstantPool constantPool) {
+               Constant constant = constantPool.getConstant(index);
 
-               switch (c.getTag()) {
-               case org.aspectj.apache.bcel.Constants.CONSTANT_String:
-                       int i = ((org.aspectj.apache.bcel.classfile.ConstantString) c).getStringIndex();
-                       c = cpg.getConstant(i);
-                       return ((org.aspectj.apache.bcel.classfile.ConstantUtf8) c).getValue();
+               switch (constant.getTag()) {
+               case Constants.CONSTANT_String:
+                       int i = ((ConstantString) constant).getStringIndex();
+                       constant = constantPool.getConstant(i);
+                       return ((ConstantUtf8) constant).getValue();
 
-               case org.aspectj.apache.bcel.Constants.CONSTANT_Float:
-                       return new Float(((org.aspectj.apache.bcel.classfile.ConstantFloat) c).getValue());
+               case Constants.CONSTANT_Float:
+                       return ((ConstantFloat) constant).getValue();
 
-               case org.aspectj.apache.bcel.Constants.CONSTANT_Integer:
-                       return new Integer(((org.aspectj.apache.bcel.classfile.ConstantInteger) c).getValue());
+               case Constants.CONSTANT_Integer:
+                       return ((ConstantInteger) constant).getValue();
 
-                       // from ldc2_w:
-               case org.aspectj.apache.bcel.Constants.CONSTANT_Long:
-                       return new Long(((org.aspectj.apache.bcel.classfile.ConstantLong) c).getValue());
+               case Constants.CONSTANT_Long:
+                       return ((ConstantLong) constant).getValue();
 
-               case org.aspectj.apache.bcel.Constants.CONSTANT_Double:
-                       return new Double(((org.aspectj.apache.bcel.classfile.ConstantDouble) c).getValue());
-               default: // Never reached
+               case Constants.CONSTANT_Double:
+                       return ((ConstantDouble) constant).getValue();
+               default:
                        throw new RuntimeException("Unknown or invalid constant type at " + index);
                }
        }
 
+       public boolean equals(Object other) {
+               if (!(other instanceof InstructionCP)) {
+                       return false;
+               }
+               InstructionCP o = (InstructionCP) other;
+               return o.opcode == opcode && o.index == index;
+       }
+
+       public int hashCode() {
+               return opcode * 37 + index;
+       }
+
 }
index d114a600ee0f1c08a7e2705e5feff5a34cd8e540..2f2691df12e241a539184602d2184098bc2fa64f 100644 (file)
@@ -68,7 +68,7 @@ import org.aspectj.apache.bcel.classfile.Utility;
  * doubly-linked list. From the outside only the next and the previous instruction (handle) are accessible. One can traverse the
  * list via an Enumeration returned by InstructionList.elements().
  * 
- * @version $Id: InstructionHandle.java,v 1.8 2009/09/28 16:39:46 aclement Exp $
+ * @version $Id: InstructionHandle.java,v 1.9 2009/10/05 17:35:36 aclement Exp $
  * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  * @see Instruction
  * @see BranchHandle
@@ -77,9 +77,17 @@ import org.aspectj.apache.bcel.classfile.Utility;
 public class InstructionHandle implements java.io.Serializable {
        InstructionHandle next, prev; // Will be set from the outside
        Instruction instruction;
-       protected int i_position = -1; // byte code offset of instruction
+       protected int pos = -1; // byte code offset of instruction
        private Set<InstructionTargeter> targeters = Collections.emptySet();
 
+       protected InstructionHandle(Instruction i) {
+               setInstruction(i);
+       }
+
+       static final InstructionHandle getInstructionHandle(Instruction i) {
+               return new InstructionHandle(i);
+       }
+
        public final InstructionHandle getNext() {
                return next;
        }
@@ -102,41 +110,19 @@ public class InstructionHandle implements java.io.Serializable {
                instruction = i;
        }
 
-       protected InstructionHandle(Instruction i) {
-               setInstruction(i);
-       }
-
-       static final InstructionHandle getInstructionHandle(Instruction i) {
-               return new InstructionHandle(i);
-       }
-
-       /**
-        * Called by InstructionList.setPositions when setting the position for every instruction. In the presence of variable length
-        * instructions 'setPositions()' performs multiple passes over the instruction list to calculate the correct (byte) positions
-        * and offsets by calling this function.
-        * 
-        * @param offset additional offset caused by preceding (variable length) instructions
-        * @param max_offset the maximum offset that may be caused by these instructions
-        * @return additional offset caused by possible change of this instruction's length
-        */
-       protected int updatePosition(int offset, int max_offset) {
-               i_position += offset;
-               return 0;
-       }
-
        /**
         * @return the position, i.e., the byte code offset of the contained instruction. This is accurate only after
         *         InstructionList.setPositions() has been called.
         */
        public int getPosition() {
-               return i_position;
+               return pos;
        }
 
        /**
         * Set the position, i.e., the byte code offset of the contained instruction.
         */
        void setPosition(int pos) {
-               i_position = pos;
+               this.pos = pos;
        }
 
        /**
@@ -147,7 +133,7 @@ public class InstructionHandle implements java.io.Serializable {
                next = prev = null;
                instruction.dispose();
                instruction = null;
-               i_position = -1;
+               pos = -1;
                removeAllTargeters();
        }
 
@@ -179,7 +165,6 @@ public class InstructionHandle implements java.io.Serializable {
                return !targeters.isEmpty();
        }
 
-
        public Set<InstructionTargeter> getTargeters() {
                return targeters;
        }
@@ -194,7 +179,7 @@ public class InstructionHandle implements java.io.Serializable {
         * @return a (verbose) string representation of the contained instruction.
         */
        public String toString(boolean verbose) {
-               return Utility.format(i_position, 4, false, ' ') + ": " + instruction.toString(verbose);
+               return Utility.format(pos, 4, false, ' ') + ": " + instruction.toString(verbose);
        }
 
        public String toString() {
index b49a768708b277367bc8bf9d7d6aa7204ba172ba..73c27801603cb3d04501c4176845df54582bb599 100644 (file)
@@ -61,7 +61,7 @@ import org.aspectj.apache.bcel.Constants;
 /**
  * Abstract super class for instructions dealing with local variables.
  * 
- * @version $Id: InstructionLV.java,v 1.4 2008/08/28 00:05:01 aclement Exp $
+ * @version $Id: InstructionLV.java,v 1.5 2009/10/05 17:35:36 aclement Exp $
  * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  */
 public class InstructionLV extends Instruction {
@@ -263,4 +263,16 @@ public class InstructionLV extends Instruction {
                return lvar > Constants.MAX_BYTE;
        }
 
+       public boolean equals(Object other) {
+               if (!(other instanceof InstructionLV)) {
+                       return false;
+               }
+               InstructionLV o = (InstructionLV) other;
+               return o.opcode == opcode && o.lvar == lvar;
+       }
+
+       public int hashCode() {
+               return opcode * 37 + lvar;
+       }
+
 }
index 46d1198d19d188c0bdc79fc1acb9bf8a383fdea3..c5e2ab66f9f3dda16440a8433b336a438ff32016 100644 (file)
@@ -76,7 +76,7 @@ import org.aspectj.apache.bcel.util.ByteSequence;
  * 
  * A list is finally dumped to a byte code array with <a href="#getByteCode()">getByteCode</a>.
  * 
- * @version $Id: InstructionList.java,v 1.9 2009/09/10 03:59:33 aclement Exp $
+ * @version $Id: InstructionList.java,v 1.10 2009/10/05 17:35:36 aclement Exp $
  * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  * @see Instruction
  * @see InstructionHandle
@@ -247,35 +247,34 @@ public class InstructionList implements Serializable {
        /**
         * Append another list after instruction (handle) ih contained in this list. Consumes argument list, i.e., it becomes empty.
         * 
-        * @param ih where to append the instruction list
-        * @param il Instruction list to append to this one
+        * @param appendTo where to append the instruction list
+        * @param appendee Instruction list to append to this one
         * @return instruction handle pointing to the <B>first</B> appended instruction
         */
-       public InstructionHandle append(InstructionHandle ih, InstructionList il) {
-               if (il == null) {
-                       throw new ClassGenException("Appending null InstructionList");
-               }
+       public InstructionHandle append(InstructionHandle appendTo, InstructionList appendee) {
+               assert appendee != null;
 
-               if (il.isEmpty()) {
-                       return ih;
+               if (appendee.isEmpty()) {
+                       return appendTo;
                }
 
-               InstructionHandle next = ih.next, ret = il.start;
+               InstructionHandle next = appendTo.next;
+               InstructionHandle ret = appendee.start;
 
-               ih.next = il.start;
-               il.start.prev = ih;
+               appendTo.next = appendee.start;
+               appendee.start.prev = appendTo;
 
-               il.end.next = next;
+               appendee.end.next = next;
 
                if (next != null) {
-                       next.prev = il.end;
+                       next.prev = appendee.end;
                } else {
-                       end = il.end; // Update end ...
+                       end = appendee.end; // Update end ...
                }
 
-               length += il.length; // Update length
+               length += appendee.length; // Update length
 
-               il.clear();
+               appendee.clear();
 
                return ret;
        }
@@ -304,9 +303,7 @@ public class InstructionList implements Serializable {
         * @return instruction handle of the <B>first</B> appended instruction
         */
        public InstructionHandle append(InstructionList il) {
-               if (il == null) {
-                       throw new ClassGenException("Appending null InstructionList");
-               }
+               assert il != null;
 
                if (il.isEmpty()) {
                        return null;
@@ -853,41 +850,13 @@ public class InstructionList implements Serializable {
         * @param check Perform sanity checks, e.g. if all targeted instructions really belong to this list
         */
        public void setPositions(boolean check) {
-               int max_additional_bytes = 0, additional_bytes = 0;
+               int maxAdditionalBytes = 0;
                int index = 0, count = 0;
                int[] pos = new int[length];
 
                // Pass 0: Sanity checks
                if (check) {
-                       for (InstructionHandle ih = start; ih != null; ih = ih.next) {
-                               Instruction i = ih.instruction;
-
-                               if (i instanceof InstructionBranch) { // target instruction within list?
-                                       Instruction inst = ((InstructionBranch) i).getTarget().instruction;
-                                       if (!contains(inst)) {
-                                               throw new ClassGenException("Branch target of " + Constants.OPCODE_NAMES[i.opcode] + ":" + inst
-                                                               + " not in instruction list");
-                                       }
-
-                                       if (i instanceof InstructionSelect) {
-                                               InstructionHandle[] targets = ((InstructionSelect) i).getTargets();
-
-                                               for (int j = 0; j < targets.length; j++) {
-                                                       inst = targets[j].instruction;
-                                                       if (!contains(inst)) {
-                                                               throw new ClassGenException("Branch target of " + Constants.OPCODE_NAMES[i.opcode] + ":" + inst
-                                                                               + " not in instruction list");
-                                                       }
-                                               }
-                                       }
-
-                                       if (!(ih instanceof BranchHandle)) {
-                                               throw new ClassGenException("Branch instruction " + Constants.OPCODE_NAMES[i.opcode] + ":" + inst
-                                                               + " not contained in BranchHandle.");
-                                       }
-
-                               }
-                       }
+                       checkInstructionList();
                }
 
                // Pass 1: Set position numbers and sum up the maximum number of bytes an
@@ -904,40 +873,81 @@ public class InstructionList implements Serializable {
                        switch (i.opcode) {
                        case Constants.JSR:
                        case Constants.GOTO:
-                               max_additional_bytes += 2;
+                               maxAdditionalBytes += 2;
                                break;
 
                        case Constants.TABLESWITCH:
                        case Constants.LOOKUPSWITCH:
-                               max_additional_bytes += 3;
+                               maxAdditionalBytes += 3;
                                break;
                        }
                        index += i.getLength();
                }
 
+               // OPTIMIZE positions will only move around if there have been expanding instructions
+               // if (max_additional_bytes==0...) {
+               //                      
+               // }
+
                /*
                 * Pass 2: Expand the variable-length (Branch)Instructions depending on the target offset (short or int) and ensure that
                 * branch targets are within this list.
                 */
+               int offset = 0;
                for (InstructionHandle ih = start; ih != null; ih = ih.next) {
-                       additional_bytes += ih.updatePosition(additional_bytes, max_additional_bytes);
+                       if (ih instanceof BranchHandle) {
+                               offset += ((BranchHandle) ih).updatePosition(offset, maxAdditionalBytes);
+                       }
                }
-
-               /*
-                * Pass 3: Update position numbers (which may have changed due to the preceding expansions), like pass 1.
-                */
-               index = count = 0;
-               for (InstructionHandle ih = start; ih != null; ih = ih.next) {
-                       Instruction i = ih.instruction;
-                       ih.setPosition(index);
-                       pos[count++] = index;
-                       index += i.getLength();
+               if (offset != 0) {
+                       /*
+                        * Pass 3: Update position numbers (which may have changed due to the preceding expansions), like pass 1.
+                        */
+                       index = count = 0;
+                       for (InstructionHandle ih = start; ih != null; ih = ih.next) {
+                               Instruction i = ih.instruction;
+                               ih.setPosition(index);
+                               pos[count++] = index;
+                               index += i.getLength();
+                       }
                }
 
                positions = new int[count]; // Trim to proper size
                System.arraycopy(pos, 0, positions, 0, count);
        }
 
+       private void checkInstructionList() {
+               for (InstructionHandle ih = start; ih != null; ih = ih.next) {
+                       Instruction i = ih.instruction;
+
+                       if (i instanceof InstructionBranch) { // target instruction within list?
+                               Instruction inst = ((InstructionBranch) i).getTarget().instruction;
+                               if (!contains(inst)) {
+                                       throw new ClassGenException("Branch target of " + Constants.OPCODE_NAMES[i.opcode] + ":" + inst
+                                                       + " not in instruction list");
+                               }
+
+                               if (i instanceof InstructionSelect) {
+                                       InstructionHandle[] targets = ((InstructionSelect) i).getTargets();
+
+                                       for (int j = 0; j < targets.length; j++) {
+                                               inst = targets[j].instruction;
+                                               if (!contains(inst)) {
+                                                       throw new ClassGenException("Branch target of " + Constants.OPCODE_NAMES[i.opcode] + ":" + inst
+                                                                       + " not in instruction list");
+                                               }
+                                       }
+                               }
+
+                               if (!(ih instanceof BranchHandle)) {
+                                       throw new ClassGenException("Branch instruction " + Constants.OPCODE_NAMES[i.opcode] + ":" + inst
+                                                       + " not contained in BranchHandle.");
+                               }
+
+                       }
+               }
+       }
+
        /**
         * When everything is finished, use this method to convert the instruction list into an array of bytes.
         * 
index dcebe3a0f8f8382e030189265c1b49d71b7e27ce..b4e00c027d833cebd18843deb6525820ec114f87 100644 (file)
@@ -61,7 +61,7 @@ import org.aspectj.apache.bcel.util.ByteSequence;
 /**
  * Select - Abstract super class for LOOKUPSWITCH and TABLESWITCH instructions.
  * 
- * @version $Id: InstructionSelect.java,v 1.3 2008/08/28 00:05:41 aclement Exp $
+ * @version $Id: InstructionSelect.java,v 1.4 2009/10/05 17:35:36 aclement Exp $
  * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  * @see LOOKUPSWITCH
  * @see TABLESWITCH
@@ -78,15 +78,13 @@ public abstract class InstructionSelect extends InstructionBranch {
        protected short length;
 
        /**
-        * (Match, target) pairs for switch. `Match' and `targets' must have the
-        * same length of course.
+        * (Match, target) pairs for switch. `Match' and `targets' must have the same length of course.
         * 
         * @param match array of matching values
         * @param targets instruction targets
         * @param target default instruction target
         */
-       InstructionSelect(short opcode, int[] match, InstructionHandle[] targets,
-                       InstructionHandle target) {
+       InstructionSelect(short opcode, int[] match, InstructionHandle[] targets, InstructionHandle target) {
                super(opcode, target);
 
                this.targets = targets;
@@ -97,8 +95,7 @@ public abstract class InstructionSelect extends InstructionBranch {
                this.match = match;
 
                if ((matchLength = match.length) != targets.length) {
-                       throw new ClassGenException(
-                                       "Match and target array have not the same length");
+                       throw new ClassGenException("Match and target array have not the same length");
                }
 
                indices = new int[matchLength];
@@ -106,37 +103,30 @@ public abstract class InstructionSelect extends InstructionBranch {
 
        protected int getTargetOffset(InstructionHandle target) {
                if (target == null) {
-                       throw new ClassGenException("Target of " + super.toString(true)
-                                       + " is invalid null handle");
+                       throw new ClassGenException("Target of " + super.toString(true) + " is invalid null handle");
                }
 
                int t = target.getPosition();
 
                if (t < 0) {
-                       throw new ClassGenException(
-                                       "Invalid branch target position offset for "
-                                                       + super.toString(true) + ":" + t + ":" + target);
+                       throw new ClassGenException("Invalid branch target position offset for " + super.toString(true) + ":" + t + ":"
+                                       + target);
                }
 
                return t - positionOfThisInstruction;
        }
 
        /**
-        * Since this is a variable length instruction, it may shift the following
-        * instructions which then need to update their position.
+        * Since this is a variable length instruction, it may shift the following instructions which then need to update their
+        * position.
         * 
-        * Called by InstructionList.setPositions when setting the position for
-        * every instruction. In the presence of variable length instructions
-        * `setPositions' performs multiple passes over the instruction list to
-        * calculate the correct (byte) positions and offsets by calling this
-        * function.
+        * Called by InstructionList.setPositions when setting the position for every instruction. In the presence of variable length
+        * instructions `setPositions' performs multiple passes over the instruction list to calculate the correct (byte) positions and
+        * offsets by calling this function.
         * 
-        * @param offset additional offset caused by preceding (variable length)
-        *        instructions
-        * @param max_offset the maximum offset that may be caused by these
-        *        instructions
-        * @return additional offset caused by possible change of this instruction's
-        *         length
+        * @param offset additional offset caused by preceding (variable length) instructions
+        * @param max_offset the maximum offset that may be caused by these instructions
+        * @return additional offset caused by possible change of this instruction's length
         */
        protected int updatePosition(int offset, int max_offset) {
                positionOfThisInstruction += offset; // Additional offset caused by
@@ -170,8 +160,7 @@ public abstract class InstructionSelect extends InstructionBranch {
                out.writeInt(targetIndex);
        }
 
-       public InstructionSelect(short opcode, ByteSequence bytes)
-                       throws IOException {
+       public InstructionSelect(short opcode, ByteSequence bytes) throws IOException {
                super(opcode);
                padding = (4 - bytes.getIndex() % 4) % 4; // Compute number of pad bytes
 
@@ -198,8 +187,7 @@ public abstract class InstructionSelect extends InstructionBranch {
                                        s = targets[i].getInstruction().toString();
                                }
 
-                               buf.append("(" + match[i] + ", " + s + " = {" + indices[i]
-                                               + "})");
+                               buf.append("(" + match[i] + ", " + s + " = {" + indices[i] + "})");
                        }
                } else {
                        buf.append(" ...");
@@ -268,14 +256,6 @@ public abstract class InstructionSelect extends InstructionBranch {
                }
        }
 
-       public boolean equals(Object other) {
-               return this == other;
-       }
-
-       public int hashCode() {
-               return opcode * 37;
-       }
-
        /**
         * @return array of match indices
         */
@@ -290,6 +270,14 @@ public abstract class InstructionSelect extends InstructionBranch {
                return indices;
        }
 
+       public boolean equals(Object other) {
+               return this == other;
+       }
+
+       public int hashCode() {
+               return opcode * 37;
+       }
+
        /**
         * @return array of match targets
         */
index dd8a72eb0e356c97599b8331328f6253adbf0577..99054cbff43640c56939eab417c451be0505b4b1 100644 (file)
@@ -61,20 +61,32 @@ import java.io.IOException;
  * Instruction that needs one short
  */
 public class InstructionShort extends Instruction {
-       private final short s;
+       private final short value;
 
-       public InstructionShort(short opcode, short s) {
+       public InstructionShort(short opcode, short value) {
                super(opcode);
-               this.s = s;
+               this.value = value;
        }
 
        public void dump(DataOutputStream out) throws IOException {
                out.writeByte(opcode);
-               out.writeShort(s);
+               out.writeShort(value);
        }
 
        public String toString(boolean verbose) {
-               return super.toString(verbose) + " " + s;
+               return super.toString(verbose) + " " + value;
+       }
+
+       public boolean equals(Object other) {
+               if (!(other instanceof InstructionShort)) {
+                       return false;
+               }
+               InstructionShort o = (InstructionShort) other;
+               return o.opcode == opcode && o.value == value;
+       }
+
+       public int hashCode() {
+               return opcode * 37 + value;
        }
 
 }
index fbc55a66a847c37de9d3d61c71345e1efbdfe4b3..89cd43474f83a2d3658212c528c4e68b7a66e373 100644 (file)
@@ -61,72 +61,77 @@ import org.aspectj.apache.bcel.classfile.ConstantPool;
 
 /**
  * Super class for the INVOKExxx family of instructions.
- *
- * @version $Id: InvokeInstruction.java,v 1.5 2008/05/28 23:52:54 aclement Exp $
- * @author  <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * 
+ * @version $Id: InvokeInstruction.java,v 1.6 2009/10/05 17:35:36 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  */
 public class InvokeInstruction extends FieldOrMethod {
 
-  /**
-   * @param index to constant pool
-   */
-  public InvokeInstruction(short opcode, int index) {
-    super(opcode, index);
-  }
+       /**
+        * @param index to constant pool
+        */
+       public InvokeInstruction(short opcode, int index) {
+               super(opcode, index);
+       }
 
-  /**
-   * @return mnemonic for instruction with symbolic references resolved
-   */
-  public String toString(ConstantPool cp) {
-    Constant        c   = cp.getConstant(index);
-    StringTokenizer tok = new StringTokenizer(cp.constantToString(c));
+       /**
+        * @return mnemonic for instruction with symbolic references resolved
+        */
+       public String toString(ConstantPool cp) {
+               Constant c = cp.getConstant(index);
+               StringTokenizer tok = new StringTokenizer(cp.constantToString(c));
 
-    return Constants.OPCODE_NAMES[opcode] + " " +
-      tok.nextToken().replace('.', '/') + tok.nextToken();
-  }
+               return Constants.OPCODE_NAMES[opcode] + " " + tok.nextToken().replace('.', '/') + tok.nextToken();
+       }
 
-  /**
-   * Also works for instructions whose stack effect depends on the
-   * constant pool entry they reference.
-   * @return Number of words consumed from stack by this instruction
-   */
-  public int consumeStack(ConstantPool cpg) {
-      String signature = getSignature(cpg);
-      int sum = Type.getArgumentSizes(signature);
-      if (opcode!=Constants.INVOKESTATIC) sum+=1;
-      return sum;
-   }
+       /**
+        * Also works for instructions whose stack effect depends on the constant pool entry they reference.
+        * 
+        * @return Number of words consumed from stack by this instruction
+        */
+       public int consumeStack(ConstantPool cpg) {
+               String signature = getSignature(cpg);
+               int sum = Type.getArgumentSizes(signature);
+               if (opcode != Constants.INVOKESTATIC) {
+                       sum += 1;
+               }
+               return sum;
+       }
 
-  /**
-   * Also works for instructions whose stack effect depends on the
-   * constant pool entry they reference.
-   * @return Number of words produced onto stack by this instruction
-   */
-  public int produceStack(ConstantPool cpg) {
-    return getReturnType(cpg).getSize();
-  }
+       /**
+        * Also works for instructions whose stack effect depends on the constant pool entry they reference.
+        * 
+        * @return Number of words produced onto stack by this instruction
+        */
+       public int produceStack(ConstantPool cpg) {
+               return getReturnType(cpg).getSize();
+       }
 
-  /** @return return type of referenced method.
-   */
-  public Type getType(ConstantPool cpg) {
-    return getReturnType(cpg);
-  }
+       /**
+        * @return return type of referenced method.
+        */
+       public Type getType(ConstantPool cpg) {
+               return getReturnType(cpg);
+       }
 
-  /** @return name of referenced method.
-   */
-  public String getMethodName(ConstantPool cpg) {
-    return getName(cpg);
-  }
+       /**
+        * @return name of referenced method.
+        */
+       public String getMethodName(ConstantPool cpg) {
+               return getName(cpg);
+       }
 
-  /** @return return type of referenced method.
-   */
-  public Type getReturnType(ConstantPool cpg) {
-    return Type.getReturnType(getSignature(cpg));
-  }
+       /**
+        * @return return type of referenced method.
+        */
+       public Type getReturnType(ConstantPool cpg) {
+               return Type.getReturnType(getSignature(cpg));
+       }
 
-  /** @return argument types of referenced method.
-   */
-  public Type[] getArgumentTypes(ConstantPool cpg) {
-    return Type.getArgumentTypes(getSignature(cpg));
-  }
+       /**
+        * @return argument types of referenced method.
+        */
+       public Type[] getArgumentTypes(ConstantPool cpg) {
+               return Type.getArgumentTypes(getSignature(cpg));
+       }
 }
index 724f0cad82518752cff1b5675a2b4037426636d8..7a4fab4e9ff6da8c7970954a35953e21b4551c75 100644 (file)
 package org.aspectj.apache.bcel.generic;
 
 public final class LocalVariableTag extends Tag {
-       private Type type; // not always known, in which case signature has to be used
        private final String signature;
        private String name;
        private int slot;
-       private final int startPos;
-       boolean remapped = false;
+       private final int startPosition;
+       private boolean remapped = false;
+
+       private int hashCode = 0;
+       private Type type; // not always known, in which case signature has to be used
 
        // AMC - pr101047, two local vars with the same name can share the same slot, but must in that case
        // have different start positions.
-       public LocalVariableTag(String sig, String name, int slot, int startPosition) {
-               this.signature = sig;
+       public LocalVariableTag(String signature, String name, int slot, int startPosition) {
+               this.signature = signature;
                this.name = name;
                this.slot = slot;
-               this.startPos = startPosition;
+               this.startPosition = startPosition;
        }
 
-       public LocalVariableTag(Type t, String sig, String name, int slot, int startPosition) {
-               this.type = t;
-               this.signature = sig;
+       public LocalVariableTag(Type type, String signature, String name, int slot, int startPosition) {
+               this.type = type;
+               this.signature = signature;
                this.name = name;
                this.slot = slot;
-               this.startPos = startPosition;
+               this.startPosition = startPosition;
        }
 
        public String getName() {
@@ -57,6 +59,12 @@ public final class LocalVariableTag extends Tag {
        public void updateSlot(int newSlot) {
                this.slot = newSlot;
                this.remapped = true;
+               this.hashCode = 0;
+       }
+
+       public void setName(String name) {
+               this.name = name;
+               this.hashCode = 0;
        }
 
        public boolean isRemapped() {
@@ -68,25 +76,19 @@ public final class LocalVariableTag extends Tag {
        }
 
        public boolean equals(Object other) {
-               if (!(other instanceof LocalVariableTag))
+               if (!(other instanceof LocalVariableTag)) {
                        return false;
+               }
                LocalVariableTag o = (LocalVariableTag) other;
-               return o.slot == slot && o.startPos == startPos && o.signature.equals(signature) && o.name.equals(name);
+               return o.slot == slot && o.startPosition == startPosition && o.signature.equals(signature) && o.name.equals(name);
        }
 
-       public void setName(String name) {
-               this.name = name;
-       }
-
-       private int hashCode = 0;
-
        public int hashCode() {
                if (hashCode == 0) {
-                       int ret = 17;
-                       ret = 37 * ret + signature.hashCode();
+                       int ret = signature.hashCode();
                        ret = 37 * ret + name.hashCode();
                        ret = 37 * ret + slot;
-                       ret = 37 * ret + startPos;
+                       ret = 37 * ret + startPosition;
                        hashCode = ret;
                }
                return hashCode;
index eddc2e9957ecf4fc716cffad8679ad7e4cd1c654..94a213a253e7e506a2d4de7e2b68fbcde63c0ea5 100644 (file)
@@ -53,109 +53,131 @@ package org.aspectj.apache.bcel.generic;
  * information on the Apache Software Foundation, please see
  * <http://www.apache.org/>.
  */
-import java.io.*;
-import org.aspectj.apache.bcel.classfile.ConstantPool;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
 import org.aspectj.apache.bcel.Constants;
 import org.aspectj.apache.bcel.ExceptionConstants;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
 
-/** 
+/**
  * MULTIANEWARRAY - Create new mutidimensional array of references
- * <PRE>Stack: ..., count1, [count2, ...] -&gt; ..., arrayref</PRE>
- *
- * @version $Id: MULTIANEWARRAY.java,v 1.3 2008/05/28 23:52:59 aclement Exp $
- * @author  <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * 
+ * <PRE>
+ * Stack: ..., count1, [count2, ...] -&gt; ..., arrayref
+ * </PRE>
+ * 
+ * @version $Id: MULTIANEWARRAY.java,v 1.4 2009/10/05 17:35:36 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  */
 public class MULTIANEWARRAY extends InstructionCP {
-  private short dimensions;
-
-  public MULTIANEWARRAY(int index, short dimensions) {
-    super(Constants.MULTIANEWARRAY, index);
-    this.dimensions = dimensions;
-  }
-
-  /**
-   * Dump instruction as byte code to stream out.
-   * @param out Output stream
-   */
-  public void dump(DataOutputStream out) throws IOException {
-    out.writeByte(opcode);
-    out.writeShort(index);
-    out.writeByte(dimensions);
-  }
-
-  /**
-   * Read needed data (i.e., no. dimension) from file.
-   */
-//  protected void initFromFile(ByteSequence bytes, boolean wide)
-//       throws IOException
-//  {
-//    super.initFromFile(bytes, wide);
-//    dimensions = bytes.readByte();
-////    length     = 4;
-//  }
-
-  /**
-   * @return number of dimensions to be created
-   */
-  public final short getDimensions() { return dimensions; }
-
-  /**
-   * @return mnemonic for instruction
-   */
-  public String toString(boolean verbose) {
-    return super.toString(verbose) + " " + index + " " + dimensions;
-  }
-
-  /**
-   * @return mnemonic for instruction with symbolic references resolved
-   */
-  public String toString(ConstantPool cp) {
-    return super.toString(cp) + " " + dimensions;
-  }
-
-  /**
-   * Also works for instructions whose stack effect depends on the
-   * constant pool entry they reference.
-   * @return Number of words consumed from stack by this instruction
-   */
-  public int consumeStack(ConstantPool cpg) { return dimensions; }
-
-  public Class[] getExceptions() {
-    Class[] cs = new Class[2 + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length];
-
-    System.arraycopy(ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 0,
-                    cs, 0, ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length);
-
-    cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length+1] = ExceptionConstants.NEGATIVE_ARRAY_SIZE_EXCEPTION;
-    cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length]   = ExceptionConstants.ILLEGAL_ACCESS_ERROR;
-
-    return cs;
-  }
-
-  public ObjectType getLoadClassType(ConstantPool cpg) {
-    Type t = getType(cpg);
-    
-    if (t instanceof ArrayType){
-      t = ((ArrayType) t).getBasicType();
-    }
-    
-    return (t instanceof ObjectType)? (ObjectType) t : null;
-  }
-
-//  /**
-//   * Call corresponding visitor method(s). The order is:
-//   * Call visitor methods of implemented interfaces first, then
-//   * call methods according to the class hierarchy in descending order,
-//   * i.e., the most specific visitXXX() call comes last.
-//   *
-//   * @param v Visitor object
-//   */
-//  public void accept(Visitor v) {
-//    v.visitLoadClass(this);
-//    v.visitAllocationInstruction(this);
-//    v.visitExceptionThrower(this);
-//    v.visitTypedInstruction(this);
-//    v.visitCPInstruction(this);
-//    v.visitMULTIANEWARRAY(this);
-//  }
+       private short dimensions;
+
+       public MULTIANEWARRAY(int index, short dimensions) {
+               super(Constants.MULTIANEWARRAY, index);
+               this.dimensions = dimensions;
+       }
+
+       /**
+        * Dump instruction as byte code to stream out.
+        * 
+        * @param out Output stream
+        */
+       public void dump(DataOutputStream out) throws IOException {
+               out.writeByte(opcode);
+               out.writeShort(index);
+               out.writeByte(dimensions);
+       }
+
+       /**
+        * Read needed data (i.e., no. dimension) from file.
+        */
+       // protected void initFromFile(ByteSequence bytes, boolean wide)
+       // throws IOException
+       // {
+       // super.initFromFile(bytes, wide);
+       // dimensions = bytes.readByte();
+       // // length = 4;
+       // }
+
+       /**
+        * @return number of dimensions to be created
+        */
+       public final short getDimensions() {
+               return dimensions;
+       }
+
+       /**
+        * @return mnemonic for instruction
+        */
+       public String toString(boolean verbose) {
+               return super.toString(verbose) + " " + index + " " + dimensions;
+       }
+
+       /**
+        * @return mnemonic for instruction with symbolic references resolved
+        */
+       public String toString(ConstantPool cp) {
+               return super.toString(cp) + " " + dimensions;
+       }
+
+       /**
+        * Also works for instructions whose stack effect depends on the constant pool entry they reference.
+        * 
+        * @return Number of words consumed from stack by this instruction
+        */
+       public int consumeStack(ConstantPool cpg) {
+               return dimensions;
+       }
+
+       public Class[] getExceptions() {
+               Class[] cs = new Class[2 + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length];
+
+               System.arraycopy(ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 0, cs, 0,
+                               ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length);
+
+               cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length + 1] = ExceptionConstants.NEGATIVE_ARRAY_SIZE_EXCEPTION;
+               cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length] = ExceptionConstants.ILLEGAL_ACCESS_ERROR;
+
+               return cs;
+       }
+
+       public ObjectType getLoadClassType(ConstantPool cpg) {
+               Type t = getType(cpg);
+
+               if (t instanceof ArrayType) {
+                       t = ((ArrayType) t).getBasicType();
+               }
+
+               return (t instanceof ObjectType) ? (ObjectType) t : null;
+       }
+
+       // /**
+       // * Call corresponding visitor method(s). The order is:
+       // * Call visitor methods of implemented interfaces first, then
+       // * call methods according to the class hierarchy in descending order,
+       // * i.e., the most specific visitXXX() call comes last.
+       // *
+       // * @param v Visitor object
+       // */
+       // public void accept(Visitor v) {
+       // v.visitLoadClass(this);
+       // v.visitAllocationInstruction(this);
+       // v.visitExceptionThrower(this);
+       // v.visitTypedInstruction(this);
+       // v.visitCPInstruction(this);
+       // v.visitMULTIANEWARRAY(this);
+       // }
+
+       public boolean equals(Object other) {
+               if (!(other instanceof MULTIANEWARRAY)) {
+                       return false;
+               }
+               MULTIANEWARRAY o = (MULTIANEWARRAY) other;
+               return o.opcode == opcode && o.index == index && o.dimensions == dimensions;
+       }
+
+       public int hashCode() {
+               return opcode * 37 + index * (dimensions + 17);
+       }
 }
index 15c9000e917a97220cdc7044db3166eea10afe0e..94c42938ff3a7d881f6ffc66d3e7e51d9ccd20fc 100644 (file)
@@ -84,7 +84,7 @@ import org.aspectj.apache.bcel.classfile.annotation.RuntimeParamAnnos;
  * While generating code it may be necessary to insert NOP operations. You can use the `removeNOPs' method to get rid off them. The
  * resulting method object can be obtained via the `getMethod()' method.
  * 
- * @version $Id: MethodGen.java,v 1.15 2009/09/15 19:40:14 aclement Exp $
+ * @version $Id: MethodGen.java,v 1.16 2009/10/05 17:35:36 aclement Exp $
  * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  * @author <A HREF="http://www.vmeng.com/beard">Patrick C. Beard</A> [setMaxStack()]
  * @see InstructionList
@@ -264,8 +264,9 @@ public class MethodGen extends FieldGenOrMethodGen {
                                                        for (int k = 0; k < ln.length; k++) {
                                                                LineNumber l = ln[k];
                                                                int lnum = l.getLineNumber();
-                                                               if (lnum > highestLineNumber)
+                                                               if (lnum > highestLineNumber) {
                                                                        highestLineNumber = lnum;
+                                                               }
                                                                LineNumberTag lt = new LineNumberTag(lnum);
                                                                il.findHandle(l.getStartPC(), arrayOfInstructions, true).addTargeter(lt);
                                                        }
@@ -290,8 +291,9 @@ public class MethodGen extends FieldGenOrMethodGen {
                                                                byte b = t.getType();
                                                                if (b != Constants.T_ADDRESS) {
                                                                        int increment = t.getSize();
-                                                                       if (l.getIndex() + increment > maxLocals)
+                                                                       if (l.getIndex() + increment > maxLocals) {
                                                                                maxLocals = l.getIndex() + increment;
+                                                                       }
                                                                }
                                                                int end = l.getStartPC() + l.getLength();
                                                                do {
@@ -311,24 +313,29 @@ public class MethodGen extends FieldGenOrMethodGen {
                                                                InstructionHandle end = il.findHandle(l.getStartPC() + l.getLength(), arrayOfInstructions);
                                                                // AMC, this actually gives us the first instruction AFTER the range,
                                                                // so move back one... (findHandle can't cope with mid-instruction indices)
-                                                               if (end != null)
+                                                               if (end != null) {
                                                                        end = end.getPrev();
+                                                               }
                                                                // Repair malformed handles
-                                                               if (null == start)
+                                                               if (null == start) {
                                                                        start = il.getStart();
-                                                               if (null == end)
+                                                               }
+                                                               if (null == end) {
                                                                        end = il.getEnd();
+                                                               }
 
                                                                addLocalVariable(l.getName(), Type.getType(l.getSignature()), l.getIndex(), start, end);
                                                        }
                                                }
-                                       } else
+                                       } else {
                                                addCodeAttribute(a);
+                                       }
                                }
                        } else if (a instanceof ExceptionTable) {
                                String[] names = ((ExceptionTable) a).getExceptionNames();
-                               for (int j = 0; j < names.length; j++)
+                               for (int j = 0; j < names.length; j++) {
                                        addException(names[j]);
+                               }
                        } else if (a instanceof RuntimeAnnos) {
                                RuntimeAnnos runtimeAnnotations = (RuntimeAnnos) a;
                                List<AnnotationGen> l = runtimeAnnotations.getAnnotations();
@@ -395,10 +402,12 @@ public class MethodGen extends FieldGenOrMethodGen {
                LocalVariableGen h;
 
                do {
-                       while (vars[i].getIndex() < m)
+                       while (vars[i].getIndex() < m) {
                                i++;
-                       while (m < vars[j].getIndex())
+                       }
+                       while (m < vars[j].getIndex()) {
                                j--;
+                       }
 
                        if (i <= j) {
                                h = vars[i];
@@ -409,10 +418,12 @@ public class MethodGen extends FieldGenOrMethodGen {
                        }
                } while (i <= j);
 
-               if (l < j)
+               if (l < j) {
                        sort(vars, l, j);
-               if (i < r)
+               }
+               if (i < r) {
                        sort(vars, i, r);
+               }
        }
 
        /*
@@ -427,15 +438,18 @@ public class MethodGen extends FieldGenOrMethodGen {
                localVariablesList.toArray(lg);
 
                for (int i = 0; i < size; i++) {
-                       if (lg[i].getStart() == null)
+                       if (lg[i].getStart() == null) {
                                lg[i].setStart(il.getStart());
+                       }
 
-                       if (lg[i].getEnd() == null)
+                       if (lg[i].getEnd() == null) {
                                lg[i].setEnd(il.getEnd());
+                       }
                }
 
-               if (size > 1)
+               if (size > 1) {
                        sort(lg, 0, size - 1);
+               }
 
                return lg;
        }
@@ -448,8 +462,9 @@ public class MethodGen extends FieldGenOrMethodGen {
                int size = lg.length;
                LocalVariable[] lv = new LocalVariable[size];
 
-               for (int i = 0; i < size; i++)
+               for (int i = 0; i < size; i++) {
                        lv[i] = lg[i].getLocalVariable(cp);
+               }
 
                return new LocalVariableTable(cp.addUtf8("LocalVariableTable"), 2 + lv.length * 10, lv, cp);
        }
@@ -516,8 +531,9 @@ public class MethodGen extends FieldGenOrMethodGen {
         */
        public CodeExceptionGen addExceptionHandler(InstructionHandle start_pc, InstructionHandle end_pc, InstructionHandle handler_pc,
                        ObjectType catch_type) {
-               if ((start_pc == null) || (end_pc == null) || (handler_pc == null))
+               if ((start_pc == null) || (end_pc == null) || (handler_pc == null)) {
                        throw new ClassGenException("Exception handler target is null instruction");
+               }
 
                CodeExceptionGen c = new CodeExceptionGen(start_pc, end_pc, handler_pc, catch_type);
                exceptionsList.add(c);
@@ -605,8 +621,9 @@ public class MethodGen extends FieldGenOrMethodGen {
                int[] ex = new int[size];
 
                try {
-                       for (int i = 0; i < size; i++)
+                       for (int i = 0; i < size; i++) {
                                ex[i] = cp.addClass(exceptionsThrown.get(i));
+                       }
                } catch (ArrayIndexOutOfBoundsException e) {
                }
 
@@ -625,8 +642,9 @@ public class MethodGen extends FieldGenOrMethodGen {
        }
 
        public void addParameterAnnotationsAsAttribute(ConstantPool cp) {
-               if (!hasParameterAnnotations)
+               if (!hasParameterAnnotations) {
                        return;
+               }
                Attribute[] attrs = Utility.getParameterAnnotationAttributes(cp, param_annotations);
                if (attrs != null) {
                        for (int i = 0; i < attrs.length; i++) {
@@ -674,8 +692,9 @@ public class MethodGen extends FieldGenOrMethodGen {
                 */
                byte[] byte_code = null;
 
-               if (il != null)
+               if (il != null) {
                        byte_code = il.getByteCode();
+               }
 
                LineNumberTable lnt = null;
                LocalVariableTable lvt = null;
@@ -684,11 +703,13 @@ public class MethodGen extends FieldGenOrMethodGen {
                /*
                 * Create LocalVariableTable and LineNumberTable attributes (for debuggers, e.g.)
                 */
-               if ((localVariablesList.size() > 0) && !stripAttributes)
+               if ((localVariablesList.size() > 0) && !stripAttributes) {
                        addCodeAttribute(lvt = getLocalVariableTable(cp));
+               }
 
-               if ((lineNumbersList.size() > 0) && !stripAttributes)
+               if ((lineNumbersList.size() > 0) && !stripAttributes) {
                        addCodeAttribute(lnt = getLineNumberTable(cp));
+               }
 
                Attribute[] code_attrs = getCodeAttributes();
 
@@ -696,8 +717,9 @@ public class MethodGen extends FieldGenOrMethodGen {
                 * Each attribute causes 6 additional header bytes
                 */
                int attrs_len = 0;
-               for (int i = 0; i < code_attrs.length; i++)
+               for (int i = 0; i < code_attrs.length; i++) {
                        attrs_len += (code_attrs[i].getLength() + 6);
+               }
 
                CodeException[] c_exc = getCodeExceptions();
                int exc_len = c_exc.length * 8; // Every entry takes 8 bytes
@@ -709,8 +731,9 @@ public class MethodGen extends FieldGenOrMethodGen {
                        List<Attribute> attributes = getAttributes();
                        for (int i = 0; i < attributes.size(); i++) {
                                Attribute a = attributes.get(i);
-                               if (a instanceof Code)
+                               if (a instanceof Code) {
                                        removeAttribute(a);
+                               }
                        }
 
                        code = new Code(cp.addUtf8("Code"), 8 + byte_code.length + // prologue byte code
@@ -726,21 +749,26 @@ public class MethodGen extends FieldGenOrMethodGen {
 
                ExceptionTable et = null;
 
-               if (exceptionsThrown.size() > 0)
+               if (exceptionsThrown.size() > 0) {
                        addAttribute(et = getExceptionTable(cp)); // Add `Exceptions' if there are "throws" clauses
+               }
 
                Method m = new Method(modifiers, name_index, signature_index, getAttributesImmutable(), cp);
 
                // Undo effects of adding attributes
                // OPTIMIZE why redo this? is there a better way to clean up?
-               if (lvt != null)
+               if (lvt != null) {
                        removeCodeAttribute(lvt);
-               if (lnt != null)
+               }
+               if (lnt != null) {
                        removeCodeAttribute(lnt);
-               if (code != null)
+               }
+               if (code != null) {
                        removeAttribute(code);
-               if (et != null)
+               }
+               if (et != null) {
                        removeAttribute(et);
+               }
                // J5TODO: Remove the annotation attributes that may have been added
                return m;
        }
@@ -807,10 +835,11 @@ public class MethodGen extends FieldGenOrMethodGen {
        }
 
        public String[] getArgumentNames() {
-               if (parameterNames != null)
+               if (parameterNames != null) {
                        return parameterNames.clone();
-               else
+               } else {
                        return new String[0];
+               }
        }
 
        public void setArgumentName(int i, String name) {
@@ -838,10 +867,11 @@ public class MethodGen extends FieldGenOrMethodGen {
         * Computes max. stack size by performing control flow analysis.
         */
        public void setMaxStack() {
-               if (il != null)
+               if (il != null) {
                        maxStack = getMaxStack(cp, il, getExceptionHandlers());
-               else
+               } else {
                        maxStack = 0;
+               }
        }
 
        /**
@@ -851,9 +881,11 @@ public class MethodGen extends FieldGenOrMethodGen {
                if (il != null) {
                        int max = isStatic() ? 0 : 1;
 
-                       if (parameterTypes != null)
-                               for (int i = 0; i < parameterTypes.length; i++)
+                       if (parameterTypes != null) {
+                               for (int i = 0; i < parameterTypes.length; i++) {
                                        max += parameterTypes[i].getSize();
+                               }
+                       }
 
                        for (InstructionHandle ih = il.getStart(); ih != null; ih = ih.getNext()) {
                                Instruction ins = ih.getInstruction();
@@ -861,14 +893,16 @@ public class MethodGen extends FieldGenOrMethodGen {
                                if ((ins instanceof InstructionLV) || (ins instanceof RET)) {
                                        int index = ins.getIndex() + ins.getType(cp).getSize();
 
-                                       if (index > max)
+                                       if (index > max) {
                                                max = index;
+                                       }
                                }
                        }
 
                        maxLocals = max;
-               } else
+               } else {
                        maxLocals = 0;
+               }
        }
 
        public void stripAttributes(boolean flag) {
@@ -890,8 +924,9 @@ public class MethodGen extends FieldGenOrMethodGen {
                Hashtable<InstructionHandle, BranchTarget> visitedTargets = new Hashtable<InstructionHandle, BranchTarget>();
 
                public void push(InstructionHandle target, int stackDepth) {
-                       if (visited(target))
+                       if (visited(target)) {
                                return;
+                       }
 
                        branchTargets.push(visit(target, stackDepth));
                }
@@ -925,17 +960,19 @@ public class MethodGen extends FieldGenOrMethodGen {
        public static int getMaxStack(ConstantPool cp, InstructionList il, CodeExceptionGen[] et) {
                BranchStack branchTargets = new BranchStack();
 
-               int stackDepth = 0, maxStackDepth = 0;
+               int stackDepth = 0;
+               int maxStackDepth = 0;
+
                /*
                 * Initially, populate the branch stack with the exception handlers, because these aren't (necessarily) branched to
-                * explicitly. in each case, the stack will have depth 1, containing the exception object.
+                * explicitly. In each case, the stack will have depth 1, containing the exception object.
                 */
-               for (int i = 0; i < et.length; i++) {
-                       InstructionHandle handler_pc = et[i].getHandlerPC();
-                       if (handler_pc != null) {
+               for (int i = 0, max = et.length; i < max; i++) {
+                       InstructionHandle handlerPos = et[i].getHandlerPC();
+                       if (handlerPos != null) {
                                // it must be at least 1 since there is an exception handler
                                maxStackDepth = 1;
-                               branchTargets.push(handler_pc, 1);
+                               branchTargets.push(handlerPos, 1);
                        }
                }
 
@@ -948,8 +985,9 @@ public class MethodGen extends FieldGenOrMethodGen {
                        int delta = prod - con;
 
                        stackDepth += delta;
-                       if (stackDepth > maxStackDepth)
+                       if (stackDepth > maxStackDepth) {
                                maxStackDepth = stackDepth;
+                       }
 
                        // choose the next instruction based on whether current is a branch.
                        if (instruction instanceof InstructionBranch) {
@@ -958,15 +996,17 @@ public class MethodGen extends FieldGenOrMethodGen {
                                        // explore all of the select's targets. the default target is handled below.
                                        InstructionSelect select = (InstructionSelect) branch;
                                        InstructionHandle[] targets = select.getTargets();
-                                       for (int i = 0; i < targets.length; i++)
+                                       for (int i = 0; i < targets.length; i++) {
                                                branchTargets.push(targets[i], stackDepth);
+                                       }
                                        // nothing to fall through to.
                                        ih = null;
                                } else if (!(branch.isIfInstruction())) {
                                        // if an instruction that comes back to following PC,
                                        // push next instruction, with stack depth reduced by 1.
-                                       if (opcode == Constants.JSR || opcode == Constants.JSR_W)
+                                       if (opcode == Constants.JSR || opcode == Constants.JSR_W) {
                                                branchTargets.push(ih.getNext(), stackDepth - 1);
+                                       }
                                        ih = null;
                                }
                                // for all branches, the target of the branch is pushed on the branch stack.
@@ -976,12 +1016,14 @@ public class MethodGen extends FieldGenOrMethodGen {
                        } else {
                                // check for instructions that terminate the method.
                                if (opcode == Constants.ATHROW || opcode == Constants.RET
-                                               || (opcode >= Constants.IRETURN && opcode <= Constants.RETURN))
+                                               || (opcode >= Constants.IRETURN && opcode <= Constants.RETURN)) {
                                        ih = null;
+                               }
                        }
                        // normal case, go to the next instruction.
-                       if (ih != null)
+                       if (ih != null) {
                                ih = ih.getNext();
+                       }
                        // if we have no more instructions, see if there are any deferred branches to explore.
                        if (ih == null) {
                                BranchTarget bt = branchTargets.pop();
@@ -1009,8 +1051,9 @@ public class MethodGen extends FieldGenOrMethodGen {
                StringBuffer buf = new StringBuffer(signature);
 
                if (exceptionsThrown.size() > 0) {
-                       for (Iterator<String> e = exceptionsThrown.iterator(); e.hasNext();)
+                       for (Iterator<String> e = exceptionsThrown.iterator(); e.hasNext();) {
                                buf.append("\n\t\tthrows " + e.next());
+                       }
                }
 
                return buf.toString();
@@ -1023,8 +1066,9 @@ public class MethodGen extends FieldGenOrMethodGen {
         */
        public List getAnnotationsOnParameter(int i) {
                ensureExistingParameterAnnotationsUnpacked();
-               if (!hasParameterAnnotations || i > parameterTypes.length)
+               if (!hasParameterAnnotations || i > parameterTypes.length) {
                        return null;
+               }
                return param_annotations[i];
        }
 
@@ -1055,10 +1099,11 @@ public class MethodGen extends FieldGenOrMethodGen {
 
                                hasParameterAnnotations = true;
                                RuntimeParamAnnos rpa = (RuntimeParamAnnos) attribute;
-                               if (rpa.areVisible())
+                               if (rpa.areVisible()) {
                                        paramAnnVisAttr = rpa;
-                               else
+                               } else {
                                        paramAnnInvisAttr = rpa;
+                               }
                                for (int j = 0; j < parameterTypes.length; j++) {
                                        // This returns Annotation[] ...
                                        AnnotationGen[] annos = rpa.getAnnotationsOnParameter(j);
@@ -1071,10 +1116,12 @@ public class MethodGen extends FieldGenOrMethodGen {
                                }
                        }
                }
-               if (paramAnnVisAttr != null)
+               if (paramAnnVisAttr != null) {
                        removeAttribute(paramAnnVisAttr);
-               if (paramAnnInvisAttr != null)
+               }
+               if (paramAnnInvisAttr != null) {
                        removeAttribute(paramAnnInvisAttr);
+               }
                haveUnpackedParameterAnnotations = true;
        }
 
index 1dc19d446f2a70d4913057e28256045f29711a7d..0fd2f498d8cc5a5ecf078ef8218d1f10286dd24c 100644 (file)
@@ -66,12 +66,12 @@ import org.aspectj.apache.bcel.classfile.ConstantPool;
  * Stack: ..., -&gt; ..., address
  * </PRE>
  * 
- * @version $Id: RET.java,v 1.4 2009/10/04 03:21:45 aclement Exp $
+ * @version $Id: RET.java,v 1.5 2009/10/05 17:35:36 aclement Exp $
  * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  */
 public class RET extends Instruction {
        private boolean wide;
-       private int index; // index to local variable containg the return address
+       private int index; // index to local variable containing the return address
 
        public RET(int index, boolean wide) {
                super(Constants.RET);
@@ -82,7 +82,7 @@ public class RET extends Instruction {
 
        public void dump(DataOutputStream out) throws IOException {
                if (wide) {
-                       out.writeByte(org.aspectj.apache.bcel.Constants.WIDE);
+                       out.writeByte(Constants.WIDE);
                }
                out.writeByte(opcode);
                if (wide) {
@@ -106,7 +106,7 @@ public class RET extends Instruction {
 
        public final void setIndex(int index) {
                this.index = index;
-               this.wide = index > org.aspectj.apache.bcel.Constants.MAX_BYTE;
+               this.wide = index > Constants.MAX_BYTE;
        }
 
        public String toString(boolean verbose) {
@@ -117,4 +117,16 @@ public class RET extends Instruction {
                return ReturnaddressType.NO_TARGET;
        }
 
+       public boolean equals(Object other) {
+               if (!(other instanceof RET)) {
+                       return false;
+               }
+               RET o = (RET) other;
+               return o.opcode == opcode && o.index == index;
+       }
+
+       public int hashCode() {
+               return opcode * 37 + index;
+       }
+
 }
index a98facde22cef4b35be9cc01c33d56b669ffeef3..d337fc796e8932b423c86e10ff0095715804116d 100644 (file)
@@ -67,7 +67,7 @@ import org.aspectj.apache.bcel.classfile.Utility;
  * Abstract super class for all possible java types, namely basic types such as int, object types like String and array types, e.g.
  * int[]
  * 
- * @version $Id: Type.java,v 1.12 2009/09/10 03:59:34 aclement Exp $
+ * @version $Id: Type.java,v 1.13 2009/10/05 17:35:36 aclement Exp $
  * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  * 
  *         modified: AndyClement 2-mar-05: Removed unnecessary static and optimized
@@ -177,8 +177,9 @@ public abstract class Type {
 
        public static final Type getType(String signature) {
                Type t = commonTypes.get(signature);
-               if (t != null)
+               if (t != null) {
                        return t;
+               }
                byte type = Utility.typeOfSignature(signature);
                if (type <= Constants.T_VOID) {
                        return BasicType.getType(type);
@@ -212,8 +213,9 @@ public abstract class Type {
                                                genericDepth--;
                                                break;
                                        case ';':
-                                               if (genericDepth == 0)
+                                               if (genericDepth == 0) {
                                                        endOfSigReached = true;
+                                               }
                                                break;
                                        default:
                                        }
@@ -248,8 +250,9 @@ public abstract class Type {
                } else { // type == T_REFERENCE
                        // Format is 'Lblahblah;'
                        int index = signature.indexOf(';'); // Look for closing ';'
-                       if (index < 0)
+                       if (index < 0) {
                                throw new ClassFormatException("Invalid signature: " + signature);
+                       }
 
                        // generics awareness
                        int nextAngly = signature.indexOf('<');
@@ -269,8 +272,9 @@ public abstract class Type {
                                                genericDepth--;
                                                break;
                                        case ';':
-                                               if (genericDepth == 0)
+                                               if (genericDepth == 0) {
                                                        endOfSigReached = true;
+                                               }
                                                break;
                                        default:
                                        }
@@ -312,8 +316,9 @@ public abstract class Type {
                Type[] types;
 
                try { // Read all declarations between for `(' and `)'
-                       if (signature.charAt(0) != '(')
+                       if (signature.charAt(0) != '(') {
                                throw new ClassFormatException("Invalid method signature: " + signature);
+                       }
 
                        index = 1; // current string position
 
@@ -337,8 +342,9 @@ public abstract class Type {
         */
        public static int getArgumentSizes(String signature) {
                int size = 0;
-               if (signature.charAt(0) != '(')
+               if (signature.charAt(0) != '(') {
                        throw new ClassFormatException("Invalid method signature: " + signature);
+               }
 
                int index = 1; // current string position
                try {
@@ -375,8 +381,9 @@ public abstract class Type {
                                                                genericDepth--;
                                                                break;
                                                        case ';':
-                                                               if (genericDepth == 0)
+                                                               if (genericDepth == 0) {
                                                                        endOfSigReached = true;
+                                                               }
                                                                break;
                                                        default:
                                                        }