summaryrefslogtreecommitdiffstats
path: root/src/main
diff options
context:
space:
mode:
authorchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>2007-05-29 03:51:47 +0000
committerchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>2007-05-29 03:51:47 +0000
commit2cecffb9c750eeb468700e90a00710821ad534c3 (patch)
tree7c6dfb8e1ee17a43344953e3061c7243ec2023c3 /src/main
parentf57f2a7450beac7f29b7287ed27f4ff32b8ed3dc (diff)
downloadjavassist-2cecffb9c750eeb468700e90a00710821ad534c3.tar.gz
javassist-2cecffb9c750eeb468700e90a00710821ad534c3.zip
fixed bugs of javassist.bytecode.stackmap
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@375 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
Diffstat (limited to 'src/main')
-rw-r--r--src/main/javassist/bytecode/stackmap/Liveness.java7
-rw-r--r--src/main/javassist/bytecode/stackmap/MapMaker.java22
-rw-r--r--src/main/javassist/bytecode/stackmap/Tracer.java18
-rw-r--r--src/main/javassist/bytecode/stackmap/TypeData.java46
-rw-r--r--src/main/javassist/bytecode/stackmap/TypedBlock.java3
5 files changed, 73 insertions, 23 deletions
diff --git a/src/main/javassist/bytecode/stackmap/Liveness.java b/src/main/javassist/bytecode/stackmap/Liveness.java
index 8676b969..a086e0cc 100644
--- a/src/main/javassist/bytecode/stackmap/Liveness.java
+++ b/src/main/javassist/bytecode/stackmap/Liveness.java
@@ -60,6 +60,7 @@ public class Liveness {
private void computeLiveness1(TypedBlock tb) {
if (tb.updating) {
+ // a loop was detected.
computeLiveness1u(tb);
return;
}
@@ -193,12 +194,12 @@ public class Liveness {
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;
diff --git a/src/main/javassist/bytecode/stackmap/MapMaker.java b/src/main/javassist/bytecode/stackmap/MapMaker.java
index 17725903..7dabbf65 100644
--- a/src/main/javassist/bytecode/stackmap/MapMaker.java
+++ b/src/main/javassist/bytecode/stackmap/MapMaker.java
@@ -114,6 +114,7 @@ public class MapMaker extends Tracer {
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 @@ public class MapMaker extends Tracer {
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 @@ public class MapMaker extends Tracer {
}
else
offsetDelta += bb.length;
-
}
return writer.toStackMapTable(cpool);
diff --git a/src/main/javassist/bytecode/stackmap/Tracer.java b/src/main/javassist/bytecode/stackmap/Tracer.java
index bae3ae16..8142f103 100644
--- a/src/main/javassist/bytecode/stackmap/Tracer.java
+++ b/src/main/javassist/bytecode/stackmap/Tracer.java
@@ -307,7 +307,7 @@ public abstract class Tracer implements TypeTag {
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 @@ public abstract class Tracer implements TypeTag {
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 @@ public abstract class Tracer implements TypeTag {
stackTop--;
// implicit upcast might be done.
localsTypes[index] = stackTypes[stackTop].copy();
-
return 2;
}
@@ -632,6 +638,7 @@ public abstract class Tracer implements TypeTag {
= 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 @@ public abstract class Tracer implements TypeTag {
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);
diff --git a/src/main/javassist/bytecode/stackmap/TypeData.java b/src/main/javassist/bytecode/stackmap/TypeData.java
index 804264a0..6c073702 100644
--- a/src/main/javassist/bytecode/stackmap/TypeData.java
+++ b/src/main/javassist/bytecode/stackmap/TypeData.java
@@ -209,20 +209,20 @@ public abstract class TypeData {
return;
ArrayList equiv = this.equivalences;
- String name = this.expectedName;
int n = equiv.size();
- for (int i = 0; i < n; i++) {
- TypeData td = (TypeData)equiv.get(i);
- if (td instanceof TypeName) {
- TypeName tn = (TypeName)td;
- if (update(cp, name, tn.expectedName))
- name = tn.expectedName;
+ 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) {
+ TypeName tn = (TypeName)td;
+ if (update(cp, name, tn.expectedName))
+ name = tn.expectedName;
+ }
}
}
- if (name == null)
- name = evalExpectedType2(equivalences, n);
-
for (int i = 0; i < n; i++) {
TypeData td = (TypeData)equiv.get(i);
if (td instanceof TypeName) {
@@ -257,6 +257,14 @@ public abstract class TypeData {
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 abstract class TypeData {
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 @@ public abstract class TypeData {
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;
+ }
}
/**
diff --git a/src/main/javassist/bytecode/stackmap/TypedBlock.java b/src/main/javassist/bytecode/stackmap/TypedBlock.java
index 9d908755..42ab3497 100644
--- a/src/main/javassist/bytecode/stackmap/TypedBlock.java
+++ b/src/main/javassist/bytecode/stackmap/TypedBlock.java
@@ -7,7 +7,10 @@ public class TypedBlock extends BasicBlock {
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;