« August 2007 | Main | October 2007 »

September 2007

September 10, 2007

IronRuby Libraries

The IronRuby libraries are divided into two groups: built-ins and the standard libraries. We will distribute both sets of libraries in the standard IronRuby distribution. The distinction is whether a library must be required prior to use.

The code is organized in two separate directories under trunk\src:

src

The built-in libraries are compiled alongside the rest of the compiler into the Ruby.dll assembly (this will be renamed in the future to IronRuby.dll). The standard libraries are compiled into IronRuby.Libraries.dll for the time being. These libraries may be refactored into some additional assemblies in the future, but for the time being we'll likely go down the path of extending the assembly-level RubyLibraryAttribute to identify the Ruby libraries implemented within an assembly. All Ruby libraries must contain this attribute. Kernel#require will inspect these attributes when it goes to try and find a library by name.

Let's walk through some simple library code to better understand what's going on:

Ruby - Microsoft Visual Studio

This defines a module called Sample which will be loaded implicitly when we require the IronRuby.Libraries assembly. In the future, we will be able to require Sample directly. We can run this code via rbx.exe:

Administrator Visual Studio 2005 Command Prompt - rbx (2)

There's something interesting in the implementation of the Hello method. As you know, all Ruby methods must return a value, yet we've defined Hello as a method that returns void. If you look at the output of the console, you'll see that it returns nil, as expected. So how did this magic work?

Let's take a tour via the debugger. Much of the magic happens in RubyActionBinder.cs. Set a breakpoint on MakeRuleForInvokeMember<T> and execute the require from the screenshot above (you'll need to step over the execution of the require method itself). When you execute Sample.hello, you'll hit the breakpoint.

First, notice that the type of T is DynamicSiteTarget<object, object>. This method is responsible for generating a rule from the available information: the name of the method, the type of the receiver, the execution context, and some information about the parameters.

What's a rule? A rule is (currently) a conditional statement. There are two parts, a Test and a Target. The Test guards the Target, and if true will execute the Target. Rules are used by the DLR to generate Dynamic Sites, which is our mechanism for caching the results of our method lookups.

Here's some pseudo-code for the rule produced by MakeRuleForInvokeMember<T>:

if (typeof(target) == Sample && !HasVersionChanged(target))

  return target.hello();

Rules contain DLR expression trees. These expression trees are converted into executable CIL by the DLR. This is what the generated IL looks like after decompiling back to C# using Reflector:

public static object Handle2(object[] objArray1,

  FastDynamicSite<object, object> site1, object obj1)

{

  if ((obj1 == ((RubyModule) objArray1[0]))

     && (((RubyModule) objArray1[1]).Version == 0x815))

  {

    Sample.Hello((RubyModule) obj1);

    return null;

  }

  return site1.UpdateBindingAndInvoke(obj1);

}

Notice that we return null from the site since the method binder knows that we are invoking a void method, so we generate the correct return statement.

If you want to see the dynamic site yourself, you can run IronRuby in debug mode using these command line switches:

rbx.exe -X:SaveAssemblies -X:StaticMethods -D app.rb

app.rb is a file that contains the code that we're running. IronRuby will generate a file called snippets1.dll in the same directory as app.rb. Open it up using Reflector, and you'll see the dynamic site that we generate for calling Sample#hello:

Lutz Roeders .NET Reflector

Lutz Roeders .NET Reflector (3)

Quite a lot of the code in the RubyActionBinder is targeted for refactoring, so this isn't what it's going to look like in the long run. However, it's a good start and it generates correct, fast code today.

In a future post, I'll walk you through more complex samples where we accept parameters, dispatch to blocks, throw exceptions etc. Hope this helps you understand some of what we're doing for method dispatch to C# library code today.

September 06, 2007

Company Meeting Day

Macaw

Today is the Microsoft Company Meeting Day at Safeco field, so I wanted to point folks to a few things before I go offline for the day. I've updated the IronRuby home page with a screencast on what it looks like to contribute a patch to the core team.

As for communications, we've got the forums activated on the Rubyforge project homepage. However, I think it would be better if folks subscribed to the ironruby-core mailing list instead (I prefer mailing lists over web-based forums).

See you on the list!

September 04, 2007

New IronRuby build instructions

The Big Cougar

I spent some time today creating the IronRuby project homepage, and a screencast that will help newcomers get oriented. The latest sources in the Subversion repository should build correctly on external machines (I now have a dedicated VM that I can test build configurations on).

I've also created an IronRuby.sln file that you can find in the trunk directory. The only catch to the IronRuby.sln file is that you must set the build configuration manually to ExternalDebug or ExternalRelease, and set the startup project to IronRuby.Console if you want to do some debugging. All of these issues are captured in the screencast as well.

Enjoy!

September 01, 2007

What is this Merlin thing in IronRuby?

Playing in the Sand

One of our challenges in the IronRuby project is reconciling two different source code layouts - the external subversion layout and our internal Team Foundation Server layout. We have quite a different environment internally, complete with customized shells etc. I'm the guy responsible for the transformation script that lays things out for you guys to hack on without having to take dependencies on our internal environment - so bugs here are all my fault.

The guts of the transformation script can be found in the Rakefile for those who are curious.

Since this is the first big test of this system, there are some issues that folks have found. For the time being, you should be able to build from the command line via the rakefile (rake compile). Note that you must run from the same directory as the rakefile - there is a bug in the rakefile for generating resources.

I still have to put together a .sln file for external folks, and remove some of the key signing residue from our .csproj files.

Oh yes, Merlin is the original code-name for our team, which was originally IronPython but has now expanded to include the Dynamic Language Runtime and IronRuby.

Photos

  • www.flickr.com
    This is a Flickr badge showing public photos from John Lam. Make your own badge here.

Recent Comments

Recent Posts

May 2008

Sun Mon Tue Wed Thu Fri Sat
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Blog powered by TypePad