<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>TURBU Tech &#187; Anonymous Methods</title>
	<atom:link href="http://tech.turbu-rpg.com/category/delphi/anonymous-methods/feed" rel="self" type="application/rss+xml" />
	<link>http://tech.turbu-rpg.com</link>
	<description>My thoughts on Delphi programming in general, and particularly on the technical aspects of developing the TURBU engine and editor.</description>
	<lastBuildDate>Wed, 01 Sep 2010 21:11:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>How to leak a class you never defined</title>
		<link>http://tech.turbu-rpg.com/52/how-to-leak-a-class-you-never-defined</link>
		<comments>http://tech.turbu-rpg.com/52/how-to-leak-a-class-you-never-defined#comments</comments>
		<pubDate>Thu, 29 Oct 2009 02:45:29 +0000</pubDate>
		<dc:creator>Mason Wheeler</dc:creator>
				<category><![CDATA[Anonymous Methods]]></category>
		<category><![CDATA[Delphi]]></category>

		<guid isPermaLink="false">http://tech.turbu-rpg.com/?p=52</guid>
		<description><![CDATA[Quick, what&#8217;s wrong with this code? procedure ContrivedExample; var &#160; &#160;factorial: TFunc; begin &#160; &#160;factorial := &#160; &#160; &#160; function&#40;input: Integer&#41;: integer &#160; &#160; &#160; begin &#160; &#160; &#160; &#160; &#160;if &#40;input = 0&#41; or &#40;input = 1&#41; then &#160; &#160; &#160; &#160; &#160; &#160; result := input &#160; &#160; &#160; &#160; &#160;else result := [...]]]></description>
			<content:encoded><![CDATA[<p>Quick, what&#8217;s wrong with this code?</p>
<pre>
<div class="codesnip-container" >
<div class="delphi codesnip" style="font-family:monospace;"><span class="kw1">procedure</span> ContrivedExample<span class="sy1">;</span>
<span class="kw1">var</span>
&nbsp; &nbsp;factorial<span class="sy1">:</span> TFunc<span class="sy1">;</span>
<span class="kw1">begin</span>
&nbsp; &nbsp;factorial <span class="sy1">:</span><span class="sy3">=</span>
&nbsp; &nbsp; &nbsp; <span class="kw1">function</span><span class="br0">&#40;</span>input<span class="sy1">:</span> <span class="kw4">Integer</span><span class="br0">&#41;</span><span class="sy1">:</span> <span class="kw4">integer</span>
&nbsp; &nbsp; &nbsp; <span class="kw1">begin</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span>input <span class="sy3">=</span> 0<span class="br0">&#41;</span> <span class="kw1">or</span> <span class="br0">&#40;</span>input <span class="sy3">=</span> 1<span class="br0">&#41;</span> <span class="kw1">then</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result <span class="sy1">:</span><span class="sy3">=</span> input
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">else</span> result <span class="sy1">:</span><span class="sy3">=</span> input <span class="sy3">*</span> <span class="br0">&#40;</span>factorial<span class="br0">&#40;</span>input <span class="sy3">-</span> 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy1">;</span>
&nbsp; &nbsp; &nbsp; <span class="kw1">end</span><span class="sy1">;</span>

&nbsp; &nbsp;<span class="kw3">writeln</span><span class="br0">&#40;</span>factorial<span class="br0">&#40;</span>5<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy1">;</span>
<span class="kw1">end</span><span class="sy1">;</span></div>
</div>
</pre>
<p><span id="more-52"></span><br />
Or how about this one, which doesn&#8217;t use recursion, and is based on something I noticed when using the list comparison algorithm to solve a problem at work?</p>
<pre>
<div class="codesnip-container" >
<div class="delphi codesnip" style="font-family:monospace;"><span class="kw1">procedure</span> SomewhatLessContrivedExample<span class="br0">&#40;</span>list1<span class="sy1">,</span> list2<span class="sy1">:</span> TList<span class="br0">&#41;</span><span class="sy1">;</span>
<span class="kw1">var</span>
&nbsp; &nbsp;newItem<span class="sy1">,</span> editItem<span class="sy1">,</span> deleteItem<span class="sy1">:</span> TProc<span class="sy1">;</span>
<span class="kw1">begin</span>
&nbsp; &nbsp;newItem <span class="sy1">:</span><span class="sy3">=</span>
&nbsp; &nbsp; &nbsp; <span class="kw1">procedure</span><span class="br0">&#40;</span>value<span class="sy1">:</span> TMyObject<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; <span class="kw1">begin</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;fMainList<span class="sy1">.</span><span class="me1">Add</span><span class="br0">&#40;</span>value<span class="br0">&#41;</span><span class="sy1">;</span>
&nbsp; &nbsp; &nbsp; <span class="kw1">end</span><span class="sy1">;</span>

&nbsp; &nbsp;editItem <span class="sy1">:</span><span class="sy3">=</span>
&nbsp; &nbsp; &nbsp; <span class="kw1">procedure</span><span class="br0">&#40;</span>value<span class="sy1">:</span> TMyObject<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; <span class="kw1">begin</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">if</span> value<span class="sy1">.</span><span class="me1">CheckSomeFlag</span> <span class="sy3">=</span> <span class="kw2">true</span> <span class="kw1">then</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; newItem<span class="br0">&#40;</span>value<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">else</span> fMainList<span class="br0">&#91;</span>value<span class="sy1">.</span><span class="me1">id</span><span class="br0">&#93;</span><span class="sy1">.</span><span class="me1">Update</span><span class="br0">&#40;</span>value<span class="br0">&#41;</span><span class="sy1">;</span>
&nbsp; &nbsp; &nbsp; <span class="kw1">end</span><span class="sy1">;</span>

&nbsp; &nbsp;deleteItem <span class="sy1">:</span><span class="sy3">=</span>
&nbsp; &nbsp; &nbsp; <span class="kw1">procedure</span><span class="br0">&#40;</span>value<span class="sy1">:</span> TMyObject<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; <span class="kw1">begin</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;fMainList<span class="sy1">.</span><span class="kw3">Delete</span><span class="br0">&#40;</span>value<span class="br0">&#41;</span><span class="sy1">;</span>
&nbsp; &nbsp; &nbsp; <span class="kw1">end</span><span class="sy1">;</span>

&nbsp; &nbsp;listCompare<span class="br0">&#40;</span>list1<span class="sy1">,</span> list2<span class="sy1">,</span> editItem<span class="sy1">,</span> newItem<span class="sy1">,</span> deleteItem<span class="br0">&#41;</span><span class="sy1">;</span>
<span class="kw1">end</span><span class="sy1">;</span></div>
</div>
</pre>
<p>If you were paying close attention in my first two posts about how anonymous methods are implemented, you might realize that these anonymous method references are interface references to a TInterfacedObject descendant, and that by having the closure capture one, the object now holds a reference to itself.  Which means that when you actually run the code, you could end up with FastMM4 reporting something like this:</p>
<p>An unexpected memory leak has occurred. The unexpected small block leaks are:<br />
21 &#8211; 28 bytes: ContrivedExample$ActRec x 1</p>
<p>Oops!  That&#8217;s not good, especially if you call ContrivedExample in a main loop somewhere and end up leaking hundreds of thousands of them.  This is too bad, since there are all sorts of interesting things you could do by using anonymous methods recursively.  And since anonymous methods don&#8217;t have a name, they can&#8217;t invoke themselves recursively without capturing the reference variable.</p>
<p>There&#8217;s probably no way for the compiler to prevent this in the general case, but it could be solved easily enough for examples that fit the pattern described in my examples:  When an anonymous method reference variable is only assigned once in an enclosing procedure, and that one point is where the method is defined within the procedure (i.e. it&#8217;s not passed in as a parameter or already assigned at global or object scope), then the compiler can be certain that the Self pointer for the underlying object is the same as the one it&#8217;s currently executing on, and transform it behind the scenes from an interface reference to a normal method call.</p>
<p>Can anyone else think of possible ways to fix this?</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.turbu-rpg.com/52/how-to-leak-a-class-you-never-defined/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Under the hood of an anonymous method</title>
		<link>http://tech.turbu-rpg.com/30/under-the-hood-of-an-anonymous-method</link>
		<comments>http://tech.turbu-rpg.com/30/under-the-hood-of-an-anonymous-method#comments</comments>
		<pubDate>Fri, 16 Oct 2009 05:22:38 +0000</pubDate>
		<dc:creator>Mason Wheeler</dc:creator>
				<category><![CDATA[Anonymous Methods]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[RTTI]]></category>

		<guid isPermaLink="false">http://tech.turbu-rpg.com/?p=30</guid>
		<description><![CDATA[I woke up this morning and checked DelphiFeeds, and found a very interesting post by Joylon Smith about the use of the absolute keyword.  That reminded me that I had to go and write up this article.  Why?  Because it&#8217;s the only way I know of to get inside an anonymous method&#8217;s functor object and [...]]]></description>
			<content:encoded><![CDATA[<p>I woke up this morning and checked <a href="http://www.delphifeeds.com/">DelphiFeeds</a>, and found a very interesting post by Joylon Smith about <a href="http://www.deltics.co.nz/blog/?p=586">the use of the <strong>absolute</strong> keyword</a>.  That reminded me that I had to go and write up this article.  Why?  Because it&#8217;s the only way I know of to get inside an anonymous method&#8217;s functor object and do some looking around.</p>
<p><span id="more-30"></span></p>
<p>It&#8217;s been explained several times by several different people, including me in <a href="http://tech.turbu-rpg.com/13/whats-in-a-name-less-method">my last article about anonymous methods</a>, that anonymous methods are implemented through interfaces.  And all it takes is a trivial little console application to writeln the sizeof a <strong>reference to </strong>variable and come up with 4, the size of a pointer.  Interestingly enough, though, the compiler won&#8217;t allow you to typecast a <strong>reference to</strong> to an IInterface, a Pointer, an Integer or anything else.  It&#8217;s an anonymous method reference and it won&#8217;t be anything else no matter what you do.</p>
<p>&#8230;unless, of course, you have another variable occupying the same four bytes of memory.  Something like this:</p>
<pre>
<div class="codesnip-container" >
<div class="delphi codesnip" style="font-family:monospace;"><span class="kw1">procedure</span> TClassViewer<span class="sy1">.</span><span class="me1">FormShow</span><span class="br0">&#40;</span>Sender<span class="sy1">:</span> <span class="kw4">TObject</span><span class="br0">&#41;</span><span class="sy1">;</span>
<span class="kw1">var</span>
&nbsp; &nbsp;proc<span class="sy1">:</span> TProc<span class="sy1">;</span>
&nbsp; &nbsp;func<span class="sy1">:</span> TFunc&lt;string&gt;<span class="sy1">;</span>
&nbsp; &nbsp;intf<span class="sy1">:</span> IInterface absolute proc<span class="sy1">;</span>
<span class="kw1">begin</span>
&nbsp; &nbsp;ReportMemoryLeaksOnShutdown <span class="sy1">:</span><span class="sy3">=</span> <span class="kw2">true</span><span class="sy1">;</span>
&nbsp; &nbsp;proc <span class="sy1">:</span><span class="sy3">=</span> <span class="kw1">procedure</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp;<span class="kw1">begin</span>
&nbsp; &nbsp; &nbsp; <span class="kw3">assert</span><span class="br0">&#40;</span>sender <span class="kw1">is</span> <span class="kw4">TObject</span><span class="br0">&#41;</span><span class="sy1">;</span>
&nbsp; &nbsp;<span class="kw1">end</span><span class="sy1">;</span>
&nbsp; &nbsp;func <span class="sy1">:</span><span class="sy3">=</span> <span class="kw1">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy1">:</span> <span class="kw4">string</span>
&nbsp; &nbsp;<span class="kw1">begin</span>
&nbsp; &nbsp; &nbsp; result <span class="sy1">:</span><span class="sy3">=</span> sender<span class="sy1">.</span><span class="me1">ClassName</span><span class="sy1">;</span>
&nbsp; &nbsp;<span class="kw1">end</span><span class="sy1">;</span>
&nbsp; &nbsp;loadClass<span class="br0">&#40;</span>intf <span class="kw1">as</span> <span class="kw4">TObject</span><span class="br0">&#41;</span><span class="sy1">;</span>
<span class="kw1">end</span><span class="sy1">;</span></div>
</div>
</pre>
<p>I set this up to load itself into <a href="http://tech.turbu-rpg.com/3/dynamic-class-creation">my class RTTI inspector tool</a>, and used Delphi 2010&#8242;s trick of <a href="http://blogs.embarcadero.com/abauer/2009/08/21/38893">casting an interface to an object</a>, and it worked!  And here&#8217;s what the object looks like:</p>
<p><a href="http://tech.turbu-rpg.com/wp-content/uploads/2009/10/anon_rtti_1.png"><img class="alignnone size-thumbnail wp-image-31" title="anon_rtti_1" src="http://tech.turbu-rpg.com/wp-content/uploads/2009/10/anon_rtti_1-150x150.png" alt="anon_rtti_1" width="150" height="150" /></a></p>
<p>The name of the functor object&#8217;s class is the full name of the enclosing method, plus $ActRec tacked onto it.  Its parent class is TInterfacedObject.</p>
<p><a href="http://tech.turbu-rpg.com/wp-content/uploads/2009/10/anon_rtti_2.png"><img class="alignnone size-thumbnail wp-image-32" title="anon_rtti_2" src="http://tech.turbu-rpg.com/wp-content/uploads/2009/10/anon_rtti_2-150x150.png" alt="anon_rtti_2" width="150" height="150" /></a></p>
<p>It implements two interfaces, one for each anonymous method.  (There&#8217;s a third, IInterface, at the TInterfacedObject level, of course.)</p>
<p><a href="http://tech.turbu-rpg.com/wp-content/uploads/2009/10/anon_rtti_3.png"><img class="alignnone size-thumbnail wp-image-33" title="anon_rtti_3" src="http://tech.turbu-rpg.com/wp-content/uploads/2009/10/anon_rtti_3-150x150.png" alt="anon_rtti_3" width="150" height="150" /></a></p>
<p>Interestingly enough, even though the compiler goes to great pains to make sure this is only treated as an anonymous method and never as an actual object, Delphi 2010 still generates extended RTTI for the variables that the closure captures.</p>
<p>There&#8217;s not too much to see in the other tabs, but if you want to explore further with some more complex functor objects, feel free to download the RTTI inspector and take a look around.</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.turbu-rpg.com/30/under-the-hood-of-an-anonymous-method/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>What&#8217;s in a name-less method?</title>
		<link>http://tech.turbu-rpg.com/13/whats-in-a-name-less-method</link>
		<comments>http://tech.turbu-rpg.com/13/whats-in-a-name-less-method#comments</comments>
		<pubDate>Tue, 29 Sep 2009 22:23:34 +0000</pubDate>
		<dc:creator>Mason Wheeler</dc:creator>
				<category><![CDATA[Anonymous Methods]]></category>
		<category><![CDATA[Delphi]]></category>

		<guid isPermaLink="false">http://tech.turbu-rpg.com/?p=13</guid>
		<description><![CDATA[When I first saw the announcements for the new Delphi 2009 features, a little more than a year ago, my reactions went something like this: Unicode: Hmm&#8230; looks interesting. Generics: YES! FINALLY! Anonymous methods: &#8230;huh? I think that&#8217;s pretty much how everyone reacted to anonymous methods at first.  The syntax is kinda ugly, and you [...]]]></description>
			<content:encoded><![CDATA[<p>When I first saw the announcements for the new Delphi 2009 features, a little more than a year ago, my reactions went something like this:</p>
<p>Unicode: Hmm&#8230; looks interesting.<br />
Generics: YES! FINALLY!<br />
Anonymous methods: &#8230;huh?</p>
<p>I think that&#8217;s pretty much how everyone reacted to anonymous methods at first. <span id="more-13"></span> The syntax is kinda ugly, and you could get lost trying to read through a procedure and finding another procedure declared in the middle of it like that.  And all this so you could have&#8230; drumroll please&#8230; <a href="http://tvtropes.org/pmwiki/pmwiki.php/Main/ptitle8px80d2wm3pd">a procedure <em>with no name! </em>Ta-da!</a> Umm&#8230; yeah.  OK, whatever.</p>
<p>Things got a little more interesting, and more clear as to what they were useful for, when people started talking about anonymous methods as closures.  Storing local variables inside an anonymous method that retains state and can be passed around.  That&#8217;s actually kinda cool!  But how does it work?  Well, let&#8217;s find out.</p>
<pre>
<div class="codesnip-container" >
<div class="delphi codesnip" style="font-family:monospace;"><span class="kw1">program</span> Project1<span class="sy1">;</span>

<span class="co2">{$APPTYPE CONSOLE}</span>

<span class="kw1">uses</span>
&nbsp; &nbsp;SysUtils<span class="sy1">;</span>

<span class="kw1">type</span>
&nbsp; &nbsp;TAnonProc <span class="sy3">=</span> reference <span class="kw1">to</span> <span class="kw1">procedure</span><span class="sy1">;</span>

<span class="kw1">procedure</span> doStuff<span class="sy1">;</span>
<span class="kw1">var</span>
&nbsp; &nbsp;counter<span class="sy1">:</span> <span class="kw4">integer</span><span class="sy1">;</span>
&nbsp; &nbsp;i<span class="sy1">:</span> <span class="kw4">integer</span><span class="sy1">;</span>
&nbsp; &nbsp;countProc<span class="sy1">:</span> TAnonProc<span class="sy1">;</span>
<span class="kw1">begin</span>
&nbsp; &nbsp;counter <span class="sy1">:</span><span class="sy3">=</span> <span class="nu0">0</span><span class="sy1">;</span>
&nbsp; &nbsp;countProc <span class="sy1">:</span><span class="sy3">=</span> <span class="kw1">procedure</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">begin</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw3">inc</span><span class="br0">&#40;</span>counter<span class="br0">&#41;</span><span class="sy1">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">end</span><span class="sy1">;</span>
&nbsp; &nbsp;<span class="kw1">for</span> i <span class="sy1">:</span><span class="sy3">=</span> 1 <span class="kw1">to</span> 10 <span class="kw1">do</span>
&nbsp; &nbsp; &nbsp; countProc<span class="sy1">;</span>
&nbsp; &nbsp;<span class="kw3">writeln</span><span class="br0">&#40;</span>counter<span class="br0">&#41;</span><span class="sy1">;</span>
<span class="kw1">end</span><span class="sy1">;</span>

<span class="kw1">begin</span>
&nbsp; &nbsp;<span class="kw1">try</span>
&nbsp; &nbsp; &nbsp; doStuff<span class="sy1">;</span>
&nbsp; &nbsp;<span class="kw1">except</span>
&nbsp; &nbsp;<span class="kw1">on</span> E<span class="sy1">:</span> Exception <span class="kw1">do</span>
&nbsp; &nbsp; &nbsp; <span class="kw3">Writeln</span><span class="br0">&#40;</span>E<span class="sy1">.</span><span class="me1">ClassName</span><span class="sy1">,</span> <span class="st0">': '</span><span class="sy1">,</span> E<span class="sy1">.</span><span class="me1">Message</span><span class="br0">&#41;</span><span class="sy1">;</span>
&nbsp; &nbsp;<span class="kw1">end</span><span class="sy1">;</span>
&nbsp; &nbsp;<span class="kw3">readln</span><span class="sy1">;</span>
<span class="kw1">end</span><span class="sy1">.</span></div>
</div>
</pre>
<p>When I run this, the result that gets output is 10, showing that the closure has been modifying the actual local variable for the doStuff procedure and not its own private copy.  But how does that work?  Local variables are stored on the stack, but this closure can be assigned to a reference that can be passed out of the scope of the procedure.  Well, let&#8217;s look at the assembly code for DoStuff to get a sense of what&#8217;s really going on.  It may not be pretty, but it&#8217;s honest.  Nothing can hide from the assembly view.</p>
<pre>
<div class="codesnip-container" >
<div class="asm codesnip" style="font-family:monospace;">Project1<span class="sy0">.</span>dpr<span class="sy0">.</span>16<span class="sy0">:</span> begin
<span class="kw1">push</span> <span class="kw3">ebp</span>
<span class="kw1">mov</span> <span class="kw3">ebp</span><span class="sy0">,</span><span class="kw3">esp</span>
<span class="kw1">push</span> $00
<span class="kw1">push</span> $00
<span class="kw1">push</span> <span class="kw3">ebx</span>
<span class="kw1">push</span> <span class="kw3">esi</span>
<span class="kw1">xor</span> <span class="kw3">eax</span><span class="sy0">,</span><span class="kw3">eax</span>
<span class="kw1">push</span> <span class="kw3">ebp</span>
<span class="kw1">push</span> $0040e8f1
<span class="kw1">push</span> <span class="kw5">dword</span> <span class="kw4">ptr</span> <span class="kw3">fs</span><span class="sy0">:</span><span class="br0">&#91;</span><span class="kw3">eax</span><span class="br0">&#93;</span>
<span class="kw1">mov</span> <span class="kw3">fs</span><span class="sy0">:</span><span class="br0">&#91;</span><span class="kw3">eax</span><span class="br0">&#93;</span><span class="sy0">,</span><span class="kw3">esp</span>
<span class="kw1">mov</span> <span class="kw3">dl</span><span class="sy0">,</span>$01
<span class="kw1">mov</span> <span class="kw3">eax</span><span class="sy0">,</span><span class="br0">&#91;</span>$0040e7a8<span class="br0">&#93;</span>
<span class="kw1">call</span> TObject<span class="sy0">.</span>Create
<span class="kw1">mov</span> <span class="kw3">esi</span><span class="sy0">,</span><span class="kw3">eax</span>
<span class="kw1">lea</span> <span class="kw3">eax</span><span class="sy0">,</span><span class="br0">&#91;</span><span class="kw3">ebp</span><span class="sy0">-</span>$08<span class="br0">&#93;</span>
<span class="kw1">mov</span> <span class="kw3">edx</span><span class="sy0">,</span><span class="kw3">esi</span>
<span class="kw1">test</span> <span class="kw3">edx</span><span class="sy0">,</span><span class="kw3">edx</span>
<span class="kw1">jz</span> $0040e891
<span class="kw1">sub</span> <span class="kw3">edx</span><span class="sy0">,-</span>$08
<span class="kw1">call</span> @IntfCopy

Project1<span class="sy0">.</span>dpr<span class="sy0">.</span>17<span class="sy0">:</span> counter <span class="sy0">:</span>= <span class="nu0">0</span><span class="co1">;</span>
<span class="kw1">xor</span> <span class="kw3">eax</span><span class="sy0">,</span><span class="kw3">eax</span>
<span class="kw1">mov</span> <span class="br0">&#91;</span><span class="kw3">esi</span><span class="sy0">+</span>$0c<span class="br0">&#93;</span><span class="sy0">,</span><span class="kw3">eax</span>

Project1<span class="sy0">.</span>dpr<span class="sy0">.</span>18<span class="sy0">:</span> countProc <span class="sy0">:</span>= procedure
<span class="kw1">lea</span> <span class="kw3">eax</span><span class="sy0">,</span><span class="br0">&#91;</span><span class="kw3">ebp</span><span class="sy0">-</span>$04<span class="br0">&#93;</span>
<span class="kw1">mov</span> <span class="kw3">edx</span><span class="sy0">,</span><span class="kw3">esi</span>
<span class="kw1">test</span> <span class="kw3">edx</span><span class="sy0">,</span><span class="kw3">edx</span>
<span class="kw1">jz</span> $0040e8a7
<span class="kw1">sub</span> <span class="kw3">edx</span><span class="sy0">,-</span>$10
<span class="kw1">call</span> @IntfCopy

Project1<span class="sy0">.</span>dpr<span class="sy0">.</span>22<span class="sy0">:</span> <span class="kw4">for</span> i <span class="sy0">:</span>= 1 to 10 do
<span class="kw1">mov</span> <span class="kw3">ebx</span><span class="sy0">,</span>$0000000a

Project1<span class="sy0">.</span>dpr<span class="sy0">.</span>23<span class="sy0">:</span> countProc<span class="co1">;</span>
<span class="kw1">mov</span> <span class="kw3">eax</span><span class="sy0">,</span><span class="br0">&#91;</span><span class="kw3">ebp</span><span class="sy0">-</span>$04<span class="br0">&#93;</span>
<span class="kw1">mov</span> <span class="kw3">edx</span><span class="sy0">,</span><span class="br0">&#91;</span><span class="kw3">eax</span><span class="br0">&#93;</span>
<span class="kw1">call</span> <span class="kw5">dword</span> <span class="kw4">ptr</span> <span class="br0">&#91;</span><span class="kw3">edx</span><span class="sy0">+</span>$0c<span class="br0">&#93;</span>

Project1<span class="sy0">.</span>dpr<span class="sy0">.</span>22<span class="sy0">:</span> <span class="kw4">for</span> i <span class="sy0">:</span>= 1 to 10 do
<span class="kw1">dec</span> <span class="kw3">ebx</span>
<span class="kw1">jnz</span> $0040e8b1

Project1<span class="sy0">.</span>dpr<span class="sy0">.</span>24<span class="sy0">:</span> writeln<span class="br0">&#40;</span>counter<span class="br0">&#41;</span><span class="co1">;</span>
<span class="kw1">mov</span> <span class="kw3">eax</span><span class="sy0">,</span><span class="br0">&#91;</span>$00411ccc<span class="br0">&#93;</span>
<span class="kw1">mov</span> <span class="kw3">edx</span><span class="sy0">,</span><span class="br0">&#91;</span><span class="kw3">esi</span><span class="sy0">+</span>$0c<span class="br0">&#93;</span>
<span class="kw1">call</span> @Write0Long
<span class="kw1">call</span> @WriteLn
<span class="kw1">call</span> @_IOTest

Project1<span class="sy0">.</span>dpr<span class="sy0">.</span>25<span class="sy0">:</span> <span class="kw4">end</span><span class="co1">;</span>
<span class="kw1">xor</span> <span class="kw3">eax</span><span class="sy0">,</span><span class="kw3">eax</span>
<span class="kw1">pop</span> <span class="kw3">edx</span>
<span class="kw1">pop</span> <span class="kw3">ecx</span>
<span class="kw1">pop</span> <span class="kw3">ecx</span>
<span class="kw1">mov</span> <span class="kw3">fs</span><span class="sy0">:</span><span class="br0">&#91;</span><span class="kw3">eax</span><span class="br0">&#93;</span><span class="sy0">,</span><span class="kw3">edx</span>
<span class="kw1">push</span> $0040e8f8
<span class="kw1">lea</span> <span class="kw3">eax</span><span class="sy0">,</span><span class="br0">&#91;</span><span class="kw3">ebp</span><span class="sy0">-</span>$08<span class="br0">&#93;</span>
<span class="kw1">call</span> @IntfClear
<span class="kw1">lea</span> <span class="kw3">eax</span><span class="sy0">,</span><span class="br0">&#91;</span><span class="kw3">ebp</span><span class="sy0">-</span>$04<span class="br0">&#93;</span>
<span class="kw1">call</span> @IntfClear
<span class="kw1">ret</span>
<span class="kw1">jmp</span> @HandleFinally
<span class="kw1">jmp</span> $0040e8e0
<span class="kw1">pop</span> <span class="kw3">esi</span>
<span class="kw1">pop</span> <span class="kw3">ebx</span>
<span class="kw1">pop</span> <span class="kw3">ecx</span>
<span class="kw1">pop</span> <span class="kw3">ecx</span>
<span class="kw1">pop</span> <span class="kw3">ebp</span>
<span class="kw1">ret</span></div>
</div>
</pre>
<p>Wow, that&#8217;s a lot of code!  The really interesting stuff here is what&#8217;s going on in the &#8220;<strong>begin</strong>&#8221; line.  After a bit of standard setup, it creates a try block, then does this:</p>
<pre>
<div class="codesnip-container" >
<div class="asm codesnip" style="font-family:monospace;"><span class="kw1">mov</span> <span class="kw3">eax</span><span class="sy0">,</span><span class="br0">&#91;</span>$0040e7a8<span class="br0">&#93;</span>
<span class="kw1">call</span> TObject<span class="sy0">.</span>Create
<span class="kw1">mov</span> <span class="kw3">esi</span><span class="sy0">,</span><span class="kw3">eax</span>
<span class="kw1">lea</span> <span class="kw3">eax</span><span class="sy0">,</span><span class="br0">&#91;</span><span class="kw3">ebp</span><span class="sy0">-</span>$08<span class="br0">&#93;</span>
<span class="kw1">mov</span> <span class="kw3">edx</span><span class="sy0">,</span><span class="kw3">esi</span>
<span class="kw1">test</span> <span class="kw3">edx</span><span class="sy0">,</span><span class="kw3">edx</span>
<span class="kw1">jz</span> $0040e891
<span class="kw1">sub</span> <span class="kw3">edx</span><span class="sy0">,-</span>$08
<span class="kw1">call</span> @IntfCopy</div>
</div>
</pre>
<p>It places a class pointer in EAX, then calls TObject.Create to set up a new instance of that class, and stores the resulting object pointer in the ESI register.  Then it copies ESI to EDX (second parameter in the <strong>register</strong> calling convention), loads the stack location for our anonymous procedure reference into EAX (first parameter), and calls System._IntfCopy, which is declared as</p>
<pre>
<div class="codesnip-container" >
<div class="delphi codesnip" style="font-family:monospace;"><span class="kw1">procedure</span> _IntfCopy<span class="br0">&#40;</span><span class="kw1">var</span> Dest<span class="sy1">:</span> IInterface<span class="sy1">;</span> 
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">const</span> Source<span class="sy1">:</span> IInterface<span class="br0">&#41;</span><span class="sy1">;</span></div>
</div>
</pre>
<p>So now we have an interface reference to an object containing an anonymous method, used to implement the closure.  When we go to assign to counter locally, we get this:</p>
<pre>
<div class="codesnip-container" >
<div class="asm codesnip" style="font-family:monospace;">Project1<span class="sy0">.</span>dpr<span class="sy0">.</span>17<span class="sy0">:</span> counter <span class="sy0">:</span>= <span class="nu0">0</span><span class="co1">;</span>
<span class="kw1">xor</span> <span class="kw3">eax</span><span class="sy0">,</span><span class="kw3">eax</span>
<span class="kw1">mov</span> <span class="br0">&#91;</span><span class="kw3">esi</span><span class="sy0">+</span>$0c<span class="br0">&#93;</span><span class="sy0">,</span><span class="kw3">eax</span></div>
</div>
</pre>
<p>Aha!  So it&#8217;s not stored on the stack after all; it&#8217;s treated more or less as a <strong>var</strong> parameter referring to a field inside the closure object.  It&#8217;s referenced as [esi + $0C], so our &#8220;local&#8221; variable is stored 12 bytes in, which is right where we&#8217;d expect to find the first data field on an object that implements two interfaces: IInterface and the &#8220;anonymous method interface&#8221; for this closure.  This explains <a href="http://stackoverflow.com/questions/801147/scope-of-anonymous-methods">why an anonymous method can&#8217;t capture by-reference parameters</a> or the Result variable, which canonically resides either in EAX or on the stack, depending on your calling convention.  The compiler needs to be able to reference it inside the closure object&#8217;s heap space, and it can&#8217;t do that if the variable&#8217;s already living somewhere else.</p>
<p>This raises an interesting question:  What happens if you create two anonymous methods that both refer to the same local variable?  Where is the variable stored then?  I won&#8217;t waste space posting another big disassembly, but the answer is, &#8220;in the closure object for that procedure.&#8221;  Only one gets created, with multiple (anonymous) methods and multiple interface references.  (Incidentally, this is also how <a href="http://en.wikipedia.org/wiki/Common_Lisp_Object_System">CLOS</a> creates objects:  by wrapping multiple closures around the same set of variables.)</p>
<p>There&#8217;s more interesting stuff that can be found by poking around in closure objects, but this post is getting long enough, so that&#8217;s all for now.  I&#8217;ll go into more details about anonymous methods and closure objects in a few days.</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.turbu-rpg.com/13/whats-in-a-name-less-method/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
