# Wednesday, 31 July 2002
What's wrong with this picture?
class DivTest
{
 public static void Main()
 {
  int i = int.MinValue;
  System.Console.WriteLine(-i);
  System.Console.WriteLine(i * -1);
  System.Console.WriteLine(i / -1);
 }
}

Why does div throw an OverflowException when you're trying to divide MinInt by -1? I'm assuming that since dividing by zero throws a DivideByZeroException, the CLR designers thought it would be nice if div would throw an exception for overflow as well.

This sucks!

Partition III CIL.doc section 3.31 about div says:

Exceptions:

Integral operations throw ArithmeticException if the result cannot be represented in the result type. This can happen if value1 is the maximum negative value, and value2 is -1.

Integral operations throw DivideByZeroException if value2 is zero.

Implementation Specific (Microsoft)

On the x86 an OverflowException is thrown when computing (minint div –1).

Why didn't they define a div.ovf (like there are add.ovf, sub.ovf, mul.ovf, etc.) in addition to div (and then make div behave consistently with add, submul)?

Question: What should I do? Implement Java's idiv bytecode using this broken div or compile them into conditional code that checks for MinInt / -1 and treats that specially (and thus slowing down integer division).

BTW, J# uses div but I'm not sure they actually thought about this issue. The following code crashes the J# compiler:

 System.out.println(Integer.MIN_VALUE / - 1);
Wednesday, 31 July 2002 16:14:23 (W. Europe Daylight Time, UTC+02:00)  #    Comments [2]
No Title

I only just noticed that Stuart commented on the July 25 item:

The natural "con" that I can think of regarding your alternative implementation is that it would make it very difficult for Java code to catch System.Exception. At least it would require that code that wants to catch *any* exception would have to know that it might be running under IK.VM and explicitly catch System.Exception, where a normal Java program might expect to be able to catch Throwable.

I didn't mention this, but I would still map all usages of java.lang.Throwable to System.Exception (except in the case of the base class, when a class is derived from Throwable, it would be derived from Throwable). Sensible interop between .NET and Java exceptions is definitely something I'm aiming for.

The difficulty, it seems to me, is ensuring that you don't just have a good mapping from Java to C#, but that your mapping is fully *reversible*, and makes just as much sense going the other way. Java code expects to know exactly what exceptions are going to happen for a particular method, so you'll need to be remapping things like IOException already - and you'll need some way to ensure that any exception that's going to be thrown by a method where Java doesn't expect it gets mapped to a RuntimeException (or Error or direct Throwable subclass) with the original exception as the cause.

I'm not actually remapping exceptions like IOException, what happens is that the "native" code that implements an I/O function catches the System.IO.IOException and throws a java.io.IOException.

CLR generated exceptions get converted to the Java equivalent when they are first caught. At the moment I don't convert them back, so when .NET code calls Java code it can expect both System.NullReferenceException and java.lang.NullPointerException to be thrown (for example) depending on whether the Java code "caught" (a finally also triggers the conversion) the exception before it was propagated out the calling .NET code. This isn't very elegant, so I expect that in the future I'll be swapping the original exception back when the Java code rethrows the exception.

I suppose that your generated JAR files (described in your previous entry in response to my comment) will have to declare every method as "throws Exception", right?

To be honest, I hadn't even thought about this. My initial thought would be to make it seem (for the Java compiler) as if every .NET exception is derived from RuntimeException to get around this mess. This might cause additional complications, so I'm going to have to think about this a little more. Adding "throws Exception" doesn't appeal to me either, because that would make it very uncomfortable for the Java programmer trying to call .NET code.

Wednesday, 31 July 2002 15:29:13 (W. Europe Daylight Time, UTC+02:00)  #    Comments [2]
# Monday, 29 July 2002
No Title

I found an interesting paper on jsr/ret verification. It contains the following example of valid Java code that is not verifiable with the verification algorithm described in the JVM spec:

static int m(boolean x) {
  int y;
  try {
    if(x) return 1;
    y = 2;
  } finally {
    if(x) y = 3;
  }
  return y;
}
Monday, 29 July 2002 18:12:48 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
# Saturday, 27 July 2002
No Title

