<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Sep 12, 2014 at 2:12 PM, Frank Shearar <span dir="ltr">&lt;<a href="mailto:frank.shearar@gmail.com" target="_blank">frank.shearar@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On 12 September 2014 21:49, Eliot Miranda &lt;<a href="mailto:eliot.miranda@gmail.com">eliot.miranda@gmail.com</a>&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;#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>
</span>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></blockquote><div><br></div><div>it can be as specific a label as you&#39;d like.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">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></blockquote><div><br></div><div>I hear you.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">&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>
</span>Right, because BlockContext has been marked for death? (Because<br>
MethodContext has a closureOrNil instvar, which disambiguates between<br>
MethodContexts-for-block-activations and<br>
MethodContexts-for-method-activations.)<br></blockquote><div><br></div><div>Right.  BlockCOntext is obsolete and unused.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">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></blockquote><div><br></div><div>Well, the inst vars contexts need are defined in InstructionStream and MethodContext. So implementing in MethodCOntext allows e.g. direct access to method.  So I don&#39;t recommend putting things in ContextPart any more.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class="HOEnZb"><font color="#888888"><br>
frank<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
&gt; On Fri, Sep 12, 2014 at 1:40 PM, &lt;<a href="mailto:commits@source.squeak.org">commits@source.squeak.org</a>&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/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-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 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 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>
&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 the error<br>
&gt;&gt; handling context.<br>
&gt;&gt; +       See MethodContext&gt;&gt;#isHandlerOrSignalingContext. &quot;<br>
&gt;&gt; +       &lt;primitive: 199&gt;<br>
&gt;&gt; -       &quot;Evaluate the receiver in the scope of an exception handler.&quot;<br>
&gt;&gt; -<br>
&gt;&gt; -       | handlerActive |<br>
&gt;&gt; -       &lt;primitive: 199&gt;  &quot;just a marker, fail and execute the 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>
&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 the error<br>
&gt;&gt; handling context.<br>
&gt;&gt; +       See MethodContext&gt;&gt;#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 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 exception class<br>
&gt;&gt; (first arg) handles exception then return true, otherwise forward this<br>
&gt;&gt; message to the next handler context.  If none left, return false (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: exception<br>
&gt;&gt; ].!<br>
&gt;&gt; -       ^ (((self tempAt: 1) handles: exception) and: [self tempAt: 3])<br>
&gt;&gt; -               or: [self nextHandlerContext canHandleSignal: 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;#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 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;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;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 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 findNextHandlerOrSignalingContext.<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 context, it<br>
&gt;&gt; must be a signaling context.<br>
&gt;&gt; +       When we reach a signaling context we must skip over any handlers<br>
&gt;&gt; +       that might be on the stack between the signaling context and the<br>
&gt;&gt; handler<br>
&gt;&gt; +       context for that signal.&quot;<br>
&gt;&gt; +       ^ context exceptionClass privHandlerContext nextHandlerContext!<br>
&gt;&gt;<br>
&gt;&gt; Item was removed:<br>
&gt;&gt; - ----- Method: ContextPart&gt;&gt;findNextHandlerContextStarting (in category<br>
&gt;&gt; &#39;private-exceptions&#39;) -----<br>
&gt;&gt; - findNextHandlerContextStarting<br>
&gt;&gt; -       &quot;Return the next handler marked context, returning nil 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;findNextHandlerOrSignalingContext (in<br>
&gt;&gt; category &#39;private-exceptions&#39;) -----<br>
&gt;&gt; + findNextHandlerOrSignalingContext<br>
&gt;&gt; +       &quot;Return the next handler/signaling marked context, 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 exception class<br>
&gt;&gt; (first arg) handles exception then execute my handle block (second arg),<br>
&gt;&gt; otherwise forward this message to the next handler context.  If 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 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 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 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 == #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;isHandlerOrSignalingContext (in 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;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!<br>
&gt;&gt;<br>
&gt;&gt; Item was removed:<br>
&gt;&gt; - ----- Method: ContextPart&gt;&gt;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 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 &#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 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;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;isHandlerOrSignalingContext (in 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>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br>best,<div>Eliot</div>
</div></div>