Output from Reflector:
public static object $1()
{
Debug.ProcedureEnter();
Debug.ExpressionIn();
Debug.ExpressionOut();
Closure.Create(new CallTarget1(eval-core(003).::foo), 1);
Debug.ExpressionIn();
Debug.ExpressionOut();
Closure.Create(new CallTarget2(eval-core(003).::bar), 2);
Debug.ExpressionIn();
Debug.ExpressionOut();
Debug.ExpressionIn();
Debug.ExpressionOut();
::dummy$2(::foo(RuntimeHelpers.Int32ToObject(20)));
return Builtins.Unspecified;
Debug.ProcedureExit();
}
Output from ILSpy (almost correct):
public static object $1()
{
Debug.ProcedureEnter();
Delegate arg_17_0 = new CallTarget1(eval-core(003).::foo);
int arg_17_1 = 1;
Debug.ExpressionIn();
Closure.Create(arg_17_0, arg_17_1);
Debug.ExpressionOut();
Delegate arg_34_0 = new CallTarget2(eval-core(003).::bar);
int arg_34_1 = 2;
Debug.ExpressionIn();
Closure.Create(arg_34_0, arg_34_1);
Debug.ExpressionOut();
object arg_4B_0 = RuntimeHelpers.Int32ToObject(20);
Debug.ExpressionIn();
object arg_5A_0 = eval-core(003).::foo(arg_4B_0);
Debug.ExpressionOut();
Debug.ExpressionIn();
eval-core(003).::dummy$2(arg_5A_0);
Debug.ExpressionOut();
return Builtins.Unspecified;
}
Just silly
ILSpy does seem to hide the call to Debug.ProcedureExit(). But that is my bad ;P
Here is the IL:
.method public static
object $1 () cil managed
{
// Method begins at RVA 0x20dc
// Code size 112 (0x70)
.maxstack 3
IL_0000: call void [Microsoft.Scripting]Microsoft.Scripting.Debugging.Debug::ProcedureEnter()
IL_0005: ldnull
IL_0006: ldftn object 'eval-core(003)'::'::foo'(object)
IL_000c: newobj instance void [Microsoft.Scripting]Microsoft.Scripting.CallTarget1::.ctor(object, native int)
IL_0011: ldc.i4.1
IL_0012: call void [Microsoft.Scripting]Microsoft.Scripting.Debugging.Debug::ExpressionIn()
IL_0017: call class [IronScheme.Closures]IronScheme.Runtime.Callable [IronScheme.Closures]IronScheme.Runtime.Closure::Create(class [mscorlib]System.Delegate, int32)
IL_001c: call void [Microsoft.Scripting]Microsoft.Scripting.Debugging.Debug::ExpressionOut()
IL_0021: pop
IL_0022: ldnull
IL_0023: ldftn object 'eval-core(003)'::'::bar'(object, object)
IL_0029: newobj instance void [Microsoft.Scripting]Microsoft.Scripting.CallTarget2::.ctor(object, native int)
IL_002e: ldc.i4.2
IL_002f: call void [Microsoft.Scripting]Microsoft.Scripting.Debugging.Debug::ExpressionIn()
IL_0034: call class [IronScheme.Closures]IronScheme.Runtime.Callable [IronScheme.Closures]IronScheme.Runtime.Closure::Create(class [mscorlib]System.Delegate, int32)
IL_0039: call void [Microsoft.Scripting]Microsoft.Scripting.Debugging.Debug::ExpressionOut()
IL_003e: pop
IL_003f: ldc.i4.s 20
IL_0041: call object [Microsoft.Scripting]Microsoft.Scripting.RuntimeHelpers::Int32ToObject(int32)
IL_0046: call void [Microsoft.Scripting]Microsoft.Scripting.Debugging.Debug::ExpressionIn()
IL_004b: call object 'eval-core(003)'::'::foo'(object)
IL_0050: call void [Microsoft.Scripting]Microsoft.Scripting.Debugging.Debug::ExpressionOut()
IL_0055: call void [Microsoft.Scripting]Microsoft.Scripting.Debugging.Debug::ExpressionIn()
IL_005a: call object 'eval-core(003)'::'::dummy$2'(object)
IL_005f: call void [Microsoft.Scripting]Microsoft.Scripting.Debugging.Debug::ExpressionOut()
IL_0064: pop
IL_0065: ldsfld object [IronScheme]IronScheme.Runtime.Builtins::Unspecified
IL_006a: ret
IL_006b: call void [Microsoft.Scripting]Microsoft.Scripting.Debugging.Debug::ProcedureExit()
} // end of method 'eval-core(003)'::$1
Output from latest dotPeek:
public static object \u00241()
{
Debug.ProcedureEnter();
CallTarget1 callTarget1 = new CallTarget1(eval\u002Dcore\u0028003\u0029.\u003A\u003Afoo);
int paramcount1 = 1;
Debug.ExpressionIn();
Closure.Create((Delegate) callTarget1, paramcount1);
Debug.ExpressionOut();
CallTarget2 callTarget2 = new CallTarget2(eval\u002Dcore\u0028003\u0029.\u003A\u003Abar);
int paramcount2 = 2;
Debug.ExpressionIn();
Closure.Create((Delegate) callTarget2, paramcount2);
Debug.ExpressionOut();
object x = RuntimeHelpers.Int32ToObject(20);
Debug.ExpressionIn();
object a = eval\u002Dcore\u0028003\u0029.\u003A\u003Afoo(x);
Debug.ExpressionOut();
Debug.ExpressionIn();
eval\u002Dcore\u0028003\u0029.\u003A\u003Adummy\u00242(a);
Debug.ExpressionOut();
object obj = Builtins.Unspecified;
Debug.ProcedureExit();
return obj;
}
How well does dotPeek do in comparison?
By: Patrik on July 20, 2011
at 9:18 am
Added dotPeek. Output is ‘correct’ but the rendering of non-[A-Z] identifiers freak me out a bit
By: leppie on July 20, 2011
at 9:36 am
Oh, well, we have already known that Reflector works only on code that was generated by C# compiler. For anything else, it just does not work.
So what is the thing that makes ILSpy “almost correct”? I do not see a problem. On the other hand, the dotPeek’s version calls Debug.ProcedureExit() before returning, which it should not.
The escapes of non-alphanumeric identifiers in dotPeek are freaky, but it is the correct thing to do, so I acutally give them that as advantage over us.
By: David Srbecky on July 20, 2011
at 11:31 am
ILSpy was indeed correct, bar the error on my side. the dotPeek listing came from the generated code after I fixed the above mentioned issue. Obviously I need to call that as late as possible, with the notable exclusion of tail calls, but that gets handled on its own.
As for the escaped characters, interestingly, when you hover over it, it renders correctly.
By: leppie on July 20, 2011
at 11:49 am