<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:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 14 (filtered medium)">
<style><!--
/* Font Definitions */
@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;}
@font-face
        {font-family:Consolas;
        panose-1:2 11 6 9 2 2 4 3 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;}
p.MsoAcetate, li.MsoAcetate, div.MsoAcetate
        {mso-style-priority:99;
        mso-style-link:"Balloon Text Char";
        margin:0in;
        margin-bottom:.0001pt;
        font-size:8.0pt;
        font-family:"Tahoma","sans-serif";}
span.BalloonTextChar
        {mso-style-name:"Balloon Text Char";
        mso-style-priority:99;
        mso-style-link:"Balloon Text";
        font-family:"Tahoma","sans-serif";}
span.EmailStyle19
        {mso-style-type:personal-reply;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri","sans-serif";}
@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:"Calibri","sans-serif";color:#1F497D">Comments below…<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">From:</span></b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif""> Reid Kleckner [mailto:rnk@google.com]
<br>
<b>Sent:</b> Friday, April 10, 2015 5:01 PM<br>
<b>To:</b> Kaylor, Andrew<br>
<b>Cc:</b> David Majnemer <david.majnemer@gmail.com> (david.majnemer@gmail.com); LLVM Developers Mailing List<br>
<b>Subject:</b> Re: [WinEH] Cloning blocks that reference non-cloned PHI nodes<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal">Yeah, wrapping up the whole selector comparison into one intrinsic would help. Thanks for the idea. :)<o:p></o:p></p>
<div>
<p class="MsoNormal"><br>
The current strategy also seems pretty fragile around complex cleanups. If the cleanup isn't some simple destructor call with easily traceable unconditional branch control flow, we get lost and can't find our way to the next selector comparison. Having an explicit
 'resume' or some other intrinsic at the end of the cleanup would be pretty helpful here.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">---<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">We also talked a lot about making WinEHPrepare try to less work all at once, and split it into phases. This is separable from the landingswitch proposal, which is more about making it easier to identify handler start points. Here's a sketch
 of the phases we came up with:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Step 1: Identify selector dispatch conditional branches. Identify all cleanup actions, and split basic blocks to make them start and end on a basic block boundary. Build a list of all basic blocks that start a handler.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">[Andy Kaylor] This sounds an awful lot like what we’re doing now except for the block splitting part.  I guess that you are talking about doing this for all
 landing pads before we go any further, right?  I agree that the current code to identify cleanup blocks is too fragile.  We can probably fix it though.  Intrinsics to mark the start and/or end of cleanup code would help immensely.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal">Step 2: Do a forwards-backwards dataflow analysis to mark basic blocks as reachable and unreachable from each handler start block. The forwards part is an easy DFS, the backwards part is basically about pruning unreachable blocks like 'ret'
 from a handler. We can probably skip the backwards part initially.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">[Andy Kaylor] I have some concerns about this part.   When blocks have been merged so that handlers are sharing blocks with non-exception code things are going
 to get fairly messy.  The existing cloning code takes care of this (in theory at least) by scrubbing things after resolving PHIs based on which blocks didn’t get cloned.  I suppose this is a potential fault line if the code we didn’t want loops back into the
 shared block.  I’m guessing that this is the sort of problem you’re thinking of that has you wanting to change things.  Do you have a test case that exposes the problem?  More importantly, do you have a solution in mind?<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">With catch handlers we have clear markers for the beginning and end of the catch (possibly including multiple end calls).  Having similar markers for cleanup
 would help a lot.  I still think there’s potential for getting lost.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal">Step 3: Clone all blocks that are reachable from more than one handler until all blocks belong to exactly one handler, and sink code from landingpads back into handlers if necessary. We don't have many code commoning optimizations, so this
 step is more of a defense against theoretical future optimization passes that do more than tail merging.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">[Andy Kaylor] I’m not sure I see how this is better than the current cloning approach.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal">Step 4: Demote all SSA values live from one handler into or out of another. The only SSA values referenceable across handlers are static allocas.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">[Andy Kaylor] Again, if I underststand correctly we’re doing this now, just with a fairly distributed mechanism.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal">Step 5: Extract the blocks belonging to each handler into their own functions. Rewrite static alloca references in each new handler to use llvm.framerecover.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Step 6: Profit?<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Does this seem like a reasonable plan? IMO simplifying the overarching design is a higher priority right now than fixing individual test cases.<o:p></o:p></p>
</div>
</div>
<div>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">[Andy Kaylor] I think there’s significant value in getting some core suite of tests working so that we can get out of our current pattern of rewriting all of
 our tests every time we make a significant change and into a situation where we’ll have some stable tests that will verify that any redesign isn’t breaking something.  I also think that in chasing down problems with the implementation we have now we’ll learn
 more about the problems that need to be solved.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">I don’t have a strong objection to your working on a redesign while I try to work through some bugs in the current implementation, but I’d like to ask you to
 hold off on committing significant restructuring for a little while unless I run into something that can’t be solved within the current design.  I feel like I can have the small test suite that I’m working on passing within a week or so.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<div>
<p class="MsoNormal">On Fri, Apr 10, 2015 at 4:36 PM, Kaylor, Andrew <<a href="mailto:andrew.kaylor@intel.com" target="_blank">andrew.kaylor@intel.com</a>> 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;font-family:"Calibri","sans-serif";color:#1F497D">Just as an off-the-cuff idea that I haven’t thought through at all, what would you think of the possibility
 of replacing this:</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;font-family:"Calibri","sans-serif";color:#1F497D"> </span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">  %12 = call i32 @llvm.eh.typeid.for(i8* bitcast (%eh.CatchHandlerType* @llvm.eh.handlertype.H.0 to i8*))</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">  %matches7 = icmp eq i32 %sel6, %12</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;font-family:"Calibri","sans-serif";color:#1F497D"> </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;font-family:"Calibri","sans-serif";color:#1F497D">with this:</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;font-family:"Calibri","sans-serif";color:#1F497D"> </span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">  %matches7 = call i32 @llvm.eh.cmp.selector(i32 %sel6, i8* bitcast (%eh.CatchHandlerType* @llvm.eh.handlertype.H.0 to i8*))</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;font-family:"Calibri","sans-serif";color:#1F497D"> </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;font-family:"Calibri","sans-serif";color:#1F497D">If we did that, the outlining code could just assume %sel6 was the current selector (because we don’t
 clone into nested landing pads) and we wouldn’t need to track it at all.</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;font-family:"Calibri","sans-serif";color:#1F497D"> </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;font-family:"Calibri","sans-serif";color:#1F497D">-Andy</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;font-family:"Calibri","sans-serif";color:#1F497D"> </span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">From:</span></b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif""> Reid Kleckner [mailto:<a href="mailto:rnk@google.com" target="_blank">rnk@google.com</a>]
<br>
<b>Sent:</b> Friday, April 10, 2015 4:06 PM<br>
<b>To:</b> Kaylor, Andrew<br>
<b>Cc:</b> David Majnemer <<a href="mailto:david.majnemer@gmail.com" target="_blank">david.majnemer@gmail.com</a>> (<a href="mailto:david.majnemer@gmail.com" target="_blank">david.majnemer@gmail.com</a>); LLVM Developers Mailing List<br>
<b>Subject:</b> Re: [WinEH] Cloning blocks that reference non-cloned PHI nodes</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Sounds reasonable. Honestly, we've been having some serious whiteboard discussions about how to get out of doing all this selector pattern matching. I think that's basically the
 most fragile part of winehprepare, and if we can add some new constructs that wrap that up in something opaque to mid-level passes, that would be great.<o:p></o:p></p>
<div>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Unfortunately, I haven't really been able to get enough consensus to write something down. If I can't convince my coworkers that we need a new construct in person, there's not much
 point in writing up a detailed RFC. :(<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Here's the gist of the new idea:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">- Leave invoke alone, too many optimizations care about it<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">- Add a new 'landingswitch' (name under debate) instruction that fills the landingpad role and is also a terminator<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">- landingswitch clauses have some fixed operands (RTTI, handler label) and some variable number of operands as required by the EH personality (catch object, adjectives)<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">- Allow the 'resume' instruction to have 0, 1, or 2 successors, one of which can be a landingpad.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">- Add a 'resume' clause to landingswitches to allow them to continue the unwind process at another landingpad in the same function<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">I've tried to sell this idea, but I'm getting push back suggesting that we fix it a different way. The most compelling suggestion is to have the existing landingpad instruction
 produce an i8* selector instead of an i32 selector, and then we indirectbr on it. This would save the selector pattern matching that we do today, but I don't particularly like it. Optimization passes can do basic block commoning, tail merging, and hoist instructions
 between the landingpad and the indirectbr, and I don't like dealing with that.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">I also don't like it because we'd need to teach the inliner about indirectbr, which today it refuses to inline.<o:p></o:p></p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">On Fri, Apr 10, 2015 at 3:45 PM, Kaylor, Andrew <<a href="mailto:andrew.kaylor@intel.com" target="_blank">andrew.kaylor@intel.com</a>> wrote:<o:p></o:p></p>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Hi Reid and David,<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">I just wanted to give you a heads up that I’m currently working on a problem where the WinEHPrepare outlining code stumbles and asserts while cloning code that references extracted
 landing pad values via PHI nodes that are in intermediate blocks that aren’t being cloned.  The test I’m looking at fails with an assertion claiming that llvm.eh.begincatch was called twice inside a handler.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">I have an idea for how to address this (giving the cloning director a chance to replace operands before an instruction is remapped).  I’ll put something up for review as soon as
 I have it working.  In the mean time I wanted to make sure you weren’t working on the same problem.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">I’m seeing it with some C++ EH tests I’m working on, but I think it may be possible for it to happen with SEH cleanup.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">If you’re curious, here’s a reproducer.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:blue;background:white">int</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white"> main(</span><span style="font-size:9.5pt;font-family:Consolas;color:blue;background:white">void</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">)
 {</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white"> 
</span><span style="font-size:9.5pt;font-family:Consolas;color:blue;background:white">try</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white"> {</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">   
</span><span style="font-size:9.5pt;font-family:Consolas;color:blue;background:white">try</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white"> {</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">     
</span><span style="font-size:9.5pt;font-family:Consolas;color:blue;background:white">throw</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">
</span><span style="font-size:9.5pt;font-family:Consolas;color:#A31515;background:white">'a'</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">;</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">    }
</span><span style="font-size:9.5pt;font-family:Consolas;color:blue;background:white">catch</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white"> (</span><span style="font-size:9.5pt;font-family:Consolas;color:blue;background:white">char</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">
 c) {</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">      printf(</span><span style="font-size:9.5pt;font-family:Consolas;color:#A31515;background:white">"%c\n"</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">,
 c);</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">    }</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">   
</span><span style="font-size:9.5pt;font-family:Consolas;color:blue;background:white">throw</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white"> 1;</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">  }
</span><span style="font-size:9.5pt;font-family:Consolas;color:blue;background:white">catch</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">(</span><span style="font-size:9.5pt;font-family:Consolas;color:blue;background:white">int</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">
 x) {</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">    printf(</span><span style="font-size:9.5pt;font-family:Consolas;color:#A31515;background:white">"%d\n"</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">,
 x);</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">  }
</span><span style="font-size:9.5pt;font-family:Consolas;color:blue;background:white">catch</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">(...) {</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">    printf(</span><span style="font-size:9.5pt;font-family:Consolas;color:#A31515;background:white">"...\n"</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">);</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">  }</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white"> </span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white"> 
</span><span style="font-size:9.5pt;font-family:Consolas;color:blue;background:white">try</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white"> {</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">   
</span><span style="font-size:9.5pt;font-family:Consolas;color:blue;background:white">try</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white"> {</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">     
</span><span style="font-size:9.5pt;font-family:Consolas;color:blue;background:white">throw</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">
</span><span style="font-size:9.5pt;font-family:Consolas;color:#A31515;background:white">'b'</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">;</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">    }
</span><span style="font-size:9.5pt;font-family:Consolas;color:blue;background:white">catch</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white"> (</span><span style="font-size:9.5pt;font-family:Consolas;color:blue;background:white">char</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">
 c) {</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">      printf(</span><span style="font-size:9.5pt;font-family:Consolas;color:#A31515;background:white">"%c\n"</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">,
 c);</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">    }</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">   
</span><span style="font-size:9.5pt;font-family:Consolas;color:blue;background:white">throw</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white"> 2;</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">  }
</span><span style="font-size:9.5pt;font-family:Consolas;color:blue;background:white">catch</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">(</span><span style="font-size:9.5pt;font-family:Consolas;color:blue;background:white">int</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">
 x) {</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">    printf(</span><span style="font-size:9.5pt;font-family:Consolas;color:#A31515;background:white">"%d\n"</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">,
 x);</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">  }
</span><span style="font-size:9.5pt;font-family:Consolas;color:blue;background:white">catch</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white"> (</span><span style="font-size:9.5pt;font-family:Consolas;color:blue;background:white">char</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">
 c) {</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">    printf(</span><span style="font-size:9.5pt;font-family:Consolas;color:#A31515;background:white">"%c\n"</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">,
 c);</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">  }
</span><span style="font-size:9.5pt;font-family:Consolas;color:blue;background:white">catch</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">(...) {</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">    printf(</span><span style="font-size:9.5pt;font-family:Consolas;color:#A31515;background:white">"...\n"</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">);</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">  }</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white"> 
</span><span style="font-size:9.5pt;font-family:Consolas;color:blue;background:white">return</span><span style="font-size:9.5pt;font-family:Consolas;color:black;background:white"> 0;</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-autospace:none">
<span style="font-size:9.5pt;font-family:Consolas;color:black;background:white">}</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">-Andy<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
</div>
</div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
</div>
</div>
</div>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
</body>
</html>