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

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

Hi Christoph, Hi Jaromir, Hi All,

> On May 15, 2021, at 6:56 AM, commits at source.squeak.org wrote:
> A new version of Kernel was added to project The Inbox:
> http://source.squeak.org/inbox/Kernel-ct.1405.mcz
> ==================== Summary ====================
> Name: Kernel-ct.1405
> Author: ct
> Time: 15 May 2021, 3:56:24.713389 pm
> UUID: 9a92be9b-d778-b54f-b659-713451a2ddb2
> Ancestors: Kernel-nice.1402
> 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. There are two reasons for that:
> 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.
> 2. The pattern proposed by Jaromir reminds me of the current implementation of Object >> #doesNotUnderstand: or Object >> #at:, that is, when the error was resumed, just try it again in the manner of a (potentially) infinite recursion. While the issue with infinite debuggers (which was eventually tripped by exactly this pattern) has been solved some time ago [1], I do not really agree with the pattern in general - it makes it unnecessarily hard for ToolSet implementors to consciously resume from an error instead of retrying it (which we have an extra selector on Exception for).

But the pattern is a really useful one in a dynamic environment where one is doing edit and continue.  I don’t see any practical alternative, having lived for several years without it, and been frustrated at not being able to catch MessageNotUnderstood, do something (become the receiver, create a method, etc), and continue.

To solve the infinite recursion problem we could implement a wrapper around the 
    message sentTo: receiver
     [aMessage sentTo: receiver]
         on: MessageNotUnderstood
         do: [:ex| | args |
               args := ex message arguments.
               (ex receiver == self
               and: [ex message selector == aMessage selector
                and: [(1 to: aMessage size) allSatisfy: [:i| (args at: i) == (aMessage argumentAt: i)]]]) ifFalse:
               [ex pass].
            self error: ‘infinite recursion in doesNotUnderstand:’]

(& similarly in at: etc).

> [1] http://forum.world.st/Please-try-out-Fixes-for-debugger-invocation-during-code-simulation-td5127684.html
> =============== Diff against Kernel-nice.1402 ===============
> Item was added:
> + ----- Method: BlockCannotReturn>>defaultResumeValue (in category 'defaults') -----
> + defaultResumeValue
> + 
> +    ^ self result!
> Item was changed:
>  ----- Method: Context>>cannotReturn: (in category 'private-exceptions') -----
>  cannotReturn: result
> +    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].
> -    closureOrNil ifNotNil: [^ self cannotReturn: result to: self home sender].
>      Processor debugWithTitle: 'Computation has been terminated!!' translated full: false.!

More information about the Squeak-dev mailing list