You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "Emmanuel Bourg (JIRA)" <ji...@apache.org> on 2014/04/24 10:33:18 UTC

[jira] [Updated] (BCEL-135) BCELifier issue: BCELFactory fails to handle float and long constants

     [ https://issues.apache.org/jira/browse/BCEL-135?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Emmanuel Bourg updated BCEL-135:
--------------------------------

         Priority: Blocker
      Environment:     (was: Operating System: All
Platform: All)
    Fix Version/s: 6.0
         Priority:   (was: P2)
         Severity:   (was: normal)

> BCELifier issue: BCELFactory fails to handle float and long constants
> ---------------------------------------------------------------------
>
>                 Key: BCEL-135
>                 URL: https://issues.apache.org/jira/browse/BCEL-135
>             Project: Commons BCEL
>          Issue Type: Bug
>          Components: Main
>    Affects Versions: 5.2
>            Reporter: Matthew Wilson
>            Assignee: Apache Commons Developers
>            Priority: Blocker
>             Fix For: 6.0
>
>         Attachments: TestIncorrectLiterals.java, TestOutOfRangeLiterals.java
>
>
> BCELifier calls BCELFactory.  The BCELFactory.createConstant method does not
> handle floats and longs correctly:
>     private void createConstant( Object value ) {
>         String embed = value.toString();
>         if (value instanceof String) {
>             embed = '"' + Utility.convertString(embed) + '"';
>         } else if (value instanceof Character) {
>             embed = "(char)0x" + Integer.toHexString(((Character)
> value).charValue());
>         }
>         _out.println("il.append(new PUSH(_cp, " + embed + "));");
>     } 
> Note that the types String and char are handled separately.  As for the other
> types, it's relying on there being an overloaded constructor of PUSH that takes
> the constant in its correct form once it is converted to a String.
> Let's examine all the other types:
> - boolean:  Boolean.toString() produces the values "true" and "false", which
> javac picks up as booleans, e.g. "new PUSH(_cp, false)".
> - byte, short, int:  Integer.toString() produces valid values.  In the
> bytecode, there is no (significant) distinction between these types (except for
> method signatures, fields, etc.).
> - double:  Double.toString() produces valid values, e.g. "new PUSH(_cp, 0.0)".
> - float:  Float.toString() produces values that look like doubles, e.g. "new
> PUSH(_cp, 0.0)".  These are mishandled.
> - long:  Long.toString() produces values that look like ints, e.g. "new
> PUSH(_cp, 0)", or, even worse, "new PUSH(_cp, 4000000000)" (which doesn't
> compile).
> I've attached two simple test cases that illustrate the issues.  Do the
> following with BCEL-5.2.jar on your classpath:
> % javac TestIncorrectLiterals.java
> % java TestIncorrectLiterals
> % java org.apache.bcel.util.BCELifier TestIncorrectLiterals
> >TestIncorrectLiteralsCreator.java
> % javac TestIncorrectLiteralsCreator.java
> % java TestIncorrectLiteralsCreator
> % java TestIncorrectLiterals
> Exception in thread "main" java.lang.VerifyError: (class:
> TestIncorrectLiterals, method: main signature: ([Ljava/lang/String;)V)
> Expecting to find float on stack
> % javac TestOutOfRangeLiterals.java
> % java TestOutOfRangeLiterals
> % java org.apache.bcel.util.BCELifier TestOutOfRangeLiterals
> >TestOutOfRangeLiteralsCreator.java
> % javac TestOutOfRangeLiteralsCreator.java
> TestOutOfRangeLiteralsCreator.java:41: integer number too large: 4000000000
>     InstructionHandle ih_0 = il.append(new PUSH(_cp, 4000000000));
>                                                      ^
> 1 error
> Here's my suggested fix:
>     private void createConstant( Object value ) {
>         String embed = value.toString();
>         if (value instanceof String) {
>             embed = '"' + Utility.convertString(embed) + '"';
>         } else if (value instanceof Character) {
>             embed = "(char)0x" + Integer.toHexString(((Character)
> value).charValue());
>         } else if (value instanceof Float) {
>             embed += "f";
>         } else if (value instanceof Long) {
>             embed += "L";
>         }
>         _out.println("il.append(new PUSH(_cp, " + embed + "));");
>     } 
> I shall test out this fix, and report back.
> This issue seems to exist in the SVN trunk code too.



--
This message was sent by Atlassian JIRA
(v6.2#6252)