# Friday, 28 June 2002
Status Update

"Hello, world!" is now fully verifiable. I haven't got all the corner cases of jsr support worked out, but the most important chunk of work in handling try {} catch {} blocks is now done. Next task is to translate the CLR exceptions (System.NullReferenceException, System.IndexOutOfRangeException, and may be others) into the corresponding Java exceptions.

Friday, 28 June 2002 16:03:39 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
# Thursday, 27 June 2002
Status Update

"Hello, world!" now runs without first having to process the entire transitive closure of classes. It turns out that there is (what I feel) a bug in ModuleBuilder.GetType(string). It can be used to construct array types for types that have not yet been finished, but whenever you do that, it does fire the AppDomain.TypeResolveEvent, which caused me to finish the type (which wouldn't work because it was already in the process of being finished). Fortunately, it's easy to workaround, by setting a flag to ignore the TypeResolveEvent while inside ModuleBuilder.GetType().

Running "Hello, world!" takes slightly less than 2 seconds. So startup performance could be better ;-)

Thursday, 27 June 2002 14:33:14 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
Naming

I removed the << from the title of the blog, because of Radio's problems with them.

Thursday, 27 June 2002 13:24:12 (W. Europe Daylight Time, UTC+02:00)  #    Comments [1]
Hello, world!

It's running! Those who have ever implemented a JVM know that running "Hello, World!" requires a very large percentage of the VM to be up and running, so I'm very happy to have reached this point.

If anyone wants to see the results for themselves, a zip file containing the executable and two dlls is available here.

The full project is available here.

There are still many things todo (in no particular order):

  • Implement jumping into and out of try blocks (run peverify on hello.exe to see what I mean ;-))
  • A few missing bytecodes need to be implemented
  • CLR exceptions need to be mapped to Java exceptions
  • Exceptions should retain their stacktraces even though they are thrown again
  • Many classpath native methods have to be implemented
  • Many JNI methods need to be implemented
  • Figure out how to deal with final fields (CLR initonly is not the same as Java's final. In Java a class is allowed to change a final field (although most JITs don't support that))
  • Figure out a way to make sure that generated types are finished in the proper order, to avoid deadlock. This is a major problem now, if I don't save the dynamic assembly before starting to execute the main method, the loading of classes deadlocks.
  • Many things I haven't even discovered yet ;-)
Thursday, 27 June 2002 12:39:22 (W. Europe Daylight Time, UTC+02:00)  #    Comments [2]
# Wednesday, 26 June 2002
No Title

Milestone! I just managed to JIT the entire transitive closure of classes required to run Hello World (304 classes).

It doesn't run yet, because I don't have the required classpath native methods yet and the resulting exe (708KB) contains tons of verification errors, but this is definitely an exciting step.

I had to make a few minor changes to the classpath source:

  • removed java/lang/CharSequence interface from java/lang/String and added workarounds to make it compile after this

  • removed equals() and hashCode() from java/util/Collection

  • removed equals() from java/util/Comparator

The equals() and hashCode() methods in interfaces don't really do anything, but at the moment I cannot handle them. It would be trivial to add code to handle them, but I don't want to hardcode that kind of stuff, all method remapping should be based on the XML file that defines the remappings.

Download here.

Wednesday, 26 June 2002 18:48:04 (W. Europe Daylight Time, UTC+02:00)  #    Comments [1]
# Tuesday, 25 June 2002
No Title

I've been trying to get "Hello World" working with the classpath library. I implemented tons of bytecodes, fixed bugs and enhanced the method (and now field) remapping functionality. Still not there yet. I just ran into the problem that the constructors for java.lang.Throwable and System.Exception aren't the same, so for classes derived from java.lang.Throwable I will need to rewrite the call to the superclass constructor, to supply the proper arguments.

I updated the download.

Tuesday, 25 June 2002 18:52:19 (W. Europe Daylight Time, UTC+02:00)  #    Comments [1]
# Monday, 24 June 2002
No Title

