RunSharp: Reflection Emit for Mere Mortals
I have been dealing with IL generation using Reflection Emit for about two years. I believe that I have enough experience with it to get a feeling for how it goes, and it usually goes slowly and painfully. There are wrappers around it (Castle Dynamic Proxy has a AST for this), but they are fairly specialized, and anyone somehow I always find myself needing to fix the code that build the AST, mostly because I have users that throws weird curve balls at Rhino Mocks.
Nevertheless, IL generation is a powerful technique, just very cumbersome to deal with. RunSharp is a OSS project that aims to solve this issue, it generate code on the fly, using high-level syntax.
This means that you can write code like this:
g.Assign(x, o.Invoke("MyMethod", arg1, arg2)); g.Assign(y, o.Property("MyProperty")); g.Assign(o.Property("MyProperty"), z); g.Assign(f, o.Field("myField"));
And it will generate the appropriate:
x = o.MyMethod(arg1, arg2); y = o.MyProperty; o.MyProperty = z; f = o.myField;
I am impressed, if this works, it can mean some very interesting possibilities. I took a very brief glance at the code, and it is using the ILGenerator from the framework, I would be very interested in getting this to work on (a) dynamic methods, (b) cecil.
The license is GPL, however, which means that it is a problem to use in any scenario. In my opinion, such a thing should be LGPL, which would allow its use in other projects, but that is a subject for another day.
Thanks Roy, for finding it.
Comments
Hi Ayende (and others ;),
I'd like only to comment on the GPL issue, as I believe this is something that more people are interested in - I've chosen GPL not to limit the usefulness of the library, but rather to limit it's use while it's still very immature. The 1.0 release (or maybe even the betas before) will be very likely distributed under LGPL, maybe even a BSD-style license.
Regards,
Stefan
What's wrong with MSIL? It's just assembly language... :-p
But it does help to go one step up sometimes. While I think going up to the level of an AST is too much if you're just doing code-gen, going up to the level of a typed register transfer language with somewhat friendlier control flow primitives would probably be useful.
From what I remember, the old DynamicProxy (1) code-gen helpers straddled an uncomfortable middle ground between AST and RTL. I found the AST stuff got in the way while I was down in there adding support for out/ref params and fixing other bugs.
Jeff,
Yes, they did, somewhat.
The main issue is that the AST was very useful when building the code, but most of the maintenance on DP is at a level below that.
Not much. the question should be, what's wrong with Reflection.Emit? The main problem IMO is that certain errors are just thrown on TypeBuilder.CreateType, and there are no hints as to where in your IL code the error is. This is like coding in PL SQL ;-)
Comment preview