aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/javassist/bytecode/stackmap
diff options
context:
space:
mode:
authorchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>2012-09-24 14:42:54 +0000
committerchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>2012-09-24 14:42:54 +0000
commitfc32a1d8493f30ee2e543d54797d36e822c8248a (patch)
treee25ac3c2b0ad66528be0fdd5551c19f14a478963 /src/main/javassist/bytecode/stackmap
parentb667870a98525cacac572c8657c6f5135e25a385 (diff)
downloadjavassist-fc32a1d8493f30ee2e543d54797d36e822c8248a.tar.gz
javassist-fc32a1d8493f30ee2e543d54797d36e822c8248a.zip
fixed JASSIST-160 by rewriting the whole javassist.bytecode.stackmap package.
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@665 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
Diffstat (limited to 'src/main/javassist/bytecode/stackmap')
-rw-r--r--src/main/javassist/bytecode/stackmap/Tracer.java19
-rw-r--r--src/main/javassist/bytecode/stackmap/TypeData.java57
2 files changed, 72 insertions, 4 deletions
diff --git a/src/main/javassist/bytecode/stackmap/Tracer.java b/src/main/javassist/bytecode/stackmap/Tracer.java
index d63fa75a..8a5aa97d 100644
--- a/src/main/javassist/bytecode/stackmap/Tracer.java
+++ b/src/main/javassist/bytecode/stackmap/Tracer.java
@@ -801,13 +801,30 @@ public abstract class Tracer implements TypeTag {
checkParamTypes(desc, 1);
if (notStatic) {
String className = cpool.getMethodrefClassName(i);
- stackTypes[--stackTop].setType(className, classPool);
+ TypeData target = stackTypes[--stackTop];
+ if (target instanceof TypeData.UninitTypeVar && target.isUninit())
+ constructorCalled((TypeData.UninitTypeVar)target);
+
+ target.setType(className, classPool);
}
pushMemberType(desc);
return 3;
}
+ /* This is a constructor call on an uninitialized object.
+ * Sets flags of other references to that object.
+ */
+ private void constructorCalled(TypeData.UninitTypeVar target) {
+ int offset = target.offset();
+ target.constructorCalled(offset);
+ for (int i = 0; i < stackTop; i++)
+ stackTypes[i].constructorCalled(offset);
+
+ for (int i = 0; i < localsTypes.length; i++)
+ localsTypes[i].constructorCalled(offset);
+ }
+
private int doInvokeIntfMethod(int pos, byte[] code) throws BadBytecode {
int i = ByteArray.readU16bit(code, pos + 1);
String desc = cpool.getInterfaceMethodrefType(i);
diff --git a/src/main/javassist/bytecode/stackmap/TypeData.java b/src/main/javassist/bytecode/stackmap/TypeData.java
index 2b11905f..d77f6a55 100644
--- a/src/main/javassist/bytecode/stackmap/TypeData.java
+++ b/src/main/javassist/bytecode/stackmap/TypeData.java
@@ -92,6 +92,9 @@ public abstract class TypeData {
*/
protected TypeVar toTypeVar() { return null; }
+ // see UninitTypeVar and UninitData
+ public void constructorCalled(int offset) {}
+
/**
* Primitive types.
*/
@@ -147,7 +150,8 @@ public abstract class TypeData {
public boolean eq(TypeData d) { return getName().equals(d.getName()); }
}
- // a type variable representing a class type.
+ /* a type variable representing a class type or a basic type.
+ */
public static class TypeVar extends AbsTypeVar {
protected ArrayList lowers; // lower bounds of this type. ArrayList<TypeData>
protected ArrayList usedBy; // reverse relations of lowers
@@ -615,6 +619,42 @@ public abstract class TypeData {
}
}
+ public static class UninitTypeVar extends AbsTypeVar {
+ protected TypeData type; // UninitData or TOP
+
+ public UninitTypeVar(UninitData t) { type = t; }
+ public int getTypeTag() { return type.getTypeTag(); }
+ public int getTypeData(ConstPool cp) { return type.getTypeData(cp); }
+ public BasicType isBasicType() { return type.isBasicType(); }
+ public boolean is2WordType() { return type.is2WordType(); }
+ public boolean isUninit() { return type.isUninit(); }
+ public boolean eq(TypeData d) { return type.eq(d); }
+ public String getName() { return type.getName(); }
+
+ protected TypeVar toTypeVar() { return null; }
+ public TypeData join() { return type.join(); }
+
+ public void setType(String s, ClassPool cp) throws BadBytecode {
+ type.setType(s, cp);
+ }
+
+ public void merge(TypeData t) {
+ if (!t.eq(type))
+ type = TypeTag.TOP;
+ }
+
+ public void constructorCalled(int offset) {
+ type.constructorCalled(offset);
+ }
+
+ public int offset() {
+ if (type instanceof UninitData)
+ return ((UninitData)type).offset;
+ else // if type == TypeTag.TOP
+ throw new RuntimeException("not available");
+ }
+ }
+
/**
* Type data for OBJECT.
*/
@@ -675,6 +715,8 @@ public abstract class TypeData {
this.initialized = false;
}
+ public UninitData copy() { return new UninitData(offset, getName()); }
+
public int getTypeTag() {
return StackMapTable.UNINIT;
}
@@ -684,8 +726,10 @@ public abstract class TypeData {
}
public TypeData join() {
- TypeData td = initialized ? new ClassName(getName()) : this;
- return new TypeVar(td);
+ if (initialized)
+ return new TypeVar(new ClassName(getName()));
+ else
+ return new UninitTypeVar(copy());
}
public boolean isUninit() { return true; }
@@ -705,6 +749,11 @@ public abstract class TypeData {
}
public String toString() { return "uninit:" + getName() + "@" + offset; }
+
+ public void constructorCalled(int offset) {
+ if (offset == this.offset)
+ initialized = true;
+ }
}
public static class UninitThis extends UninitData {
@@ -712,6 +761,8 @@ public abstract class TypeData {
super(-1, className);
}
+ public UninitData copy() { return new UninitThis(getName()); }
+
public int getTypeTag() {
return StackMapTable.THIS;
}