I came across a class file that was the equivalent of the following source:
public static final int FOO = 1;
FOO = 1;
This isn't legal Java, but the class file equivalent is. The FOO field has a ConstValue attribute with the value 1 and then there is code in the static initializer to set the value again. The code in the static initializer isn't needed and the Java compilers I've seen so far don't emit it.
Anyway, IKVM handles assignments to (non-blank) final fields by just ignoring the assignment, but my code generator emitted a nop instruction, instead of a pop (because it should consume the value on the stack). Fixed.
GNU Classpath is about to release version 0.05, so I got their code from cvs and updated my native methods to work with the latest code (the only changes required were for Object[In][Out]putStream, because Mark cleaned those up to use less native code, a nice improvement!). There was still one remaining issue with compiling the classpath code with ikvmc, I had to comment out a line of code in java/nio/charset/Charset.java:
public final ByteBuffer encode (String str)
return encode (CharBuffer.wrap (str));
CharBuffer.wrap takes an CharSequence as its argument, but my java.lang.String doesn't implement CharSequence (yet). It occurred to me that since it is legal for any reference type to be passed where an interface is expected (see here) this code was legal as well (even if String doesn't implement CharSequence), so I added support to the compiler to insert casts when the arguments on the stack do not match with the expected method arguments (but only for interface references).
Finally, there is still one patch required to Classpath, because new File("c://") hangs:
RCS file: /cvsroot/classpath/classpath/java/io/File.java,v
retrieving revision 1.21
diff -r1.21 File.java
< if (!PlatformHelper.isRootDirectory(path))
< while (PlatformHelper.endWithSeparator(path))
> while (!PlatformHelper.isRootDirectory(path) &&
You wouldn't expect this to be a common occurrence, but it turns out that this exact path is constructed by the code that computes the current directory, so if you use ikvm to run a Java application in the root directory of a drive it hangs (without this patch).