Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

IL Generator syntax proposal

0 views
Skip to first unread message

John Lam

unread,
Dec 2, 2005, 12:17:03 PM12/2/05
to
In my rewrite of my Ruby <=> CLR bridge, I've been thinking about pushing
most of the logic into Ruby, and leaving as little as possible in Managed
C++. I was just hacking around this morning in emacs thinking about what the
syntax for an IL generator should look like, and this was what I came up
with:

d = DynamicMethod.new("Int32, UInt32*, UInt32")
g = d.get_generator

g.begin_exception_block do
g.call "static Throws.ThrowException()"
g.br_s "EndOfMethod"
g.catch("Exception") do
g.call "ToString()"
g.call "static Console.WriteLine(String)"
end
g.label "EndOfMethod"
g.ldc_i4 Qnil
g.ret
end

I'd love it if folks could comment on how this syntax might be improved in
Ruby before I crank out the underlying MC++ / Ruby code ...

Thanks!
-John
http://www.iunknown.com

Phil Tomson

unread,
Dec 2, 2005, 9:12:07 PM12/2/05
to
In article <d0b50b7f0512020916h6a...@mail.gmail.com>,
John Lam <drj...@gmail.com> wrote:
>------=_Part_949_1409715.1133543816267
>Content-Type: text/plain; charset=ISO-8859-1
>Content-Transfer-Encoding: quoted-printable
>Content-Disposition: inline
>
>In my rewrite of my Ruby <=3D> CLR bridge, I've been thinking about pushing

>most of the logic into Ruby, and leaving as little as possible in Managed
>C++. I was just hacking around this morning in emacs thinking about what th=

>e
>syntax for an IL generator should look like, and this was what I came up
>with:
>
>d =3D DynamicMethod.new("Int32, UInt32*, UInt32")
>g =3D d.get_generator

>
>g.begin_exception_block do
> g.call "static Throws.ThrowException()"
> g.br_s "EndOfMethod"
> g.catch("Exception") do
> g.call "ToString()"
> g.call "static Console.WriteLine(String)"
> end
> g.label "EndOfMethod"
> g.ldc_i4 Qnil
> g.ret
>end
>
>I'd love it if folks could comment on how this syntax might be improved in
>Ruby before I crank out the underlying MC++ / Ruby code ...
>

Are you the person who got the Google summer of code grant to do a Ruby/.NET
bridge?

Phil

Florian Groß

unread,
Dec 2, 2005, 11:22:49 PM12/2/05
to
Phil Tomson wrote:

> Are you the person who got the Google summer of code grant to do a Ruby/.NET
> bridge?

Wasn't that a Summer of Code grant to do a Ruby.NET compiler...? ;)

Wayne Vucenic

unread,
Dec 3, 2005, 6:49:55 PM12/3/05
to
Hi John,

It was great meeting you at RubyConf!

We can avoid having to do all the "g." prefixes on the methods like this:

module CLR_IL
def use_generator(g)
@il_generator = g
end

def begin_exception_block
@il_generator.begin_exception_block
end

def call(s)
@il_generator.call(s)
end
end

then your example becomes

d = DynamicMethod.new("Int32, UInt32*, UInt32")
g = d.get_generator

use_generator(g)

begin_exception_block do
call "static Throws.ThrowException()"
br_s "EndOfMethod"
...etc...

Of course, we could use method_missing in module CLR_IL to avoid
having to write each of the individual wrappers that forward to
@il_generator.whatever.

Wayne Vucenic
No Bugs Software
"Ruby and C++ Agile Contract Programming in Silicon Valley"

John Lam

unread,
Dec 3, 2005, 9:28:16 PM12/3/05
to
Hi Wayne,

It was great meeting you too! Thanks for the suggestion - I was already
thinking along the lines of moving everything to modules, and your example
really drives home just how much better the syntax can be if I implement
method_missing on the module itself. Hopefully I'll have something working
early next week so that I can post some code for folks to try out.

Thanks for the suggestion!
-John
http://www.iunknown.com

Wayne Vucenic

unread,
Dec 4, 2005, 3:10:45 AM12/4/05
to
Hi John,

I just noticed that I left out the line

include CLR_IL

before the line

d = DynamicMethod.new("Int32, UInt32*, UInt32")

> Hopefully I'll have something working


> early next week so that I can post some code for folks to try out.

I'm looking forward to seeing this.

By the way, iunknown.com is such an outrageously good domain name for a COM guy!

Wayne


John Lam

unread,
Dec 4, 2005, 11:50:59 PM12/4/05
to
I had some free cycles this evening to do a first pass implementation of
some of the ideas that Wayne proposed, and here's the net result:

require 'RbDynamicMethod'
include RbDynamicMethod
include ILGenerator

create_ruby_method('say_hello') do
ldstr 'Hello, World'
call 'static System.Console.WriteLine(System.String)'
ldc_i4_4
ret
end

say_hello

This code generates a Ruby method with a VALUE (int, VALUE*, VALUE)
signature. The create_ruby_method yields to the block, and uses
method_missing to generate the IL instructions. Once the block has finished
executing, I bake the dynamic method into the RbDynamicMethod module.
Overall I'm pretty happy with this syntax. I'm attaching the implementation
of ILGenerator below for those who are curious. The MC++ part
(RbDynamicMethod) weighs in at about 160 lines of code.

Comments appreciated!

Thanks
-John
http://www.iunknown.com

module ILGenerator
include RbDynamicMethod

@@op_codes = {
'ldstr' => 's',
'call' => 'm',
'ret' => nil,
'ldc_i4_4' => nil
}

def create_ruby_method(name)
method = create_dynamic_method('', 'System.UInt32', 'System.Int32,
System.UInt32*,System.UInt32')
@@g = get_cil_generator(method)
yield if block_given?
define_ruby_method(method, name)
end

def parse_method_ref(sig)
re = /(static )?(.*)\.(\w+)\((.*)\)/
m = re.match(sig)
is_static = m[1] == 'static '
type_name = m[2]
method_name = m[3]
parameters = m[4]
return is_static, type_name, method_name, parameters
end

def method_missing(name, *parameters)
op_code = name.to_s
type = @@op_codes[op_code]
case type
when 's': emit_string(@@g, op_code, parameters[0])
when 'm': emit_method_ref(@@g, op_code,
*parse_method_ref(parameters[0]))
when nil: emit(@@g, op_code)
end
end
end

Florian Groß

unread,
Dec 6, 2005, 5:56:44 PM12/6/05
to
John Lam wrote:

> create_ruby_method('say_hello') do
> ldstr 'Hello, World'
> call 'static System.Console.WriteLine(System.String)'
> ldc_i4_4
> ret
> end
>
> say_hello

This is pretty cool and I would really like to see a Ruby in Ruby
compiler that utilizes this for generating .NET byte code. I've spend
some time thinking on it and might do that at next year's Summer of Code
(if I am accepted) if it hasn't already been done by then.

Will you continue working on it? Where is this going?

John Lam

unread,
Dec 6, 2005, 7:56:13 PM12/6/05
to
This is going to be the way that I implement my Ruby <=> CLR bridge. I got
to a point where there was just too much C++ code, and it was getting hard
to add features. There is only about 300 lines of C++ code in
RbDynamicMethod, and I suspect there won't be much more that's needed.
Everything else is going to be implemented in Ruby.

I'm getting ready to ship a build of RbDynamicMethod tonight so that folks
can take a look at it. So hang in there - should be about 4 hours before I
ship :)

Cheers,
-John
http://www.iunknown.com

0 new messages