Quantcast
Viewing latest article 3
Browse Latest Browse All 9

Inside Extension Methods: Compiler to IL

Extension Methods is a nice feature introduced in .Net Framework 3.5, it opens up lots of possibilities including LINQ. Even after reading short description of this feature anyone can guess that Extension method is simply syntactic sugar. It doesn't in any way modify the type that is being extended nor it can access private members, nor is the extension method returned when reflecting the extended type. I decided to dig little dipper to see how compiler is achieving this feature. First I will scratch the surface and look at the IL then we will dig in to the compiler. I don’t have access to Microsoft CS compiler source, so I will use Mono CS compiler (mcs) to investigate Extension method implementation.

Following is the very simple extension method, notice the use of ‘this’ as a first argument to indicate this is as extension method to compiler.

   1:publicstaticint WordCount(this String str)
   2: {
   3:return str.Split(newchar[] { ' ', '.', '?' }, StringSplitOptions.RemoveEmptyEntries).Length;
   4: }

And here is how this extension method is being used.

   1:string statement = "Hey this is a test";
   2: Console.WriteLine("Word Count = " + statement.WordCount().ToString());

Following is the partial IL of extension method.

   1: .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor()
   2: .method public hidebysig static int32 WordCount(string str) cil managed
   3: {
   4:    .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor()
   5:    .maxstack 4
   6:    .locals init (
   7:        [0] int32 statement)
   8:    L_0000: nop 

Following is the IL of the code which uses extension method

   1: L_000d: call int32 ExtMethods.MyExtensions::WordCount(string)

You can notice in the extension method IL that compiler has removed ‘this’ argument and decorated the method with System.Runtime.CompilerServices.ExtensionAttribute attribute. In the IL of the code which used extension method, you can see that method is invoked as a regular static method.

Now let’s dig in to the compiler (mcs – Mono CSharp compiler). You can see following Emit method, which will be called for each method in the type. The flag Modifiers.METHOD_EXTENSION is set if the methods first argument is of type ‘this’.  The compiler will emit the System.Runtime.CompilerServices.ExtensionAttribute attribute when this flag is set.

   1:publicoverridevoid Emit ()
   2: {
   3:base.Emit ();
   4:  
   5:if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
   6:         PredefinedAttributes.Get.Extension.EmitAttribute (TypeBuilder);
   7: }

Now let’s look at the extension method resolution mechanism. Following code shows the part of ComputeNamespaces method. It calls RegisterExtensionMethodClass method, which in turn registers type exposing extension method in the Namespace object by calling RegisterExternalExtensionMethodClass. This method add the type exposing extension method to arraylist named external_exmethod_classes.

   1:foreach (Type t in assembly.GetTypes ()) {
   2:if ((t.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute &&
   3:  contains_extension_methods && t.IsDefined (extensionType, false))
   4:  RegisterExtensionMethodClass (t);

The DoResolve method of Mono.CSharp.Invocation contains following logic to resolve the method invocation call. As a last step of method resolution it tries to find extension method for the targeted type.

   1: mg = ec.LookupExtensionMethod (me.Type, me.Name, loc);
   2:if (mg == null) {
   3:     ec.Report.Error (1955, loc, "The member `{0}' cannot be used as method or delegate",
   4:         expr_resolved.GetSignatureForError ());
   5:returnnull;
   6: }
   7:  
   8: ((ExtensionMethodGroupExpr)mg).ExtensionExpression = me.InstanceExpression;

I hope you found this quick detour to Mono compiler interesting.



Image may be NSFW.
Clik here to view.

Viewing latest article 3
Browse Latest Browse All 9

Trending Articles