Christoph Thiede uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel-jar.1539.mcz
==================== Summary ====================
Name: Kernel-jar.1539 Author: jar Time: 28 November 2023, 1:07:51.739521 am UUID: 7dfe0ed8-86ec-f54a-9b12-11c337e0e8e5 Ancestors: Kernel-jar.1538
fix a bug in runUntilErrorOrReturnFrom: that prevents removing the guard contexts if they are placed below the bottom context (or above a dead context). The bug is a part of a series of bugs described in detail in the post from 27 Nov 2023 at:
https://lists.squeakfoundation.org/archives/list/squeak-dev@lists.squeakfoun...
This changeset requires and complements its ancestor Kernel-jar.1538
=============== Diff against Kernel-jar.1538 ===============
Item was changed: ----- Method: Context>>runUntilErrorOrReturnFrom: (in category 'controlling') ----- runUntilErrorOrReturnFrom: aSender "ASSUMES aSender is a sender of self. Execute self's stack until aSender returns or an unhandled exception is raised. Return a pair containing the new top context and a possibly nil exception. The exception is not nil if it was raised before aSender returned and it was not handled. The exception is returned rather than openning the debugger, giving the caller the choice of how to handle it." "Self is run by jumping directly to it (the active process abandons thisContext and executes self). However, before jumping to self we insert an ensure block under aSender that jumps back to thisContext when evaluated. We also insert an exception handler under aSender that jumps back to thisContext when an unhandled exception is raised. In either case, the inserted ensure and exception handler are removed once control jumps back to thisContext."
| error ctxt here topContext | here := thisContext.
"Insert ensure and exception handler contexts under aSender" error := nil. ctxt := aSender insertSender: (Context contextOn: UnhandledError do: [:ex | error ifNil: [ error := ex exception. topContext := thisContext. ex resumeUnchecked: here jump] ifNotNil: [ex pass] ]). ctxt := ctxt insertSender: (Context contextEnsure: [error ifNil: [ topContext := thisContext. here jump] ]). self jump. "Control jumps to self"
"Control resumes here once above ensure block or exception handler is executed" ^ error ifNil: [ "No error was raised, remove ensure context by stepping until popped" + [ctxt isDead or: [topContext isNil]] whileFalse: [topContext := topContext stepToCalleeOrNil]. - [ctxt isDead or: [topContext isNil]] whileFalse: [topContext := topContext stepToCallee]. {topContext. nil}
] ifNotNil: [ "Error was raised, remove inserted above contexts then return signaler context" aSender terminateTo: ctxt sender. "remove above ensure and handler contexts" {topContext. error} ]!
Item was added: + ----- Method: Context>>stepToCalleeOrNil (in category 'private') ----- + stepToCalleeOrNil + "Step to callee or sender; step to return and answer nil in case sender cannot be returned to." + + | ctxt | + ctxt := self. + [(ctxt willReturn and: [ctxt sender isNil or: [ctxt sender isDead]]) not and: [(ctxt := ctxt step) == self]] whileTrue. + ctxt == self ifTrue: [^nil]. + ^ctxt!
packages@lists.squeakfoundation.org