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());
+ }
}