[jboss-cvs] javassist SVN: r665 - in trunk: src/main/javassist/bytecode/stackmap and 1 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Mon Sep 24 10:42:54 EDT 2012


Author: chiba
Date: 2012-09-24 10:42:54 -0400 (Mon, 24 Sep 2012)
New Revision: 665

Modified:
   trunk/Readme.html
   trunk/src/main/javassist/bytecode/stackmap/Tracer.java
   trunk/src/main/javassist/bytecode/stackmap/TypeData.java
   trunk/src/test/javassist/bytecode/StackMapTest.java
Log:
fixed JASSIST-160 by rewriting the whole javassist.bytecode.stackmap package.

Modified: trunk/Readme.html
===================================================================
--- trunk/Readme.html	2012-09-20 13:19:41 UTC (rev 664)
+++ trunk/Readme.html	2012-09-24 14:42:54 UTC (rev 665)
@@ -284,7 +284,7 @@
 <p>-version 3.17
 <ul>
 	<li>OSGi bundle info is now included in the jar file.
-	<li>JIRA JASSIST-163, 166, 168, 170, 171 have been fixed.
+	<li>JIRA JASSIST-160, 163, 166, 168, 170, 171 have been fixed.
 </ul>
 
 <p>-version 3.16.1 on March 6, 2012

Modified: trunk/src/main/javassist/bytecode/stackmap/Tracer.java
===================================================================
--- trunk/src/main/javassist/bytecode/stackmap/Tracer.java	2012-09-20 13:19:41 UTC (rev 664)
+++ trunk/src/main/javassist/bytecode/stackmap/Tracer.java	2012-09-24 14:42:54 UTC (rev 665)
@@ -801,13 +801,30 @@
         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);

Modified: trunk/src/main/javassist/bytecode/stackmap/TypeData.java
===================================================================
--- trunk/src/main/javassist/bytecode/stackmap/TypeData.java	2012-09-20 13:19:41 UTC (rev 664)
+++ trunk/src/main/javassist/bytecode/stackmap/TypeData.java	2012-09-24 14:42:54 UTC (rev 665)
@@ -92,6 +92,9 @@
      */
     protected TypeVar toTypeVar() { return null; }
 
+    // see UninitTypeVar and UninitData
+    public void constructorCalled(int offset) {}
+
     /**
      * Primitive types.
      */
@@ -147,7 +150,8 @@
         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 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 @@
             this.initialized = false;
         }
 
+        public UninitData copy() { return new UninitData(offset, getName()); }
+
         public int getTypeTag() {
             return StackMapTable.UNINIT;
         }
@@ -684,8 +726,10 @@
         }
 
         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 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 @@
             super(-1, className);
         }
 
+        public UninitData copy() { return new UninitThis(getName()); }
+
         public int getTypeTag() {
             return StackMapTable.THIS;
         }

Modified: trunk/src/test/javassist/bytecode/StackMapTest.java
===================================================================
--- trunk/src/test/javassist/bytecode/StackMapTest.java	2012-09-20 13:19:41 UTC (rev 664)
+++ trunk/src/test/javassist/bytecode/StackMapTest.java	2012-09-24 14:42:54 UTC (rev 665)
@@ -294,6 +294,51 @@
         }
     }
 
+    public void testRebuildConstructor() throws Exception {
+        CtClass cc = loader.get("javassist.bytecode.StackMapTest$T5");
+        rebuildStackMaps2(cc);
+        cc.writeFile();
+        Object t1 = make(cc.getName());
+        assertEquals(122, invoke(t1, "test"));
+    }
+
+    public static class T5 {
+        int count;
+        public T5() { count = 0; }
+        public T5(int k) {
+            if (k > 0) count = 10;
+            else count = 100;
+            count++;
+        }
+        public T5(double d) {
+            this(d > 0.0 ? 1 : -1);
+            if (d > 1.0) count += 10;
+            else count += 100;
+            count++;
+        }
+        public int test() {
+            return new T5(3).count + new T5(1.0).count;
+        }
+    }
+
+    public void testRebuildConstructor2() throws Exception {
+        CtClass cc = loader.get("javassist.bytecode.StackMapTest$T6");
+        rebuildStackMaps2(cc);
+        cc.writeFile();
+        Object t1 = make(cc.getName());
+        assertEquals(101, invoke(t1, "test2"));
+    }
+
+    public static class T6 {
+        public int test2() {
+            T5 t0 = new T5();
+            T5 t = new T5(t0.count > 0 ? (new T5(t0.count > 0 ? 1 : -1).count) : -1);
+            if (t0.count > 0)
+                t.count += 1000;
+            return t.count;
+        }
+    }
+
     public void tstCtClassType() throws Exception {
         ClassPool cp = ClassPool.getDefault();
         CtClass cc = cp.get("javassist.CtClassType");



More information about the jboss-cvs-commits mailing list