Yesterday, I wrote a partial bytecode verifier to track the types on the stack and in the locals, and based on this, today, I wrote a new bytecode compiler that, instead of decompiling the bytecode into an AST and then recompiling that (as I did previously) just converts individual bytecode instructions. This is a much better approach, as I will now be able to handle all sorts of weird code constructs not typically generated by Java compilers. Of course, it'll also be easier to handle the bytecode that is produced by the Java compilers.

The new code can be downloaded here.

Monday, 24 June 2002 14:34:18 (W. Europe Daylight Time, UTC+02:00)  #    Comments [1]
# Friday, 21 June 2002
Old News

Last week as was thinking about local variable handling, I found a bug in Sun's 1.4 JVM. Visit this url to crash your browser (if you use the Sun JVM, it doesn't work on the MS VM).

The pseudo source for the applet is:

public class test extends Applet
{
    synchronized void foo()
    {
        this = null;
    }

    public void init()
    {
        for(;;)  foo();
    }
}

The CLR (and Rotor too) throws an ArgumentNullException for similar code, which isn't ideal either, but at least it isn't crashing.
Friday, 21 June 2002 18:21:30 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
# Thursday, 20 June 2002
No Title

The .NET Guy: I believe that if you check out his implementation, he's JITting Java byte-code into MSIL, and then implementing the Java libraries in terms of the .NET BCL. At least, I couldn't see any other way to make it reasonably fast... why re-implement garbage collection if there's already a garbage collector? :)

Right, except that I'm not reimplementing the Java libraries. I plan to use GNU Classpath for that. The only thing I need to reimplement is the native part of it, which I will do in terms of the .NET BCL (as much as possible). It'll be a long while before AWT is running though ;-)

Thursday, 20 June 2002 17:02:03 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
Exception woes

I just found another problem with exception handling. There is no way in .NET to throw an exception without overwriting the stack trace information.

When native code is invoked from Java and the native code in turn invokes a Java method which throws an exception, the native code can handle the exception, but if it doesn't the Java code that called the native code gets the exception.

I need the ability to rethrow an existing exception object. In Java the stack trace for the exception is done at construction time, not when the exception is actually thrown.

Thursday, 20 June 2002 16:45:40 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
No Title

I forgot Exception in my reply to Sam. I'm still thinking about the exception mappings. java.lang.Throwable should probably map to System.Exception, and then use reflection to emulate the virtual methods that don't correspond, but what to do about java.lang.NullPointerException vs System.NullReferenceException? Obviously when the CLR throws a System.NullReferenceException, Java code should be able to catch it as a java.lang.NullPointerException, but also as a java.lang.Exception or java.lang.RuntimeException.

