[
https://issues.apache.org/jira/browse/BCEL-159?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Emmanuel Bourg updated BCEL-159:
--------------------------------
Priority: Blocker
Environment: (was: Operating System: Linux
Platform: PC)
Fix Version/s: 6.0
Summary: LocalVariableGen.getLocalVariable() computes incorrect
length (was: [BUG?/PATCH] LocalVariableGen.getLocalVariable() computes
incorrect length)
> LocalVariableGen.getLocalVariable() computes incorrect length
> -------------------------------------------------------------
>
> Key: BCEL-159
> URL: https://issues.apache.org/jira/browse/BCEL-159
> Project: Commons BCEL
> Issue Type: Bug
> Components: Main
> Affects Versions: 5.3
> Reporter: Thiago
> Assignee: Apache Commons Developers
> Priority: Blocker
> Fix For: 6.0
>
> Attachments: patch.diff
>
>
> It seems that getLocalVariable computes incorrect length for the returning
> LocalVariable if its range is not the whole method. This is the original code:
> public LocalVariable getLocalVariable( ConstantPoolGen cp ) {
> int start_pc = start.getPosition();
> int length = end.getPosition() - start_pc;
> if (length > 0) {
> length += end.getInstruction().getLength();
> }
> int name_index = cp.addUtf8(name);
> int signature_index = cp.addUtf8(type.getSignature());
> return new LocalVariable(start_pc, length, name_index,
> signature_index, index, cp.getConstantPool());
> }
> I think that the check "if (length > 0)" is a "workaround" for local
> variables whose end targets the last instruction. In this case, we must add
> the instruction length to recover the actual range for the local variable.
> However, we should not add the instruction's length if it is not the last
> instruction of the list because variable ranges are exclusive in the end_pc
> (note that the JVM spec used to say that the range is inclusive, but this was
> corrected in JVM5 - see
> http://java.sun.com/docs/books/jvms/second_edition/jvms-clarify.html or more
> specifically page 143 of
> http://java.sun.com/docs/books/jvms/second_edition/ClassFileFormat-Java5.pdf
> ).
> This error can be verified by parsing a method that has local variables whose
> range is not the whole method (like variables for exceptions in an exception
> handler), creating a MethodGen and then comparing the local variable tables.
> Something like this:
> ClassParser parser = new ClassParser(...);
> JavaClass clazz = parser.parse();
> Method m = clazz.getMethods()[...];
> ConstantPoolGen cpg = new ConstantPoolGen(clazz.getConstantPool());
> MethodGen mg = new MethodGen(m, clazz.getClassName(), cpg);
> System.out.println(mg.getLocalVariableTable(cpg));
> System.out.println("==");
> System.out.println(m.getLocalVariableTable());
> would produce some output which includes:
> LocalVariable(start_pc = 17, length = 7, index = 2:Exception e1)
> ...
> ==
> ...
> LocalVariable(start_pc = 17, length = 6, index = 2:Exception e1)
> Note that the length is greater than the original.
> If this is really a bug, I believe a fix is to use if (end.getNext() == null)
> instead (see the patch in attachment). I ran the whole test suite with this
> fix and it passes, but I am not sure what else it affects.
> Cheers,
> Thiago
--
This message was sent by Atlassian JIRA
(v6.2#6252)