<div dir="ltr">Hi Frank,<div><br></div><div>    I&#39;d rather see</div><div><br></div><div><span class="Apple-style-span" style="border-collapse:collapse;font-family:arial,sans-serif;font-size:14px;color:rgb(0,0,0)">on: exception do: handlerAction<br>       &quot;Evaluate the receiver in the scope of an exception handler.<br>       The following primitive is just a marker used to find the error handling context.<br>       See MethodContext&gt;&gt;#isHandlerOrSignalingContext. &quot;<br>       &lt;primitive: 199&gt;</span></div><div><span class="Apple-style-span" style="border-collapse:collapse;font-family:arial,sans-serif;font-size:14px;color:rgb(0,0,0)">       &lt;handler&gt;<br>       ^ self value!</span><br></div><div><span class="Apple-style-span" style="border-collapse:collapse;font-family:arial,sans-serif;font-size:14px;color:rgb(0,0,0)"><br></span></div><div><span class="Apple-style-span" style="border-collapse:collapse;font-family:arial,sans-serif;font-size:14px;color:rgb(0,0,0)">isHandlerContext<br>       &quot;is this context for #on:do:?&quot;<br>       ^self isHandlerOrSignalingContext and: [ (self method pragmaAt: #handler) notNil: ]<br></span></div><div><span class="Apple-style-span" style="border-collapse:collapse;font-family:arial,sans-serif;font-size:14px;color:rgb(0,0,0)"><br></span></div><div><span class="Apple-style-span" style="border-collapse:collapse;font-family:arial,sans-serif;font-size:14px;color:rgb(0,0,0)">etc, rather than testing the selector.  I&#39;d also like to see the code in MethodCOntext (e.g. where method can be directly accessed) than in ContextPart.  Remember that some time soon we can collapse ContextPart and MethodContext onto Context as the Pharo folks have already done.</span></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Sep 12, 2014 at 1:40 PM,  <span dir="ltr">&lt;<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Frank Shearar uploaded a new version of Kernel to project The Inbox:<br>
<a href="http://source.squeak.org/inbox/Kernel-fbs.870.mcz" target="_blank">http://source.squeak.org/inbox/Kernel-fbs.870.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: Kernel-fbs.870<br>
Author: fbs<br>
Time: 12 September 2014, 9:40:45.406 pm<br>
UUID: 868e0d8a-5e9d-d34d-ba2d-688800331f5b<br>
Ancestors: Kernel-eem.869<br>
<br>
These are the changes Andres Valloud made to Cuis, to address a long-standing bug in Cuis, Squeak and Pharo, in ExceptionsTests &gt;&gt; #testHandlerFromAction.<br>
<br>
However, it causes a regression in #testHandlerReentrancy, so as it stands it is NOT READY FOR MERGING.<br>
<br>
Please take a look, and see if we can bend Andres&#39; code slightly so that we get both the fix and don&#39;t break anything.<br>
<br>
=============== Diff against Kernel-eem.869 ===============<br>
<br>
Item was changed:<br>
  ----- Method: BlockClosure&gt;&gt;on:do: (in category &#39;exceptions&#39;) -----<br>
  on: exception do: handlerAction<br>
+       &quot;Evaluate the receiver in the scope of an exception handler.<br>
+       The following primitive is just a marker used to find the error handling context.<br>
+       See MethodContext&gt;&gt;#isHandlerOrSignalingContext. &quot;<br>
+       &lt;primitive: 199&gt;<br>
-       &quot;Evaluate the receiver in the scope of an exception handler.&quot;<br>
-<br>
-       | handlerActive |<br>
-       &lt;primitive: 199&gt;  &quot;just a marker, fail and execute the following&quot;<br>
-       handlerActive := true.<br>
        ^ self value!<br>
<br>
Item was changed:<br>
  ----- Method: BlockContext&gt;&gt;on:do: (in category &#39;exceptions&#39;) -----<br>
  on: exception do: handlerAction<br>
+       &quot;Evaluate the receiver in the scope of an exception handler.<br>
+       The following primitive is just a marker used to find the error handling context.<br>
+       See MethodContext&gt;&gt;#isHandlerOrSignalingContext. &quot;<br>
+       &lt;primitive: 199&gt;<br>
+       ^ self value!<br>
-       &quot;Evaluate the receiver in the scope of an exception handler.&quot;<br>
-       | handlerActive |<br>
-       &lt;primitive: 199&gt;<br>
-       handlerActive := true.<br>
-       ^self value!<br>
<br>
Item was changed:<br>
  ----- Method: ContextPart&gt;&gt;canHandleSignal: (in category &#39;private-exceptions&#39;) -----<br>
  canHandleSignal: exception<br>
        &quot;Sent to handler (on:do:) contexts only.  If my exception class (first arg) handles exception then return true, otherwise forward this message to the next handler context.  If none left, return false (see nil&gt;&gt;canHandleSignal:)&quot;<br>
<br>
+       ^ (self exceptionClass handles: exception)<br>
+               or: [ self nextHandlerContext canHandleSignal: exception ].!<br>
-       ^ (((self tempAt: 1) handles: exception) and: [self tempAt: 3])<br>
-               or: [self nextHandlerContext canHandleSignal: exception].<br>
- !<br>
<br>
Item was added:<br>
+ ----- Method: ContextPart&gt;&gt;evaluateSignal: (in category &#39;private-exceptions&#39;) -----<br>
+ evaluateSignal: exception<br>
+       &quot;The following primitive is just a marker used to find the evaluation context.<br>
+       See MethodContext&gt;&gt;#isHandlerOrSignalingContext. &quot;<br>
+<br>
+       &lt;primitive: 199&gt;<br>
+       | value |<br>
+       exception privHandlerContext: self contextTag.<br>
+       value := self exceptionHandlerBlock valueWithPossibleArgument: exception.<br>
+       &quot;return from self if not otherwise directed in handle block&quot;<br>
+       self return: value!<br>
<br>
Item was added:<br>
+ ----- Method: ContextPart&gt;&gt;exceptionClass (in category &#39;private-exceptions&#39;) -----<br>
+ exceptionClass<br>
+<br>
+       ^self tempAt: 1!<br>
<br>
Item was added:<br>
+ ----- Method: ContextPart&gt;&gt;exceptionHandlerBlock (in category &#39;private-exceptions&#39;) -----<br>
+ exceptionHandlerBlock<br>
+       &quot;handler context only. access temporaries from BlockClosure&gt;&gt;#on:do:&quot;<br>
+<br>
+       ^self tempAt: 2!<br>
<br>
Item was added:<br>
+ ----- Method: ContextPart&gt;&gt;findNextHandlerContext (in category &#39;private-exceptions&#39;) -----<br>
+ findNextHandlerContext<br>
+       &quot;Return the next handler marked context, returning nil if there is none.  Search starts with self and proceeds up to nil.&quot;<br>
+<br>
+       | context |<br>
+       context := self findNextHandlerOrSignalingContext.<br>
+       context isNil<br>
+               ifTrue: [ ^ nil ].<br>
+       context isHandlerContext<br>
+               ifTrue: [ ^ context ].  &quot;If it isn&#39;t a handler context, it must be a signaling context.<br>
+       When we reach a signaling context we must skip over any handlers<br>
+       that might be on the stack between the signaling context and the handler<br>
+       context for that signal.&quot;<br>
+       ^ context exceptionClass privHandlerContext nextHandlerContext!<br>
<br>
Item was removed:<br>
- ----- Method: ContextPart&gt;&gt;findNextHandlerContextStarting (in category &#39;private-exceptions&#39;) -----<br>
- findNextHandlerContextStarting<br>
-       &quot;Return the next handler marked context, returning nil if there is none.  Search starts with self and proceeds up to nil.&quot;<br>
-<br>
-       | ctx |<br>
-       &lt;primitive: 197&gt;<br>
-       ctx := self.<br>
-               [ctx isHandlerContext ifTrue:[^ctx].<br>
-               (ctx := ctx sender) == nil ] whileFalse.<br>
-       ^nil!<br>
<br>
Item was added:<br>
+ ----- Method: ContextPart&gt;&gt;findNextHandlerOrSignalingContext (in category &#39;private-exceptions&#39;) -----<br>
+ findNextHandlerOrSignalingContext<br>
+       &quot;Return the next handler/signaling marked context, answering nil if there is none.<br>
+       Search starts with self and proceeds up to nil.&quot;<br>
+<br>
+       &lt;primitive: 197&gt;<br>
+       | context |<br>
+       context := self.<br>
+       [<br>
+       context isHandlerOrSignalingContext<br>
+               ifTrue: [ ^ context ].<br>
+       (context := context sender) == nil ] whileFalse.<br>
+       ^ nil!<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>
+       (self exceptionClass handles: exception)<br>
+               ifFalse: [ ^ self nextHandlerContext handleSignal: exception ].<br>
+       self evaluateSignal: exception!<br>
-       | val |<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>
Item was changed:<br>
  ----- Method: ContextPart&gt;&gt;isHandlerContext (in category &#39;private-exceptions&#39;) -----<br>
  isHandlerContext<br>
+       &quot;is this context for #on:do:?&quot;<br>
+       ^self isHandlerOrSignalingContext and: [ self selector == #on:do: ]!<br>
-       ^false!<br>
<br>
Item was added:<br>
+ ----- Method: ContextPart&gt;&gt;isHandlerOrSignalingContext (in category &#39;private-exceptions&#39;) -----<br>
+ isHandlerOrSignalingContext<br>
+       &quot;Both BlockClosure&gt;&gt;on:do: (handler) and ContextPart&gt;&gt;evaluateSignal: (signaling)<br>
+       are marked with primitive 199.&quot;<br>
+<br>
+       ^false!<br>
<br>
Item was changed:<br>
  ----- Method: ContextPart&gt;&gt;nextHandlerContext (in category &#39;private-exceptions&#39;) -----<br>
  nextHandlerContext<br>
<br>
+       ^ self sender findNextHandlerContext!<br>
-       ^ self sender findNextHandlerContextStarting!<br>
<br>
Item was removed:<br>
- ----- Method: ContextPart&gt;&gt;rearmHandlerDuring: (in category &#39;private-exceptions&#39;) -----<br>
- rearmHandlerDuring: aBlock<br>
-       &quot;Sent to handler (on:do:) contexts only. Makes me re-entrant for the duration of aBlock. Only works in a closure-enabled image&quot;<br>
-<br>
-       ^ [self tempAt: 3 put: true. aBlock value]<br>
-               ensure: [self tempAt: 3 put: false]!<br>
<br>
Item was added:<br>
+ ----- Method: Exception&gt;&gt;privHandlerContext (in category &#39;priv handling&#39;) -----<br>
+ privHandlerContext<br>
+<br>
+       ^handlerContext!<br>
<br>
Item was removed:<br>
- ----- Method: Exception&gt;&gt;rearmHandlerDuring: (in category &#39;handling&#39;) -----<br>
- rearmHandlerDuring: aBlock<br>
- &quot;Make the current error handler re-entrant while it is running aBlock. Only works in a closure-enabled image&quot;<br>
-<br>
-       ^ handlerContext rearmHandlerDuring: aBlock!<br>
<br>
Item was removed:<br>
- ----- Method: MethodContext&gt;&gt;isHandlerContext (in category &#39;private-exceptions&#39;) -----<br>
- isHandlerContext<br>
- &quot;is this context for  method that is marked?&quot;<br>
-       ^method primitive = 199!<br>
<br>
Item was added:<br>
+ ----- Method: MethodContext&gt;&gt;isHandlerOrSignalingContext (in category &#39;private-exceptions&#39;) -----<br>
+ isHandlerOrSignalingContext<br>
+       &quot;Both BlockClosure&gt;&gt;on:do: (handler) and ContextPart&gt;&gt;evaluateSignal: (signaling)<br>
+       are marked with primitive 199.&quot;<br>
+<br>
+       ^method primitive = 199!<br>
<br>
<br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br>best,<div>Eliot</div>
</div>