Missing autoboxing in generated code for conditional expression with null literal

Issue #226 resolved
Jesper Öqvist created an issue

ExtendJ 8.0.1-222-g9a85c80 Java SE 8

The following test code should generate an implicit autoboxing operation for the non-null argument in the conditional expressions, however no such operation is generated by ExtendJ, leading to inconsistent stack heights during runtime.

// Test runtime autoboxing forced by null in a conditional expression.
class Test {
  public static void main(String[] args) {
    new Test().test1(true, 0.16, 2L);
    new Test().test2(false, 0.42, 42L);
  }

  void test1(boolean a, double b, long c) {
    f(a ? b : null); // Calls Test.f(double).
  }

  void test2(boolean a, double b, long c) {
    f(a ? null : c); // Calls Test.f(long).
  }

  void f(double v) {
    System.out.println("double: " + v);
  }

  void f(long v) {
    System.out.println("long: " + v);
  }
}

Expected result: should execute without error.

Actual result: runtime error when executing:

    [junit] [FAIL] runTest[run/conditional_03](tests.extendj.TestJava7)
    [junit] Error output files differ expected:<[]> but was:<[Error: A JNI error has occurred, please check your installation and try again
    [junit] Exception in thread "main" java.lang.VerifyError: (class: Test, method: test1 signature: (ZDJ)V) Inconsistent stack height 2 != 3
    [junit]     at java.lang.Class.getDeclaredMethods0(Native Method)
    [junit]     at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
    [junit]     at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
    [junit]     at java.lang.Class.getMethod0(Class.java:3018)
    [junit]     at java.lang.Class.getMethod(Class.java:1784)
    [junit]     at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
    [junit]     at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)]>

Comments (2)

  1. Jesper Öqvist reporter

    The following bytecode is generated for test1 by ExtendJ:

             0: aload_0
             1: iload_1
             2: ifeq          9
             5: dload_2
             6: goto          10
             9: aconst_null
            10: invokevirtual #38                 // Method f:(D)V
            13: return
    

    The missing autoboxing operations is apparent when compared to the bytecode output by javac:

             0: aload_0
             1: iload_1
             2: ifeq          12
             5: dload_2
             6: invokestatic  #9                  // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
             9: goto          13
            12: aconst_null
            13: invokevirtual #10                 // Method java/lang/Double.doubleValue:()D
            16: invokevirtual #11                 // Method f:(D)V
            19: return
    
  2. Log in to comment