Jasmin how to force long field to be long constant?

406 views Asked by At

I managed to isolate my problem in this test case:

.bytecode 50.0
.class public test
.super java/lang/Object

.field public static final foo1 J = 1

.method public <init>()V
    .limit stack 1
    .limit locals 1
    .var 0 is this Ltest; from init_start to init_end

init_start:
    aload_0
    invokespecial java/lang/Object/<init>()V 
init_end:
    return
.end method

.method public static main([Ljava/lang/String;)V
    .limit stack 1
    .limit locals 1
main_start:
    new test
    invokespecial test/<init>()V
main_end:
    return
.end method

When I try to run this, I get this:

$ jasmin test.j
$ java test
Exception in thread "main" java.lang.ClassFormatError: Inconsistent constant value type in class file test
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:634)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:277)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:73)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:212)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
Could not find the main class: test. Program will exit.

Some investigation(with javap) reveals this:

public static final long foo1;
  Constant value: int 1

In other words, the value of the long constant is being stored in the class file as an integer. Is there some way to force Jasmin to store the constant in the pool as a long? I've tried 1L but it doesn't work. Setting the value of foo1 to be a number greater than INT_MAX (such as 2147483648) does fix the error, but I was hoping for a solution that wouldn't require me to change the constant values.

Does Jasmin provide any way to do this or will this require me to change the source code of jasmin?

2

There are 2 answers

0
luiscubal On BEST ANSWER

I've released a modified version of Jasmin that allows me to do this. It is available on https://github.com/luiscubal/jasmin

To use long constants on this modified version, do this:

.field public static foo J = 1l
0
Matt Pedersen On

same issue with exists with public static final double constants:

.field public static PHASE_1 D = 5.0

also seems to crash with the same Java runtime error.

I worked around it by removing the 'final' flag and moving the initialization to the constructor ;-)