You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by br...@apache.org on 2017/08/30 19:34:23 UTC

svn commit: r1806728 - in /commons/proper/bcel/trunk/src: changes/changes.xml main/java/org/apache/bcel/classfile/LocalVariable.java main/java/org/apache/bcel/generic/LocalVariableGen.java main/java/org/apache/bcel/generic/MethodGen.java

Author: britter
Date: Wed Aug 30 19:34:23 2017
New Revision: 1806728

URL: http://svn.apache.org/viewvc?rev=1806728&view=rev
Log:
BCEL-276: LocalVariableTypeTable is not updated. Updated fix thanks to Mark Roberts. This closes #12 from GitHub.

Modified:
    commons/proper/bcel/trunk/src/changes/changes.xml
    commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/LocalVariable.java
    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

Modified: commons/proper/bcel/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/changes/changes.xml?rev=1806728&r1=1806727&r2=1806728&view=diff
==============================================================================
--- commons/proper/bcel/trunk/src/changes/changes.xml [utf-8] (original)
+++ commons/proper/bcel/trunk/src/changes/changes.xml [utf-8] Wed Aug 30 19:34:23 2017
@@ -66,7 +66,7 @@ The <action> type attribute can be add,u
       <action issue="BCEL-287" type="fix" dev="britter" due-to="Mark Roberts">IINC does not handle -128 properly</action>
       <action issue="BCEL-283" type="fix" dev="britter" due-to="Mark Roberts">Support for StackMap should be different from StackMapTable</action>
       <action issue="BCEL-289" type="fix" dev="kinow">Crash when parsing constructor of inner classes with parameters annotated</action>
-      <action issue="BCEL-276" type="fix" dev="britter" due-to="Sam Yoon">LocalVariableTypeTable is not updated.</action>
+      <action issue="BCEL-276" type="fix" dev="britter" due-to="Sam Yoon, Mark Roberts">LocalVariableTypeTable is not updated.</action>
       <action issue="BCEL-277" type="fix" dev="britter" due-to="Sam Yoon">Resolving the String representation of a constant throws NoSuchElementException in case of CONSTANT_NameAndType constant.</action>
     </release>
 

Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/LocalVariable.java
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/LocalVariable.java?rev=1806728&r1=1806727&r2=1806728&view=diff
==============================================================================
--- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/LocalVariable.java (original)
+++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/LocalVariable.java Wed Aug 30 19:34:23 2017
@@ -41,6 +41,7 @@ public final class LocalVariable impleme
      * this method's frame.
      */
     private ConstantPool constant_pool;
+    private int orig_index; // never changes; used to match up with LocalVariableTypeTable entries
 
 
     /**
@@ -50,6 +51,7 @@ public final class LocalVariable impleme
     public LocalVariable(final LocalVariable c) {
         this(c.getStartPC(), c.getLength(), c.getNameIndex(), c.getSignatureIndex(), c.getIndex(),
                 c.getConstantPool());
+        this.orig_index = c.getOrigIndex();
     }
 
 
@@ -80,6 +82,28 @@ public final class LocalVariable impleme
         this.signature_index = signature_index;
         this.index = index;
         this.constant_pool = constant_pool;
+        this.orig_index = index;
+    }
+
+
+    /**
+     * @param start_pc Range in which the variable
+     * @param length ... is valid
+     * @param name_index Index in constant pool of variable name
+     * @param signature_index Index of variable's signature
+     * @param index Variable is `index'th local variable on the method's frame
+     * @param constant_pool Array of constants
+     * @param orig_index Variable is `index'th local variable on the method's frame prior to any changes
+     */
+    public LocalVariable(final int start_pc, final int length, final int name_index, final int signature_index, final int index,
+            final ConstantPool constant_pool, final int orig_index) {
+        this.start_pc = start_pc;
+        this.length = length;
+        this.name_index = name_index;
+        this.signature_index = signature_index;
+        this.index = index;
+        this.constant_pool = constant_pool;
+        this.orig_index = orig_index;
     }
 
 
@@ -171,6 +195,14 @@ public final class LocalVariable impleme
     }
 
 
