[squeak-dev] The Inbox: Kernel-ct.1405.mcz

Eliot Miranda eliot.miranda at gmail.com
Thu Nov 18 18:01:52 UTC 2021



> On May 15, 2021, at 2:20 PM, Jaromir Matas <m at jaromir.net> wrote:
> 
> Hi Christoph,
> 
>> Counterproposal to Kernel-jar.1404 for fixing VM crashes when resuming
>> from a BlockCannotReturn. Instead of enforcing retrial, repair the context
>> stack if the receiver has ended.
> 
> I was considering the idea whether it could make sense to "fix" the stack
> but dumped it eventually because it would completely change the semantics of
> non-local returns. In my opinion once the home context sender is not
> available it means it's gone irreparably. There are two situation to
> consider: double return to the same context within one stack (e.g. the
> return context is gone or it may even still exist but its pc has moved) or
> the home sender is on a different context stack - in case of forks etc.
> Non-local returns between forks could in theory work but not in the current
> environment; Squeak strictly requires the home context sender to be on the
> same stack. 

+1

>> Not in all situations, the receiver of #cannotReturn: is actually unable
>> to resume. Consider this example for a disproof:
>>    `a := [true ifTrue: [^ 1]. 2].`
>>    "Both statements need to be executed separately in a Workspace so that
>> [a outerContext sender] becomes nil!"
>>    `a value.`
>> In this situation, it is valid to resume from BlockCannotReturn and
>> currently also possible in the Trunk. Note that BlockCannotReturn even
>> overrides #isResumable to answer true, though the class comment
>> discrecommends resuming it.
> 
> My interpretation of this example is the home sender of  ^1 is gone once the
> first do-it ends. So the second do-it correctly, in my opinion, invokes the
> cannot return error. Current Trunk returning 2 seems wildly incorrect to me.

+1000

> Resuming BlockCannotReturn sounds crazy to me by definition and you're
> right: it's set as resumable, I haven't noticed. I'd set it non-resumable.
> If a block cannot return, why should we be tempted to do that? :)

Resumability *is not the same* as continuability.  If I want to catch BlockCannotReturn, perform surgery to make continuing possible, I shouldn’t be prevented by the damn exception being non-resumable.  In general I find non-resumabity being hard-coded and not controllable by an inst var & accessor no Exception to be a RRPITA (a right royal pain in the ass).

So I agree that BlockCannotReturn should be non-resumable by default.  But I wish any and all exceptions could be made resumable via an accessor.

>> Nevertheless, this raises another question - what would you expect from
>> this
>> example to return?
>> 
>> `a := [true ifTrue: [^ 1] yourself].`
>> "Both statements need to be executed separately in a Workspace so that [a
>> outerContext sender] becomes nil!"
>> `[a value] on: BlockCannotReturn do: [:ex | ex resume].`
>> 
>> Should it be 1 or nil? In the Trunk, is it nil, if we override
>> \#defaultResumeValue as below, it will be 1.
> 
> This is a mean example... My fix ended in an infinite loop :)

Because that’s what it is.

>  I tried to
> fix it but the only clean solution that occurred to me is to set
> BlockCannotReturn as non-resumable.

+1.

> 
> But again, my interpretation here is any attempt to "repair" the context
> that cannot return means a substantial change of the non-local return
> semantics. It means I'd return nil because the meaning of the error is: I
> cannot return 1 to my home sender. Here's one of my examples I'm planning to
> send as test cases to the Inbox soon:
> 
> [
>    [
>        [ ] ensure: [
>            [] ensure: [
>                ^Transcript show: 'x1']. 
>            Transcript show: 'x2']
>    ] ensure: [
>        Transcript show: 'x3'].
>    Transcript show: 'x4'
> ] fork
> 
> In this case the expected outcome is ---> x1 x3. Neither x2 nor x4 should be
> printed (x2 is intentionally skipped by the non-local return and x4 is
> outside the ensure blocks). With the fix you propose the outcome is either
> ---> x1 x2 x3 if pressed Abandon or ---> x1 x2 x3 x4 if pressed Proceed -
> this would be equivalent to no non-local return at all :)

+1

> 
> I hope I'll be able to put the tests together and publish in a few days.
> 
> Juan Vuletich showed me a beautiful example about the non-local return
> semantics - take a look in [1] in the middle of the post.
> 
> Thanks for discussing this!
> 
> best,
> 
> [1] [[Cuis-dev\] Unwind mechanism during termination is broken and
> inconsistent](https://lists.cuis.st/mailman/archives/cuis-dev/2021-April/003055.html)
> 
> 
> -----
> ^[^ Jaromir
> --
> Sent from: http://forum.world.st/Squeak-Dev-f45488.html
> 


More information about the Squeak-dev mailing list