[Cuis-dev] Changes to unwind logic and termination
Jaromir Matas
mail at jaromir.net
Thu Nov 20 00:33:59 PST 2025
Hi Juan,
I've patched the previous test to avoid the VM crash. Indeed the problem
was it forced the VM resume "inside" a quick return. Unlike Squeak, you
allowed the Debugger to step into quick returns. What still confuses me
is when you debug
`true not`
then step into #not and explore thisContext: what's the meaning of the
pc counter relative to the method? It doesn't point to an existing
bytecode (there's none actually) - is it ok? Why 25? It's confusing...
Anyway, the test now passes. If you remove the line:
`ctx tempAt: 2 put: #unwindComplete`
from #unwindAndResume:evaluating:, the test will fail because of the
suspension point on the backward branch of the #whileFalse loop,
demonstrating the reason for adding the additional #ensure:
completionStatus variable value.
Best regards,
Jaromir
On Nov 19 2025, at 8:19 pm, Jaromir Matas via Cuis-dev
<cuis-dev at lists.cuis.st> wrote:
> Hi Juan,
>
> I wanted to add an interesting test by Christoph testing that
> termination works correctly at each step of the computation. This was
> the test that discovered some treacherous suspension points in the
> unwind mechanism and the motivation for adding the third value to the
> #ensure: complete temp var.
>
> However, while it works flawlessly in Squeak, it crashes the VM in Cuis
> immediately. Both for the new VM you've just uploaded as well as for the
> previous one. And also regardless whether the latest unwind update
> you've just integrated is applied.
>
> Please see for yourself: Using the latest image (new VM, updated unwind)
> the crash happens at step 526. I'm enclosing the test with a halt at
> this step for you to explore the process suspendeContext: you see the
> problem happens when terminating inside `true not` evaluation which is a
> quick return. I'm not familiar with how quick return is supposed to work
> precisely here but it looks suspicious to me the Debugger shows pc = 25
> but the method code has no such instruction. In Squeak this doesn't seem
> to be a problem but I'm still not sure where exactly the problem is.
> Maybe, but I'm speculating here wildly, it has something to do with the
> fact that the quick return may not be a VM resumption point and in real
> time (not simulation) the computation would never be stopped (preempted)
> at this particular point, i.e. "inside a quick return", and hence the VM
> crashes when forced to resume in such an undefined point.
>
> Question: does the quick return evaluate in a separate frame (context)
> or is it inlined or executed similarly like a primitive?
>
> In an older image the problem happens at a different step but always
> when inside True>>#not.
>
> I'm hoping you might spot a problem right away being familiar with quick
> returns :)
>
> Best,
> Jaromir
>
> On Nov 19 2025, at 1:18 pm, Juan Vuletich via Cuis-dev
> <cuis-dev at lists.cuis.st> wrote:
>
>> Hi Jaromir,
>>
>> On 2025-11-19 6:15 AM, Jaromir Matas via Cuis-dev wrote:
>>
>>> Hi Juan,
>>>
>>> On Nov 18 2025, at 10:33 pm, Juan Vuletich via Cuis-dev
>>> <cuis-dev at lists.cuis.st> wrote:
>>>
>>>
>>>
>>>> Hi Jaromir,
>>>>
>>>> Apologies for the delayed answer. We were midst the FAST Smalltalks
>>>>
>>>> conference in Argentina and a wonderful course on VM internals by
>>>> Eliot
>>>>
>>> What a treat! I just regret Buenos Aires is so far away from Prague :)
>>>
>> Well, we need to find out how to make it possible for you to join us
>> next year! You'd have a great time. I promise. BTW do you usually
>> attend ESUG conference? Maybe we can meet there next year too.
>>
>>
>>
>>
>>> I know Eliot had a presentation at Smalltalks 2025; any chance the
>>> presentation was recorded?
>> Yes. There were several other really good presentations, and all of
>> them were recorded. They will be published on YouTube, like those of
>> rpevious years.
>>
>>
>>
>>
>>>
>>>
>>>> and I didn't have any brains left for anything else for a while.
>>>>
>>>> I just reviewed your changes. These are welcome and important enhancements.
>>>>
>>>> Thank you for keeping us updated and sinc'ed with Squeak! This is
>>>> most
>>>> valuable!
>>>>
>>>>
>>> All pleasure's mine; Cuis is an invaluable source of feedback and
>>> inspiration. Thank you!
>>>
>>>
>>>
>>>> When I loaded your changes, I found that in #unwindTo:safely: the
>>>> old
>>>> version had a guard against (ctx tempAt: 1) being nil. Your new code
>>>>
>>>> doesn't include that guard, and #testTerminateWithNiledUnwindBlock
>>>> will
>>>> fail. You can also see this with your 'Workspace example' included
>>>> at
>>>> that test:
>>>>
>>>> Workspace example:
>>>> p := [[Processor activeProcess suspend] ensure: nil] newProcess.
>>>> p resume.
>>>> [p terminate] fork
>>>>
>>>> I found that adding a simple #ifNotNil: appears to solve the issue.
>>>>
>>>>
>>> I originally added the nil check and the test but we have discussed this
>>> issue with Christoph Thiede recently and decided to remove the check.
>>> There's no point to guard against nil in place of an unwind block as
>>> it's apparently just a user error and should show up. Only a block
>>> should be allowed as an unwind block. Potentially, the nil check could
>>> even obscure a user's error and make debugging harder (perhaps). This
>>> way the user should be able more quickly identify the error in the Debugger.
>>>
>>> On the other hand we have a slight inconsistency here: if you run
>>>
>>> [] ensure: nil
>>>
>>> nothing happens, because we have `Object >> #value` returning self :)
>>>
>>>
>>> So frankly, I don't have a strong opinion here. A guard is ok too or you
>>> could even use the nil check to raise an explicit error if you
>>> prefer.
>>>
>>> In such case one should probably add the same guard to
>>> #unwindAndResume:evaluating: too.
>> I think the analysis you did with Christoph makes total sense. It is
>> better this way. So, I just pushed your code.
>>
>>
>>> I'm surprised I forgot to add the test to Squeak :) So depending on your
>>> decision it might want to be moved to expected failures.
>> I just removed that test, and replaced it with a possibly redundant
>> #testTerminateWithEmptyUnwindBlock, just to document all this a bit.
>>
>>
>>>
>>> Thanks again and best regards,
>>> Jaromir
>>>
>> Thank you. Cheers!
>>
>> --
>> Juan Vuletich
>> www.cuis.st
>> github.com/jvuletich
>> researchgate.net/profile/Juan-Vuletich
>> independent.academia.edu/JuanVuletich
>> patents.justia.com/inventor/juan-manuel-vuletich
>> --
>>
>> Cuis-dev mailing list
>>
>> Cuis-dev at lists.cuis.st
>>
>> https://lists.cuis.st/mailman/listinfo/cuis-dev--
> Cuis-dev mailing list
> Cuis-dev at lists.cuis.st
> https://lists.cuis.st/mailman/listinfo/cuis-dev
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ProcessTest-testTerminateEverywhere_fix.st
Type: application/octet-stream
Size: 866 bytes
Desc: not available
URL: <http://lists.cuis.st/mailman/archives/cuis-dev/attachments/20251120/ce034508/attachment-0001.obj>
More information about the Cuis-dev
mailing list