[squeak-dev] The Inbox: Kernel-jar.1478.mcz
commits at source.squeak.org
commits at source.squeak.org
Wed Jun 8 21:16:12 UTC 2022
A new version of Kernel was added to project The Inbox:
http://source.squeak.org/inbox/Kernel-jar.1478.mcz
==================== Summary ====================
Name: Kernel-jar.1478
Author: jar
Time: 8 June 2022, 11:16:07.949882 pm
UUID: f5720d99-9ce2-374c-adb0-811c23b2cfe5
Ancestors: Kernel-jar.1477
Fix a bug in #runUntilReturnFrom:: while searching for a context that cannot return (to avoid the VM crash) I forgot to limit the search to the relevant part of the stack only (i.e. search only *between* the contexts to be executed). As a result the following example currently fails to unwind:
p := [[[^2] on: BlockCannotReturn do: [Semaphore new wait]] ensure: [Transcript show: 'been here ']] fork.
Processor yield.
[p terminate] fork
Plus a minor change to allow unwinding even in this case:
p := [[] ensure: [[[^2] on: BlockCannotReturn do: [Semaphore new wait]] ensure: [Transcript show: 'been here ']]] fork.
Processor yield.
[p terminate] fork
A test will follow later.
=============== Diff against Kernel-jar.1477 ===============
Item was changed:
----- Method: Context>>runUntilReturnFrom: (in category 'private-exceptions') -----
runUntilReturnFrom: aContext
"Run the receiver (which must be its stack top context) until aContext returns. Avoid a context that cannot return.
Note: to avoid infinite recursion of MNU error inside unwind blocks, implement e.g. a wrapper around the message
sentTo: receiver in #doesNotUnderstand:. Note: This method is a trivialized version of #runUntilErrorOrReturnFrom:
and was intended to be used by #unwindTo as a helper method to unwind non-local returns inside unwind blocks."
| here unwindBottom newTop |
here := thisContext.
+ "Avoid a context that cannot return between self and aContext (see Note 1 below)."
+ unwindBottom := self findContextSuchThat: [:ctx | ctx == aContext or: [ctx selector = #cannotReturn:]].
+ newTop := unwindBottom sender.
- "Avoid a context that cannot return (see Note 1 below)"
- unwindBottom := (self findContextSuchThat: [:ctx | ctx selector = #cannotReturn:]) ifNil: [aContext].
- newTop := aContext sender.
"Insert ensure context under unwindBottom in self's stack (see Note 2 below)"
unwindBottom insertSender: (Context contextEnsure: [here jump]).
self jump. "Control jumps to the receiver's stack (see Note 2 below)"
"Control resumes here once the above inserted ensure block is executed (see #jump comments)"
^newTop "Return the new top context (see Note 3 below)"
"Note 1: returning from #cannotReturn's sender would crash the VM so we install a guard ensure context right
above it; after returning here the unwind will continue safely. Try running and debugging this example
(avoid Proceeding the BCR error though; it may indeed crash the image):
[[[] ensure: [^2]] ensure: [^42]] fork"
"Note 2: the receiver (self) is run by jumping directly to it (the active process abandons thisContext and executes
self on its own stack; self must be its top context). However, before jumping to self we insert an ensure block under
unwindBottom context that will execute a jump back to thisContext when evaluated. The inserted guard ensure
context is removed once control jumps back to thisContext."
"Note 3: it doesn't matter newTop is not a proper stack top context because #unwindTo will only use it as a starting
point in the search for the next unwind context and the computation will never return here. We could make newTop
a proper top context by pushing nil to its stack (^newTop push: nil) if need be (see #jump comments).
Cf. the pattern in #runUntilErrorOrReturnFrom:: removing the inserted ensure context by stepping until popped
when executing non-local returns wouldn't work here and would fail tests testTerminateInNestedEnsureWithReturn1
through 4."!
More information about the Squeak-dev
mailing list
|