But what should happen when Java code throws a NullPointerException (or worse, it's own subclass of it)? Should this be translated to System.NullReferenceException? One thing I haven't talked about much is my wish for interoperability between Java and .NET code, but I do intent for it to be possible (and convenient) to use Java class libraries from your C# (or whatever .NET language) code. In order for this to work, the exception mappings need to make sense to both the Java and the .NET side.

Thursday, 20 June 2002 12:31:21 (W. Europe Daylight Time, UTC+02:00)  #    Comments [1]
No Title

Sam Ruby: I<<K.VM.NET is a Java byte code to CIL converter (some prefer to call it MSIL, but not me).  My guess is that Jeroen is using the same hooks that CLAW does to modify the byte codes immediately prior to JIT, but in this case the translation is a wee bit more involved.

I'm not using the same hooks as CLAW, I'm using the AppDomain.TypeResolve event. This works very well together with Reflection.Emit, because it allows me to lazily emit a type whenever the CLR needs it. The one downside of it is that it doesn't provide the assembly where it thinks the type lives, so when I'm going to implement multiple classloader support I will need to mangle the classnames.

If all goes well, one should be able to simply put JAR files in a CLASSPATH and transparently call Java code from C#.

That's exactly the idea. My starter executable (the equivalent of jre.exe) looks like this:

public class Starter
{
 static void Main(string[] args)
 {
  JVM.Init();
  string[] vmargs = new string[args.Length - 1];
  for(int i = 1; i < args.Length; i++)
  {
   vmargs[i - 1] = args[i];
  }
  Type type = Type.GetType(args[0], true);
  MethodInfo main = type.GetMethod("main");
  main.Invoke(null, new object[] { vmargs });
 }
}

I suspect the hardest part will be handling the class libraries - in particular three classes: Object, String, and Exception.

Exactly. Mapping java.lang.Object to System.Object turns out to be easy, they have the exact same virtual methods, but in order for this to work java.lang.String also has to be mapped to System.String, since string is final, not much to worry about (methods can be redirected to static helpers), except for one thing: interfaces. If java.lang.String implements an interface, System.String should implement the equivalent interfaces. In JDK 1.4 java.lang.String implements: Serializable, Comparable and CharSequence. Serializable has no methods, so it's not a big deal. Comparable maps nicely to System.IComparable, so that's easy, but CharSequence is a problem, System.String doesn't have that, so that interface will probably have to be emulated via some reflection hack. Of course, at the moment I'm aiming for JDK 1.1 compatibility, so it's not really an issue yet :-)

Thursday, 20 June 2002 10:36:27 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
# Wednesday, 19 June 2002
Download

It'll be a while before the code becomes available in any structured format, but for the time being I'll post a snapshot every once in a while. I haven't decided on a license yet, any thoughts on that topic are appreciated.

Wednesday, 19 June 2002 14:36:15 (W. Europe Daylight Time, UTC+02:00)  #    Comments [3]
Current Status

What I currently have is:

  • java/lang/Object to System.Object & java/lang/String to System.String mapping
  • On demand class loading infrastructure (but no ClassLoader support)
  • Code to read and parse Java .class files
  • Compiler that parses (small subset) of Java bytecode and converts it into MSIL
  • Small subset of JNI support (calling native methods & calling Java from native code)

What is needed

  • Exception object model mapping needs to be worked out
  • Bytecode parser needs much improvement
  • Classpath native code needs to be written
  • Classpath VM interface needs to be investigated and adapted where necessary
  • ClassLoader support
  • Flesh out JNI support
  • Testing, testing and more testing
  • Documentation
Wednesday, 19 June 2002 12:43:40 (W. Europe Daylight Time, UTC+02:00)  #    Comments [2]
What about J#?

When I looked at beta 1 of J#, I found so many bugs in the first day of playing with it, that I decided to report the bugs to Microsoft and then ignore the product until the next beta. When beta 2 arrived, two of bugs I reported hadn't been fixed, but I decided to go ahead and play with it for a couple of days anyways. What I found was devastating: The J# object model is fundamentally broken. In order for it to function, it requires a huge security hole. I reported this to Microsoft and gave up on the tool. Since then I've been looking for an alternative, but recently I finally decided to build my own JVM for .NET.

Wednesday, 19 June 2002 12:22:26 (W. Europe Daylight Time, UTC+02:00)  #    Comments [3]
What is I<<K.VM.NET?

I<<K.VM.NET is a Java VM implemented in .NET. The goal is to implement a fully functional JVM. Initialy, I'll probably be aiming at the JDK 1.1 compatibility level, but in the future newer versions should be possible.

How does it work?

Java .class files are converted just-in-time to .NET classes. This enables me to take advantage of the .NET JIT compiler and GC. The Java class library that will be used is GNU Classpath.

Why?

I have a large Java application that I would like to slowly migrate to .NET, in order to be able to do that, I need a way to interoperate with Java code, the existing solutions I have looked at are inadequate. Besides, It's lots of fun to build something like this :-)

Wednesday, 19 June 2002 12:17:37 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
Finally started blogging

After several false starts, I finally decided to start blogging seriously, using Radio. I'd built a (broken) prototype blogging engine in ASP.NET, but that just didn't work well enough to be used seriously.

The reason I'm starting this blog, is to act as documentation of the development of I<

Wednesday, 19 June 2002 11:52:37 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]