<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} --></style>
</head>
<body dir="ltr">
<div id="divtagdefaultwrapper" style="font-size:12pt;color:#000000;font-family:Calibri,Helvetica,sans-serif;" dir="ltr">
<p><span style="font-size: 12pt;">Hi Jaromir,</span><br>
</p>
<div dir="ltr">
<div id="x_divtagdefaultwrapper" dir="ltr" style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;">
<p><br>
</p>
<p>first of all, please let me clarify one thing:</p>
<p><br>
</p>
<p>BlockCannotReturn is an Error, of course, and thus under normal circumstances should never be resumed. Just like it would usually be an anti-pattern to resume from a subscript error, KeyNotFound error, or anything else. Not for nothing, Error implements
 #isResumeable with false so that sending #resume[:] to an error will usually raise an IllegalResumeAttempt.</p>
<p>Nevertheless, our debugger supports enforcing the resumption of an exception using Proceed, even if the exception is not marked as resumable. So this should only be used for debugging scenarios, but still, I think that we could - and maybe also should - make
 it as convenient as possible to perform this non-recommended operation if you are debugging some unusual scenarios. This is mainly helpful to manipulate the behavior of a program during runtime (similar to the "return entered value" in the stack list menu
 of the debugger).</p>
<p><br>
</p>
<p>> <span style="font-size:12pt">Resuming BlockCannotReturn sounds crazy to me by definition and you're </span><span style="font-size:12pt">right: it's set as resumable, I haven't noticed. I'd set it non-resumable. </span><span style="font-size:12pt">If a
 block cannot return, why should we be tempted to do that? :)</span></p>
<p><br>
</p>
<p></p>
<div>I don't know whether there was a special reason to mark it as resumable, but if there wasn't one, I totally agree with you on this point! Just talkin' about the conscious decision of the debugging person to ignore the non-resumability of this exception
 and resume it anyway, just like you can do it for any other normal error. :-)</div>
<p></p>
<p><br>
</p>
<p></p>
<div>> >     `a := [true ifTrue: [^ 1]. 2].`</div>
<div>> >     "Both statements need to be executed separately in a Workspace so that <span style="font-size:12pt">[a outerContext sender] becomes nil!"</span></div>
<div>> >     `a value.`</div>
<div>> > In this situation, it is valid to resume from BlockCannotReturn and <span style="font-size:12pt">currently also possible in the Trunk. Note that BlockCannotReturn even </span><span style="font-size:12pt">overrides #isResumable to answer true, though
 the class comment </span><span style="font-size:12pt">discrecommends resuming it.</span></div>
<div>> </div>
<div>> My interpretation of this example is the home sender of  ^1 is gone once the <span style="font-size:12pt">first do-it ends. So the second do-it correctly, in my opinion, invokes the </span><span style="font-size:12pt">cannot return error. Current Trunk
 returning 2 seems  wildly incorrect to me.</span></div>
<div><br>
</div>
<div>Again, just for clarification: The example does raise a BlockCannotReturn in the second expression in the current Trunk as it should do. :-) Maybe my explanation was not precise enough here. I was only referring to the unusual edge case in which you attempt
 to proceed the process from this BlockCannotReturn error. In the Trunk, the expression will return 2 in this case. With your example, you won't be able to escape from the situation without pressing Abandon.</div>
<div><br>
</div>
<div>> <span style="font-size:12pt">[</span>
<div>>         [</div>
<div>>                 [ ] ensure: [</div>
<div>>                         [] ensure: [</div>
<div>>                                 ^Transcript show: 'x1'].</div>
<div>>                         Transcript show: 'x2']</div>
<div>>         ] ensure: [</div>
<div>>                 Transcript show: 'x3'].</div>
<div>>         Transcript show: 'x4'</div>
<div>> ] fork</div>
<div>> </div>
<div>> In this case the expected outcome is ---> x1 x3. Neither x2 nor x4 should be <span style="font-size:12pt">printed (x2 is intentionally skipped by the non-local return and x4 is </span><span style="font-size:12pt">outside the ensure blocks). With the
 fix you propose the outcome is either </span><span style="font-size:12pt">---> x1 x2 x3 if pressed Abandon or ---> x1 x2 x3 x4 if pressed Proceed - </span><span style="font-size:12pt">this would be equivalent to no non-local return at all :)</span></div>
<div><br>
</div>
<div>Wait, wait, wait. This smells to me. <span>:-)</span> #cannotReturn: should not be *resumed* after the error was abandoned. Otherwise, something is wrong with the termination logic. Process >> #terminate *must not* resume in this place.
<span>Terminating means only executing all uncompleted unwind contexts. </span>I just reverted to the version <span>ct 1/17/2021 18:35 of Process >> #terminate and with regard to your example, both implementations of #cannotReturn: behave the save (---> x1 x3)
 as expected. Hm, I'm sorry, but Process >> #terminate is not yet done correctly IMHO. I'll send you another message concerning this method soon, but I'm checking many things while drafting the message, so please have some more patience. :-)</span></div>
<div><br>
</div>
<div>> <span>Thanks for discussing this!</span></div>
<div><span><br>
</span></div>
<div><span>Thank *you* for whipping the "machine room" of Squeak into shape again and bringing up all these interesting questions along the way! :-)</span></div>
<div><span><br>
</span></div>
<div><span>Best,</span></div>
<div><span>Christoph</span></div>
<div><br>
</div>
</div>
<p></p>
<div id="x_Signature">
<div id="x_divtagdefaultwrapper" dir="ltr" style="font-size:12pt; color:rgb(0,0,0); font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple Color Emoji","Segoe UI Emoji",NotoColorEmoji,"Segoe UI Symbol","Android Emoji",EmojiSymbols">
<div name="x_divtagdefaultwrapper" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:; margin:0">
<div><font size="2" color="#808080"></font></div>
</div>
</div>
</div>
</div>
<hr tabindex="-1" style="display:inline-block; width:98%">
<div id="x_divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>Von:</b> Squeak-dev <squeak-dev-bounces@lists.squeakfoundation.org> im Auftrag von Jaromir Matas <m@jaromir.net><br>
<b>Gesendet:</b> Samstag, 15. Mai 2021 23:20:54<br>
<b>An:</b> squeak-dev@lists.squeakfoundation.org<br>
<b>Betreff:</b> Re: [squeak-dev] The Inbox: Kernel-ct.1405.mcz</font>
<div> </div>
</div>
</div>
<font size="2"><span style="font-size:10pt">
<div class="PlainText">Hi Christoph,<br>
<br>
> Counterproposal to Kernel-jar.1404 for fixing VM crashes when resuming<br>
> from a BlockCannotReturn. Instead of enforcing retrial, repair the context<br>
> stack if the receiver has ended.<br>
<br>
I was considering the idea whether it could make sense to "fix" the stack<br>
but dumped it eventually because it would completely change the semantics of<br>
non-local returns. In my opinion once the home context sender is not<br>
available it means it's gone irreparably. There are two situation to<br>
consider: double return to the same context within one stack (e.g. the<br>
return context is gone or it may even still exist but its pc has moved) or<br>
the home sender is on a different context stack - in case of forks etc.<br>
Non-local returns between forks could in theory work but not in the current<br>
environment; Squeak strictly requires the home context sender to be on the<br>
same stack. <br>
<br>
<br>
<br>
> Not in all situations, the receiver of #cannotReturn: is actually unable<br>
> to resume. Consider this example for a disproof:<br>
>     `a := [true ifTrue: [^ 1]. 2].`<br>
>     "Both statements need to be executed separately in a Workspace so that<br>
> [a outerContext sender] becomes nil!"<br>
>     `a value.`<br>
> In this situation, it is valid to resume from BlockCannotReturn and<br>
> currently also possible in the Trunk. Note that BlockCannotReturn even<br>
> overrides #isResumable to answer true, though the class comment<br>
> discrecommends resuming it.<br>
<br>
My interpretation of this example is the home sender of  ^1 is gone once the<br>
first do-it ends. So the second do-it correctly, in my opinion, invokes the<br>
cannot return error. Current Trunk returning 2 seems wildly incorrect to me.<br>
<br>
Resuming BlockCannotReturn sounds crazy to me by definition and you're<br>
right: it's set as resumable, I haven't noticed. I'd set it non-resumable.<br>
If a block cannot return, why should we be tempted to do that? :)<br>
<br>
<br>
<br>
> Nevertheless, this raises another question - what would you expect from<br>
> this<br>
> example to return?<br>
><br>
> `a := [true ifTrue: [^ 1] yourself].`<br>
> "Both statements need to be executed separately in a Workspace so that [a<br>
> outerContext sender] becomes nil!"<br>
> `[a value] on: BlockCannotReturn do: [:ex | ex resume].`<br>
><br>
> Should it be 1 or nil? In the Trunk, is it nil, if we override<br>
> \#defaultResumeValue as below, it will be 1.<br>
<br>
This is a mean example... My fix ended in an infinite loop :)  I tried to<br>
fix it but the only clean solution that occurred to me is to set<br>
BlockCannotReturn as non-resumable.<br>
<br>
But again, my interpretation here is any attempt to "repair" the context<br>
that cannot return means a substantial change of the non-local return<br>
semantics. It means I'd return nil because the meaning of the error is: I<br>
cannot return 1 to my home sender. Here's one of my examples I'm planning to<br>
send as test cases to the Inbox soon:<br>
<br>
[<br>
        [<br>
                [ ] ensure: [<br>
                        [] ensure: [<br>
                                ^Transcript show: 'x1']. <br>
                        Transcript show: 'x2']<br>
        ] ensure: [<br>
                Transcript show: 'x3'].<br>
        Transcript show: 'x4'<br>
] fork<br>
<br>
In this case the expected outcome is ---> x1 x3. Neither x2 nor x4 should be<br>
printed (x2 is intentionally skipped by the non-local return and x4 is<br>
outside the ensure blocks). With the fix you propose the outcome is either<br>
---> x1 x2 x3 if pressed Abandon or ---> x1 x2 x3 x4 if pressed Proceed -<br>
this would be equivalent to no non-local return at all :)<br>
<br>
I hope I'll be able to put the tests together and publish in a few days.<br>
<br>
Juan Vuletich showed me a beautiful example about the non-local return<br>
semantics - take a look in [1] in the middle of the post.<br>
<br>
Thanks for discussing this!<br>
<br>
best,<br>
<br>
[1] [[Cuis-dev\] Unwind mechanism during termination is broken and<br>
inconsistent](<a href="https://lists.cuis.st/mailman/archives/cuis-dev/2021-April/003055.html" id="LPlnk378869" previewremoved="true">https://lists.cuis.st/mailman/archives/cuis-dev/2021-April/003055.html</a>)<br>
<br>
<br>
<br>
<br>
<br>
-----<br>
^[^ Jaromir<br>
--<br>
Sent from: <a href="http://forum.world.st/Squeak-Dev-f45488.html" id="LPlnk513433" previewremoved="true">
http://forum.world.st/Squeak-Dev-f45488.html</a>
<div id="LPBorder_GT_16212607392050.9027596455890294" style="margin-bottom: 20px; overflow: auto; width: 100%; text-indent: 0px;">
<table id="LPContainer_16212607392030.7141641775940035" role="presentation" cellspacing="0" style="width: 90%; background-color: rgb(255, 255, 255); position: relative; overflow: auto; padding-top: 20px; padding-bottom: 20px; margin-top: 20px; border-top: 1px dotted rgb(200, 200, 200); border-bottom: 1px dotted rgb(200, 200, 200);">
<tbody>
<tr valign="top" style="border-spacing: 0px;">
<td id="TextCell_16212607392040.6126231744272133" colspan="2" style="vertical-align: top; position: relative; padding: 0px; display: table-cell;">
<div id="LPRemovePreviewContainer_16212607392040.10102334053060757"></div>
<div id="LPTitle_16212607392040.26526996813581305" style="top: 0px; color: rgb(36, 96, 118); font-weight: 400; font-size: 21px; font-family: wf_segoe-ui_light, "Segoe UI Light", "Segoe WP Light", "Segoe UI", "Segoe WP", Tahoma, Arial, sans-serif; line-height: 21px;">
<a id="LPUrlAnchor_16212607392040.7507520439202566" href="http://forum.world.st/Squeak-Dev-f45488.html" target="_blank" style="text-decoration: none;">Smalltalk - Squeak - Dev | Mailing List Archive</a></div>
<div id="LPMetadata_16212607392040.9643971273818119" style="margin: 10px 0px 16px; color: rgb(102, 102, 102); font-weight: 400; font-family: wf_segoe-ui_normal, "Segoe UI", "Segoe WP", Tahoma, Arial, sans-serif; font-size: 14px; line-height: 14px;">
forum.world.st</div>
<div id="LPDescription_16212607392050.7132282854395948" style="display: block; color: rgb(102, 102, 102); font-weight: 400; font-family: wf_segoe-ui_normal, "Segoe UI", "Segoe WP", Tahoma, Arial, sans-serif; font-size: 14px; line-height: 20px; max-height: 100px; overflow: hidden;">
Squeak - Dev forum and mailing list archive. The general-purpose Squeak developers list</div>
</td>
</tr>
</tbody>
</table>
</div>
<br>
<br>
<br>
</div>
</span></font></div>
</body>
</html>