aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenedikt Ritter <britter@apache.org>2017-08-30 19:34:23 +0000
committerBenedikt Ritter <britter@apache.org>2017-08-30 19:34:23 +0000
commit54a95d899854ad5a0a7b896f99cd8ba68b89d471 (patch)
tree2105505b525770c1954f16dd130d9b624b1b2f39 /src
parent93c12bbb6d22a165a407b6184cdb40545f86c683 (diff)
downloadapache-commons-bcel-54a95d899854ad5a0a7b896f99cd8ba68b89d471.tar.gz
BCEL-276: LocalVariableTypeTable is not updated. Updated fix thanks to Mark Roberts. This closes #12 from GitHub.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/bcel/trunk@1806728 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r--src/changes/changes.xml2
-rw-r--r--src/main/java/org/apache/bcel/classfile/LocalVariable.java32
-rw-r--r--src/main/java/org/apache/bcel/generic/LocalVariableGen.java27
-rw-r--r--src/main/java/org/apache/bcel/generic/MethodGen.java62
4 files changed, 108 insertions, 15 deletions
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 083c7093..f270dcc0 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -66,7 +66,7 @@ The <action> type attribute can be add,update,fix,remove.
<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>
diff --git a/src/main/java/org/apache/bcel/classfile/LocalVariable.java b/src/main/java/org/apache/bcel/classfile/LocalVariable.java
index 2594a235..e171f244 100644
--- a/src/main/java/org/apache/bcel/classfile/LocalVariable.java
+++ b/src/main/java/org/apache/bcel/classfile/LocalVariable.java
@@ -41,6 +41,7 @@ public final class LocalVariable implements Cloneable, Node, Constants {
* 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 implements Cloneable, Node, Constants {
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 implements Cloneable, Node, Constants {
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;
}
@@ -172,6 +196,14 @@ public final class LocalVariable implements Cloneable, Node, Constants {
/**
+ * @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
*/
public final int getStartPC() {
diff --git a/src/main/java/org/apache/bcel/generic/LocalVariableGen.java b/src/main/java/org/apache/bcel/generic/LocalVariableGen.java
index 0698e15e..d5ee8fcd 100644
--- a/src/main/java/org/apache/bcel/generic/LocalVariableGen.java
+++ b/src/main/java/org/apache/bcel/generic/LocalVariableGen.java
@@ -37,6 +37,7 @@ public class LocalVariableGen implements InstructionTargeter, NamedAndTyped, Clo
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 InstructionTargeter, NamedAndTyped, Clo
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 InstructionTargeter, NamedAndTyped, Clo
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 InstructionTargeter, NamedAndTyped, Clo
}
+ public int getOrigIndex() {
+ return orig_index;
+ }
+
+
@Override
public void setName( final String name ) {
this.name = name;
diff --git a/src/main/java/org/apache/bcel/generic/MethodGen.java b/src/main/java/org/apache/bcel/generic/MethodGen.java
index dbe42661..6833bc9e 100644
--- a/src/main/java/org/apache/bcel/generic/MethodGen.java
+++ b/src/main/java/org/apache/bcel/generic/MethodGen.java
@@ -66,7 +66,6 @@ public class MethodGen extends FieldGenOrMethodGen {
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 FieldGenOrMethodGen {
}
}
} 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 FieldGenOrMethodGen {
* 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 FieldGenOrMethodGen {
+ " 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 FieldGenOrMethodGen {
.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 FieldGenOrMethodGen {
/**
+ * 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 FieldGenOrMethodGen {
* Remove all code attributes.
*/
public void removeCodeAttributes() {
+ local_variable_type_table = null;
code_attrs_vec.clear();
}
@@ -619,15 +650,13 @@ public class MethodGen extends FieldGenOrMethodGen {
/* 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 FieldGenOrMethodGen {
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 FieldGenOrMethodGen {
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;
}
}