+    /**
+     * @return index of register where variable was originally stored
+     */
+    public final int getOrigIndex() {
+        return orig_index;
+    }
+
+
     /**
      * @return Start of range where he variable is valid
      */

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=1806728&r1=1806727&r2=1806728&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 Wed Aug 30 19:34:23 2017
@@ -37,6 +37,7 @@ public class LocalVariableGen implements
     private Type type;
     private InstructionHandle start;
     private InstructionHandle end;
+    private int orig_index; // never changes; used to match up with LocalVariableTypeTable entries
 
 
     /**
@@ -59,6 +60,25 @@ public class LocalVariableGen implements
         this.index = index;
         setStart(start);
         setEnd(end);
+        this.orig_index = index;
+    }
+
+
+    /**
+     * Generate a local variable that with index `index'. Note that double and long
+     * variables need two indexs. Index indices have to be provided by the user.
+     *
+     * @param index index of local variable
+     * @param name its name
+     * @param type its type
+     * @param start from where the instruction is valid (null means from the start)
+     * @param end until where the instruction is valid (null means to the end)
+     * @param orig_index index of local variable prior to any changes to index
+     */
+    public LocalVariableGen(final int index, final String name, final Type type, final InstructionHandle start,
+            final InstructionHandle end, final int orig_index) {
+        this(index, name, type, start, end);
+        this.orig_index = orig_index;
     }
 
 
@@ -89,7 +109,7 @@ public class LocalVariableGen implements
         final int name_index = cp.addUtf8(name);
         final int signature_index = cp.addUtf8(type.getSignature());
         return new LocalVariable(start_pc, length, name_index, signature_index, index, cp
-                .getConstantPool());
+                .getConstantPool(), orig_index);
     }
 
 
@@ -103,6 +123,11 @@ public class LocalVariableGen implements
     }
 
 
+    public int getOrigIndex() {
+        return orig_index;
+    }
+
+
     @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=1806728&r1=1806727&r2=1806728&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 Wed Aug 30 19:34:23 2017
@@ -66,7 +66,6 @@ public class MethodGen extends FieldGenO
     private int max_stack;
     private InstructionList il;
     private boolean strip_attributes;
-    private LocalVariableTable local_variable_table = null;
     private LocalVariableTypeTable local_variable_type_table = null;
     private final List<LocalVariableGen> variable_vec = new ArrayList<>();
     private final List<LineNumberGen> line_number_vec = new ArrayList<>();
@@ -225,10 +224,9 @@ public class MethodGen extends FieldGenO
                             }
                         }
                     } else if (a instanceof LocalVariableTable) {
-                        this.local_variable_table = (LocalVariableTable) a;
-                        updateLocalVariableTable(this.local_variable_table);
+                        updateLocalVariableTable((LocalVariableTable) a);
                     } else if (a instanceof LocalVariableTypeTable) {
-                        this.local_variable_type_table = (LocalVariableTypeTable) a;
+                        this.local_variable_type_table = (LocalVariableTypeTable) a.copy(cp.getConstantPool());
                     } else {
                         addCodeAttribute(a);
                     }
@@ -259,18 +257,19 @@ public class MethodGen extends FieldGenO
      * index is slot+2
      * @param start from where the variable is valid
      * @param end until where the variable is valid
