[jboss-cvs] javassist/src/main/javassist/bytecode/stackmap ...
Shigeru Chiba
chiba at is.titech.ac.jp
Mon May 28 23:51:48 EDT 2007
User: chiba
Date: 07/05/28 23:51:48
Modified: src/main/javassist/bytecode/stackmap MapMaker.java
TypedBlock.java Liveness.java TypeData.java
Tracer.java
Log:
fixed bugs of javassist.bytecode.stackmap
Revision Changes Path
1.4 +21 -1 javassist/src/main/javassist/bytecode/stackmap/MapMaker.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: MapMaker.java
===================================================================
RCS file: /cvsroot/jboss/javassist/src/main/javassist/bytecode/stackmap/MapMaker.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- MapMaker.java 6 May 2007 15:41:43 -0000 1.3
+++ MapMaker.java 29 May 2007 03:51:47 -0000 1.4
@@ -114,6 +114,7 @@
throws BadBytecode
{
TypedBlock first = blocks[0];
+ fixParamTypes(first);
TypeData[] srcTypes = first.localsTypes;
copyFrom(srcTypes.length, srcTypes, this.localsTypes);
make(code, first);
@@ -123,6 +124,26 @@
evalExpected(blocks[i]);
}
+ /*
+ * If a parameter type is String but it is used only as Object
+ * within the method body, this MapMaker class will report its type
+ * is Object. To avoid this, fixParamTypes calls TypeData.setType()
+ * on each parameter type.
+ */
+ private void fixParamTypes(TypedBlock first) throws BadBytecode {
+ TypeData[] types = first.localsTypes;
+ int n = types.length;
+ for (int i = 0; i < n; i++) {
+ TypeData t = types[i];
+ if (t instanceof TypeData.ClassName) {
+ /* Skip the following statement if t.isNullType() is true
+ * although a parameter type is never null type.
+ */
+ TypeData.setType(t, t.getName(), classPool);
+ }
+ }
+ }
+
// Phase 1
private void make(byte[] code, TypedBlock tb)
@@ -283,7 +304,6 @@
}
else
offsetDelta += bb.length;
-
}
return writer.toStackMapTable(cpool);
1.2 +3 -0 javassist/src/main/javassist/bytecode/stackmap/TypedBlock.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: TypedBlock.java
===================================================================
RCS file: /cvsroot/jboss/javassist/src/main/javassist/bytecode/stackmap/TypedBlock.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- TypedBlock.java 6 May 2007 15:41:43 -0000 1.1
+++ TypedBlock.java 29 May 2007 03:51:47 -0000 1.2
@@ -7,7 +7,10 @@
public TypeData[] stackTypes, localsTypes;
// set by a Liveness object.
+ // inputs[i] is true if the i-th variable is used within this block.
public boolean[] inputs;
+
+ // working area for Liveness class.
public boolean updating;
public int status;
public byte[] localsUsage;
1.2 +4 -3 javassist/src/main/javassist/bytecode/stackmap/Liveness.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: Liveness.java
===================================================================
RCS file: /cvsroot/jboss/javassist/src/main/javassist/bytecode/stackmap/Liveness.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- Liveness.java 6 May 2007 15:41:43 -0000 1.1
+++ Liveness.java 29 May 2007 03:51:47 -0000 1.2
@@ -60,6 +60,7 @@
private void computeLiveness1(TypedBlock tb) {
if (tb.updating) {
+ // a loop was detected.
computeLiveness1u(tb);
return;
}
@@ -193,12 +194,12 @@
boolean changed = false;
for (int i = 0; i < n; i++) {
TypedBlock tb = blocks[i];
- if (tb.status == DONE)
- tb.status = NOT_YET;
- else {
+ if (tb.status == CHANGED_NOW) {
tb.status = CHANGED_LAST;
changed = true;
}
+ else
+ tb.status = NOT_YET;
}
return changed;
1.5 +32 -14 javassist/src/main/javassist/bytecode/stackmap/TypeData.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: TypeData.java
===================================================================
RCS file: /cvsroot/jboss/javassist/src/main/javassist/bytecode/stackmap/TypeData.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- TypeData.java 24 May 2007 07:46:56 -0000 1.4
+++ TypeData.java 29 May 2007 03:51:47 -0000 1.5
@@ -209,8 +209,10 @@
return;
ArrayList equiv = this.equivalences;
- String name = this.expectedName;
int n = equiv.size();
+ String name = evalExpectedType2(equiv, n);
+ if (name == null) {
+ name = this.expectedName;
for (int i = 0; i < n; i++) {
TypeData td = (TypeData)equiv.get(i);
if (td instanceof TypeName) {
@@ -219,9 +221,7 @@
name = tn.expectedName;
}
}
-
- if (name == null)
- name = evalExpectedType2(equivalences, n);
+ }
for (int i = 0; i < n; i++) {
TypeData td = (TypeData)equiv.get(i);
@@ -257,6 +257,14 @@
return true;
else if (oldName.equals(typeName))
return false;
+ else if (typeName.charAt(0) == '['
+ && oldName.equals("[Ljava.lang.Object;")) {
+ /* this rule is not correct but Tracer class sets the type
+ of the operand of arraylength to java.lang.Object[].
+ Thus, int[] etc. must be a subtype of java.lang.Object[].
+ */
+ return true;
+ }
try {
if (cache == null)
@@ -365,10 +373,10 @@
public String getExpected() throws BadBytecode {
String en = expectedName;
if (en == null) {
- ArrayList equiv = equivalences;
- if (equiv.size() == 1)
- return getName();
- else
+ // ArrayList equiv = equivalences;
+ // if (equiv.size() == 1)
+ // return getName();
+ // else
return "java.lang.Object";
}
else
@@ -416,6 +424,16 @@
else
return "[L" + elementType.replace('.', '/') + ";";
}
+
+ public static String getElementType(String arrayType) {
+ char c = arrayType.charAt(1);
+ if (c == 'L')
+ return arrayType.substring(2, arrayType.length() - 1).replace('/', '.');
+ else if (c == '[')
+ return arrayType.substring(1);
+ else
+ return arrayType;
+ }
}
/**
1.4 +13 -5 javassist/src/main/javassist/bytecode/stackmap/Tracer.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: Tracer.java
===================================================================
RCS file: /cvsroot/jboss/javassist/src/main/javassist/bytecode/stackmap/Tracer.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- Tracer.java 6 May 2007 15:41:43 -0000 1.3
+++ Tracer.java 29 May 2007 03:51:47 -0000 1.4
@@ -307,7 +307,7 @@
return 2;
}
- private int doOpcode54_95(int pos, byte[] code, int op) {
+ private int doOpcode54_95(int pos, byte[] code, int op) throws BadBytecode {
TypeData[] localsTypes = this.localsTypes;
TypeData[] stackTypes = this.stackTypes;
switch (op) {
@@ -366,11 +366,18 @@
case Opcode.LASTORE :
case Opcode.FASTORE :
case Opcode.DASTORE :
+ stackTop -= (op == Opcode.LASTORE || op == Opcode.DASTORE) ? 4 : 3;
+ break;
case Opcode.AASTORE :
+ TypeData.setType(stackTypes[stackTop - 1],
+ TypeData.ArrayElement.getElementType(stackTypes[stackTop - 3].getName()),
+ classPool);
+ stackTop -= 3;
+ break;
case Opcode.BASTORE :
case Opcode.CASTORE :
case Opcode.SASTORE :
- stackTop -= (op == Opcode.LASTORE || op == Opcode.DASTORE) ? 4 : 3;
+ stackTop -= 3;
break;
case Opcode.POP :
stackTop--;
@@ -437,7 +444,6 @@
stackTop--;
// implicit upcast might be done.
localsTypes[index] = stackTypes[stackTop].copy();
-
return 2;
}
@@ -632,6 +638,7 @@
= new TypeData.ClassName(type);
return 3; }
case Opcode.ARRAYLENGTH :
+ TypeData.setType(stackTypes[stackTop - 1], "[Ljava.lang.Object;", classPool);
stackTypes[stackTop - 1] = INTEGER;
break;
case Opcode.ATHROW :
@@ -639,17 +646,18 @@
visitThrow(pos, code);
break;
case Opcode.CHECKCAST : {
- // TypeData.setType(stackData[stackTop - 1], "java.lang.Object", classPool);
+ // TypeData.setType(stackTypes[stackTop - 1], "java.lang.Object", classPool);
int i = ByteArray.readU16bit(code, pos + 1);
stackTypes[stackTop - 1] = new TypeData.ClassName(cpool.getClassInfo(i));
return 3; }
case Opcode.INSTANCEOF :
- // TypeData.setType(stackData[stackTop - 1], "java.lang.Object", classPool);
+ // TypeData.setType(stackTypes[stackTop - 1], "java.lang.Object", classPool);
stackTypes[stackTop - 1] = INTEGER;
return 3;
case Opcode.MONITORENTER :
case Opcode.MONITOREXIT :
stackTop--;
+ // TypeData.setType(stackTypes[stackTop], "java.lang.Object", classPool);
break;
case Opcode.WIDE :
return doWIDE(pos, code);
More information about the jboss-cvs-commits
mailing list