changeset 802:0bb8f4009f26

Merge
author lana
date Tue, 11 Nov 2014 10:39:47 -0800
parents d8886dede94d (current diff) 572db6f408a2 (diff)
children 3eaaa67e886e
files
diffstat 2 files changed, 101 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/com/sun/org/apache/bcel/internal/classfile/DescendingVisitor.java	Wed Nov 05 12:54:09 2014 -0800
+++ b/src/com/sun/org/apache/bcel/internal/classfile/DescendingVisitor.java	Tue Nov 11 10:39:47 2014 -0800
@@ -213,6 +213,10 @@
   public void visitLocalVariableTypeTable(LocalVariableTypeTable obj) {
     stack.push(obj);
     obj.accept(visitor);
+
+    LocalVariable[] vars = obj.getLocalVariableTypeTable();
+    for(int i=0; i < vars.length; i++)
+      vars[i].accept(this);
     stack.pop();
   }
 
--- a/src/com/sun/org/apache/bcel/internal/generic/MethodGen.java	Wed Nov 05 12:54:09 2014 -0800
+++ b/src/com/sun/org/apache/bcel/internal/generic/MethodGen.java	Tue Nov 11 10:39:47 2014 -0800
@@ -87,6 +87,7 @@
   private boolean         strip_attributes;
 
   private ArrayList       variable_vec    = new ArrayList();
+  private ArrayList       type_vec        = new ArrayList();
   private ArrayList       line_number_vec = new ArrayList();
   private ArrayList       exception_vec   = new ArrayList();
   private ArrayList       throws_vec      = new ArrayList();
@@ -260,7 +261,7 @@
             }
           } else if (a instanceof LocalVariableTypeTable) {
              LocalVariable[] lv = ((LocalVariableTypeTable) a).getLocalVariableTypeTable();
-             removeLocalVariables();
+             removeLocalVariableTypes();
              for (int k = 0; k < lv.length; k++) {
                  LocalVariable l = lv[k];
                  InstructionHandle start = il.findHandle(l.getStartPC());
@@ -272,7 +273,7 @@
                  if (null == end) {
                      end = il.getEnd();
                  }
-                 addLocalVariable(l.getName(), Type.getType(l.getSignature()), l
+                 addLocalVariableType(l.getName(), Type.getType(l.getSignature()), l
                          .getIndex(), start, end);
               }
           } else
@@ -406,6 +407,31 @@
     return lg;
   }
 
+  /*
+   * If the range of the variable has not been set yet, it will be set to be
+   * val id from the start to the end of the instruction list.
+   *
+   * @return array of declared local variable types sorted by index
+   */
+  private LocalVariableGen[] getLocalVariableTypes() {
+    int                size = type_vec.size();
+    LocalVariableGen[] lg   = new LocalVariableGen[size];
+    type_vec.toArray(lg);
+
+    for(int i=0; i < size; i++) {
+      if(lg[i].getStart() == null)
+        lg[i].setStart(il.getStart());
+
+      if(lg[i].getEnd() == null)
+        lg[i].setEnd(il.getEnd());
+    }
+
+    if(size > 1)
+      sort(lg, 0, size - 1);
+
+    return lg;
+  }
+
   /**
    * @return `LocalVariableTable' attribute of all the local variables of this method.
    */
@@ -422,6 +448,68 @@
   }
 
   /**
+   * @return `LocalVariableTypeTable' attribute of all the local variable
+   * types of this method.
+   */
+  public LocalVariableTypeTable getLocalVariableTypeTable(ConstantPoolGen cp) {
+    LocalVariableGen[] lg   = getLocalVariableTypes();
+    int                size = lg.length;
+    LocalVariable[]    lv   = new LocalVariable[size];
+
+    for(int i=0; i < size; i++)
+      lv[i] = lg[i].getLocalVariable(cp);
+
+    return new LocalVariableTypeTable(cp.addUtf8("LocalVariableTypeTable"),
+                                  2 + lv.length * 10, lv, cp.getConstantPool());
+  }
+
+  /**
+   * Adds a local variable type 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
+   */
+  private LocalVariableGen addLocalVariableType(String name, Type type, int slot,
+                                           InstructionHandle start,
+                                           InstructionHandle end) {
+    byte t = type.getType();
+
+    if(t != Constants.T_ADDRESS) {
+      int  add = type.getSize();
+
+      if(slot + add > max_locals)
+        max_locals = slot + add;
+
+      LocalVariableGen l = new LocalVariableGen(slot, name, type, start, end);
+      int i;
+
+      if((i = type_vec.indexOf(l)) >= 0) // Overwrite if necessary
+        type_vec.set(i, l);
+      else
+        type_vec.add(l);
+
+      return l;
+    } else {
+      throw new IllegalArgumentException("Can not use " + type +
+                                         " as type for local variable");
+
+    }
+  }
+
+  /**
+   * Remove all local variable types.
+   */
+  private void removeLocalVariableTypes() {
+    type_vec.clear();
+  }
+
+  /**
    * Give an instruction a line number corresponding to the source code line.
    *
    * @param ih instruction to tag
@@ -637,12 +725,17 @@
 
     LineNumberTable    lnt = null;
     LocalVariableTable lvt = null;
+    LocalVariableTypeTable lvtt = null;
 
-    /* Create LocalVariableTable and LineNumberTable attributes (for debuggers, e.g.)
+    /* Create LocalVariableTable, LocalvariableTypeTable, and LineNumberTable
+     * attributes (for debuggers, e.g.)
      */
     if((variable_vec.size() > 0) && !strip_attributes)
       addCodeAttribute(lvt = getLocalVariableTable(cp));
 
+    if((type_vec.size() > 0) && !strip_attributes)
+      addCodeAttribute(lvtt = getLocalVariableTypeTable(cp));
+
     if((line_number_vec.size() > 0) && !strip_attributes)
       addCodeAttribute(lnt = getLineNumberTable(cp));
 
@@ -691,6 +784,7 @@
 
     // Undo effects of adding attributes
     if(lvt != null)  removeCodeAttribute(lvt);
+    if(lvtt != null) removeCodeAttribute(lvtt);
     if(lnt != null)  removeCodeAttribute(lnt);
     if(code != null) removeAttribute(code);
     if(et != null)   removeAttribute(et);