Overview: CLR to JVM
Both Microsoft's .NET Framework as well as Sun Microsystem's virtual machine are stack-based. While both support similar features, they also offer distinct capabilities. In particular .NET has features such as value types and delegates that are not supported natively by Sun's VM. The front-end generates two flavors of XMLVM referred to XMLVMCLR and XMLVMJVM depending on whether the source file stemmed from .NET or a Java class file. The main difference of the two flavors are the byte code instructions supported by the respective platform. XMLVM can cross-compile XMLVMCLR to XMLVMJVM. This effectively enables the deployment of .NET executables on a JVM.
Consider for example numerical operations. .NET's byte code instructions are untyped, i.e., there is only one instruction for computing the remainder after division, while Sun's VM offers several remainder instructions for integers, floats, and doubles. When cross-compiling from the CLR to the JVM it becomes necessary to determine the precise type on which the instruction operates so it can be mapped correctly to a corresponding JVM instruction. This can be accomplished through a data-flow analysis (DFA). The DFA essentially annotates each instruction of a program with a transition that this instruction causes on the type-stack.
XMLVM introduces new XML-markup to represent the result of the DFA. <stack-pre> describes the type-stack before execution of an instruction and <stack-post> describes the content of the type-stack after execution of an instruction. Both tags are added as children to each byte code instruction. The resulting XML-document is referred to XMLVMDFA-CLR as can be seen in the following figure:
As can be seen, the <clr:ldc> (load constant) pushes one integer onto the type stack, while the <clr:rem> (remainder after division) pops off two integers and pushes one back onto the type-stack. Each element of the type stack is represented by the <elem> tag. Based on the information computed by the DFA, it is possible to map CLR instructions to the JVM. This can be accomplished by XSL stylesheets with appropriate XPath expressions. The following XSL template maps the <clr:rem> instruction to <jvm:irem> if the top of the type stack has an integer:
<xsl:template match="clr:rem[stack-post/elem[last()][@type = 'int']]">
<jvm:irem/>
</xsl:template>
To demonstrate this approach, we have written a C# version of the calculator that was also used for the AJAX demo. The following links show the various artifacts created during the cross-compilation process:
- Calculator.cs: C# source code of this calculator using WinForms as the GUI library.
- Calculator.xmlvm-clr: the XMLVMCLR version of Calculator.cs
- Calculator.xmlvm-clr-dfa: the XMLVMCLR-DFA version showing the result of the DFA.
- Calculator.xmlvm-jvm: the resulting XMLVMJVM version only featuring JVM byte code instructions.
The following screenshots show the original Calculator.cs compiled under Mono (left) and the cross-compiled Java version executed on a standard Java VM (right). Java wrappers have been written for the WinForms API using the Swing library.