Posted by: leppie | July 20, 2011

Decompiler FUUU!!!

ILSpy:

Debug.ProcedureEnter(ldtoken($1()));   // WTF?

Reflector:

Crashes blatantly! Unhandled ‘ldtoken’ at offset 0000.

dotPeek:

Well well, at least it got this right! Not sure why it is an issue though…

// ISSUE: method reference
Debug.ProcedureEnter(__methodref (eval\u002Dcore\u0028003\u0029.\u00241));
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;
  }
Posted by: leppie | May 12, 2011

Reflector FUUUUUUUU!!!

What Reflector makes out the C# to be:

  object[] a = new object[2];
  a[0] = symbol_free-id;
  s11n:8 = objArray[8];
  a[1] = s11n:8;
  $c$00BA = Builtins.List(symbol__, symbol_any, Builtins.ListStar(a, symbol_each-any));

What the actual IL is:

  L_045e: ldc.i4.2 
  L_045f: newarr object
  L_0464: dup 
  L_0465: ldc.i4.0 
  L_0466: ldsfld object contracts::symbol_free-id
  L_046b: stelem.ref 
  L_046c: dup 
  L_046d: ldc.i4.1 
  L_046e: ldsfld object contracts::s11n:8
  L_0473: ldloc.0 
  L_0474: ldc.i4.8 
  L_0475: ldelem.ref 
  L_0476: stsfld object contracts::s11n:8
  L_047b: stelem.ref 
  L_047c: ldsfld object contracts::symbol_each-any
  L_0481: call object [IronScheme]IronScheme.Runtime.Builtins::ListStar(object, object)
  L_0486: call object [IronScheme]IronScheme.Runtime.Builtins::List(object, object, object)
  L_048b: stsfld object contracts::$c$00BA

Note, L_046e and L_0476, completely wrong order in the C# 😦

So there has long been a heavy discussion about calling Dispose on IDisposable objects. This also requires that Dispose be implemented correctly, iow calling GC.SuppressFinalize(this).

After my umpteenth time saying it should NOT be needed to call Dispose, I got a response from a well-respected StackOverflow user that made me think about it more. Although he did not mention why I was wrong, I could just had to figure this one out.

As we know, IDisposable is recommended primarily to release unmanaged resources in a deterministic way for managed types. If implemented correctly, you need to call GC.SuppressFinalize in your Dispose method. GC.SuppressFinalize prevents the object’s finalizer to be called.

All good up to here?

So lets run a little test:

class Foo
{
  byte[] buffer = new byte[50 * 1024];

  ~Foo()
  {
    Console.WriteLine("Finalized");
  }

  public void Moo()
  {
    Console.WriteLine("Moosposed");
    GC.SuppressFinalize(this);
  }
}

class Program
{
  static void Main(string[] args)
  {
    while (true)
    {
      new Foo();
    }
  }
}

Run the above, and within seconds you should get an OutOfMemoryException. Funny, seems the GC is not doing it’s job, or the printing in the finalizer is causing it not to be collected? This can be ‘confirmed’ by removing that printing statement. Strange indeed why something that has no reference to the object can prevent it being finalized.

Now change the code to:

class Program
{
  static void Main(string[] args)
  {
    while (true)
    {
      new Foo().Moo();
    }
  }
}

Now the program runs happily till the cows come home, with barely any memory usage (under 18MB on my PC). So what is happening? Is GC.SuppressFinalize actually freeing the objects memory deterministically when called? It would appear so, but nowhere in any documentation is this extremely important fact noted. It also does not appear so, as adding GC.SuppressFinalize(this) to the finalizer after the printing statement also causes an OutOfMemoryException. Also, why is MS recommending calling GC.SuppressFinalize from the finalizer? This does not make sense. Can it be GC’d twice?

