чт, 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
