A new version of Kernel was added to project The Inbox: http://source.squeak.org/inbox/Kernel-ct.1296.mcz
==================== Summary ====================
Name: Kernel-ct.1296 Author: ct Time: 27 January 2020, 12:59:15.057199 pm UUID: e60f4637-b4fc-9947-94d3-50e7aa58ab82 Ancestors: Kernel-tonyg.1293
Fixes context simulation bug in #contextEnsure: and #contextOn:do:
As ctxt is *not* a top context as required by #jump, we need to put a (fake) return value (nil) on its stack. Otherwise, #jump will pop something different from the stack. Concretely, this caused the bug described in [1] (Scenario 1) because the latest stack top was the closure vector {chain}. This closure vector was accidently popped away so that in the final return statement, #pushRemoteTemp:inVectorAt: raised an error subscript bounds (because the next stack item was not variable). Read the linked bug report for more details.
[1] http://forum.world.st/BUG-s-in-Context-control-jump-runUntilErrorOrReturnFro...
=============== Diff against Kernel-tonyg.1293 ===============
Item was changed: ----- Method: Context class>>contextEnsure: (in category 'special context creation') ----- contextEnsure: block "Create an #ensure: context that is ready to return from executing its receiver"
| ctxt chain | ctxt := thisContext. + [chain := thisContext sender cut: ctxt. + ctxt push: nil. + ctxt jump] ensure: block. - [chain := thisContext sender cut: ctxt. ctxt jump] ensure: block. "jump above will resume here without unwinding chain" ^ chain!
Item was changed: ----- Method: Context class>>contextOn:do: (in category 'special context creation') ----- contextOn: exceptionClass do: block "Create an #on:do: context that is ready to return from executing its receiver"
| ctxt chain | ctxt := thisContext. + [chain := thisContext sender cut: ctxt. + ctxt push: nil. + ctxt jump] on: exceptionClass do: block. - [chain := thisContext sender cut: ctxt. ctxt jump] on: exceptionClass do: block. "jump above will resume here without unwinding chain" ^ chain!
As ctxt is *not* a top context as required by #jump, we need to put a (fake) return value (nil) on its stack. Otherwise, #jump will pop something different from the stack. Concretely, this caused the bug described in [1] (Scenario 1) because the latest stack top was the closure vector {chain}. This closure vector was accidently popped away so that in the final return statement, #pushRemoteTemp:inVectorAt: raised an error subscript bounds (because the next stack item was not variable).
To refine this description even more: From the perspective of the #jump context, the latest stack top of its receiver was the block closure in #contextEnsure: (or #contextOn:do:) rather than the closure vector. So after returning from #jump, the closure vector was on the stack top and thus got popped by the next bytecode statement. But that's rather a detail; it does not affect the problem and its solution. Just for protocol. Btw: I found the new BytecodeDebuggerhttp://forum.world.st/Changeset-Concept-BytecodeDebugger-3-cs-td5110352.html quite useful for investigating this bug :-)
Best, Christoph ________________________________ Von: Squeak-dev squeak-dev-bounces@lists.squeakfoundation.org im Auftrag von commits@source.squeak.org commits@source.squeak.org Gesendet: Montag, 27. Januar 2020 12:59:29 An: squeak-dev@lists.squeakfoundation.org Betreff: [squeak-dev] The Inbox: Kernel-ct.1296.mcz
A new version of Kernel was added to project The Inbox: http://source.squeak.org/inbox/Kernel-ct.1296.mcz
==================== Summary ====================
Name: Kernel-ct.1296 Author: ct Time: 27 January 2020, 12:59:15.057199 pm UUID: e60f4637-b4fc-9947-94d3-50e7aa58ab82 Ancestors: Kernel-tonyg.1293
Fixes context simulation bug in #contextEnsure: and #contextOn:do:
As ctxt is *not* a top context as required by #jump, we need to put a (fake) return value (nil) on its stack. Otherwise, #jump will pop something different from the stack. Concretely, this caused the bug described in [1] (Scenario 1) because the latest stack top was the closure vector {chain}. This closure vector was accidently popped away so that in the final return statement, #pushRemoteTemp:inVectorAt: raised an error subscript bounds (because the next stack item was not variable). Read the linked bug report for more details.
[1] http://forum.world.st/BUG-s-in-Context-control-jump-runUntilErrorOrReturnFro...
=============== Diff against Kernel-tonyg.1293 ===============
Item was changed: ----- Method: Context class>>contextEnsure: (in category 'special context creation') ----- contextEnsure: block "Create an #ensure: context that is ready to return from executing its receiver"
| ctxt chain | ctxt := thisContext. + [chain := thisContext sender cut: ctxt. + ctxt push: nil. + ctxt jump] ensure: block. - [chain := thisContext sender cut: ctxt. ctxt jump] ensure: block. "jump above will resume here without unwinding chain" ^ chain!
Item was changed: ----- Method: Context class>>contextOn:do: (in category 'special context creation') ----- contextOn: exceptionClass do: block "Create an #on:do: context that is ready to return from executing its receiver"
| ctxt chain | ctxt := thisContext. + [chain := thisContext sender cut: ctxt. + ctxt push: nil. + ctxt jump] on: exceptionClass do: block. - [chain := thisContext sender cut: ctxt. ctxt jump] on: exceptionClass do: block. "jump above will resume here without unwinding chain" ^ chain!
squeak-dev@lists.squeakfoundation.org