So all in all, one should never call Console.WriteLine() from within the finalizer else it will prevent the object from being considered for immediate garbage collection. What else can you not call from the finalizer? Clearly, when dealing with unmanaged resources, you will have to at least free them in your Dispose method, but if this is called from the finalizer, it seems you are in the same boat. What happens if your unmanaged component logs stuff to the console when you ‘close it’s handle’ ? Are you doomed?

I think the moral of the story is that one should at all costs prevent calling any unknown code (and Console methods) from the finalizer. This might be the reason why Dispose is pushed so heavily by MS.

On a side note, given we have ‘clean’ finalizers, it does not really matter if you call Dispose or not on an IDisposable object. The GC will take care of it, unless something happens like above.

I still stick to my point I made several months back. You should call Dispose, however it is not a must. It is only a must if it prints something or something that prevents the immediate GC of the object.

Posted by: leppie | February 2, 2011

Dynamic binding in C#

So someone asked a question on StackOverflow today, and I gathered the best solution was to use dynamic binding.

Here follows a simple example on how to achieve it:

class DynamicConsole : TextWriter
{
  readonly TextWriter orig;
  readonly TextWriter output;

  public DynamicConsole(string filename)
  {
     orig = Console.Out;
    output = File.AppendText(filename);
    Console.SetOut(output);
  }

  public override System.Text.Encoding Encoding
  {
    get { return output.Encoding; }
  }

  public override void Write(char value)
  {
    output.Write(value);
  }

  protected override void Dispose(bool disposing)
  {
    Console.SetOut(orig);
    output.Dispose();
  }
}

Usage:

Console.WriteLine("Real 1");

using (new DynamicConsole("Foo.txt"))
{
  Console.WriteLine("Moo");

  using (new DynamicConsole("Bar.txt"))
  {
    Console.WriteLine("Ork");
  }

  Console.WriteLine("Bar");
}

Console.WriteLine("Real 2");

When running you get the following:

This will print to the Console:

Real 1
Real 2

It will append to Foo.txt:

Moo
Bar

It will append to Bar.txt:

Ork

I will update the code later to make it generic, so any property, method or field can be used for the dynamic binding. Stay tuned!

Update:

Posted an article on CodeProject last Friday. This is a generic implementation: Dynamic binding in C#

Posted by: leppie | February 1, 2011

Using IronScheme in Unity3D

valerydc has successfully managed to embed and use IronScheme in Unity3D 🙂

See http://forum.unity3d.com/threads/76266-Facilities-for-script-languages-Scheme-in-particular for details. You can also view the initial discussion @ http://ironscheme.codeplex.com/Thread/View.aspx?ThreadId=243958.

Thanks a lot!

Posted by: leppie | January 3, 2011

MTN/HTC service nightmare (updated 10 feb)

Sadly I had to escalate my service issues to hellopeter.com. Unfortunately, they only have place for 1200 characters. Here is the entire service experience:

