IronJS - In Conversation with Fredrik Holmström
Written by Nikos Vaggalis   
Wednesday, 11 July 2012
Article Index
IronJS - In Conversation with Fredrik Holmström
Why choose .NET?

What advantages are there to implementing a dynamic language for the .NET platform and the DLR? How does it work? What better way than to ask someone that has already done it.

We set out to investigate what it takes to implement a dynamic language for the .NET platform and the DLR, and what better way than to ask someone that has already done it. So we interviewed Fredrik Holmström who has successfully ported Javascript under the name of IronJS, consistent with the naming pattern of the .NET dynamic languages like IronRuby or IronPython. We discovered what possibilities a dynamic language adds on top of the static CLR languages, what the porting process is, as well as a deep look into the IronJS internals.

First what exacly is IronJS and for that matter what is an "Iron" language?

The IronJS is a port of standard JavaScript to the .NET environment. This is made easier by the extensive facilities that .NET provides for working with language structure. For example .NET framework provides access to ASTs - Abstract Syntax Trees - which represent the syntax of a language.

The Dynamic Language Runtime (DLR) which shipped in 2010 and is now part of the .NET 4 framework was designed to make implementing dynamic languages easier. Such languages usually have "Iron" in front of their names, such as IronRuby, IronPython and now a JavaScript variant, IronJS. The DLR was intended to be used to implement Visual Basic 2010 and Managed JScript by Microsoft but Managed JScript was abandoned in favour of supporting standard JavaScript.

ironJSlogo

Now that we have the background to the project, its time to ask some questions:

NV:What is the advantage of porting a dynamic language to the .NET platform?

FH: I think the main advantage is just the DLR, I was investigating an implementation on top of the JVM at first, this was back in early 2010 if I remember correctly. The DLR gives you a lot of really great stuff for free.

NV: Like language interop and what else ?

FH: That is one thing for sure, but also just how solid the DLR code is and how big of a piece of the technology it solves for you (emitting the IL)

NV: DLR has a reputation of making it easy to create a new language implementation. Why is that? Does it provide better parsing facilities or is it in sense that the language implementer can borrow facilities out of the box like the CLR GC or JIT?

FH: The DLR itself doesn't give you anything related to parsing or lexing, but rather lets you turn your AST into what they call an Expression Tree, which is a high level, object oriented version, of IL. In reality, the expression trees are syntax trees, but they are compiled to IL by the DLR and while emitting IL isn't a complicated task, it's time-consuming to write code that does it. So, getting that for free, is a big thing.

NV: After emitting IL, is it compiled or interpreted by the DLR at runtime?

FH: Well, that's pretty much one process, you hand the DLR your expression tree, it gives you back a delegate which you can invoke. The delegate itself can either be interpreted by the DLR or compiled by the JIT; it's something you specify when you compile it.

NV: At the backend how does language interop work? Is every language creating its own AST which is then transformed to a DLR tree which acts as the common language denominator?

FH: Yes, that is pretty much it. There are special classes/objects called binders which take care of the language inter-op. A binder basically defines how a language implements the binary add operator, or the function call mechanic, etc. However, IronJS does not use these binders as they are "slow".

NV: So what alternative does IronJS use ?

FH: There's basically two ways you can use the DLR, either full-out and you use all the associated binders and all other DLR stuff which basically gives you free inter-op with all other Iron* languages; and while this is great, a lot of these mechanics are pretty slow. So IronJS uses the DLR as an IL generation and compiler tool and I do my own binding, that is ironJS specific.

NV: That's pretty deep...so how can I access the IronjS libraries from C# ? Do I have to go through a hosting process?

FH: The inter-op is a bit "so-so" currently, it's something I am working on (whenever I have time), but yes there is a hosting context

NV: How would C# types be mapped to IronJS ones and vice versa?

FH: IronJS types have no direct mapping into C#. You can access the raw JavaScript objects as their C# objects though mapping a C# type into a JS type is somewhat complicated and you need to create a proxy-javascript object which forwards the call back and forth
This is something we're working on making better Forward the calls/property accesses back and forth between JS/C# I mean
A lot of sacrifices was made in IronJS to make it as fast as possible, which means some functionality ended up being sidelined, sadly

NV: So can you take us through the design process of how you made IronJS ? (like parsing to create the AST and how you end up with a DLR tree etc)

FH: IronJS was something I've been thinking about building for a long time, but I ended up changing the way it worked many times over before it was done. The 0.2 version available on github is completely hand written, earlier versions had a generated lexer and parser but they ended up being too slow.

But, it's a very standard control flow: 

  1. Read all the input into a buffer
  2. Run a lexer across the input to produce a list of source tokens
  3. Run a parser over the list of tokens to produce an AST
  4. perform a bunch of optimizations/analyzes on the AST
  5. Create a DLR expression tree
  6. Hand the DLR tree of to the DLR itself for compilation into a delegate



Last Updated ( Wednesday, 31 October 2012 )