Posted by: leppie | July 20, 2011

Another Reflector FUUUU

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;
  }
About these ads

Responses

  1. How well does dotPeek do in comparison?

    • Added dotPeek. Output is ‘correct’ but the rendering of non-[A-Z] identifiers freak me out a bit :)

  2. 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.

    • 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. :)


Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: