<div dir="ltr"><div>Anyone willing to compare with Inbox: Kernel-nice.857.mcz ?<br><a href="http://lists.squeakfoundation.org/pipermail/squeak-dev/2014-June/178492.html">http://lists.squeakfoundation.org/pipermail/squeak-dev/2014-June/178492.html</a><br><br>follow up:<br><a href="http://lists.squeakfoundation.org/pipermail/squeak-dev/2014-June/178493.html">http://lists.squeakfoundation.org/pipermail/squeak-dev/2014-June/178493.html</a><br><a href="http://lists.squeakfoundation.org/pipermail/squeak-dev/2014-June/178497.html">http://lists.squeakfoundation.org/pipermail/squeak-dev/2014-June/178497.html</a><br><a href="http://lists.squeakfoundation.org/pipermail/squeak-dev/2014-June/178506.html">http://lists.squeakfoundation.org/pipermail/squeak-dev/2014-June/178506.html</a><br><br>Note that rearmHandlerDuring: is used by some of Eliot&#39;s scripts (see above).<br></div><div>So I tried to preserve it.<br></div><div><br><div>IMO testHandlerReentrancy is fallacy.<br></div>It&#39;s just that it seems to be used by Island mechanism in latest versions of in Tweak see
<a href="https://code.google.com/p/pharo/issues/detail?id=2519">https://code.google.com/p/pharo/issues/detail?id=2519</a><br><br></div><div class="gmail_extra">Note that Andres&#39; code still use tempAt: 1 &amp; 2 (understand the temps of on:do: context) so removing tempAt: 3, while possibly a good thing, is not that spectacular: we still need some introspection of execution stack, one way or another...<br><br></div><div class="gmail_extra"><div class="gmail_quote">2014-09-13 2:57 GMT+02:00 Andres Valloud <span dir="ltr">&lt;<a href="mailto:avalloud@smalltalk.comcastbiz.net" target="_blank">avalloud@smalltalk.comcastbiz.net</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Feel free to improve the code.  I merely adapted the Pharo changes to Cuis.  I am not really aware of your long term plans.  Please let me know what you decide to do in the end, as I&#39;d like to keep Cuis in the loop.<span class=""><br>
<br>
On 9/12/14 17:14 , Eliot Miranda wrote:<br>
</span><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">
<br>
<br>
On Fri, Sep 12, 2014 at 2:12 PM, Frank Shearar &lt;<a href="mailto:frank.shearar@gmail.com" target="_blank">frank.shearar@gmail.com</a><br></span><span class="">
&lt;mailto:<a href="mailto:frank.shearar@gmail.com" target="_blank">frank.shearar@gmail.<u></u>com</a>&gt;&gt; wrote:<br>
<br>
    On 12 September 2014 21:49, Eliot Miranda &lt;<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a><br></span><div><div class="h5">
    &lt;mailto:<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.<u></u>com</a>&gt;&gt; wrote:<br>
    &gt; Hi Frank,<br>
    &gt;<br>
    &gt;     I&#39;d rather see<br>
    &gt;<br>
    &gt; on: exception do: handlerAction<br>
    &gt;        &quot;Evaluate the receiver in the scope of an exception handler.<br>
    &gt;        The following primitive is just a marker used to find the error<br>
    &gt; handling context.<br>
    &gt;        See MethodContext&gt;&gt;#<u></u>isHandlerOrSignalingContext. &quot;<br>
    &gt;        &lt;primitive: 199&gt;<br>
    &gt;        &lt;handler&gt;<br>
    &gt;        ^ self value!<br>
    &gt;<br>
    &gt; isHandlerContext<br>
    &gt;        &quot;is this context for #on:do:?&quot;<br>
    &gt;        ^self isHandlerOrSignalingContext and: [ (self method pragmaAt:<br>
    &gt; #handler) notNil: ]<br>
    &gt;<br>
    &gt; etc, rather than testing the selector.<br>
<br>
    OK, I see what you&#39;re doing there. I guess the only worry I have is<br>
    that &lt;handler&gt; doesn&#39;t seem terribly specific to me.<br>
<br>
<br>
it can be as specific a label as you&#39;d like.<br>
<br>
<br>
    One thing I don&#39;t get is the tempAt: 3 stuff. This code removes it,<br>
    and that seems to be the root of why #testHandlerReentrancy fails. But<br>
    this is beyond my depth (which is most of why I made Andres&#39; code more<br>
    available for those for home this is _not_ out of depth).<br>
<br>
<br>
I hear you.<br>
<br>
    &gt;  I&#39;d also like to see the code in<br>
    &gt; MethodCOntext (e.g. where method can be directly accessed) than in<br>
    &gt; ContextPart.  Remember that some time soon we can collapse ContextPart and<br>
    &gt; MethodContext onto Context as the Pharo folks have already done.<br>
<br>
    Right, because BlockContext has been marked for death? (Because<br>
    MethodContext has a closureOrNil instvar, which disambiguates between<br>
    MethodContexts-for-block-<u></u>activations and<br>
    MethodContexts-for-method-<u></u>activations.)<br>
<br>
<br>
Right.  BlockCOntext is obsolete and unused.<br>
<br>
    But since at some point we&#39;re going to merge MethodContext and<br>
    ContextPart, why not just leave the code where it is? I guess it just<br>
    depends on whether we merge MethodContext -&gt; ContextPart, or<br>
    ContextPart -&gt; MethodContext.<br>
<br>
<br>
Well, the inst vars contexts need are defined in InstructionStream and<br>
MethodContext. So implementing in MethodCOntext allows e.g. direct<br>
access to method.  So I don&#39;t recommend putting things in ContextPart<br>
any more.<br>
<br>
<br>
    frank<br>
<br>
     &gt; On Fri, Sep 12, 2014 at 1:40 PM, &lt;<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a><br></div></div><div><div class="h5">
    &lt;mailto:<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.<u></u>org</a>&gt;&gt; wrote:<br>
     &gt;&gt;<br>
     &gt;&gt; Frank Shearar uploaded a new version of Kernel to project The Inbox:<br>
     &gt;&gt; <a href="http://source.squeak.org/inbox/Kernel-fbs.870.mcz" target="_blank">http://source.squeak.org/<u></u>inbox/Kernel-fbs.870.mcz</a><br>
     &gt;&gt;<br>
     &gt;&gt; ==================== Summary ====================<br>
     &gt;&gt;<br>
     &gt;&gt; Name: Kernel-fbs.870<br>
     &gt;&gt; Author: fbs<br>
     &gt;&gt; Time: 12 September 2014, 9:40:45.406 pm<br>
     &gt;&gt; UUID: 868e0d8a-5e9d-d34d-ba2d-<u></u>688800331f5b<br>
     &gt;&gt; Ancestors: Kernel-eem.869<br>
     &gt;&gt;<br>
     &gt;&gt; These are the changes Andres Valloud made to Cuis, to address a<br>
     &gt;&gt; long-standing bug in Cuis, Squeak and Pharo, in ExceptionsTests &gt;&gt;<br>
     &gt;&gt; #testHandlerFromAction.<br>
     &gt;&gt;<br>
     &gt;&gt; However, it causes a regression in #testHandlerReentrancy, so as<br>
    it stands<br>
     &gt;&gt; it is NOT READY FOR MERGING.<br>
     &gt;&gt;<br>
     &gt;&gt; Please take a look, and see if we can bend Andres&#39; code slightly<br>
    so that<br>
     &gt;&gt; we get both the fix and don&#39;t break anything.<br>
     &gt;&gt;<br>
     &gt;&gt; =============== Diff against Kernel-eem.869 ===============<br>
     &gt;&gt;<br>
     &gt;&gt; Item was changed:<br>
     &gt;&gt;   ----- Method: BlockClosure&gt;&gt;on:do: (in category &#39;exceptions&#39;)<br>
    -----<br>
     &gt;&gt;   on: exception do: handlerAction<br>
     &gt;&gt; +       &quot;Evaluate the receiver in the scope of an exception handler.<br>
     &gt;&gt; +       The following primitive is just a marker used to find<br>
    the error<br>
     &gt;&gt; handling context.<br>
     &gt;&gt; +       See MethodContext&gt;&gt;#<u></u>isHandlerOrSignalingContext. &quot;<br>
     &gt;&gt; +       &lt;primitive: 199&gt;<br>
     &gt;&gt; -       &quot;Evaluate the receiver in the scope of an exception<br>
    handler.&quot;<br>
     &gt;&gt; -<br>
     &gt;&gt; -       | handlerActive |<br>
     &gt;&gt; -       &lt;primitive: 199&gt;  &quot;just a marker, fail and execute the<br>
    following&quot;<br>
     &gt;&gt; -       handlerActive := true.<br>
     &gt;&gt;         ^ self value!<br>
     &gt;&gt;<br>
     &gt;&gt; Item was changed:<br>
     &gt;&gt;   ----- Method: BlockContext&gt;&gt;on:do: (in category &#39;exceptions&#39;)<br>
    -----<br>
     &gt;&gt;   on: exception do: handlerAction<br>
     &gt;&gt; +       &quot;Evaluate the receiver in the scope of an exception handler.<br>
     &gt;&gt; +       The following primitive is just a marker used to find<br>
    the error<br>
     &gt;&gt; handling context.<br>
     &gt;&gt; +       See MethodContext&gt;&gt;#<u></u>isHandlerOrSignalingContext. &quot;<br>
     &gt;&gt; +       &lt;primitive: 199&gt;<br>
     &gt;&gt; +       ^ self value!<br>
     &gt;&gt; -       &quot;Evaluate the receiver in the scope of an exception<br>
    handler.&quot;<br>
     &gt;&gt; -       | handlerActive |<br>
     &gt;&gt; -       &lt;primitive: 199&gt;<br>
     &gt;&gt; -       handlerActive := true.<br>
     &gt;&gt; -       ^self value!<br>
     &gt;&gt;<br>
     &gt;&gt; Item was changed:<br>
     &gt;&gt;   ----- Method: ContextPart&gt;&gt;canHandleSignal: (in category<br>
     &gt;&gt; &#39;private-exceptions&#39;) -----<br>
     &gt;&gt;   canHandleSignal: exception<br>
     &gt;&gt;         &quot;Sent to handler (on:do:) contexts only.  If my<br>
    exception class<br>
     &gt;&gt; (first arg) handles exception then return true, otherwise<br>
    forward this<br>
     &gt;&gt; message to the next handler context.  If none left, return false<br>
    (see<br>
     &gt;&gt; nil&gt;&gt;canHandleSignal:)&quot;<br>
     &gt;&gt;<br>
     &gt;&gt; +       ^ (self exceptionClass handles: exception)<br>
     &gt;&gt; +               or: [ self nextHandlerContext canHandleSignal:<br>
    exception<br>
     &gt;&gt; ].!<br>
     &gt;&gt; -       ^ (((self tempAt: 1) handles: exception) and: [self<br>
    tempAt: 3])<br>
     &gt;&gt; -               or: [self nextHandlerContext canHandleSignal:<br>
    exception].<br>
     &gt;&gt; - !<br>
     &gt;&gt;<br>
     &gt;&gt; Item was added:<br>
     &gt;&gt; + ----- Method: ContextPart&gt;&gt;evaluateSignal: (in category<br>
     &gt;&gt; &#39;private-exceptions&#39;) -----<br>
     &gt;&gt; + evaluateSignal: exception<br>
     &gt;&gt; +       &quot;The following primitive is just a marker used to find the<br>
     &gt;&gt; evaluation context.<br>
     &gt;&gt; +       See MethodContext&gt;&gt;#<u></u>isHandlerOrSignalingContext. &quot;<br>
     &gt;&gt; +<br>
     &gt;&gt; +       &lt;primitive: 199&gt;<br>
     &gt;&gt; +       | value |<br>
     &gt;&gt; +       exception privHandlerContext: self contextTag.<br>
     &gt;&gt; +       value := self exceptionHandlerBlock<br>
    valueWithPossibleArgument:<br>
     &gt;&gt; exception.<br>
     &gt;&gt; +       &quot;return from self if not otherwise directed in handle block&quot;<br>
     &gt;&gt; +       self return: value!<br>
     &gt;&gt;<br>
     &gt;&gt; Item was added:<br>
     &gt;&gt; + ----- Method: ContextPart&gt;&gt;exceptionClass (in category<br>
     &gt;&gt; &#39;private-exceptions&#39;) -----<br>
     &gt;&gt; + exceptionClass<br>
     &gt;&gt; +<br>
     &gt;&gt; +       ^self tempAt: 1!<br>
     &gt;&gt;<br>
     &gt;&gt; Item was added:<br>
     &gt;&gt; + ----- Method: ContextPart&gt;&gt;<u></u>exceptionHandlerBlock (in category<br>
     &gt;&gt; &#39;private-exceptions&#39;) -----<br>
     &gt;&gt; + exceptionHandlerBlock<br>
     &gt;&gt; +       &quot;handler context only. access temporaries from<br>
     &gt;&gt; BlockClosure&gt;&gt;#on:do:&quot;<br>
     &gt;&gt; +<br>
     &gt;&gt; +       ^self tempAt: 2!<br>
     &gt;&gt;<br>
     &gt;&gt; Item was added:<br>
     &gt;&gt; + ----- Method: ContextPart&gt;&gt;<u></u>findNextHandlerContext (in category<br>
     &gt;&gt; &#39;private-exceptions&#39;) -----<br>
     &gt;&gt; + findNextHandlerContext<br>
     &gt;&gt; +       &quot;Return the next handler marked context, returning nil<br>
    if there is<br>
     &gt;&gt; none.  Search starts with self and proceeds up to nil.&quot;<br>
     &gt;&gt; +<br>
     &gt;&gt; +       | context |<br>
     &gt;&gt; +       context := self findNextHandlerOrSignalingCont<u></u>ext.<br>
     &gt;&gt; +       context isNil<br>
     &gt;&gt; +               ifTrue: [ ^ nil ].<br>
     &gt;&gt; +       context isHandlerContext<br>
     &gt;&gt; +               ifTrue: [ ^ context ].  &quot;If it isn&#39;t a handler<br>
    context, it<br>
     &gt;&gt; must be a signaling context.<br>
     &gt;&gt; +       When we reach a signaling context we must skip over any<br>
    handlers<br>
     &gt;&gt; +       that might be on the stack between the signaling context<br>
    and the<br>
     &gt;&gt; handler<br>
     &gt;&gt; +       context for that signal.&quot;<br>
     &gt;&gt; +       ^ context exceptionClass privHandlerContext<br>
    nextHandlerContext!<br>
     &gt;&gt;<br>
     &gt;&gt; Item was removed:<br>
     &gt;&gt; - ----- Method: ContextPart&gt;&gt;<u></u>findNextHandlerContextStarting (in<br>
    category<br>
     &gt;&gt; &#39;private-exceptions&#39;) -----<br>
     &gt;&gt; - findNextHandlerContextStarting<br>
     &gt;&gt; -       &quot;Return the next handler marked context, returning nil<br>
    if there is<br>
     &gt;&gt; none.  Search starts with self and proceeds up to nil.&quot;<br>
     &gt;&gt; -<br>
     &gt;&gt; -       | ctx |<br>
     &gt;&gt; -       &lt;primitive: 197&gt;<br>
     &gt;&gt; -       ctx := self.<br>
     &gt;&gt; -               [ctx isHandlerContext ifTrue:[^ctx].<br>
     &gt;&gt; -               (ctx := ctx sender) == nil ] whileFalse.<br>
     &gt;&gt; -       ^nil!<br>
     &gt;&gt;<br>
     &gt;&gt; Item was added:<br>
     &gt;&gt; + ----- Method: ContextPart&gt;&gt;<u></u>findNextHandlerOrSignalingCont<u></u>ext (in<br>
     &gt;&gt; category &#39;private-exceptions&#39;) -----<br>
     &gt;&gt; + findNextHandlerOrSignalingCont<u></u>ext<br>
     &gt;&gt; +       &quot;Return the next handler/signaling marked context,<br>
    answering nil<br>
     &gt;&gt; if there is none.<br>
     &gt;&gt; +       Search starts with self and proceeds up to nil.&quot;<br>
     &gt;&gt; +<br>
     &gt;&gt; +       &lt;primitive: 197&gt;<br>
     &gt;&gt; +       | context |<br>
     &gt;&gt; +       context := self.<br>
     &gt;&gt; +       [<br>
     &gt;&gt; +       context isHandlerOrSignalingContext<br>
     &gt;&gt; +               ifTrue: [ ^ context ].<br>
     &gt;&gt; +       (context := context sender) == nil ] whileFalse.<br>
     &gt;&gt; +       ^ nil!<br>
     &gt;&gt;<br>
     &gt;&gt; Item was changed:<br>
     &gt;&gt;   ----- Method: ContextPart&gt;&gt;handleSignal: (in category<br>
     &gt;&gt; &#39;private-exceptions&#39;) -----<br>
     &gt;&gt;   handleSignal: exception<br>
     &gt;&gt;         &quot;Sent to handler (on:do:) contexts only.  If my<br>
    exception class<br>
     &gt;&gt; (first arg) handles exception then execute my handle block<br>
    (second arg),<br>
     &gt;&gt; otherwise forward this message to the next handler context.  If<br>
    none left,<br>
     &gt;&gt; execute exception&#39;s defaultAction (see nil&gt;&gt;handleSignal:).&quot;<br>
     &gt;&gt;<br>
     &gt;&gt; +       (self exceptionClass handles: exception)<br>
     &gt;&gt; +               ifFalse: [ ^ self nextHandlerContext handleSignal:<br>
     &gt;&gt; exception ].<br>
     &gt;&gt; +       self evaluateSignal: exception!<br>
     &gt;&gt; -       | val |<br>
     &gt;&gt; -       (((self tempAt: 1) handles: exception) and: [self<br>
    tempAt: 3])<br>
     &gt;&gt; ifFalse: [<br>
     &gt;&gt; -               ^ self nextHandlerContext handleSignal: exception].<br>
     &gt;&gt; -<br>
     &gt;&gt; -       exception privHandlerContext: self contextTag.<br>
     &gt;&gt; -       self tempAt: 3 put: false.  &quot;disable self while<br>
    executing handle<br>
     &gt;&gt; block&quot;<br>
     &gt;&gt; -       val := [(self tempAt: 2) cull: exception ]<br>
     &gt;&gt; -               ensure: [self tempAt: 3 put: true].<br>
     &gt;&gt; -       self return: val.  &quot;return from self if not otherwise<br>
    directed in<br>
     &gt;&gt; handle block&quot;<br>
     &gt;&gt; - !<br>
     &gt;&gt;<br>
     &gt;&gt; Item was changed:<br>
     &gt;&gt;   ----- Method: ContextPart&gt;&gt;isHandlerContext (in category<br>
     &gt;&gt; &#39;private-exceptions&#39;) -----<br>
     &gt;&gt;   isHandlerContext<br>
     &gt;&gt; +       &quot;is this context for #on:do:?&quot;<br>
     &gt;&gt; +       ^self isHandlerOrSignalingContext and: [ self selector<br>
    == #on:do:<br>
     &gt;&gt; ]!<br>
     &gt;&gt; -       ^false!<br>
     &gt;&gt;<br>
     &gt;&gt; Item was added:<br>
     &gt;&gt; + ----- Method: ContextPart&gt;&gt;<u></u>isHandlerOrSignalingContext (in<br>
    category<br>
     &gt;&gt; &#39;private-exceptions&#39;) -----<br>
     &gt;&gt; + isHandlerOrSignalingContext<br>
     &gt;&gt; +       &quot;Both BlockClosure&gt;&gt;on:do: (handler) and<br>
     &gt;&gt; ContextPart&gt;&gt;evaluateSignal: (signaling)<br>
     &gt;&gt; +       are marked with primitive 199.&quot;<br>
     &gt;&gt; +<br>
     &gt;&gt; +       ^false!<br>
     &gt;&gt;<br>
     &gt;&gt; Item was changed:<br>
     &gt;&gt;   ----- Method: ContextPart&gt;&gt;<u></u>nextHandlerContext (in category<br>
     &gt;&gt; &#39;private-exceptions&#39;) -----<br>
     &gt;&gt;   nextHandlerContext<br>
     &gt;&gt;<br>
     &gt;&gt; +       ^ self sender findNextHandlerContext!<br>
     &gt;&gt; -       ^ self sender findNextHandlerContextStarting<u></u>!<br>
     &gt;&gt;<br>
     &gt;&gt; Item was removed:<br>
     &gt;&gt; - ----- Method: ContextPart&gt;&gt;<u></u>rearmHandlerDuring: (in category<br>
     &gt;&gt; &#39;private-exceptions&#39;) -----<br>
     &gt;&gt; - rearmHandlerDuring: aBlock<br>
     &gt;&gt; -       &quot;Sent to handler (on:do:) contexts only. Makes me<br>
    re-entrant for<br>
     &gt;&gt; the duration of aBlock. Only works in a closure-enabled image&quot;<br>
     &gt;&gt; -<br>
     &gt;&gt; -       ^ [self tempAt: 3 put: true. aBlock value]<br>
     &gt;&gt; -               ensure: [self tempAt: 3 put: false]!<br>
     &gt;&gt;<br>
     &gt;&gt; Item was added:<br>
     &gt;&gt; + ----- Method: Exception&gt;&gt;privHandlerContext (in category &#39;priv<br>
     &gt;&gt; handling&#39;) -----<br>
     &gt;&gt; + privHandlerContext<br>
     &gt;&gt; +<br>
     &gt;&gt; +       ^handlerContext!<br>
     &gt;&gt;<br>
     &gt;&gt; Item was removed:<br>
     &gt;&gt; - ----- Method: Exception&gt;&gt;rearmHandlerDuring: (in category<br>
    &#39;handling&#39;)<br>
     &gt;&gt; -----<br>
     &gt;&gt; - rearmHandlerDuring: aBlock<br>
     &gt;&gt; - &quot;Make the current error handler re-entrant while it is running<br>
    aBlock.<br>
     &gt;&gt; Only works in a closure-enabled image&quot;<br>
     &gt;&gt; -<br>
     &gt;&gt; -       ^ handlerContext rearmHandlerDuring: aBlock!<br>
     &gt;&gt;<br>
     &gt;&gt; Item was removed:<br>
     &gt;&gt; - ----- Method: MethodContext&gt;&gt;<u></u>isHandlerContext (in category<br>
     &gt;&gt; &#39;private-exceptions&#39;) -----<br>
     &gt;&gt; - isHandlerContext<br>
     &gt;&gt; - &quot;is this context for  method that is marked?&quot;<br>
     &gt;&gt; -       ^method primitive = 199!<br>
     &gt;&gt;<br>
     &gt;&gt; Item was added:<br>
     &gt;&gt; + ----- Method: MethodContext&gt;&gt;<u></u>isHandlerOrSignalingContext (in<br>
    category<br>
     &gt;&gt; &#39;private-exceptions&#39;) -----<br>
     &gt;&gt; + isHandlerOrSignalingContext<br>
     &gt;&gt; +       &quot;Both BlockClosure&gt;&gt;on:do: (handler) and<br>
     &gt;&gt; ContextPart&gt;&gt;evaluateSignal: (signaling)<br>
     &gt;&gt; +       are marked with primitive 199.&quot;<br>
     &gt;&gt; +<br>
     &gt;&gt; +       ^method primitive = 199!<br>
     &gt;&gt;<br>
     &gt;&gt;<br>
     &gt;<br>
     &gt;<br>
     &gt;<br>
     &gt; --<br>
     &gt; best,<br>
     &gt; Eliot<br>
     &gt;<br>
     &gt;<br>
     &gt;<br>
<br>
<br>
<br>
<br>
--<br>
best,<br>
Eliot<br>
<br>
<br>
<br>
</div></div></blockquote>
<br>
</blockquote></div><br></div></div>