[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