Nicolas Cellier uploaded a new version of Kernel to project The Inbox:
http://source.squeak.org/inbox/Kernel-nice.1407.mcz==================== Summary ====================
Name: Kernel-nice.1407
Author: nice
Time: 13 May 2021, 3:34:15.142602 pm
UUID: c4b8ae2c-02a9-415b-bcf3-6628b8f9f8e7
Ancestors: Kernel-jar.1406
When simulating (for example via the debugger) correctly unwind the simulation machinery #ensure: block inserted by #runUntilErrorOrReturnFrom:
Simulating #aboutToReturn:through: did jump to first unwind context. But this first unwind context was determined BEFORE the simulation #ensure: has been inserted. This had the effect of skipping the simulation machinery protection, and did result in a BlockCannotReturn (cannotReturn:) error...
This did prevent the debugger to correctly debug a protected block with non local return like this:
[^2] ensure: [Transcript cr; show: 'done'].
Kudos to Jaromir for finding this!
=============== Diff against Kernel-jar.1406 ===============
Item was changed:
----- Method: Context>>return:from: (in category 'instruction decoding') -----
return: value from: aSender
"For simulation. Roll back self to aSender and return value from it. Execute any unwind blocks on the way. ASSUMES aSender is a sender of self"
| newTop |
aSender isDead ifTrue:
[^self send: #cannotReturn: to: self with: {value}].
newTop := aSender sender.
(self findNextUnwindContextUpTo: newTop) ifNotNil:
[:unwindProtectCtxt|
+ ^self send: #simulatedAboutToReturn:through: to: self with: {value. unwindProtectCtxt}].
- ^self send: #aboutToReturn:through: to: self with: {value. unwindProtectCtxt}].
self releaseTo: newTop.
newTop ifNotNil: [newTop push: value].
^newTop!
Item was added:
+ ----- Method: Context>>simulatedAboutToReturn:through: (in category 'private') -----
+ simulatedAboutToReturn: result through: firstUnwindContext
+ "This is the simulated version of #aboutToReturn:through:
+ Since the simulation machinery inserts its own ensure: block, we must unwind it first.
+ See #runUntilErrorOrReturnFrom:"
+
+ self methodReturnContext
+ return: result
+ through: ((thisContext findNextUnwindContextUpTo: firstUnwindContext) ifNil: [firstUnwindContext])!