{"id":3957,"date":"2012-07-23T12:23:23","date_gmt":"2012-07-23T12:23:23","guid":{"rendered":"https:\/\/test.simple-talk.com\/uncategorized\/1841\/"},"modified":"2016-07-28T10:51:16","modified_gmt":"2016-07-28T10:51:16","slug":"1841","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/blogs\/1841\/","title":{"rendered":"Inside the DLR &#8211; Callsites"},"content":{"rendered":"<p>The DLR was introduced in .NET 4 to allow dynamic languages, like Python or Ruby, to run on the CLR. The DLR is also used by C# 4, released at the same time, to implement dynamic binding via the <code>dynamic<\/code> keyword. In this post, I&#8217;ll be looking at what exactly happens when you issue a dynamically-bound call in C#.<\/p>\n<h4>What is the DLR?<\/h4>\n<p>The Dynamic Language Runtime isn&#8217;t a runtime. At least, not in the same way as the Common Language Runtime. The DLR is a library that runs on the CLR, just like any other arbitary assembly. The library itself is a large and complex beast, with hooks at all levels for various interoperability and extensibility scenarios. In this post, I&#8217;ll only be looking at the core functionality &#8211; dynamically binding to methods and executing what is found quickly and efficiently.<\/p>\n<h4>Callsites<\/h4>\n<p>What happens when you compile a dynamically-bound statement in C#? Take the following example. This method contains a single dynamic invocation of something that looks like an instance method called <code>Func<\/code>, that takes two integer arguments:  <\/p>\n<pre>public void DynamicCall(dynamic d, int i)\n{\n    d.Func(10, i);\n}<\/pre>\n<p>  When the C# compiler sees this, and notices that it&#8217;s a dynamically bound call, it doesn&#8217;t generate a normal method call using <code>call<\/code> or <code>callvirt<\/code> IL instructions. What is actually generates is this:  <\/p>\n<pre>private static class SiteContainer\n{\n    public static CallSite&lt;Action&lt;CallSite, object, int, int&gt;&gt; Site;\n}\n\npublic void DynamicCall(dynamic d, int i)\n{\n    if (SiteContainer.Site == null)\n    {\n        SiteContainer.Site = CallSite&lt;Action&lt;CallSite, object, int, int&gt;&gt;.Create(\n            Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(\n                CSharpBinderFlags.ResultDiscarded,\n                \"Func\",\n                null,\n                typeof(Program),\n                new CSharpArgumentInfo[] {\n                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),\n                    CSharpArgumentInfo.Create(\n                        CSharpArgumentInfoFlags.Constant\n                            | CSharpArgumentInfoFlags.UseCompileTimeType,\n                        null),\n                    CSharpArgumentInfo.Create(\n                        CSharpArgumentInfoFlags.UseCompileTimeType,\n                        null)\n                }));\n    }\n    \n    SiteContainer.Site.Target(SiteContainer.Site, d, 10, i);\n}<\/pre>\n<p>Woah. What on earth is going on here?<\/p>\n<h4>Creating callsites<\/h4>\n<p>The core of the DLR is built around the <code>CallSite<\/code> and <code>CallSite&lt;T&gt;<\/code> types. These types provide the bulk of the infrastructure used to implement C# and VB <code>dynamic<\/code>, by providing a sophisticated cache for reflection lookups.<\/p>\n<p>All the information required to resolve a dynamic call can be split into what is known at compile time, and what is known at runtime. Compile-time information includes the input and output types of the call (as represented by the <code>Action<\/code> or <code>Func<\/code> type argument to <code>CallSite&lt;T&gt;<\/code>), the name of what is being invoked, type arguments, argument names, etc. This information is encapsulated in a <code>CallSiteBinder<\/code> that is created the first time a dynamic call is invoked, and stored in the <code>CallSite<\/code>, inside a static site container.<\/p>\n<p>Since this is compiled and invoked from C#, the C# runtime binder, in the <code>Microsoft.CSharp.dll<\/code> assembly, is used to create and populate a subclass of <code>CallSiteBinder<\/code>. As this particular dynamic call is something that looks like a method invocation, an instance of the <code>CSharpInvokeBinder<\/code> type is passed to <code>Create<\/code>, using the <code>Binder.InvokeMember<\/code> helper method.<\/p>\n<p>This binder is created using everything it needs to resolve the call at runtime. What exactly is required varies from binder to binder, but the <code>CSharpInvokeBinder<\/code> that is used in this example requires information on: <\/p>\n<ol>\n<li>What happens to the return type (in this example, it gets discarded, if there is one)<\/li>\n<li>The name of the thing being invoked<\/li>\n<li>Any generic arguments to the method call (in this example, none)<\/li>\n<li>The type this call is made from (to resolve overloads based on accessibility)<\/li>\n<li>Information on the arguments (for example, where the value comes from, argument names, whether it&#8217;s <code>ref<\/code> or <code>out<\/code>, etc)<\/li>\n<\/ol>\n<p>Then, to actually invoke the dynamic call, the actual values used to invoke the callsite each time are passed into the callsite&#8217;s <code>Target<\/code> delegate. This delegate handles resolving the right method to call at runtime, using the information stored in the <code>CallSiteBinder<\/code>. How this works is the subject of my next post.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The DLR was introduced in .NET 4 to allow dynamic languages, like Python or Ruby, to run on the CLR. The DLR is also used by C# 4, released at the same time, to implement dynamic binding via the dynamic keyword. In this post, I&#8217;ll be looking at what exactly happens when you issue a&#8230;&hellip;<\/p>\n","protected":false},"author":186659,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[],"coauthors":[],"class_list":["post-3957","post","type-post","status-publish","format-standard","hentry","category-blogs"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/3957","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/186659"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=3957"}],"version-history":[{"count":7,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/3957\/revisions"}],"predecessor-version":[{"id":42193,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/3957\/revisions\/42193"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=3957"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=3957"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=3957"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=3957"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}