eclipse-jdt / eclipse-jdt/eclipse.jdt.core
Eclipse compiler produces bytecode which do not pass ASM 9.6 verification 'Error at instruction 0: Incompatible stack heights '
- Dominant language
- Java
- Stars
- 237
- Forks
- 195
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 47
Description
Recently I have discovered that some of the java sources in Eclipse are compiled to possibly incorrect bytecode.
For example, if you compile the following snippet in Eclipse 2023-12 it does not pass ASM verification:
```
public class InvalidClass {
public static Map readLocations(InputStream cvgReportStream)
{
Map locations = new HashMap<>();
LocationsReader reader = new LocationsReader();
Set locationRefs = new HashSet();
locationRefs.forEach(locRef -> locations.put(locRef, reader.getStoredLocation(locRef)));
return locations;
}
static class LocationsReader{
public Properties getStoredLocation(String locRef)
{
return new Properties();
}
}
}
```
An important note is that it is invalid for ASM 9.6 or above.
For older ASMs like 9.2 it passes verification flawlessly. To validate it use the following code snippet:
```
import org.junit.jupiter.api.Test;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.util.CheckClassAdapter;
public class InvalidBytecodeExample {
@Test
public void validateBytecode() {
InputStream resourceAsStream = getClass().getResourceAsStream("/InvalidClass.class");
ClassReader reader = new ClassReader(resourceAsStream);
reader.accept(new CheckClassAdapter(new ClassWriter(0)), 0);
}
}
```
and here is the error produced by the ASM verification:
```
java.lang.IllegalArgumentException: Error at instruction 0: Incompatible stack heights lambda$0(Ljava/util/Map;LInvalidClass$LocationsReader;Ljava/lang/String;)V
00000 R R R : R : L0
00001 R R R : : LINENUMBER 35 L0
00002 R R R : : ALOAD 0
00003 R R R : R : ALOAD 2
00004 R R R : R R : ALOAD 1
00005 R R R : R R R : ALOAD 2
00006 R R R : R R R R : INVOKEVIRTUAL InvalidClass$LocationsReader.getStoredLocation (Ljava/lang/String;)Ljava/util/Properties;
00007 R R R : R R R : INVOKEINTERFACE java/util/Map.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; (itf)
00008 R R R : R : RETURN
00009 ? : L1
at org.objectweb.asm.util.CheckMethodAdapter$1.throwError(CheckMethodAdapter.java:489)
at org.objectweb.asm.util.CheckMethodAdapter$1.visitEnd(CheckMethodAdapter.java:475)
at org.objectweb.asm.MethodVisitor.visitEnd(MethodVisitor.java:796)
at org.objectweb.asm.util.CheckMethodAdapter.visitEnd(CheckMethodAdapter.java:1044)
at org.objectweb.asm.ClassReader.readMethod(ClassReader.java:1519)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:745)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:425)
```
Another important note is that bytecode produced by 'javac' for the same sourcecode passes verification without any problems.
Contributor guide
Assessment
This issue has not been assessed yet.