+     * @param orig_index the index of the local variable prior to any modifications
      * @return new local variable object
      * @see LocalVariable
      */
     public LocalVariableGen addLocalVariable( final String name, final Type type, final int slot,
-            final InstructionHandle start, final InstructionHandle end ) {
+            final InstructionHandle start, final InstructionHandle end, final int orig_index ) {
         final byte t = type.getType();
         if (t != Const.T_ADDRESS) {
             final int add = type.getSize();
             if (slot + add > max_locals) {
                 max_locals = slot + add;
             }
-            final LocalVariableGen l = new LocalVariableGen(slot, name, type, start, end);
+            final LocalVariableGen l = new LocalVariableGen(slot, name, type, start, end, orig_index);
             int i;
             if ((i = variable_vec.indexOf(l)) >= 0) {
                 variable_vec.set(i, l);
@@ -283,6 +282,24 @@ public class MethodGen extends FieldGenO
                 + " as type for local variable");
     }
 
+
+    /**
+     * Adds a local variable to this method.
+     *
+     * @param name variable name
+     * @param type variable type
+     * @param slot the index of the local variable, if type is long or double, the next available
+     * index is slot+2
+     * @param start from where the variable is valid
+     * @param end until where the variable is valid
+     * @return new local variable object
+     * @see LocalVariable
+     */
+    public LocalVariableGen addLocalVariable( final String name, final Type type, final int slot,
+            final InstructionHandle start, final InstructionHandle end ) {
+        return addLocalVariable(name, type, slot, start, end, slot);
+    }
+
     /**
      * Adds a local variable to this method and assigns an index automatically.
      *
@@ -366,6 +383,12 @@ public class MethodGen extends FieldGenO
                 .getConstantPool());
     }
 
+    /**
+     * @return `LocalVariableTypeTable' attribute of this method.
+     */
+    public LocalVariableTypeTable getLocalVariableTypeTable() {
+        return local_variable_type_table;
+    }
 
     /**
      * Give an instruction a line number corresponding to the source code line.
@@ -547,6 +570,13 @@ public class MethodGen extends FieldGenO
 
 
     /**
+     * Remove the LocalVariableTypeTable
+     */
+    public void removeLocalVariableTypeTable( ) {
+        local_variable_type_table = null;
+    }
+
+    /**
      * Remove a code attribute.
      */
     public void removeCodeAttribute( final Attribute a ) {
@@ -558,6 +588,7 @@ public class MethodGen extends FieldGenO
      * Remove all code attributes.
      */
     public void removeCodeAttributes() {
+        local_variable_type_table = null;
         code_attrs_vec.clear();
     }
 
@@ -619,15 +650,13 @@ public class MethodGen extends FieldGenO
         /* Create LocalVariableTable and LineNumberTable attributes (for debuggers, e.g.)
          */
         if ((variable_vec.size() > 0) && !strip_attributes) {
-            if (local_variable_table != null) {
-                updateLocalVariableTable(local_variable_table);
-            }
+            updateLocalVariableTable(getLocalVariableTable(_cp));
             addCodeAttribute(lvt = getLocalVariableTable(_cp));
         }
         if (local_variable_type_table != null) {
             // LocalVariable length in LocalVariableTypeTable is not updated automatically. It's a difference with LocalVariableTable.
             if (lvt != null) {
-                adjustLocalVariableLength(lvt);
+                adjustLocalVariableTypeTable(lvt);
             }
             addCodeAttribute(local_variable_type_table);
         }
@@ -671,6 +700,9 @@ public class MethodGen extends FieldGenO
         if (lvt != null) {
             removeCodeAttribute(lvt);
         }
+        if (local_variable_type_table != null) {
+            removeCodeAttribute(local_variable_type_table);
+        }
         if (lnt != null) {
             removeCodeAttribute(lnt);
         }
@@ -696,19 +728,23 @@ public class MethodGen extends FieldGenO
             if (null == end) {
                 end = il.getEnd();
             }
+            // Since we are recreating the LocalVaraible, we must
+            // propagate the orig_index to new copy.
             addLocalVariable(l.getName(), Type.getType(l.getSignature()), l
-                    .getIndex(), start, end);
+                    .getIndex(), start, end, l.getOrigIndex());
         }
     }
 
-    private void adjustLocalVariableLength(final LocalVariableTable lvt) {
+    private void adjustLocalVariableTypeTable(final LocalVariableTable lvt) {
         final LocalVariable[] lv = lvt.getLocalVariableTable();
         final LocalVariable[] lvg = local_variable_type_table.getLocalVariableTypeTable();
 
         for (final LocalVariable element : lvg) {
             for (final LocalVariable l : lv) {
-                if (element.getName().equals(l.getName()) && element.getIndex() == l.getIndex()) {
+                if (element.getName().equals(l.getName()) && element.getIndex() == l.getOrigIndex()) {
                     element.setLength(l.getLength());
+                    element.setStartPC(l.getStartPC());
+                    element.setIndex(l.getIndex());
                     break;
                 }
             }