summaryrefslogtreecommitdiffstats
path: root/bcel-builder
diff options
context:
space:
mode:
authoraclement <aclement>2009-10-05 17:35:36 +0000
committeraclement <aclement>2009-10-05 17:35:36 +0000
commit9b9952cc696d268e9458b1e998b2b167da973f90 (patch)
treecf024d6c62df06c193b0eaeebd74edd35f81dc1c /bcel-builder
parent06b5401c5b05053f469e7b0312a16708b677182a (diff)
downloadaspectj-9b9952cc696d268e9458b1e998b2b167da973f90.tar.gz
aspectj-9b9952cc696d268e9458b1e998b2b167da973f90.zip
optimization
Diffstat (limited to 'bcel-builder')
-rw-r--r--bcel-builder/src/org/aspectj/apache/bcel/classfile/Code.java35
-rw-r--r--bcel-builder/src/org/aspectj/apache/bcel/generic/BranchHandle.java121
-rw-r--r--bcel-builder/src/org/aspectj/apache/bcel/generic/FieldInstruction.java81
-rw-r--r--bcel-builder/src/org/aspectj/apache/bcel/generic/FieldOrMethod.java19
-rw-r--r--bcel-builder/src/org/aspectj/apache/bcel/generic/IINC.java89
-rw-r--r--bcel-builder/src/org/aspectj/apache/bcel/generic/INVOKEINTERFACE.java95
-rw-r--r--bcel-builder/src/org/aspectj/apache/bcel/generic/Instruction.java113
-rw-r--r--bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionBranch.java4
-rw-r--r--bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionByte.java12
-rw-r--r--bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionCP.java67
-rw-r--r--bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionHandle.java43
-rw-r--r--bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionLV.java14
-rw-r--r--bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionList.java136
-rw-r--r--bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionSelect.java62
-rw-r--r--bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionShort.java22
-rw-r--r--bcel-builder/src/org/aspectj/apache/bcel/generic/InvokeInstruction.java119
-rw-r--r--bcel-builder/src/org/aspectj/apache/bcel/generic/LocalVariableTag.java44
-rw-r--r--bcel-builder/src/org/aspectj/apache/bcel/generic/MULTIANEWARRAY.java220
-rw-r--r--bcel-builder/src/org/aspectj/apache/bcel/generic/MethodGen.java157
-rw-r--r--bcel-builder/src/org/aspectj/apache/bcel/generic/RET.java20
-rw-r--r--bcel-builder/src/org/aspectj/apache/bcel/generic/Type.java23
21 files changed, 837 insertions, 659 deletions
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Code.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Code.java
index fb96fbe5f..b714e6cab 100644
--- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Code.java
+++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Code.java
@@ -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");
}
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/BranchHandle.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/BranchHandle.java
index c735075a4..35d9528b8 100644
--- a/bcel-builder/src/org/aspectj/apache/bcel/generic/BranchHandle.java
+++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/BranchHandle.java
@@ -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;
+ }
}
-
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/FieldInstruction.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/FieldInstruction.java
index e7c67d2ef..54983e7c9 100644
--- a/bcel-builder/src/org/aspectj/apache/bcel/generic/FieldInstruction.java
+++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/FieldInstruction.java
@@ -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);
+ }
+}
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/FieldOrMethod.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/FieldOrMethod.java
index 71f8157cd..bf2c73299 100644
--- a/bcel-builder/src/org/aspectj/apache/bcel/generic/FieldOrMethod.java
+++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/FieldOrMethod.java
@@ -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;
}
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/IINC.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/IINC.java
index 6df506e44..d70e20308 100644
--- a/bcel-builder/src/org/aspectj/apache/bcel/generic/IINC.java
+++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/IINC.java
@@ -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);
+ }
}
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/INVOKEINTERFACE.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/INVOKEINTERFACE.java
index 6f60afdac..b545f4d37 100644
--- a/bcel-builder/src/org/aspectj/apache/bcel/generic/INVOKEINTERFACE.java
+++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/INVOKEINTERFACE.java
@@ -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);
+ }
}
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/Instruction.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/Instruction.java
index ae85e06a0..ffdf63051 100644
--- a/bcel-builder/src/org/aspectj/apache/bcel/generic/Instruction.java
+++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/Instruction.java
@@ -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;
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionBranch.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionBranch.java
index 0a5912247..53fed8e52 100644
--- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionBranch.java
+++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionBranch.java
@@ -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));
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionByte.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionByte.java
index fcd46dc9f..5ba8a9abe 100644
--- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionByte.java
+++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionByte.java
@@ -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
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionCP.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionCP.java
index e2b4f9c68..09222d6a4 100644
--- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionCP.java
+++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionCP.java
@@ -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;
+ }
+
}
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionHandle.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionHandle.java
index d114a600e..2f2691df1 100644
--- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionHandle.java
+++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionHandle.java
@@ -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() {
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionLV.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionLV.java
index b49a76870..73c278016 100644
--- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionLV.java
+++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionLV.java
@@ -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;
+ }
+
}
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionList.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionList.java
index 46d1198d1..c5e2ab66f 100644
--- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionList.java
+++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionList.java
@@ -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.
*
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionSelect.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionSelect.java
index dcebe3a0f..b4e00c027 100644
--- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionSelect.java
+++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionSelect.java
@@ -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
*/
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionShort.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionShort.java
index dd8a72eb0..99054cbff 100644
--- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionShort.java
+++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/InstructionShort.java
@@ -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;
}
}
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/InvokeInstruction.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/InvokeInstruction.java
index fbc55a66a..89cd43474 100644
--- a/bcel-builder/src/org/aspectj/apache/bcel/generic/InvokeInstruction.java
+++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/InvokeInstruction.java
@@ -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));
+ }
}
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/LocalVariableTag.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/LocalVariableTag.java
index 724f0cad8..7a4fab4e9 100644
--- a/bcel-builder/src/org/aspectj/apache/bcel/generic/LocalVariableTag.java
+++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/LocalVariableTag.java
@@ -14,28 +14,30 @@
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;
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/MULTIANEWARRAY.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/MULTIANEWARRAY.java
index eddc2e995..94a213a25 100644
--- a/bcel-builder/src/org/aspectj/apache/bcel/generic/MULTIANEWARRAY.java
+++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/MULTIANEWARRAY.java
@@ -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);
+ }
}
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/MethodGen.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/MethodGen.java
index 15c9000e9..94c42938f 100644
--- a/bcel-builder/src/org/aspectj/apache/bcel/generic/MethodGen.java
+++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/MethodGen.java
@@ -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;
}
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/RET.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/RET.java
index 1dc19d446..0fd2f498d 100644
--- a/bcel-builder/src/org/aspectj/apache/bcel/generic/RET.java
+++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/RET.java
@@ -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;
+ }
+
}
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/Type.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/Type.java
index a98facde2..d337fc796 100644
--- a/bcel-builder/src/org/aspectj/apache/bcel/generic/Type.java
+++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/Type.java
@@ -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:
}