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 '

Open
#2,356 6 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.