Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>To make IL debuggable you need to compile the code into a debuggable assembly. There's also an immediate downside in that the assembly will not be collectible by GC. To do this you do <code>AppDomain.CurrentDomain.DefineDynamicAssembly</code>, then you call <code>DefineDynamicModule</code> and define a module in the assembly. To make it debuggable you need to set some attributes on it:</p> <pre><code>DebuggableAttribute.DebuggingModes attrs = DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.DisableOptimizations; Type[] argTypes = new Type[] { typeof(DebuggableAttribute.DebuggingModes) }; Object[] argValues = new Object[] { attrs }; _myAssembly.SetCustomAttribute(new CustomAttributeBuilder( typeof(DebuggableAttribute).GetConstructor(argTypes), argValues) ); _myModule.SetCustomAttribute(new CustomAttributeBuilder( typeof(DebuggableAttribute).GetConstructor(argTypes), argValues) ); </code></pre> <p>Finally while emitting the IL you call <a href="http://msdn.microsoft.com/en-us/library/system.reflection.emit.ilgenerator.marksequencepoint.aspx" rel="noreferrer"><code>MarkSequencePoint</code></a> to mark the lines for the following IL instructions.</p> <p>Making DLR call sites debuggable seems weird to me – generally your call site is not going to contain any user code. Rather it will contain code to perform an operation and there is no source code associated with that code. But let's say you really want to have something to step through that's associated with the expression trees you're generating for a call site. To do that you'll need to do two things. First is store the debugging info in the expression tree – you do this using a <a href="http://msdn.microsoft.com/en-us/library/system.linq.expressions.debuginfoexpression.aspx" rel="noreferrer"><code>DebugInfoExpression</code></a>. The next is compiling the method into a debuggable method and providing that delegate to the DLR. </p> <p>For compiling the method you need to use <a href="http://msdn.microsoft.com/en-us/library/dd728258.aspx" rel="noreferrer"><code>LambdaExpression&lt;T&gt;.CompileToMethod</code></a>. The <code>MethodBuilder</code> that you'll need to provide will need to be a static method defined in a type in the debuggable assembly that you created earlier. </p> <p>For providing that delegate to the DLR you have two options. Probably the easiest would be to actually return an expression which invokes the compiled debuggable delegate (just holding onto it via constant). The harder but in some ways more elegant way would be to override <code>BindDelegate&lt;T&gt;</code> on the call site and return the compiled delegate. That starts getting into creating appropriate argument <code>Expression</code>s and calling the <code>Bind*</code> methods to produce the expression tree your self though.</p> <p>All of this is done in the DLR outer layer/IronPython/IronRuby – all available at <a href="http://ironpython.codeplex.com" rel="noreferrer">ironpython.codeplex.com</a>. You can look at <code>CompilerHelpers.CompileToMethod</code> as an example of doing the compilation, the <code>Snippets</code> class (and the associated <code>AssemblyGen</code>/<code>TypeGen</code>/<code>ILGen</code> classes for creating the debuggable assemblies, and even the DLR expression tree compiler (in <code>Runtime\Microsoft.Scripting.Core\Compiler</code>) for an example of emitting the line info.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload