<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Hi Jaromir,<br>
<br>
On 5/16/2021 5:26 PM, Jaromir Matas via Cuis-dev wrote:
<blockquote
cite="mid:BN7PR08MB38426B21A4020B8EDE322AC6EE2E9@BN7PR08MB3842.namprd08.prod.outlook.com"
type="cite">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="Generator" content="Microsoft Word 15 (filtered
medium)">
<style><!--
/* Font Definitions */
@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;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
pre
{mso-style-priority:99;
mso-style-link:"HTML Preformatted Char";
margin:0in;
margin-bottom:.0001pt;
font-size:10.0pt;
font-family:"Courier New";
color:black;}
span.HTMLPreformattedChar
{mso-style-name:"HTML Preformatted Char";
mso-style-priority:99;
mso-style-link:"HTML Preformatted";
font-family:"Courier New";
color:black;}
.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>
<div class="WordSection1">
<p class="MsoNormal">Hi Juan,</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I'm enclosing an updated changeset (please
disregard the previous one); I made a stupid assumption about
#runUntilErrorOrReturnFrom:. The new changeset leaves it
untouched and adds its replica called
#runUnwindUntilErrorOrReturnFrom: with the required
functionality.</p>
</div>
</blockquote>
<br>
I think you are right in the previous email, and we'd integrate your
latest change.I have already checked that none of the tests we
recently added breaks because of it. If you could turn some of the
arguments you provide into tests, it would be great.<br>
<br>
<blockquote
cite="mid:BN7PR08MB38426B21A4020B8EDE322AC6EE2E9@BN7PR08MB3842.namprd08.prod.outlook.com"
type="cite">
<div class="WordSection1">
<p class="MsoNormal">I'd like to point out a little issue with
the proposed semantics of nested errors during termination:
</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Below’s a simple example. If you abandon
the first debugger it means you want to terminate the
execution and unwind the terminated process but an error
happens during the unwind. You get another debugger reporting
the error and asking you what to do next - to debug the error
or proceed. But proceeding a termination really means to
proceed with the *<b>unwind business only</b>* and not to
proceed with the original computation. Here's my point:
Hitting Proceed will resume the original computation beyond
the unwind blocks but Abandon will only finish the unwind
procedure which is exactly what we want. In Squeak I simply
disabled the Proceed button but in Cuis I couldn't see such a
simple solution so I left it unresolved.</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">[self error: 'x1'] ensure: [</p>
<p class="MsoNormal"> [self error: 'x2'] ensure: [</p>
<p class="MsoNormal"> Transcript show: '2'].</p>
<p class="MsoNormal"> Transcript show: '1'].</p>
<p class="MsoNormal">Transcript show: '0'</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">---> you want to see '21' but proceeding
the debugger will give you '210' where '0' is printed outside
of unwind blocks.</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">So just that you know there's still a
little inconsistency in the termination semantics.</p>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</blockquote>
<br>
I see. The issue is how to disable a button so it doesn't act? The
simplest way is by saying `aButton lock: true`. We could add #enable
and #disable to PluggableButtonMorph (calling self lock: ). Or
perhaps call it #isEnabled: like in MenuItemMorph, although it is an
ugly name. Can you prepare a change set like this? That would be
great. I mean, I don't know where those calls should be made!<br>
<br>
<blockquote
cite="mid:BN7PR08MB38426B21A4020B8EDE322AC6EE2E9@BN7PR08MB3842.namprd08.prod.outlook.com"
type="cite">
<div class="WordSection1">
<p class="MsoNormal">One more question: do you have an idea why
BlockCannotReturn error is considered resumable? I'd say it's
unresumable by definition…? Thanks :)</p>
</div>
</blockquote>
<br>
Well, that method is pretty old, and in the mean time, exception
handling has gotten a lot better, thanks to several batches of
improvements, latter ones by you. So, please provide a patch to
change that, so it properly carries your initials.<br>
<br>
<blockquote
cite="mid:BN7PR08MB38426B21A4020B8EDE322AC6EE2E9@BN7PR08MB3842.namprd08.prod.outlook.com"
type="cite">
<div class="WordSection1">
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">best regards,</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Jaromir</p>
</div>
</blockquote>
<br>
Thanks again Jaromir for this amazing work.<br>
<br>
Cheers,<br>
<br>
<blockquote
cite="mid:BN7PR08MB38426B21A4020B8EDE322AC6EE2E9@BN7PR08MB3842.namprd08.prod.outlook.com"
type="cite">
<div class="WordSection1">
<p class="MsoNormal"><o:p> </o:p></p>
<div style="border-right: medium none; border-width: 1pt medium
medium; border-style: solid none none; border-color: rgb(225,
225, 225) -moz-use-text-color -moz-use-text-color; padding:
3pt 0in 0in;">
<p class="MsoNormal" style="border: medium none; padding:
0in;"><b>From: </b><a moz-do-not-send="true"
href="mailto:cuis-dev@lists.cuis.st">Jaromir Matas via
Cuis-dev</a><br>
<b>Sent: </b>Wednesday, May 12, 2021 17:02<br>
<b>To: </b><a moz-do-not-send="true"
href="mailto:cuis-dev@lists.cuis.st">Discussion of Cuis
Smalltalk</a><br>
<b>Cc: </b><a moz-do-not-send="true"
href="mailto:mail@jaromir.net">Jaromir Matas</a>; <a
moz-do-not-send="true" href="mailto:juan@jvuletich.org">
Juan Vuletich</a>; <a moz-do-not-send="true"
href="mailto:hernan.wilkinson@10pines.com">Hernan
Wilkinson</a><br>
<b>Subject: </b>Re: [Cuis-dev] Unwind mechanism during
termination is broken and inconsistent</p>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Hi Juan,<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I apologize for responding so late to your
great comments. I felt I had to educate myself in error
handling first :)<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">> m1<o:p></o:p></p>
<p class="MsoNormal">> | a |<o:p></o:p></p>
<p class="MsoNormal">> a := Array new: 3.<o:p></o:p></p>
<p class="MsoNormal">> self m2: a.<o:p></o:p></p>
<p class="MsoNormal">> a at: 3 put: true.<o:p></o:p></p>
<p class="MsoNormal">> a print.<o:p></o:p></p>
<p class="MsoNormal">><o:p> </o:p></p>
<p class="MsoNormal">> m2: a "A"<o:p></o:p></p>
<p class="MsoNormal">> [1 + 2] ensure: [<o:p></o:p></p>
<p class="MsoNormal">> [ 3 + 4 ] ensure: [ "*1"<o:p></o:p></p>
<p class="MsoNormal">> true ifTrue: [<o:p></o:p></p>
<p class="MsoNormal">> ^a at: 1 put: true ]]. "*2"<o:p></o:p></p>
<p class="MsoNormal">> a at: 2 put: true ]<o:p></o:p></p>
<p class="MsoNormal">><o:p> </o:p></p>
<p class="MsoNormal">> In this example, the *1ensure is
there only to guarantee that *2is ran, even if [3+4] happens
to fail. If [3+4] it runs without problems, the result should
be exactly the same as:<o:p></o:p></p>
<p class="MsoNormal">><o:p> </o:p></p>
<p class="MsoNormal">> m2: a "B"<o:p></o:p></p>
<p class="MsoNormal">> [1 + 2] ensure: [<o:p></o:p></p>
<p class="MsoNormal">> 3 + 4.<o:p></o:p></p>
<p class="MsoNormal">> true ifTrue: [<o:p></o:p></p>
<p class="MsoNormal">> ^a at: 1 put: true ].<o:p></o:p></p>
<p class="MsoNormal">> a at: 2 put: true ]<o:p></o:p></p>
<p class="MsoNormal">><o:p> </o:p></p>
<p class="MsoNormal">> Applying the same argument, the
result should be the same as:<o:p></o:p></p>
<p class="MsoNormal">><o:p> </o:p></p>
<p class="MsoNormal">> m2: a "C"<o:p></o:p></p>
<p class="MsoNormal">> 1 + 2.<o:p></o:p></p>
<p class="MsoNormal">> 3 + 4.<o:p></o:p></p>
<p class="MsoNormal">> true ifTrue: [<o:p></o:p></p>
<p class="MsoNormal">> ^a at: 1 put: true ].<o:p></o:p></p>
<p class="MsoNormal">> a at: 2 put: true<o:p></o:p></p>
<p class="MsoNormal">><o:p> </o:p></p>
<p class="MsoNormal">> In implementation C it is clear that
a second isNil. So, the same should be the case for B and A.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">This is a beautiful example! Thanks a lot,
very enlightening. I fully agree, my suggestion was incorrect.
The logic you are showing says to leave the block where the
non-local return executes without unwinding but to continue
unwinding after that block. Very interesting!<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">> x := nil.<o:p></o:p></p>
<p class="MsoNormal">> [self error: 'x1'] ensure: [<o:p></o:p></p>
<p class="MsoNormal">> [self error: 'x2'] ensure: [<o:p></o:p></p>
<p class="MsoNormal">> [self error: 'x3'] ensure: [<o:p></o:p></p>
<p class="MsoNormal">> x:=3].<o:p></o:p></p>
<p class="MsoNormal">> x:=2].<o:p></o:p></p>
<p class="MsoNormal">> x:=1].<o:p></o:p></p>
<p class="MsoNormal">> x<o:p></o:p></p>
<p class="MsoNormal">><o:p> </o:p></p>
<p class="MsoNormal">> I think this case is very similar to
the one above.. For example, if we proceed the first debugger
(the x1 error), the x2 debugger opens. If we abandon it, we
are abandoning the execution of the first ensured block (that
includes the x := 1 assignment at the end). So, no assignment
is done. I think that the behavior of our fix is correct in
this case. No need to simulate "resuming".<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">In this case I'd disagree. Abandoning is
currently implemented and interpreted as terminating so I
chose to follow this logic and made abandoning equivalent to
sending #terminate, meaning the unwind will continue and
execute the second error, open a second debugger etc. Please
try out the enclosed changeset; it also follows the non-local
logic you suggested above. We've also discussed the issue with
Christoph Thiede here:
<a class="moz-txt-link-freetext" href="http://forum.world.st/Solving-multiple-termination-bugs-summary-proposal-tp5128285p5129113.html">http://forum.world.st/Solving-multiple-termination-bugs-summary-proposal-tp5128285p5129113.html</a><o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">The main idea behind the extended version
of #terminate is using the return value from
#runUntilErrorOrReturnFrom: to continue the unwind based on
the exception found.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I've also fixed a few minor bug in the
current implementation:
<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">1) using suspendedContext variable during
unwind is an incorrect approach that may lead to leaving
unterminated context chains behind which the garbage collector
wouldn't recycle; I'm using a local temp 'top' instead.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">2) I removed the part looking for an
'inner' context halfway through execution - it's unnecessary
and theoretically even incorrect - and use outerMost as the
unwind context that needs to be completed.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">3) the condition in the middle (`ifNil:
[^self]`) became unnecessary after your fix.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">4) there was an issue with infinite
recursion in case of #cannotReturn and #doesNotUnderstand -
this has been fixed by explicitly excluding the two exceptions
from returning.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">5) #cannotReturn generally causes a VM
crash if it attempts to return - this is fixed by looping
#cannotReturn back to itself and the way out leads via
Abandoning the debugger window (even accidental pressing
Proceed crashes your image so I guess it's worth fixing in
every case)<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">6) #runUntilErrorOrReturnFrom: required a
slight modification - I suggest either modify it or we can
create a copy with this modified behavior; I chose to modify
it because no current method would be affected by the change.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">As another example illustrating the changes
you can try:<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> a := Array new: 4 withAll: false.<o:p></o:p></p>
<p class="MsoNormal"> p := [<o:p></o:p></p>
<p class="MsoNormal"> [<o:p></o:p></p>
<p class="MsoNormal"> [] ensure: [<o:p></o:p></p>
<p class="MsoNormal"> [ ^2 ] ensure: [<o:p></o:p></p>
<p class="MsoNormal">
a at: 1 put: true].<o:p></o:p></p>
<p class="MsoNormal"> a at: 2 put:
true]<o:p></o:p></p>
<p class="MsoNormal"> ] ensure: [a at:
3 put: true].<o:p></o:p></p>
<p class="MsoNormal"> a at: 4 put:
true<o:p></o:p></p>
<p class="MsoNormal"> ] newProcess.<o:p></o:p></p>
<p class="MsoNormal"> p resume.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">It crashes the image without amending
#cannotReturn but works well with the enclosed changeset and
returns
<o:p></o:p></p>
<p class="MsoNormal">correctly a equal to #(true false true
false).<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Also this example is catastrophic but dealt
with safely with the new changeset:<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> [^2] newProcess resume<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I haven't built any testcases yet but I
definitely plan to if you find this interesting.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Many thanks for discussing this issue; any
comments will be greatly appreciated :)<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">best,<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Jaromir<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div style="border-right: medium none; border-width: 1pt medium
medium; border-style: solid none none; border-color: rgb(225,
225, 225) -moz-use-text-color -moz-use-text-color; padding:
3pt 0in 0in;">
<p class="MsoNormal"><b>From: </b><a moz-do-not-send="true"
href="mailto:cuis-dev@lists.cuis.st">Juan Vuletich via
Cuis-dev</a><br>
<b>Sent: </b>Friday, April 30, 2021 19:32<br>
<b>To: </b><a moz-do-not-send="true"
href="mailto:cuis-dev@lists.cuis.st">Discussion of Cuis
Smalltalk</a><br>
<b>Cc: </b><a moz-do-not-send="true"
href="mailto:juan@jvuletich.org">Juan Vuletich</a>; <a
moz-do-not-send="true" href="mailto:mail@jaromir.net">
Jaromir Matas</a>; <a moz-do-not-send="true"
href="mailto:hernan.wilkinson@10pines.com">Hernan
Wilkinson</a><br>
<b>Subject: </b>Re: [Cuis-dev] Unwind mechanism during
termination is broken and inconsistent<o:p></o:p></p>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Hi Jaromir,<br>
<br>
(inline)<br>
On 4/30/2021 7:01 AM, Jaromir Matas via Cuis-dev wrote: <o:p></o:p></p>
<blockquote style="margin-top: 5pt; margin-bottom: 5pt;">
<p class="MsoNormal">Hi Juan,<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">Awesome! I remember the idea of using the
result of #runUntilErrorOrReturnFrom crossed my mind for a
fleeting moment… and then I lost it ;) With your permission
I’d like to use your fix in my Squeak version as well.<o:p></o:p></p>
</blockquote>
<p class="MsoNormal" style="margin-bottom: 12pt;"><span
style="color: black;"> <br>
I'm glad you like it. Yes, of course. In these low level
details, it is a good thing to have as much common code as
possible!<br>
<br>
Besides, in general, all the code we publish for Cuis is MIT
license, and free for any use.<br>
<br>
<o:p></o:p></span></p>
<blockquote style="margin-top: 5pt; margin-bottom: 5pt;">
<p class="MsoNormal">I’ve tried to rewrite your #<span
style="color: black;">test1ATerminate
</span>without the method calls – and indeed it passes… and
that’s why I missed that – it was too simple; when using
sends is where your fix comes to the rescue – THANKS!<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal"> | p a |<o:p></o:p></p>
<p class="MsoNormal"> a := Array new: 4 withAll: false.<o:p></o:p></p>
<p class="MsoNormal"> p := [<o:p></o:p></p>
<p class="MsoNormal"> [<o:p></o:p></p>
<p class="MsoNormal"> [ ] ensure:
[<o:p></o:p></p>
<p class="MsoNormal">
[Processor activeProcess
suspend] ensure: [<o:p></o:p></p>
<p class="MsoNormal">
^a at: 1 put:
true]. "line L1"<o:p></o:p></p>
<p class="MsoNormal">
a at: 2 put:
true] "line L2"<o:p></o:p></p>
<p class="MsoNormal"> ] ensure:
[a at: 3 put: true].<o:p></o:p></p>
<p class="MsoNormal"> a at: 4
put: true<o:p></o:p></p>
<p class="MsoNormal"> ] newProcess.<o:p></o:p></p>
<p class="MsoNormal"> p resume.<o:p></o:p></p>
<p class="MsoNormal"> Processor yield.<o:p></o:p></p>
<p class="MsoNormal"> "make sure p is suspended and none of
the unwind blocks has finished yet"<o:p></o:p></p>
<p class="MsoNormal"> self assert: p isSuspended.<o:p></o:p></p>
<p class="MsoNormal"> a noneSatisfy: [ :b | b ].<o:p></o:p></p>
<p class="MsoNormal"> "now terminate the process and make
sure all unwind blocks have finished"<o:p></o:p></p>
<p class="MsoNormal"> p terminate.<o:p></o:p></p>
<p class="MsoNormal"> self assert: p isTerminated.<o:p></o:p></p>
<p class="MsoNormal"> self assert: a first & a third.<o:p></o:p></p>
<p class="MsoNormal"> self assert: (a second | a fourth)
not.<o:p></o:p></p>
</blockquote>
<p class="MsoNormal" style="margin-bottom: 12pt;"><span
style="color: black;"><br>
Yes it does. I just thought that a more real-life like test
of non local returns should also include actual method
calls!<o:p></o:p></span></p>
<blockquote style="margin-top: 5pt; margin-bottom: 5pt;">
<p class="MsoNormal">I’d like to raise a question here: I feel
the second item, on line L2 should ideally execute too
because it’s inside an unwind block halfway through it’s
termination. The problem is though the non-local return at
line L1 invokes it’s own unwind algorithm in
#resume:through: which ignores halfway through unwind blocks
– the reason for that is #resume:through: operates on the
active process’s stack which makes it extremely difficult to
unwind halfway through blocks. I tried to apply a similar
tactics like in termination (control the unwind from another
stack) and it works well but it’s very intrusive… I may open
a separate discussion on that later to share the results. Do
you think it may be worth exploring or it’s just not worth
the bother?<o:p></o:p></p>
</blockquote>
<p class="MsoNormal" style="margin-bottom: 12pt;"><span
style="color: black;"> <br>
Well. This is not just in the case of process #terminate,
right? To play with this without involving process handling,
but including actual method calls I just tried this:<br>
<br>
m1<br>
| a |<br>
a := Array new: 3.<br>
self m2: a.<br>
a at: 3 put: true.<br>
a print.<br>
<br>
m2: a "A"<br>
[1 + 2] ensure: [<br>
[ 3 + 4 ] ensure: [ "*1"<br>
true ifTrue: [<br>
^a at: 1 put: true ]]. "*2"<br>
a at: 2 put: true ]<br>
<br>
In this example, the *1ensure is there only to guarantee
that *2is ran, even if [3+4] happens to fail. If [3+4] it
runs without problems, the result should be exactly the same
as:<br>
<br>
m2: a "B"<br>
[1 + 2] ensure: [<br>
3 + 4.<br>
true ifTrue: [<br>
^a at: 1 put: true ].<br>
a at: 2 put: true ]<br>
<br>
Applying the same argument, the result should be the same
as:<br>
<br>
m2: a "C"<br>
1 + 2.<br>
3 + 4.<br>
true ifTrue: [<br>
^a at: 1 put: true ].<br>
a at: 2 put: true<br>
<br>
In implementation C it is clear that a second isNil. So, the
same should be the case for B and A.<br>
<br>
I think that an ensured block should be guaranteed to run
without external interference. But if it decides on its own
to exit before running all its statements, it is it's own
decision.<br>
<br>
<o:p></o:p></span></p>
<blockquote style="margin-top: 5pt; margin-bottom: 5pt;">
<p class="MsoNormal">Another issue: I considered using the
error part of the result of #runUntilErrorOrReturnFrom: to
deal with situations like this (careful – crashes the Cuis
image without the terminate fix; with the fix it works
“ok”):<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">x := nil.<o:p></o:p></p>
<p class="MsoNormal">[self error: 'x1'] ensure: [<o:p></o:p></p>
<p class="MsoNormal"> [self error: 'x2'] ensure: [<o:p></o:p></p>
<p class="MsoNormal"> [self error: 'x3'] ensure: [<o:p></o:p></p>
<p class="MsoNormal"> x:=3].<o:p></o:p></p>
<p class="MsoNormal"> x:=2].<o:p></o:p></p>
<p class="MsoNormal"> x:=1].<o:p></o:p></p>
<p class="MsoNormal">x<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">Here you have nested errors and the
question is: If we abandon the Debugger window, what do we
want to see as a result? Without the fix the image crashes
badly with unwind errors, with the fix however the Debugger
closes without unwinding – it’s a consequence of #
runUntilErrorOrReturnFrom: behavior – it returns errors
rather than opens a debugger (and leaves the decision with
the user). So what do we want to see as a result – keep
opening debugger windows and abandoning them manually or
ignoring the errors and executing the assignments? That
sounds like “resuming” rather than abandoning to me so at
the moment I don’t know and will have to think about it. I
just didn’t want to complicate the #terminate prematurely :)<o:p></o:p></p>
</blockquote>
<p class="MsoNormal" style="margin-bottom: 12pt;"><span
style="color: black;"> <br>
I think this case is very similar to the one above.. For
example, if we proceed the first debugger (the x1 error),
the x2 debugger opens. If we abandon it, we are abandoning
the execution of the first ensured block (that includes the
x := 1 assignment at the end). So, no assignment is done. I
think that the behavior of our fix is correct in this case.
No need to simulate "resuming".<br>
<br>
<o:p></o:p></span></p>
<blockquote style="margin-top: 5pt; margin-bottom: 5pt;">
<p class="MsoNormal">Juan, many thanks again, I’ll study your
tests and learn from them.<o:p></o:p></p>
</blockquote>
<p class="MsoNormal" style="margin-bottom: 12pt;"><span
style="color: black;"><br>
I'm happy to be of help. There's not nothing in those tests
that could be new to you. All I did was to add nested method
calls, and add the #resume cases, that already did work with
the fix. Let me thank you. You did a great analysis of the
issues at hand, and your fix is a great contribution.<br>
<br>
I'll integrate it right now. If any further analysis
provides additional changes, we'll integrate them too.<br>
<o:p></o:p></span></p>
<blockquote style="margin-top: 5pt; margin-bottom: 5pt;">
<p class="MsoNormal">Best regards,<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">jaromir<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
</blockquote>
<p class="MsoNormal" style="margin-bottom: 12pt;"><span
style="color: black;"><br>
Cheers,<o:p></o:p></span></p>
<pre>-- </pre>
<pre>Juan Vuletich</pre>
<pre><a moz-do-not-send="true" href="http://www.cuis-smalltalk.org">www.cuis-smalltalk.org</a></pre>
<pre><a moz-do-not-send="true" href="https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev">https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev</a></pre>
<pre><a moz-do-not-send="true" href="https://github.com/jvuletich">https://github.com/jvuletich</a></pre>
<pre><a moz-do-not-send="true" href="https://www.linkedin.com/in/juan-vuletich-75611b3">https://www.linkedin.com/in/juan-vuletich-75611b3</a></pre>
<pre>@JuanVuletich</pre>
<p class="MsoNormal"><span style="font-size: 10pt; font-family:
"Courier New"; color: black;"><o:p> </o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</blockquote>
<br>
<br>
<pre class="moz-signature" cols="72">--
Juan Vuletich
<a class="moz-txt-link-abbreviated" href="http://www.cuis-smalltalk.org">www.cuis-smalltalk.org</a>
<a class="moz-txt-link-freetext" href="https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev">https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev</a>
<a class="moz-txt-link-freetext" href="https://github.com/jvuletich">https://github.com/jvuletich</a>
<a class="moz-txt-link-freetext" href="https://www.linkedin.com/in/juan-vuletich-75611b3">https://www.linkedin.com/in/juan-vuletich-75611b3</a>
@JuanVuletich</pre>
</body>
</html>