<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">2014-06-06 0:17 GMT+02:00 Nicolas Cellier <span dir="ltr">&lt;<a href="mailto:nicolas.cellier.aka.nice@gmail.com" target="_blank">nicolas.cellier.aka.nice@gmail.com</a>&gt;</span>:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">2014-06-05 23:27 GMT+02:00 Nicolas Cellier <span dir="ltr">&lt;<a href="mailto:nicolas.cellier.aka.nice@gmail.com" target="_blank">nicolas.cellier.aka.nice@gmail.com</a>&gt;</span>:<div class="">
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>This change resolved the failing test for me, and I did not yet find what else it may break...<br>
</div>
In this danger zone, more eyes are required, so up to you to refute the method :)<br><div><div><div>
<div class="gmail_extra"><br></div></div></div></div></div></blockquote></div><div>I think I have a refutation (theoretically): if an outer handler resumes execution in signalContext, then the inner handler context won&#39;t be re-activated and will miss the next exceptions...<br>

<br></div><div>Unfortunately, resuming is the default behavior for any unhandled exception (see UndefinedObject&gt;&gt;#handleSignal:).<br></div><div>So every un-caught exception (even the most harmless Notification) will deactivate all the enclosing handlers!<br>

<br></div><div>Definitely not a good change, I must find another way...<br></div><div><div class="h5"><div><br></div></div></div></div></div></div></blockquote><div><br></div><div>I came with a brand new strategy: the goal of the testHandlerFromAction is that one:<br>
if an exception occurs while evaluating the handler block, we want to bypass all inner handlers (those inside the protected block).<br></div><br><div>Since  #handleSignal:  is upper on the stack than the inner #on:do: handler, it could be used to intercept the handling and forward to outer handlers.<br>
So here is an implementation of this strategy:<br><br>- mark the #handleSignal: context as a handler (&lt;primitive: 199&gt;) so as to intercept handling of next exception<br>- don&#39;t let #handleSignal: handle signal, but simply let it pass to the nextHandlerContext that we pre-recorded in (temp at: 4)<br>
- record the nextHandlerContext in an inst var of #handleSignal: before executing the handlerBlock [(temp at: 2) cull: exception]<br><br>I tested it with this:<br><br></div><div>1) first add a fourth temp to BlockClosure on:do: for safely inquiring (temp at: 4)<br>
<br></div><div>on: exception do: handlerAction<br>    &quot;Evaluate the receiver in the scope of an exception handler.&quot;<br><br>    | handlerActive nextHandler |<br>    &lt;primitive: 199&gt;  &quot;just a marker, fail and execute the following&quot;<br>
    handlerActive := true.<br>    nextHandler := nil.<br>    ^ self value<br><br></div><div>2) modify ContextPart handleSignal: as described above<br></div><div><br>handleSignal: exception<br>    &quot;Sent to handler (on:do: and handleSignal:) contexts only.  If my exception class (first arg) handles exception then execute my handle block (second arg), otherwise forward this message to the next handler context.  If none left, execute exception&#39;s defaultAction (see nil&gt;&gt;handleSignal:).&quot;<br>
<br>    | val active nextHandler |<br>    &lt;primitive: 199&gt;<br>    active := false.<br>    (((self tempAt: 1) handles: exception) and: [self tempAt: 3]) ifFalse: [<br>        ^((self tempAt: 4) ifNil: [self nextHandlerContext]) handleSignal: exception].<br>
<br>    exception privHandlerContext: self contextTag.<br>    self tempAt: 3 put: false.  &quot;disable self while executing handle block&quot;<br>    nextHandler := self nextHandlerContext.<br>    val := [ (self tempAt: 2) cull: exception ]<br>
        ensure: [self tempAt: 3 put: true].<br>    self return: val.  &quot;return from self if not otherwise directed in handle block&quot;<br><br>If an exception occurs while evaluating the handler block, we are first finding a #handleSignal: context down the stack,<br>
(temp at: 1) is an Exception instance, not an Exception class, it naturally does not handles: (Object&gt;&gt;handles:)<br></div><div>Instead, it will just pass the message to the nextHandler (tempAt: 4)...<br></div><div>eventually this continues thru several outer handlers.<br>
</div><div><br>With this scheme, I have a my #testHandlerFromAction passing, but a new failure: #testHandlerReentrancy<br></div><div>Indeed, #testHandlerReentrancy is signalling a Notification from within an outer handler, how could it possibly search a inner handler?<br>
</div><div>That&#39;s precisely what we tried to avoid !!!<br><br></div><div>To enable such usage of #rearmHandlerDuring: we would have to annihilate the nextHandler temp...<br></div><div>But we don&#39;t have an access to this #handleSignal: context from within the exception (it&#39;s never the handlerContext, since it does not handles:)<br>
</div><div>I could possibly add another inst.var. in Exception and fill it with thisContext from within handleSignal: <br>Above proposition would have holes (even the not rearmed inner handlers would be rearmed).</div><div>
I see no sender of #rearmHandlerDuring: in trunk, and I&#39;m not sure where it could be usefull...</div><div>It seems relatively recent in Squeak (stamp 2010, no previous version).<br><br></div><div>What do you think?<br>
</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5">
<div></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div>
<div><div class="gmail_extra"><br><div class="gmail_quote">2014-06-05 23:11 GMT+02:00  <span dir="ltr">&lt;<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>&gt;</span>:<div><div>
<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
A new version of Kernel was added to project The Inbox:<br>
<a href="http://source.squeak.org/inbox/Kernel-nice.856.mcz" target="_blank">http://source.squeak.org/inbox/Kernel-nice.856.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: Kernel-nice.856<br>
Author: nice<br>
Time: 5 June 2014, 11:11:07.752 pm<br>
UUID: 44668d33-00c2-4e36-b95b-69d83b0d7544<br>
Ancestors: Kernel-cmm.855<br>
<br>
Attempt to fix ExceptionTests&gt;&gt;#testHandlerFromAction.<br>
When the handler does not handle an Exception, simply mark the handler context as inactive (self tempAt: 3 put: false).<br>
<br>
=============== Diff against Kernel-cmm.855 ===============<br>
<br>
Item was changed:<br>
  ----- Method: ContextPart&gt;&gt;handleSignal: (in category &#39;private-exceptions&#39;) -----<br>
  handleSignal: exception<br>
        &quot;Sent to handler (on:do:) contexts only.  If my exception class (first arg) handles exception then execute my handle block (second arg), otherwise forward this message to the next handler context.  If none left, execute exception&#39;s defaultAction (see nil&gt;&gt;handleSignal:).&quot;<br>



<br>
        | val |<br>
+       ((((self tempAt: 1) handles: exception) or: [self tempAt: 3 put: false])<br>
+                and: [self tempAt: 3]) ifFalse: [<br>
-       (((self tempAt: 1) handles: exception) and: [self tempAt: 3]) ifFalse: [<br>
                ^ self nextHandlerContext handleSignal: exception].<br>
<br>
        exception privHandlerContext: self contextTag.<br>
        self tempAt: 3 put: false.  &quot;disable self while executing handle block&quot;<br>
        val := [(self tempAt: 2) cull: exception ]<br>
                ensure: [self tempAt: 3 put: true].<br>
        self return: val.  &quot;return from self if not otherwise directed in handle block&quot;<br>
  !<br>
<br>
<br>
</blockquote></div></div></div><br></div></div></div></div></div>
</blockquote></div></div></div><br></div></div>
</blockquote></div><br></div></div>