[ 
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)

Reply via email to