<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:p="urn:schemas-microsoft-com:office:powerpoint" xmlns:a="urn:schemas-microsoft-com:office:access" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema" xmlns:b="urn:schemas-microsoft-com:office:publisher" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:c="urn:schemas-microsoft-com:office:component:spreadsheet" xmlns:odc="urn:schemas-microsoft-com:office:odc" xmlns:oa="urn:schemas-microsoft-com:office:activation" xmlns:html="http://www.w3.org/TR/REC-html40" xmlns:q="http://schemas.xmlsoap.org/soap/envelope/" xmlns:rtc="http://microsoft.com/officenet/conferencing" xmlns:D="DAV:" xmlns:Repl="http://schemas.microsoft.com/repl/" xmlns:mt="http://schemas.microsoft.com/sharepoint/soap/meetings/" xmlns:x2="http://schemas.microsoft.com/office/excel/2003/xml" xmlns:ppda="http://www.passport.com/NameSpace.xsd" xmlns:ois="http://schemas.microsoft.com/sharepoint/soap/ois/" xmlns:dir="http://schemas.microsoft.com/sharepoint/soap/directory/" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:dsp="http://schemas.microsoft.com/sharepoint/dsp" xmlns:udc="http://schemas.microsoft.com/data/udc" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sub="http://schemas.microsoft.com/sharepoint/soap/2002/1/alerts/" xmlns:ec="http://www.w3.org/2001/04/xmlenc#" xmlns:sp="http://schemas.microsoft.com/sharepoint/" xmlns:sps="http://schemas.microsoft.com/sharepoint/soap/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:udcs="http://schemas.microsoft.com/data/udc/soap" xmlns:udcxf="http://schemas.microsoft.com/data/udc/xmlfile" xmlns:udcp2p="http://schemas.microsoft.com/data/udc/parttopart" xmlns:wf="http://schemas.microsoft.com/sharepoint/soap/workflow/" xmlns:dsss="http://schemas.microsoft.com/office/2006/digsig-setup" xmlns:dssi="http://schemas.microsoft.com/office/2006/digsig" xmlns:mdssi="http://schemas.openxmlformats.org/package/2006/digital-signature" xmlns:mver="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns:mrels="http://schemas.openxmlformats.org/package/2006/relationships" xmlns:spwp="http://microsoft.com/sharepoint/webpartpages" xmlns:ex12t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:ex12m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:pptsl="http://schemas.microsoft.com/sharepoint/soap/SlideLibrary/" xmlns:spsl="http://microsoft.com/webservices/SharePointPortalServer/PublishedLinksService" xmlns:Z="urn:schemas-microsoft-com:" xmlns:st="&#1;" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 12 (filtered medium)">
<style>
<!--
 /* Font Definitions */
 @font-face
        {font-family:Wingdings;
        panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
 /* Style Definitions */
 p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
span.apple-style-span
        {mso-style-name:apple-style-span;}
span.EmailStyle18
        {mso-style-type:personal-reply;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
-->
</style><!--[if gte mso 9]><xml>
 <o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
 <o:shapelayout v:ext="edit">
  <o:idmap v:ext="edit" data="1" />
 </o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:&quot;Calibri&quot;,&quot;sans-serif&quot;;
color:#1F497D">I think that&#8217;s a fair summary and ties into what I was saying about cross function switching.&nbsp; So basically this means every method needs to be re-written
 to support this including dispatching calls via returning back to an outer loop and then dispatching to the called object with the new arguments (including the perf hit that would come with that).&nbsp; I think that can certainly be done with a DLR tree AST re-write
 and replacing normal invocation with this trampoline mechanism.&nbsp; Obviously it&#8217;ll come with a significant perf hit as we need to allocate memory for local variables, calls with be slower as they need to return and call, etc&#8230;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:&quot;Calibri&quot;,&quot;sans-serif&quot;;
color:#1F497D"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:&quot;Calibri&quot;,&quot;sans-serif&quot;;
color:#1F497D">But if you can get the tree re-write going to make the code entirely stackless from there you could opt into to the tree re-write dynamically.&nbsp; That could
 be done by doing a simpler tree re-write to track where you are in the function and then throwing a .NET exception when the 1<sup>st</sup> switch occurs.&nbsp; There would need to be try/catch/rethrow blocks to save all of the relevant state (which would need to
 be in locals) and then all of the functions on the stack would need to be re-written with the full stackless re-write.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:&quot;Calibri&quot;,&quot;sans-serif&quot;;
color:#1F497D"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:&quot;Calibri&quot;,&quot;sans-serif&quot;;
color:#1F497D">I do agree that it sounds more difficult then what is going on with the CPython implementation.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:&quot;Calibri&quot;,&quot;sans-serif&quot;;
color:#1F497D"><o:p>&nbsp;</o:p></span></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt">
<div>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b><span style="font-size:10.0pt;font-family:&quot;Tahoma&quot;,&quot;sans-serif&quot;">From:</span></b><span style="font-size:10.0pt;font-family:&quot;Tahoma&quot;,&quot;sans-serif&quot;"> users-bounces@lists.ironpython.com [mailto:users-bounces@lists.ironpython.com]
<b>On Behalf Of </b>Tristan Zajonc<br>
<b>Sent:</b> Friday, June 25, 2010 4:45 AM<br>
<b>To:</b> Discussion of IronPython<br>
<b>Subject:</b> Re: [IronPython] Implementing Greenlets API in IronPython<o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal">I have been trying to hire somebody to implement the greenlet extension module, which would enable modules like eventlet and gevent to work on IronPython. &nbsp;The person I currently have looking into it, however, isn't hopeful. A condensed
 version of his perspective is below. &nbsp;Perhaps the IronPython list (Dino?) has an idea for a solution?<o:p></o:p></p>
<div>
<div>
<div>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
<div>
<p class="MsoNormal">== Response to Greenlets on IronPython ==&nbsp;<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
<div>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-size:9.0pt;
font-family:&quot;Arial&quot;,&quot;sans-serif&quot;">I looked at various solutions but none of them seem to arrive at the correct solution. I did try generating the DLR using AST again to make
 the function stackless but the limitation is with python and .NET.&nbsp;</span></span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:12.0pt"><span class="apple-style-span"><span style="font-size:9.0pt;font-family:&quot;Arial&quot;,&quot;sans-serif&quot;">Let me explain the issue.&nbsp;</span></span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:12.0pt"><span class="apple-style-span"><span style="font-size:9.0pt;font-family:&quot;Arial&quot;,&quot;sans-serif&quot;">1) .NET lanugages (C#.
<a href="http://VB.NET">VB.NET</a> etc.) are strongly typed. In other words, if I get a variable I know what its type is at compile time. IronPython actually compiles the functions into CLR and runs them on the fly. A function is compiled once and can be executed
 again and again. One must know that the function needs to be stackless at compile time and a function cannot be made stackless at run time.</span></span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-size:9.0pt;
font-family:&quot;Arial&quot;,&quot;sans-serif&quot;">2) Python is a typeless language. A variable can assume any type at any point in execution at run-time. Now consider the following code in Python
 using the greenlet API:</span></span><span style="font-size:9.0pt;font-family:&quot;Arial&quot;,&quot;sans-serif&quot;"><br>
<br>
<span class="apple-style-span">a = greenlet(foo)</span><br>
<br>
<span class="apple-style-span">def abc():</span><br>
<span class="apple-style-span">&nbsp;&nbsp; &nbsp;print &quot;X&quot;</span><br>
<span class="apple-style-span">&nbsp;&nbsp; &nbsp;a.switch()</span><br>
<span class="apple-style-span">&nbsp;&nbsp; &nbsp;print &quot;Y&quot;</span><br>
<br>
<span class="apple-style-span">Although variable a is defined, it does not have a strong type and during execution, a can be assigned a different object which can also implement the switch function and the code will execute fine.</span><br>
<br>
<span class="apple-style-span">As mentioned above, IronPython needs to know at compile time that the function has to be made stackless. In python since a is not typed, a can be greenlet in one execution of abc and any other object in the second call. Also,
 there is no way to determine at compile that the function abc needs to be made stackless since it needs to switch since the type of a is unknown till it is actually called at runtime.&nbsp;</span><br>
<br>
<span class="apple-style-span">Hence is it next to impossible to implement the switch because of the above implementation.</span></span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:&quot;Arial&quot;,&quot;sans-serif&quot;"><br>
<span class="apple-style-span">CPython dos not compile the functions and does not use the yield keyword (which is not avilable in C/C&#43;&#43; anyways) to do it. It does this by using&nbsp;context switching which is built into python and so the API is fairly&nbsp;straightforward
 in CPython. CPython basically has the stack of all previous&nbsp;functions calls and saves the stack so that it can resume later from that&nbsp;point. It needs to store the context and uses the inherent context switching&nbsp;built into Python to do it.</span></span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
<div>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-size:9.0pt;
font-family:&quot;Arial&quot;,&quot;sans-serif&quot;">== End Response ==</span></span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
<div>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-size:9.0pt;
font-family:&quot;Arial&quot;,&quot;sans-serif&quot;">Ideas?</span></span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
<div>
<p class="MsoNormal">Tristan<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<div>
<p class="MsoNormal">On Mon, May 31, 2010 at 1:28 PM, Dino Viehland &lt;<a href="mailto:dinov@microsoft.com">dinov@microsoft.com</a>&gt; wrote:<o:p></o:p></p>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;color:#1F497D">You&#8217;ll want to first look at GeneratorRewriter.cs - it&#8217;s responsible for taking a DLR AST and re-writing it so that it can re-start
 at an arbitrary location and so that it&#8217;s stackless.&nbsp; There&#8217;s one of these for debugging and one that&#8217;s used for IronPython&#8217;s generators, you can probably adapt either one.&nbsp; You can get the AST to re-write from the function code object but that&#8217;s not public
 right now (we&#8217;ll make it public if anyone has a compelling scenario to do so &#8211; this could be it but you&#8217;ll probably need more public surface area as well).</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;color:#1F497D">&nbsp;</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;color:#1F497D">From there I think you just need to worry about having to save multiple frames (which I get the impression is supported from the docs
 &#8211; eg f() calls g() and then g switches).&nbsp; For that you&#8217;ll probably want to re-write all of the dynamic expressions in the generator (these show up in several forms though based upon how we&#8217;re generating code-&nbsp; there&#8217;s a ReduciableDynamicExpression and some
 PythonDynamicExpression&#8217;s floating around now).&nbsp; If greenlets only works across calls then you just need to intercept the ones which are using invoke binders.&nbsp; If you can have a descriptor who&#8217;s __get__ or __set__ switches then you&#8217;d also need to handle gets/sets/etc&#8230;&nbsp;
 If you can do something like import a module which hasn&#8217;t been loaded yet and then have the top-level module code switch then you&#8217;ll need to start getting really creative
</span><span style="font-size:11.0pt;font-family:Wingdings;color:#1F497D">J</span><span style="font-size:11.0pt;color:#1F497D">&nbsp; You&#8217;ll then presumably need to change these into using some trampoline to do the actual invocation.</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;color:#1F497D">&nbsp;</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;color:#1F497D">Hopefully that will get you started &#8211; I&#8217;m sure there&#8217;ll be lots of little issues so if you have questions feel free to ask.&nbsp; If you
 get it all working we can figure out what exactly we need to make public and how we should expose that so you can do this as an extension &#8211; but I&#8217;m sure you&#8217;ll initially be using a bunch of internal APIs.</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;color:#1F497D">&nbsp;</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-size:11.0pt;color:#1F497D">&nbsp;</span><o:p></o:p></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt">
<div>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><b><span style="font-size:10.0pt">From:</span></b><span style="font-size:10.0pt">
<a href="mailto:users-bounces@lists.ironpython.com" target="_blank">users-bounces@lists.ironpython.com</a> [mailto:<a href="mailto:users-bounces@lists.ironpython.com" target="_blank">users-bounces@lists.ironpython.com</a>]
<b>On Behalf Of </b>Tristan Zajonc<br>
<b>Sent:</b> Sunday, May 30, 2010 6:59 PM<br>
<b>To:</b> Discussion of IronPython<br>
<b>Subject:</b> [IronPython] Implementing Greenlets API in IronPython</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">&nbsp;<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Hi -<o:p></o:p></p>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">&nbsp;<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">The greenlets C-extension&nbsp;module&nbsp;(<a href="http://packages.python.org/greenlet/" target="_blank">http://packages.python.org/greenlet/</a>) &nbsp;provides a very basic api that is used
 by eventlet and gevent to provide&nbsp;asynchronous&nbsp;programming constructs. &nbsp;It would be nice to have a reasonably performant version of the greenlet API in IronPython.<o:p></o:p></p>
</div>
<div>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">&nbsp;<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Before I start playing around with possibilities, is there an obvious approach to implement the greenlets API in IronPython?<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">&nbsp;<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Thanks<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Tristan<o:p></o:p></p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<p class="MsoNormal" style="margin-bottom:12.0pt"><br>
_______________________________________________<br>
Users mailing list<br>
<a href="mailto:Users@lists.ironpython.com">Users@lists.ironpython.com</a><br>
<a href="http://lists.ironpython.com/listinfo.cgi/users-ironpython.com" target="_blank">http://lists.ironpython.com/listinfo.cgi/users-ironpython.com</a><o:p></o:p></p>
</div>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
</div>
</div>
</div>
</div>
</body>
</html>