commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ggreg...@apache.org
Subject svn commit: r1812323 - in /commons/proper/bcel/trunk/src: changes/changes.xml main/java/org/apache/bcel/generic/LocalVariableGen.java main/java/org/apache/bcel/generic/MethodGen.java test/java/org/apache/bcel/PLSETestCase.java
Date Mon, 16 Oct 2017 20:32:13 GMT
Author: ggregory
Date: Mon Oct 16 20:32:13 2017
New Revision: 1812323

URL: http://svn.apache.org/viewvc?rev=1812323&view=rev
Log:
[BCEL-295] Fix local variable live range length; add test case.

Modified:
    commons/proper/bcel/trunk/src/changes/changes.xml
    commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/LocalVariableGen.java
    commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/MethodGen.java
    commons/proper/bcel/trunk/src/test/java/org/apache/bcel/PLSETestCase.java

Modified: commons/proper/bcel/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/changes/changes.xml?rev=1812323&r1=1812322&r2=1812323&view=diff
==============================================================================
--- commons/proper/bcel/trunk/src/changes/changes.xml [utf-8] (original)
+++ commons/proper/bcel/trunk/src/changes/changes.xml [utf-8] Mon Oct 16 20:32:13 2017
@@ -65,6 +65,7 @@ The <action> type attribute can be add,u
     <release version="6.2" date="tba" description="tba">
       <action issue="BCEL-294" type="fix" dev="britter" due-to="Mark Roberts">Incorrect
comment in StackMap.java</action>
       <action issue="BCEL-296" type="fix" dev="ggregory" due-to="Mark Roberts">Incorrect
comment in several classes.</action>
+      <action issue="BCEL-295" type="fix" dev="ggregory" due-to="Mark Roberts">Fix
local variable live range length; add test case.</action>
     </release>
 
     <release version="6.1" date="2017-09-14" description="Experimental Java 9 Support">

Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/LocalVariableGen.java
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/LocalVariableGen.java?rev=1812323&r1=1812322&r2=1812323&view=diff
==============================================================================
--- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/LocalVariableGen.java
(original)
+++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/LocalVariableGen.java
Mon Oct 16 20:32:13 2017
@@ -38,6 +38,7 @@ public class LocalVariableGen implements
     private InstructionHandle start;
     private InstructionHandle end;
     private int orig_index; // never changes; used to match up with LocalVariableTypeTable
entries
+    private boolean live_to_end;
 
 
     /**
@@ -61,6 +62,11 @@ public class LocalVariableGen implements
         setStart(start);
         setEnd(end);
         this.orig_index = index;
+        if (end == null) {
+            this.live_to_end = true;
+        } else {
+            this.live_to_end = false;
+        }
     }
 
 
@@ -88,11 +94,11 @@ public class LocalVariableGen implements
      * This relies on that the instruction list has already been dumped to byte code or
      * or that the `setPositions' methods has been called for the instruction list.
      *
-     * Note that for local variables whose scope end at the last
-     * instruction of the method's code, the JVM specification is ambiguous:
-     * both a start_pc+length ending at the last instruction and
-     * start_pc+length ending at first index beyond the end of the code are
-     * valid.
+     * Note that due to the conversion from byte code offset to InstructionHandle,
+     * it is impossible to tell the difference between a live range that ends BEFORE
+     * the last insturction of the method or a live range that ends AFTER the last
+     * instruction of the method.  Hence the live_to_end flag to differentiate
+     * between these two cases.
      *
      * @param cp constant pool
      */
@@ -102,7 +108,7 @@ public class LocalVariableGen implements
         if ((start != null) && (end != null)) {
             start_pc = start.getPosition();
             length = end.getPosition() - start_pc;
-            if (end.getNext() == null) {
+            if ((end.getNext() == null) && live_to_end) {
                 length += end.getInstruction().getLength();
             }
         }
@@ -128,6 +134,16 @@ public class LocalVariableGen implements
     }
 
 
+    public void setLiveToEnd( final boolean live_to_end) {
+        this.live_to_end = live_to_end;
+    }
+
+
+    public boolean getLiveToEnd() {
+        return live_to_end;
+    }
+
+
     @Override
     public void setName( final String name ) {
         this.name = name;

Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/MethodGen.java
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/MethodGen.java?rev=1812323&r1=1812322&r2=1812323&view=diff
==============================================================================
--- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/MethodGen.java (original)
+++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/MethodGen.java Mon Oct
16 20:32:13 2017
@@ -133,7 +133,7 @@ public class MethodGen extends FieldGenO
         InstructionHandle end = null;
         if (!abstract_) {
             start = il.getStart();
-            end = il.getEnd();
+            // end == null => live to end of method
             /* Add local variables, namely the implicit `this' and the arguments
              */
             if (!isStatic() && (class_name != null)) { // Instance method -> `this'
is local var 0
@@ -725,9 +725,7 @@ public class MethodGen extends FieldGenO
             if (null == start) {
                 start = il.getStart();
             }
-            if (null == end) {
-                end = il.getEnd();
-            }
+            // end == null => live to end of method
             // Since we are recreating the LocalVaraible, we must
             // propagate the orig_index to new copy.
             addLocalVariable(l.getName(), Type.getType(l.getSignature()), l

Modified: commons/proper/bcel/trunk/src/test/java/org/apache/bcel/PLSETestCase.java
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/test/java/org/apache/bcel/PLSETestCase.java?rev=1812323&r1=1812322&r2=1812323&view=diff
==============================================================================
--- commons/proper/bcel/trunk/src/test/java/org/apache/bcel/PLSETestCase.java (original)
+++ commons/proper/bcel/trunk/src/test/java/org/apache/bcel/PLSETestCase.java Mon Oct 16 20:32:13
2017
@@ -18,7 +18,9 @@
 
 package org.apache.bcel;
 
+import org.apache.bcel.classfile.ClassParser;
 import org.apache.bcel.classfile.JavaClass;
+import org.apache.bcel.classfile.LocalVariable;
 import org.apache.bcel.classfile.LocalVariableTable;
 import org.apache.bcel.classfile.Method;
 import org.apache.bcel.generic.ClassGen;
@@ -28,6 +30,7 @@ import org.apache.bcel.generic.Instructi
 import org.apache.bcel.generic.InvokeInstruction;
 import org.apache.bcel.generic.MethodGen;
 import org.apache.bcel.generic.Type;
+import java.io.FileInputStream;
 
 public class PLSETestCase extends AbstractTestCase
 {
@@ -86,4 +89,23 @@ public class PLSETestCase extends Abstra
         final String cn = ii.getClassName(pool);
         assertEquals("[Lorg.apache.bcel.data.PLSETestEnum;", cn);
     }
+
+    /**
+     * BCEL-295:
+     */
+    public void testB295() throws Exception
+    {
+        final JavaClass clazz = getTestClass(PACKAGE_BASE_NAME+".data.PLSETestClass2");
+        final ClassGen cg = new ClassGen(clazz);
+        final ConstantPoolGen pool = cg.getConstantPool();
+        final Method m = cg.getMethodAt(1);  // 'main'
+        final LocalVariableTable lvt = m.getLocalVariableTable();
+        final LocalVariable lv = lvt.getLocalVariable(2, 4);  // 'i'
+        //System.out.println(lv);
+        final MethodGen mg = new MethodGen(m, cg.getClassName(), pool);
+        final LocalVariableTable new_lvt = mg.getLocalVariableTable(mg.getConstantPool());
+        final LocalVariable new_lv = new_lvt.getLocalVariable(2, 4);  // 'i'
+        //System.out.println(new_lv);
+        assertEquals("live range length", lv.getLength(), new_lv.getLength());
+    }
 }



Mime
View raw message