| Summary: | Wrong bytecode created for varargs invocation when invoking compiler with Java 17 and --release 11 | ||
|---|---|---|---|
| Product: | [Eclipse Project] JDT | Reporter: | Sebastian Ratz <sebastian.ratz> |
| Component: | Core | Assignee: | JDT-Core-Inbox <jdt-core-inbox> |
| Status: | CLOSED FIXED | QA Contact: | Jay Arthanareeswaran <jarthana> |
| Severity: | normal | ||
| Priority: | P3 | CC: | jarthana, loskutov |
| Version: | 4.22 | ||
| Target Milestone: | --- | ||
| Hardware: | All | ||
| OS: | All | ||
| Whiteboard: | |||
I can reproduce on master. Compiling on Java 16 with target 11 works, also on 11/17/16 without target. Only on Java 17 with target 11 fails.
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
public class Test {
public static int i;
public static void main(String[] args) throws Throwable {
MethodHandle methodHandle = MethodHandles.lookup().unreflectGetter(Test.class.getDeclaredField("i"));
methodHandle.invoke(); // line 9
System.out.println("Success");
}
}
The "working" bytecode for line 9 above looks like
LINENUMBER 9 L1
ALOAD 1: methodHandle
INVOKEVIRTUAL MethodHandle.invoke() : void
The difference with the --release 11 is the following code generated for bad bytecode:
LINENUMBER 9 L1
ALOAD 1: methodHandle
ICONST_0
ANEWARRAY Object
INVOKEVIRTUAL MethodHandle.invoke(Object[]) : Object
POP
Looks like compiler generates an empty array and calls method with this array, as if it would do for "usual" varargs code. MethodHandle.invoke() is however special.
There is a special treatment for MethodHandle.invoke(...) calls, because usually the "wrong" generated code is *expected* for a varargs method call. But I have no idea where in the compiler the MethodHandle.invoke(Object...) is "translated" to MethodHandle.invoke() call.
Probably there is something fishy with CtSym / Java 11 signatures that are read from Java 17 image via CtSym with --release 11? May be the bug is even in JDK 17 itself.
Jay, any idea where do we translate MethodHandle.invoke(Object...) -> MethodHandle.invoke()?
(In reply to Andrey Loskutov from comment #1) > Probably there is something fishy with CtSym / Java 11 signatures that are > read from Java 17 image via CtSym with --release 11? May be the bug is even > in JDK 17 itself. Compiling with .../jdk17/bin/javac --release 11 results in the correct byte-code. Still seeing this on JDT Core 3.30.100. It only happens when using JDT to compile. Using the standard javac compiler results in the correct bytecode. I believe this is same as https://github.com/eclipse-jdt/eclipse.jdt.core/issues/147 Sebastian, please grab our latest build and let us know if it works for you. (In reply to Jay Arthanareeswaran from comment #4) > I believe this is same as > https://github.com/eclipse-jdt/eclipse.jdt.core/issues/147 > > Sebastian, please grab our latest build and let us know if it works for you. Indeed, I was not using the latest build yesterday. I can confirm that with org.eclipse.jdt.core_3.30.100.v20220709-0825.jar the problems is fixed. Thank you! |
Consider the following class: Test.java: import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; public class Test { public static int i; public static void main(String[] args) throws Throwable { MethodHandle methodHandle = MethodHandles.lookup().unreflectGetter(Test.class.getDeclaredField("i")); methodHandle.invoke(); } } 1) Compile with Java 11; --release 11 $ .../jdk11/bin/java -jar org.eclipse.jdt.core_3.28.0.v20210928-0852.jar Test.java --release 11 -proc:none && java Test -> OK $ javap -C Test 15: invokevirtual #37 // Method java/lang/invoke/MethodHandle.invoke:()V 2) Compile with Java 17; --release 17 $ .../jdk17/bin/java -jar org.eclipse.jdt.core_3.28.0.v20210928-0852.jar Test.java --release 17 -proc:none && java Test -> OK $ javap -C Test 15: invokevirtual #37 // Method java/lang/invoke/MethodHandle.invoke:()V 3) Compile with Java 17; --release 11 $ .../jdk17/bin/java -jar org.eclipse.jdt.core_3.28.0.v20210928-0852.jar Test.java --release 11 -proc:none && java Test Exception in thread "main" java.lang.invoke.WrongMethodTypeException: cannot convert MethodHandle()int to (Object[])Object at java.base/java.lang.invoke.MethodHandle.asTypeUncached(MethodHandle.java:884) at java.base/java.lang.invoke.MethodHandle.asType(MethodHandle.java:869) at java.base/java.lang.invoke.Invokers.checkGenericType(Invokers.java:542) $ javap -C Test 15: iconst_0 16: anewarray #3 // class java/lang/Object 19: invokevirtual #37 // Method java/lang/invoke/MethodHandle.invoke:([Ljava/lang/Object;)Ljava/lang/Object; 22: pop