Browse Source

fixed bugs of javassist.bytecode.stackmap


git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@375 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
tags/rel_3_17_1_ga
chiba 17 years ago
parent
commit
2cecffb9c7

+ 4
- 3
src/main/javassist/bytecode/stackmap/Liveness.java View File

@@ -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;

+ 21
- 1
src/main/javassist/bytecode/stackmap/MapMaker.java View File

@@ -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);

+ 13
- 5
src/main/javassist/bytecode/stackmap/Tracer.java View File

@@ -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);

+ 32
- 14
src/main/javassist/bytecode/stackmap/TypeData.java View File

@@ -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;
}
}

/**

+ 3
- 0
src/main/javassist/bytecode/stackmap/TypedBlock.java View File

@@ -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;

Loading…
Cancel
Save