On May 15, 2021, at 2:20 PM, Jaromir Matas m@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