[squeak-dev] The Inbox: Kernel-ct.1405.mcz
mail at jaromir.net
mail at jaromir.net
Sun Nov 21 17:57:57 UTC 2021
Hi again, Eliot,
Thanks a lot for your comments! I have a few questions below... thanks
On 2021-11-18T10:01:52-08:00, eliot.miranda at gmail.com wrote:
>
>
> > 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).
>
Yes, yes! this is what I was circling around but couldn't grasp: we do not want to "resume" from the BCR error but want to be able to "continue". Now I'd like to make sure I understand what you mean exactly:
A) The current #cannotReturn: allows you to continue (Proceed from BCR) and crash the VM if you do so:
closureOrNil ifNotNil: [^ self cannotReturn: result to: self home sender].
is this intentional or is it a bug (or just a lack of precautions)?
B) Initially I tried to "fix" the VM crash scenario by not allowing to continue:
closureOrNil ifNotNil: [self cannotReturn: result to: self home sender. thisContext privRefresh].
Is this what you're saying you DON'T want?
C) In this changeset Christoph proposed one *possible* path how to safely continue "after" a BCR error:
closureOrNil ifNotNil: [
| resumptionValue |
resumptionValue := self cannotReturn: result to: self home sender.
self pc > self endPC ifTrue: [
"This block has ended, continue with sender"
thisContext privSender: self sender].
^ resumptionValue].
Is that also what you say you DON'T want? Because that would be the type of obstacle you're referring to?
Forgive me if my questions sound silly. I lack your troubleshooting experience and came across examples like
[[self error: 'error'] ensure: [^2]] fork
when rewriting #terminate that I wanted to orderly terminate without crashes :)
Many thanks for your comments.
> 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
> >
>
>
Best regards,
Jaromir
More information about the Squeak-dev
mailing list
|