Ayende @ Rahien

Hi!
My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:

ayende@ayende.com

+972 52-548-6969

, @ Q c

Posts: 6,124 | Comments: 45,482

filter by tags archive

IL Weaving - Mystery wrapped in an Enigma containing Frustration

time to read 15 min | 2858 words

Okay, here is another exampe of using Cecil, but I think that you can figure out what I think about having to deal with raw IL.

Feel free to figure out what this does, and why I would be interested in such a thing. BTW, in Boo to Boo, that sort of thing so painless. Having to deal with the raw IL takes all the fun out of it.

I know about Cecil.FlowControl, but as far as I can find, this is mostly (only?) for reading assemblies. I am looking for a way to have a reasonable AST over cecil. This is not scalable no matter how you cast it.

import Mono.Cecil

import Mono.Cecil.Cil

class DisposableAttribute(Attribute):

      def Process(t as TypeDefinition):

            disposed = FieldDefinition("___was_disposed",t.Module.Import(bool), FieldAttributes.Private)

            t.Fields.Add(disposed)

            t.Interfaces.Add( t.Module.Import(typeof(IDisposable)))

           

            for method as MethodDefinition in t.Methods:

                  cil = method.Body.CilWorker

                  ins = method.Body.Instructions[0];

                 

                  if method.Name=="Dispose":

                        cil.InsertBefore(ins,cil.Create(OpCodes.Ldarg_0))

                        cil.InsertBefore(ins,cil.Create(OpCodes.Ldc_I4_0))

                        cil.InsertBefore(ins,cil.Create(OpCodes.Stfld, disposed))

                        continue

                 

                  wasDisposedLoc = VariableDefinition(t.Module.Import(bool))

                  method.Body.Variables.Add( wasDisposedLoc )

                 

                  cil.InsertBefore(ins,cil.Create(OpCodes.Ldarg_0))

                  cil.InsertBefore(ins,cil.Create(OpCodes.Ldfld,disposed))

                  cil.InsertBefore(ins,cil.Create(OpCodes.Ldc_I4_0))

                  cil.InsertBefore(ins,cil.Create(OpCodes.Ceq))

                  cil.InsertBefore(ins,cil.Create(OpCodes.Stloc_0))

                  cil.InsertBefore(ins,cil.Create(OpCodes.Ldloc_0))

                  cil.InsertBefore(ins, cil.Create(OpCodes.Brtrue_S,ins))

                  cil.InsertBefore(ins,cil.Create(OpCodes.Ldstr, t.FullName))

                  cil.InsertBefore(ins,cil.Create(OpCodes.Newobj,
                                      t.Module.Import(typeof(ObjectDisposedException).GetConstructors()[0]) ))

                  cil.InsertBefore(ins,cil.Create(OpCodes.Throw))

Chris, compiler!


Comments

Jb Evain

Being able to get a complete AST from a Cecil assembly, being able to modify it and to save it back is one of the goal of the Milo [1] framework. The goal is to combine Cecil.FlowAnalysis, a modified Boo AST and Cecil.

Even if we're sort of busy, Rodrigo and I are working on that.

[1] http://code.google.com/p/milo

Max Bolingbroke

I've been trying to implement some of these macros for .NET too.. am I to take it you already have such a project on the go? In particular, have you been able to implement DefaultAttribute ala Boo? I couldn't work out how to reference the attribute constructor parameters from the generated IL..

BTW, your blogs "email" field does not accept some well formed emails, in particular those with a + in the first part of the address..

Paul Burns

Firstly, thanks! I've been reading the blog for a few month now after being slamdunked into the world of .NET, C#, Monorail and full time coding.

Have to say its been a good way to get on the bandwagon and keep up with anything and everything. Not that I understand alot of it, but I guess we all have to start somewhere.

Secondly, I have a request.. While I can always go away and read up about the topic of your posts if necessary, sometimes I'm confused by the acronyms. I don't know how useful it might be to everyone else, but as a suggestion some kind of automated text to link conversion for your acronyms might be good.

ie) 'Monorail' pointing to http://www.castleproject.org/

Anyway, just a suggestion, I know it's not going to be too high on your priority list right now :-)

Comment preview

Comments have been closed on this topic.

FUTURE POSTS

  1. RavenDB 3.5 whirl wind tour: I’ll find who is taking my I/O bandwidth and they SHALL pay - 11 hours from now
  2. The design of RavenDB 4.0: Physically segregating collections - about one day from now
  3. RavenDB 3.5 Whirlwind tour: I need to be free to explore my data - 2 days from now
  4. RavenDB 3.5 whirl wind tour: I'll have the 3+1 goodies to go, please - 5 days from now
  5. The design of RavenDB 4.0: Voron has a one track mind - 6 days from now

And 12 more posts are pending...

There are posts all the way to May 30, 2016

RECENT SERIES

  1. RavenDB 3.5 whirl wind tour (14):
    02 May 2016 - You want all the data, you can’t handle all the data
  2. The design of RavenDB 4.0 (13):
    03 May 2016 - Making Lucene reliable
  3. Tasks for the new comer (2):
    15 Apr 2016 - Quartz.NET with RavenDB
  4. Code through the looking glass (5):
    18 Mar 2016 - And a linear search to rule them
  5. Find the bug (8):
    29 Feb 2016 - When you can't rely on your own identity
View all series

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats