Marcel Taeumel uploaded a new version of Kernel to project The Treated Inbox: http://source.squeak.org/treated/Kernel-jar.1471.mcz
==================== Summary ====================
Name: Kernel-jar.1471 Author: jar Time: 30 May 2022, 5:49:42.34119 pm UUID: 506f7d06-a1a5-8b41-a85b-2fc8b6ae1aef Ancestors: Kernel-jar.1470
cleanup and add a check for nil value for borderline situations (ensure as a bottom context or two ensure context above each other)
=============== Diff against Kernel-jar.1470 ===============
Item was changed: ----- Method: Context>>unwindTo:safely: (in category 'private-exceptions') ----- unwindTo: aContext safely: aBoolean "Unwind self to aContext to execute pending #ensure:/#ifCurtailed: argument blocks between self and aContext. If aBoolean is false, unwind only blocks that have not run yet, otherwise complete all pending unwind blocks including those currently in the middle of their execution; these blocks will just finish their execution. Run all unwinds on their original stack using #runUntilReturnFrom:." | top ctx | ctx := top := self. aBoolean ifTrue: [ + "If self is the top context of a stack already halfways through an unwind block, complete the outer-most - "If self is a top context of a stack already halfways through an unwind, complete the outer-most unfinished unwind block first; all nested pending unwind blocks will be completed in the process; see testTerminationDuringUnwind and tests in ProcessTest/UnwindTest. Note: Halfway-through blocks have already set the complete variable (ctxt tempAt: 2) in their defining #ensure:/#ifCurtailed contexts from nil to true; we'll search for the bottom-most one." | outerMost | ctx isUnwindContext ifFalse: [ctx := ctx findNextUnwindContextUpTo: aContext]. [ctx isNil] whileFalse: [ + (ctx tempAt: 2) ifNotNil: [ - (ctx tempAt:2) ifNotNil: [ outerMost := ctx]. ctx := ctx findNextUnwindContextUpTo: aContext]. + outerMost ifNotNil: [top := top runUntilReturnFrom: outerMost]]. - outerMost ifNotNil: [top := (top runUntilReturnFrom: outerMost) sender]]. "By now no halfway-through unwind blocks are on the stack. Note: top points to the former outerMost sender now, i.e. to the next context to be explored."
+ ctx := top ifNil: [^self]. - ctx := top. "#findNextUnwindContextUpTo: starts searching from the receiver's sender so we must check the receiver explicitly whether it is an unwind context; see testTerminateEnsureAsStackTop. Create a new top context (i.e. a new branch off the original stack) for each pending unwind block (ctxt tempAt: 1) and execute it on the unwind block's stack to evaluate non-local returns correctly." ctx isUnwindContext ifFalse: [ctx := ctx findNextUnwindContextUpTo: aContext]. [ctx isNil] whileFalse: [ (ctx tempAt: 2) ifNil: [ ctx tempAt: 2 put: true. top := (ctx tempAt: 1) asContextWithSender: ctx. top runUntilReturnFrom: top]. ctx := ctx findNextUnwindContextUpTo: aContext] "Note: Cf. the unwind pattern in the previous versions of unwindTo: (1999-2021). Using #value instead of #runUntilReturnFrom: lead to a failure to evaluate some non-local returns correctly; a non-local return must be evaluated in the evaluation context (sender chain) in which it was defined."!
packages@lists.squeakfoundation.org