I finally implemented the local variable usage tracking for subroutines in the verifier. In this instance Microsoft certainly did learn from Sun's mistakes. The JVM verifier is ridiculously complex because of two features:

  • jsr & ret instructions (subroutines within a method)
  • untyped local variables

The CLR lacks both of those features. The reason Sun introduced subroutines is because code in a finally block needs to run both in the normal case and in the exception case, there are two ways you can compile this (Java's bytecode has no concept of finally blocks): code duplication or the subroutine construct. Microsoft solved this by explicitly supporting finally blocks in MSIL, a far more elegant solution. Having typed local variables really doesn't have any downside (except that you have slightly more metadata to carry around).

Updated the snapshot.

Saturday, 27 July 2002 10:51:05 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
# Thursday, 25 July 2002
More java.lang.Throwable

I did some more work on Throwable. In my previous post I forgot to mention that virtual methods in Throwable wheren't overidable yet (because they have no equivalent in System.Exception, I cannot reuse those vtable slots, like I do for System.Object). I implemented a mechanism to support those now. Every direct subclass of Throwable is converted into a .NET subtype of System.Exception and it implements the Throwable$VirtualMethods interface. Each virtual invocation of a virtual method in Throwable is redirected to a static method in the class Throwable$VirtualMethodsHelper that checks if the type implements the Throwable$VirtualMethods interface, if it does, the method is routed there, if it doesn't the method is routed to the C# implementation of the Throwable method in ExceptionHelper.

BTW, the reason that the static helper methods are in a separate class, is because Reflection.Emit (incorrectly) doesn't allow the definition of static methods in interfaces.

The cool part of all this is that all of this virtual method handling is generic and completely based on the remappings defined in map.xml.

I also implemented the 1.4 stack trace handling, so Throwable is now fully functional.

BTW#2, there is also an alternative way I could have handled the virtual methods, by making Throwable a subtype of System.Exception. I haven't figured out the pros and cons of this, so may be I'll do the alternative implementation in a few days to see if that is a more elegant way of doing it.

Updated the snapshot.

Thursday, 25 July 2002 18:16:31 (W. Europe Daylight Time, UTC+02:00)  #    Comments [1]
# Monday, 22 July 2002
No Title

I did lots of work on exception handling. Most of it now works (fully compatible with J2SE 1.4). Some highlights:

  • java.lang.Throwable is remapped to System.Exception (for maximum compability with .NET code)
  • Throwable.getMessage(), Throwable.getCause() & Throwable.toString() all work, and are fully compatible with J2SE 1.4. Additionally, the message is stored as the System.Exception.Message property, and when the exception object was constructed with a cause, the System.Exception.InnerException property is set.
  • Stack traces now work (fully Java compatible), except for J2SE 1.4 inner exceptions stack trace dumping.
  • I made the XML remapping language more powerful. It now supports calling helper methods and using locals to twiddle around with method arguments.

Things that don't work:

  • When .NET code prints a stacktrace from an exception thrown by Java code, the stacktrace only shows the stack from the last rethrow point in the Java code.
  • Throwable.printStackTrace() doesn't yet support Caused by: in the stack traces.
  • Additional exception information object (that contains the stacktrace and the cause)  is not yet garbage collected when the exception goes away.

Here is the testcase I used.

Updated the snapshot.

Monday, 22 July 2002 19:32:54 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
# Tuesday, 16 July 2002
No Title

I cleaned up the Visual Studio .NET solution. For now it consists of the following projects:

  • IK.VM.JNI
    This is the Managed C++ project that implements the JNI interface.
  • IK.VM.NET
    This is the Virtual Machine. It contains the Java classfile parsing, classpath native code, method compiler and various other bits.
  • ikvm
    This is a very simple C# program that starts up the VM and runs the class specified on the command line. The equivalent of java.exe in the JDK.

Other changes:

  • I decided to use a license derived from the zlib license.
  • gjc (Generic Java Compiler formerly known as Pizza) now runs (i.e. it compiles Hello, World)
  • The map.xml file is now an embedded resource

I updated the snapshot.

Tuesday, 16 July 2002 16:52:24 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
# Saturday, 13 July 2002
No Title

Stuart commented on the previous item: ...That leaves #2, which seems hard to me. At the very least, it seems like it would require changes to the Java language compiler to interpret (at least metadata from) .NET classes and allow for those to be in the CLASSPATH at compilation time. Is that something you're interested in pursuing as part of IKVM, or do you regard it as a separate problem?

The way I plan to go about this, is to create a tool that generates jar files from .NET assemblies. The jar will contain all the public classes & interfaces from the .NET assembly, and all the methods will appear to be native. Standard Java compilers can then be used to compile against .NET code. The IK.VM will be aware of these special classes (they will contain an attribute to specify the fully qualified .NET type name) and reroute all access to these wrappers to the real .NET types. I haven't built any of this, but I don't expect any problems.

Saturday, 13 July 2002 10:31:48 (W. Europe Daylight Time, UTC+02:00)  #    Comments [1]
# Wednesday, 10 July 2002
No Title

I changed the Java to native code transition from my own MC++ marshaling to use the calli instruction. The code is much more elegant now, not to mention much faster. My database app now performs on a par with JDK 1.1. Not bad at all.

Also, I implemented support for interfaces that "override" java.lang.Object methods and I remapped java.lang.Comparable to System.IComparable. Both of these features use the same underlying mechanism, i.e. the ability to provide explicit interface implementations that redirect to virtual methods with a different name.

Wednesday, 10 July 2002 18:18:28 (W. Europe Daylight Time, UTC+02:00)  #    Comments [1]
# Monday, 08 July 2002
No Title

Many changes:

  • Added exception remapping support for some exceptions (NullReferenceException, IndexOutOfRangeException, InvalidCastException & TypeInitializationException)
  • Changed Throwable.printStackTrace() to print out stack traces in Java format
  • Partial support for retaining stack traces when exception is rethrown
  • java.lang.StringBuffer is now remapped to System.Text.StringBuilder
  • Rewrote file IO in classpath because it was buggy
  • Started on an ahead-of-time compiler that also emits debugging information (based on the debugging info in the Java classes)

Yesterday, I ran into a bug in MC++ when unboxing.

I've updated the snapshot and since I've made some changes to classpath, I've now put my modified version of that online as well.

Monday, 08 July 2002 12:28:53 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
# Thursday, 04 July 2002
No Title

Updated the snapshot. Many fixes to the verifier and compiler and I also implemented a few more "native" methods. My company's database server product now works (at least partially), which is a pretty exciting step. It uses JNI to do its file I/O (because it runs on JDK 1.1), so it runs a little slower than under JDK 1.1, but hopefully that will improve once I've optimized the JNI method calling implementation.

Thursday, 04 July 2002 15:45:24 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
# Tuesday, 02 July 2002
Benchmark

Just for fun, I tried to run a FFT program from the IBM Ninja (Numerically Intensive Java) package. After implementing a few more native methods, it ran, but to my surprise it ran about as fast as under JDK 1.4 (with Sun's Hotspot VM). Not bad for totally unoptimized code ;-)

The cfft.java source that I ran can be viewed here, the resulting executable (in a zip) can be found here and I've updated the project snapshot. For the array package, follow the Ninja link.

Tuesday, 02 July 2002 12:28:37 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
J# released

Yesterday, Microsoft released J#. When I first looked at it yesterday, I was happy to find that they fixed the huge flaw that existed in beta 2. In the final version they have made java.lang.Object and java.lang.String aliases for System.Object and System.String. So they no longer require a "VerifierFix" to convert System.Object references to java.lang.Object references. Even so, they've decided to remove the AllowPartiallyUntrustedCallers attribute from the J# runtime libraries.

Unfortunately, the rest of the story isn't so positive. In only an hour of trying to compile my Java code, I already encountered three bugs in the compiler and one in the runtime. So I remain very sceptical about the quality of this product.

Tuesday, 02 July 2002 11:34:38 (W. Europe Daylight Time, UTC+02:00)  #    Comments [1]