beginning nov: call MTN regarding the availability of advertised phone (HTC Desire HD), no stock
22 nov: eligible for upgrade, MTN says still no stock
30 nov: get call from MTN to say phone is now in stock, proceed upgrade process
2 dec: receive phone (very fast courier service)
2-5 dec: phone has a random reboot problem
6-10 dec: reboot problem stops
11-13 dec: reboot problem comes back
13 dec: report fault with MTNSP and Leaf/HTC (HTC confirms it is a known problem affecting a few phones)
13 dec: phone service get suspended due to account going over R1000, yet the account was only R635, had to increase limit to get activated again
15 dec: took phone into shop (Capegate A, James), said I needed the papers to make repair process go faster
15 dec: went home to fetch papers, tried to book in phone (Capegate A), at last minute MTN system goes offline
15 dec: go to the other shop (Capegate B, Dominique) to do a manual check in for repairs, assistant says she will tell her manager to prioritize it
23 dec: call MTN high volume repair centre for update on repairs, they say they have not received it
23 dec: go back to MTN shop (Capegate B), phone still in the shop, take phone back with me due to lack of service
29 dec: call MTN to discuss service issues, advised to go to MTN service centre in Century City
29 dec: book in phone at MTN service centre (Century City, Sakeena/Francisco), system offline again (MTN TFR# 020149)
31 dec: I changed my bank details when doing the upgrade, yet the money was taken from previous account details
3 jan: called MTN to change banking details, they confirm the change
3 jan: call MTN high volume repair centre for update on repairs, phone has not been booked in yet
3 jan: call MTN service centre (Century City) to find out what is happening, number forwards to 808, no info available
3 jan: called same number again (Century City), got through to someone (Cheryl, the switchboard operator) that says I cannot contact Century City directly, they have open an enquiry for the location of my phone
3 jan: reported to hellopeter out of desperation http://www.hellopeter.com/mtn-complaint-%5B505188%5D
3 jan: MTN responded on hellopeter.com with a generic remark which is hardly relevant
3 jan: Cannot contact MTN service centre (Century City), due to broken number (17:15, 17:30, 17:45)
3 jan: Sent this shittogram to the only 2 email addresses advertised for MTN
4 jan: Try call MTN service centre (Century City) again, again Cheryl answers and let me know she will try get someone to contact me
4 jan: Cheryl calls me back to let me know she has reached Sakeena at the service centre and will be in contact with me
4 jan: Sakeena calls me back, and informs me Francisco has taken over the issue, but he is not at work today, but she will ask him to contact me the following day
4 jan: Received feedback on email to confirm my banking details are in order, and my issue has been forwarded to the complaints department
6 jan: Gave feedback on hellopeter
6 jan: Contacted MTN HV repair centre, they confirm the phone has been sent to HTC, and should be back on Monday or Tuesday
10 jan: Called MTN HV repair centre, no further feedback available
10 jan: Called HTC, they can’t confirm receipt of phone, escalating issue, promised to call me back
11 jan: Called MTN HV repair centre (Thepo), apparently phone has been returned to cape town, but no repair actions were logged, waiting for feedback
11 jan: Thepo called, confirmed phone is at HTC, will be ready before end of the week
11 jan: Called HTC (Chris), informed them I wanted to make sure they find the fault, and not just reload the software. Chris informed me the issue will be escalated to his supervisor, and that they will be in contact with me
13 jan: Called MTN HV repair centre (Nolene), phone still at HTC, no further feedback
17 jan: Called MTN HV repair centre (Thepo), phone still at HTC, ‘should’ be back to MTN today
18 jan: Called MTN HV repair centre (Mpho), phone still at HTC, awaiting couriers to MTN
18 jan: Called HTC support (James) to try get a repair report, was told I will get it when collecting the phone
19 jan: Called MTN HV repair centre (Helen), phone was collected from HTC by RTT (assume this is the couriers), not at MTN HVRC yet
20 jan: Phoned everyone from MTN HVRC in JHB and CPT, called LEAF and RTT. The phone is being sent overnite to the CPT HVRC (confirmed by RTT) and that will take several working days before being sent to MTN Century City… Estimate around 25 jan.
25 jan: Expecting to get phone back today
25 jan: Been in contact with MTN HVRC Cape Town manager (Kevin) who confirmed the phone will be at MTN Century City after 1pm. Informed me that Leaf/HTC did not include a job card with the phone.
25 jan: Contacted HTC support (Chris), have no information about phone repairs
25 jan: Contacted Leaf Repairs, they tell me the software was updated and no other repairs was done… Spoke to Amit to explain the situation, demanding a replacement phone before the end of the week. He cannot make that decision and told me that the manager (Zach) will contact me tomorrow.
25 jan: Collected the phone at MTN Century City, spoke with Kevin and Noleen about my problems. While there, the phone rebooted 3 times, witnessed by Kevin. There was a repair report from LEAF stating only software was reloaded. Seems no other work was done.
25 jan: Tested a spare backup battery to eliminate the possibility of a faulty battery, but had a reboot within 2 hours after a full charge

25 jan: Still waiting for my phone call from Francisco/feedback regarding complaint from MTN, waiting on feedback from HTC (HTC said a repair report will be attached to the phone, never did get back to me…) and waiting for HTC to contact me on or before Friday.

27 jan: Contacted LEAF’s technical manager to discuss problems. They arranged for ‘express’ repair service. Told them they had to replace the mainboard (as was done with others in my situation).
28 jan: Courier collected phone.
1 feb: LEAF contacts me to inform overnight courier. Phone ‘will’ be back tomorrow.
2 feb: Courier delivered the phone this morning with a new mainboard. Will be testing today. Finally after 42 days, I hope I can lay this fiasco to rest.

10 feb: All going well still. No hardware problems.

On 2 Feb, total time phone been @ MTN/HTC = 42 days, @ me = 20 days since receiving the phone. That sucks… 😦

Finally, I have an idea where me phone is, not too happy still, but less stressed. Tomorrow I will see if the phone has actually reached the HV repair centre.

I must say Cheryl, the switchboard operator for MTN (Century City) has been by far the kindest and most helpful person in this whole fiasco. Someone make her a manager or give her a raise/bonus, she deserves it. Sakeena has also tried to help. The MTN HVRC (Cape Town) manager, Kevin has been extremely helpful too in tracking down my phone.

Posted by: leppie | December 2, 2010

Writing fast arithmetic code on IronScheme

As some may have noticed, I have started actively working on IronScheme again. After a year of fiddling with other shit like microcontrollers and other hardware-related program, the itch for ‘bare-metal’ knowledge has finally subsided enough to let IronScheme take preference.

Also, the IronScheme source code is now under a BSD license. The DLR goodies stays on MSPL however, as moving it to the new Apache license DLR would be too much effort. Now for the rest of the post.

So the general feeling is that most ‘dynamic’ languages are pretty poor with number crunching. This is true, as code is mostly generic and have no static typing. The same goes for IronScheme, but you can make code (read hotspots) behave much better with only a little extra effort.

Let’s take the naive Fibonacci algorithm to use for this example.

(define (fib n)
  (if (< n 2)
      n
      (+ (fib (- n 2)) (fib (- n 1)))))

The main problem here is the usage of generic math operators. They are generally slow, as they cover the entire number hierarchy of Scheme. This can be improved by using the fixnum specific procedures.

(define fibf (lambda (n)
  (if (fx<? n 2)
      n
      (fx+ (fibf (fx- n 1)) (fibf (fx- n 2))))))

While the above run significantly faster (about 5 times faster), there is still quite a bit of overhead due to boxing of value types, and overflow checks. This can now be improved by using a statically typed variant of lambda called typed-lambda, and by using some ‘unsafe’ operators provided by IronScheme.

(define fibt (typed-lambda (n) ((Int32) Int32)
  (if ($fx<? n 2)
      n
      ($fx+ (fibt ($fx- n 1)) (fibt ($fx- n 2))))))

The above only requires minor changes again, that could be easily made transparent with a macro or 2. The result is a very fast procedure that runs optimally on .NET (when compared to the same code generated by the C# compiler). My tests show it running almost 13 times faster than the fixnum version and subsequently around 60 times faster than the original generic approach.

Here are timings for all of the above:

isc fibs.sps
Statistics for '(fib 35)':
  Real Time:  8357ms
  CPU Time:   8344ms
  User Time:  8344ms
  GC's:       0
Statistics for '(fibf 35)':
  Real Time:  1826ms
  CPU Time:   1828ms
  User Time:  1828ms
  GC's:       0
Statistics for '(fibt 35)':
  Real Time:  147ms
  CPU Time:   141ms
  User Time:  141ms
  GC's:       0 

Update:

On the same PC, IronPython 2.6 takes 3150ms for a naive fib.

Posted by: leppie | October 15, 2010

My tags on StackOverflow

Interesting Tags
scheme lisp code-golf language-agnostic ironscheme c#* .net*

Ignored Tags
vb6 vba vb homework grails coldfusion flash iphone air sifr ms-access db2 vbscript perl sap jpa gql java-ee magento ipad qt weblogic blackberry gwt pentaho wordpress mac corba intellij-idea lucene safari seo redis itouch ant antlr ada gtk doctrine lotus tomcat jcl mongodb netlogo nosql smalltalk beamer scala spring symbian agile firebird samba jasper-reports sybase fortran qtp itunes sqlite soapui acrobat actionscript* flex* cocoa* struts* ruby* zend* *php* java-* joomla* maven* *hibernate* ipod* xcode* jboss* dotnetnuke* *facebook* java groovy* *jaxb* kanban iphone* telerik osx python* jsf* jquery* r latex oracle* android* devexpress umbraco* mathematica awk sed *dreamweaver* symfony* crystal-reports* alfresco *postgres* dojo* codeigniter* xbap oscommerce cucumber mod-rewrite mysql* jpa* extjs semantic-web kohana* django* sqlalchemy cufon birt .htaccess inno-setup jira drupal* postscript swf* automapper ssas jms asterisk amazon-ecs ios* delphi* labview jvm* *payment* *dynamics* yahoo-pipes websphere* siebel plsql* couchdb* plone elmah vb.net applescript seam opencv *swing* emf erlang* pygtk mercurial twitter-api wxwidgets boost* boxee core-data ssis numpy xtrareport sitecore* yui* fxcop festival eiffel spring* raphael* liferay oauth elearning xulrunner lotusscript outlook* jar memcached heroku spam sonar tcl adobe tapestry cmake thunderbird jqtouch tomcat* ravendb jena *ejb* eclipse-pde installshield amazon-ec2 cognos* bada node.js accurev swi-prolog seam2 junit4 excel-vba 3270 firewatir jface informix bing* h2 mybatis clojure* *qt4* eclipse-rcp quickfix komodo* mootools* uiwebview episerver doctrine* awt* wix kannel lwuit jscrollpane jmeter mfc solid openfire openid yslow rational-rose jdbc stripes dokuwiki foxpro clearcase saas richfaces filemaker jcr midp* weblogic* wxpython guava interface-builder macports smartgwt jre cassandra qt-creator rabbitmq asp-classic jetpack xmlbeans m2eclipse itextsharp authlogic blackberry* hudson j2se dbunit firebird2.1 jdo javamail wordpress* documentum sass sphinx* openlayers webkit *solr* gradle paypal* jqgrid* jni lucene.net perltk n2 axis2 gae-datastore lua npapi photoshop nusoap *curl* maple autocad vim appstore* lotus-notes subsonic* cocos2d* ssrs-2008 collatz windows-live-messenger testcocoon monotouch xul scala-2* pdftk velocity terrier dicom visualforce exchange-server nvelocity prolog cobol azure log4j selenium* *fcgid asp autofac xmpp beanstalk meebo vtk findbugs exist twitter* openoffice* redmine finch comet go uml-modeling analysis-services bioinformatics openflashchart2 uml cloud jtable mondrian bugzilla *gtk* ecos adobe-reader sugarcrm swt jersey ffmpeg tibco-ems citrix rspec jsoup core-audio mumps aptana* jruby aspose playframework hadoop propel osx-snow-leopard icefaces tibco beautifulsoup solaris pascal bb-messenger sybase* javadoc abap powerbuilder* hbase buildforge e4x poppler coremidi j prism salesforce eclipse-plugin roblox pyqt* iolanguage kynetx bdd logrotate voicexml lamp informatica thrift vxworks flot mod-perl modelica wamp amazon-web-services fusioncharts prestashop izpack mustache javacard flv flash* perl6 parrot ofbiz dkim jetty rake cappuccino yql nsstring typo3 gecko java-me boinc sesame paramiko gstreamer ivy vb.net-2010 oc4j yii glassfish junit cen-xfs pexpect template-toolkit netbeans-6.9 genshi disqus validationengine textmate android-tabhost jndi jrockit commission-junction phing jstl perforce monit youtube pylons adsense fish-shell lxml sencha* gps cxf nginx coq arcobjects cherrypy* cqrs qooxdoo rmysql puppet jackson hudson* cleartool s-maxage nicedit octave cruisecontrol erp teamcity* nokia* capistrano mongoid yii* rapidminer plesk buildr ipad* *lucene* javafx rich powerpc krl fancybox protege magento* mkreversegeocoder jsp* fpdf rebol jung graphael drools rpy2 maya fortify* gsoap aspectj avaudioplayer pyramid rhapsody spf fltk xerces* wicket pbs padrino xforms scintilla coldfusion* git windows-mobile* *svn* database-design gcore *svm* sharding 3dsmax d amazon* eclipse* pyaudio primefaces tinymce flickr-api documentum* smarty* activetcl rsync loadrunner titanium caliburn shopify vbulletin macvim imagemagick mailchimp gis odata xna bash bbedit sparc fullcalendar coffeescript jgroups rhodes wampserver powerpoint* ibm-midrange dashcode dnn* jython ms-word jxl sas *bpm* batch orkut inotify batch-file cron chmod business-intelligence pymssql maximo aspell *yaml* fbjs putty postfix grep excel modx jnlp freemarker hamachi red5 openx slickgrid jmx sinatra gerrit processing.js *glassfish* ext-gwt lynx vfp axis2c vce palm* scons sproutcore orchard winnovative openerp jfreechart way-off-topic *dbcp orchardcms skype *mongo* pear plupload zeromq vaadin hl7 blogger gnome jupload mindstorms foursquare fireworks hypervisor soa gmock series-40 jdk* testng restructuredtext matplotlib pagerank haml bouncycastle cython axis watin jmock itunes* meld multi-tenant shell igoogle guice mint autohotkey esb valgrind installshield* iwork sim-card ubuntu* narwhal contribute github telerik* jgit gate unix antlr* jekyll peoplesoft phonegap greasemonkey lotus* vst thinking-sphinx linux sftp liquibase ssh log4net aria kindle tinyxml analytics *gwt* ssrs-tablix jcarousel firefox-addon infragistics xtratreelist *cvs* vlc hql love2d sitefinity staruml watir llblgen* windows-phone* vi graphicsmagick testcomplete e107 jasper* notepad++ msword2003 linkedin postgis advertising mediawiki haxe url-shortener aix wowza psd groupwise rhomobile melt yahoo-boss-api ns2 nagios pebs dismax gnuplot matlab* fedora openstreetmap sparql jrebel debian qt* qml ps3 lyx mpi mifare membase mvcc opencl sage 3ds sfml zos htmltidy adwords clay initio radgrid couchapp xampp lighttpd openmpi activex bazaar collada nutch autotools terracotta zen google* existdb apache* elgg uiview* lint brew ireport ibatis dwr clearcase* tmux sourcegear-vault esent tmx autoit mechanicalturk icu box2d cpanel *fbml uisearchbar* uisplit* rvm n900 adaboost ruby-on-rails-3 yahoo bjam fedex-api uitableview* *pascal* vivo* blazeds teradata safari* cabal* grails* slickedit j2me* kaminari paperclip docbook arkanoid obiee ckeditor uiscrollview* three20 visio lync* zookeeper jwplayer coda* saxon knockout.js catiledlayer uinavigation* seam3 appfabric uistatus* expressionengine nstextview altova ace revit* webos twiki xpand andengine uilabel pdflatex exchange* zalgo* zk pca xen* velocity* ado innodb amazon-simpledb openal xwindow* core-plot netezza gxt posix saml firefox* vrml mule* highcharts* bonjour edi antivirus chromium orbeon simulink jasig epl relaxng quickbasic qbasic rexx pig hsqldb sikuli robohelp graphite nexus* greenplum seaside compass-css jammer vmware infopath* nuget* jaws celery extjs* microsoft-communicator excel* tumblr biztalk* neo4j* haproxy zope* stata nimbus bitbucket* navicat uitab* jenkins chef basic4android gyp corona* emacs* scrapy* indexeddb chipmunk moodle freebase* objective-c* refinerycms reddot install4j phonegap* hdfs ghostscript* openrasta janus liferay* nxc adwhirl componentone monkeyrunner gmail* talend ormlite qemu maxima xalan realbasic *-vba dozer quicksand apple* metatrader* activemq* radius webstorm opensso mapper interbase microsoft-search-server codechef sox jcarousellite silktest sqlite* sccm* *fortran* powerdesigner *netty *jscript* fmdb *jade rpm titanium-mobile spotify playn appmobi scorm* jeditable javafx* acceleo qpid flyway ews flattr sqoop flask* ipython yard osmf fest agda godaddy* zsh* xcelsius z3* derby desire2learn sip jinja* hazelcast contao netbeans* osx* javaws hive unity3d socialengine wijmo interspire* unreal* epplus appharbor adobe* lazarus xpages tridion topcoder world-of-warcraft mapnik pdfbox lingo trac petapoco ibook-author segue axapta ggplot2 infinispan ns-3 openedge zurb-foundation ehcache weka rust gitolite quickbooks composite-c1 doxygen dyndns cuda atk4 libgdx couchbase opengrok webdriver sublimetext* activereports clips nltk emma gitweb tooltwist dbase rally samsung* cocos* dart cpython arcgis* jack systemc gameboy freetype* cq5 micrium d3.js datastage opa cisco* elasticsearch homebrew cfengine ebay nservicebus bnd wikipedia radiant birt-report quartz-scheduler disruptor-pattern graphviz playframework-2.0 smart-mobile-studio alsa meteor facelets xuggler wireshark spss instagram berkeley-db soundcloud digg wso2 riak xp-cmdshell content-management-system sqlanywhere twisted osgi bulksms uwsgi sketchflow mapkit lpeg epub pkg-config borland backbone.js vnc-viewer mxml wireless-connection dia zorba intel-ipp dns owl opencart uiimageview textwrangler beyondcompare scribe reportlab autoplay cygwin cppcheck box-api jira-plugin imagej xmp dompdf gpl vlcj cydia osticket hoare-logic dotcloud minix openjpa ftp-client squid javacc pandas ms-access-2007 geometric-arc xubuntu scapy github-for-windows xdebug database braintree carrierwave tridion-2011 esper xwiki gnupg ieaddon activesync spree allegro office365 twig sendmail opentext princexml cglib whmcs ical bi-publisher opencsv guice-servlet zoho expect lwjgl gssapi pinterest apex-code jks ampchroma aviary virtualbox jaas telnet playstation apl dijit buddypress fastreport reporting-services reportviewer jogl cloudfoundry openvms praat marklogic impresspages jax-rs watcom mamp railo vtd-xml xbmc lift pango libreoffice cloudflare windows-phone bamboo word-2007 openstack wix3.5 concrete5 wkhtmltopdf fogbugz wise firebug gtalk mingw datanucleus sourceforge knitr testflight pdfkit virtualenv openinventor marmalade skipfish lsf ldif trigger.io collectd thejit sql-azure atomineerutils atmosphere yuma web2py pycharm catalyst c++builder-xe v8 opera derbyjs mozilla tornado exim4 mibs cad playframework-1.x specman esri fossil gmaps4rails youtube-api wikipedia-api ipa xtk rsa jax-ws gdata griffon dcl spl restkit charles clearcanvas appcelerator lc3 asana hornetq easy-install pyside saxparser tor jprofiler cocos2d perl-regex simplexml servlets quicktime crawler4j enterprise-architect swift j# quartz.net edifact preg-match uniobjects mks draw2d powershell opengraph nfc iso8583 beanstalkd castle-activerecord ros office-interop openam app-store xtext acrobat-sdk swig twilio graphiti ksoap cobertura m2e uikit window-tester grinder varnish spry gpars sequel hotmail dbpedia scrum jooq ussd scalaz zen-coding wsdl2java mapreduce codenameone feedburner sungridengine sge addthis yum ms-access-2010 nancy xstream gpg readline xinclude *cobol* visual-sourcesafe wso2esb egit gimp sharepoint* mockito thunderbird* behat archiva photoshop* ksoap2 keymando essbase domain-driven-design etl dovecot zmq openlaszlo gnu-make redhat betfair jpql clickonce openshift mknetworkkit displaytag boilerpipe mahout broadleaf-commerce visual-foxpro flurry scikit-learn axiom firemonkey sendgrid dbscan cocoon firebase rich-snippets javascript opengl* elisp mobile ember.js centura luntbuild gem iam logmein advertisement tkinter kinect blender cloudant visualvm icq virtuemart vimeo sitefinity-5 scribd monomac phantomjs cors kendo-ui jvisualvm centos rational azure-table-storage itk g-wan webrtc eventbrite cornerstone juddi geany x11 opencmis pcl qwt swiftmailer octopress rspec-rails jdedwards mcrypt hp jdbcrealm tikz tastypie tidesdk archlinux ibm simperium stocktwits iscroll4 dwolla youtube* casbah openmp admob point-cloud-library tropo gearman random-forest resteasy jdeveloper rmi uiimage business-objects janrain cmis filepicker typescript mips chirpy x++ woocommerce maxscript dropbox craigslist mobiscroll spark phalcon pycuda outsystems schematron mdx ejabberd flowplayer core-graphics sphinx gedit npoi xpointer xelatex cloudmade laravel wget jackrabbit away3d angularjs crossrider mako activepivot quickblox less ogre jbehave abcpdf gitlab gnome-terminal zoomooz express freebsd netsuite spreadsheetgear socket.io pixel-bender chilkat-email chilkat imacros ektron google glib hamcrest appfog drools-planner thunderhead wmi opensuse dog basecamp rrdtool avfoundation trello schema.org kdevelop mirth vkontakte hunspell xmonad activexobject pymunk vala mapbox vhdl hadoop-streaming kivy capybara freeradius fish clearquest websphere selinux allegrograph dundas sqlplus mkmapview pygame mixpanel crashrpt graniteds ms-office klocwork fasta game-center akka vtiger macbookpro ms-project tuckey-urlrewrite-filter pivotviewer groovy intuit thymeleaf xtend com+ apns winbugs restlet plasticscm codelite flyingsaucer spritely ranorex crystal-reports orient-db procmail wso2carbon wt uima xlc brightcove nautilus cloudbees opennms gensim jslint supercollider quicklook

Posted by: leppie | December 7, 2009

Calling an instance method in the CLR without an instance

A question came up how StackOverflow, blah.

I have heard about this behaviour being valid in C++, so I thought I would test it on the CLR.

.class Program
{
  .method static void  Main(string[] args)
  {
    .entrypoint
    .locals init ([0] class Program p)
    ldloc.0 // but wait, it's still null!
    call   instance void Program::Awesome()
    ret
  } 

  .method instance void Awesome()
  {
    ldstr      "Awesome!"
    call       void [mscorlib]System.Console::WriteLine(string)
    ret
  } 

  .method public specialname rtspecialname instance void  .ctor()
  {
    ldarg.0
    call       instance void [mscorlib]System.Object::.ctor()
    ret
  } 
} 

As you can see if you compile the program, “Awesome!” is printed.

Now run PEVerify. As you can see, perfect valid CLR code.

But how? And why wont in work in C#?

The C# compiler will in all cases (even weirdly, but probably for good reason) emit a callvirt instead of the call I used. This causes the runtime to perform a null check.

Secondly, the is no instance member access, so no references to ‘this’ need to be made.

Why is this like this? Not sure, but if I would guess, they left this specification loose, to allow for more flexibility in other languages.

Older Posts »

Categories