чт, 19 дек. 2019 г. в 21:43, Denis Kudriashov <[email protected]>:

> I checked Squeak. All my examples work consistently there: UnhandledError
> handler is always triggered.
> Even more: signalling new error from the handler block passes it from the
> original signallerContext:
>
> [
>>
>> [ 1/0 ] on: MyTestError do: [ :e | self halt ]
>>
>>  ] on: ZeroDivide do: [ :z | MyTestError signal ]
>>
>>
> This code halts in Squeak.
>

Squeak has special "activeHandle" logic in #handleSignal: code:

Context>>handleSignal: exception

"Sent to handler (on:do:) contexts only.  If my exception class (first arg)
handles exception

and the handler is active then execute my handle block (second arg),
otherwise forward

this message to the next handler context.  If none left, execute
exception's defaultAction

(see nil>>handleSignal:)."


| handlerActive val |

"If the context has been returned from the handlerActive temp var may not
be accessible."

handlerActive := stackp >= 3 and: [(self tempAt: 3) == true].

(((self tempAt: 1) handles: exception) and: [handlerActive]) ifFalse:

[^self nextHandlerContext handleSignal: exception].


exception privHandlerContext: self contextTag.

self tempAt: 3 put: false.  "disable self while executing handle block"

val := [(self tempAt: 2) cull: exception]

ensure: [self tempAt: 3 put: true].

self return: val  "return from self if not otherwise directed in handle
block"

 This flag is used by VM primitive to lookup next handler. We should just
copy this code into Pharo with corresponding tests

Reply via email to