commons-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Emmanuel Bourg (JIRA)" <j...@apache.org>
Subject [jira] [Updated] (BCEL-159) LocalVariableGen.getLocalVariable() computes incorrect length
Date Thu, 24 Apr 2014 08:17:25 GMT

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

Mime
View raw message