<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"><<a href="mailto:frank.shearar@gmail.com" target="_blank">frank.shearar@gmail.com</a>></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 <<a href="mailto:eliot.miranda@gmail.com">eliot.miranda@gmail.com</a>> wrote:<br>
> Hi Frank,<br>
><br>
> I'd rather see<br>
><br>
> on: exception do: handlerAction<br>
> "Evaluate the receiver in the scope of an exception handler.<br>
> The following primitive is just a marker used to find the error<br>
> handling context.<br>
> See MethodContext>>#isHandlerOrSignalingContext. "<br>
> <primitive: 199><br>
> <handler><br>
> ^ self value!<br>
><br>
> isHandlerContext<br>
> "is this context for #on:do:?"<br>
> ^self isHandlerOrSignalingContext and: [ (self method pragmaAt:<br>
> #handler) notNil: ]<br>
><br>
> etc, rather than testing the selector.<br>
<br>
</span>OK, I see what you're doing there. I guess the only worry I have is<br>
that <handler> doesn't seem terribly specific to me.<br></blockquote><div><br></div><div>it can be as specific a label as you'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'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' 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="">> I'd also like to see the code in<br>
> MethodCOntext (e.g. where method can be directly accessed) than in<br>
> ContextPart. Remember that some time soon we can collapse ContextPart and<br>
> 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'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 -> ContextPart, or<br>
ContextPart -> 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'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>
> On Fri, Sep 12, 2014 at 1:40 PM, <<a href="mailto:commits@source.squeak.org">commits@source.squeak.org</a>> wrote:<br>
>><br>
>> 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<br>
>> long-standing bug in Cuis, Squeak and Pharo, in ExceptionsTests >><br>
>> #testHandlerFromAction.<br>
>><br>
>> However, it causes a regression in #testHandlerReentrancy, so as it stands<br>
>> it is NOT READY FOR MERGING.<br>
>><br>
>> Please take a look, and see if we can bend Andres' code slightly so that<br>
>> we get both the fix and don't break anything.<br>
>><br>
>> =============== Diff against Kernel-eem.869 ===============<br>
>><br>
>> Item was changed:<br>
>> ----- Method: BlockClosure>>on:do: (in category 'exceptions') -----<br>
>> on: exception do: handlerAction<br>
>> + "Evaluate the receiver in the scope of an exception handler.<br>
>> + The following primitive is just a marker used to find the error<br>
>> handling context.<br>
>> + See MethodContext>>#isHandlerOrSignalingContext. "<br>
>> + <primitive: 199><br>
>> - "Evaluate the receiver in the scope of an exception handler."<br>
>> -<br>
>> - | handlerActive |<br>
>> - <primitive: 199> "just a marker, fail and execute the following"<br>
>> - handlerActive := true.<br>
>> ^ self value!<br>
>><br>
>> Item was changed:<br>
>> ----- Method: BlockContext>>on:do: (in category 'exceptions') -----<br>
>> on: exception do: handlerAction<br>
>> + "Evaluate the receiver in the scope of an exception handler.<br>
>> + The following primitive is just a marker used to find the error<br>
>> handling context.<br>
>> + See MethodContext>>#isHandlerOrSignalingContext. "<br>
>> + <primitive: 199><br>
>> + ^ self value!<br>
>> - "Evaluate the receiver in the scope of an exception handler."<br>
>> - | handlerActive |<br>
>> - <primitive: 199><br>
>> - handlerActive := true.<br>
>> - ^self value!<br>
>><br>
>> Item was changed:<br>
>> ----- Method: ContextPart>>canHandleSignal: (in category<br>
>> 'private-exceptions') -----<br>
>> canHandleSignal: exception<br>
>> "Sent to handler (on:do:) contexts only. If my exception class<br>
>> (first arg) handles exception then return true, otherwise forward this<br>
>> message to the next handler context. If none left, return false (see<br>
>> nil>>canHandleSignal:)"<br>
>><br>
>> + ^ (self exceptionClass handles: exception)<br>
>> + or: [ self nextHandlerContext canHandleSignal: exception<br>
>> ].!<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>>evaluateSignal: (in category<br>
>> 'private-exceptions') -----<br>
>> + evaluateSignal: exception<br>
>> + "The following primitive is just a marker used to find the<br>
>> evaluation context.<br>
>> + See MethodContext>>#isHandlerOrSignalingContext. "<br>
>> +<br>
>> + <primitive: 199><br>
>> + | value |<br>
>> + exception privHandlerContext: self contextTag.<br>
>> + value := self exceptionHandlerBlock valueWithPossibleArgument:<br>
>> exception.<br>
>> + "return from self if not otherwise directed in handle block"<br>
>> + self return: value!<br>
>><br>
>> Item was added:<br>
>> + ----- Method: ContextPart>>exceptionClass (in category<br>
>> 'private-exceptions') -----<br>
>> + exceptionClass<br>
>> +<br>
>> + ^self tempAt: 1!<br>
>><br>
>> Item was added:<br>
>> + ----- Method: ContextPart>>exceptionHandlerBlock (in category<br>
>> 'private-exceptions') -----<br>
>> + exceptionHandlerBlock<br>
>> + "handler context only. access temporaries from<br>
>> BlockClosure>>#on:do:"<br>
>> +<br>
>> + ^self tempAt: 2!<br>
>><br>
>> Item was added:<br>
>> + ----- Method: ContextPart>>findNextHandlerContext (in category<br>
>> 'private-exceptions') -----<br>
>> + findNextHandlerContext<br>
>> + "Return the next handler marked context, returning nil if there is<br>
>> none. Search starts with self and proceeds up to nil."<br>
>> +<br>
>> + | context |<br>
>> + context := self findNextHandlerOrSignalingContext.<br>
>> + context isNil<br>
>> + ifTrue: [ ^ nil ].<br>
>> + context isHandlerContext<br>
>> + ifTrue: [ ^ context ]. "If it isn't a handler context, it<br>
>> 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<br>
>> handler<br>
>> + context for that signal."<br>
>> + ^ context exceptionClass privHandlerContext nextHandlerContext!<br>
>><br>
>> Item was removed:<br>
>> - ----- Method: ContextPart>>findNextHandlerContextStarting (in category<br>
>> 'private-exceptions') -----<br>
>> - findNextHandlerContextStarting<br>
>> - "Return the next handler marked context, returning nil if there is<br>
>> none. Search starts with self and proceeds up to nil."<br>
>> -<br>
>> - | ctx |<br>
>> - <primitive: 197><br>
>> - ctx := self.<br>
>> - [ctx isHandlerContext ifTrue:[^ctx].<br>
>> - (ctx := ctx sender) == nil ] whileFalse.<br>
>> - ^nil!<br>
>><br>
>> Item was added:<br>
>> + ----- Method: ContextPart>>findNextHandlerOrSignalingContext (in<br>
>> category 'private-exceptions') -----<br>
>> + findNextHandlerOrSignalingContext<br>
>> + "Return the next handler/signaling marked context, answering nil<br>
>> if there is none.<br>
>> + Search starts with self and proceeds up to nil."<br>
>> +<br>
>> + <primitive: 197><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>>handleSignal: (in category<br>
>> 'private-exceptions') -----<br>
>> handleSignal: exception<br>
>> "Sent to handler (on:do:) contexts only. If my exception class<br>
>> (first arg) handles exception then execute my handle block (second arg),<br>
>> otherwise forward this message to the next handler context. If none left,<br>
>> execute exception's defaultAction (see nil>>handleSignal:)."<br>
>><br>
>> + (self exceptionClass handles: exception)<br>
>> + ifFalse: [ ^ self nextHandlerContext handleSignal:<br>
>> exception ].<br>
>> + self evaluateSignal: exception!<br>
>> - | val |<br>
>> - (((self tempAt: 1) handles: exception) and: [self tempAt: 3])<br>
>> ifFalse: [<br>
>> - ^ self nextHandlerContext handleSignal: exception].<br>
>> -<br>
>> - exception privHandlerContext: self contextTag.<br>
>> - self tempAt: 3 put: false. "disable self while executing handle<br>
>> block"<br>
>> - val := [(self tempAt: 2) cull: exception ]<br>
>> - ensure: [self tempAt: 3 put: true].<br>
>> - self return: val. "return from self if not otherwise directed in<br>
>> handle block"<br>
>> - !<br>
>><br>
>> Item was changed:<br>
>> ----- Method: ContextPart>>isHandlerContext (in category<br>
>> 'private-exceptions') -----<br>
>> isHandlerContext<br>
>> + "is this context for #on:do:?"<br>
>> + ^self isHandlerOrSignalingContext and: [ self selector == #on:do:<br>
>> ]!<br>
>> - ^false!<br>
>><br>
>> Item was added:<br>
>> + ----- Method: ContextPart>>isHandlerOrSignalingContext (in category<br>
>> 'private-exceptions') -----<br>
>> + isHandlerOrSignalingContext<br>
>> + "Both BlockClosure>>on:do: (handler) and<br>
>> ContextPart>>evaluateSignal: (signaling)<br>
>> + are marked with primitive 199."<br>
>> +<br>
>> + ^false!<br>
>><br>
>> Item was changed:<br>
>> ----- Method: ContextPart>>nextHandlerContext (in category<br>
>> 'private-exceptions') -----<br>
>> nextHandlerContext<br>
>><br>
>> + ^ self sender findNextHandlerContext!<br>
>> - ^ self sender findNextHandlerContextStarting!<br>
>><br>
>> Item was removed:<br>
>> - ----- Method: ContextPart>>rearmHandlerDuring: (in category<br>
>> 'private-exceptions') -----<br>
>> - rearmHandlerDuring: aBlock<br>
>> - "Sent to handler (on:do:) contexts only. Makes me re-entrant for<br>
>> the duration of aBlock. Only works in a closure-enabled image"<br>
>> -<br>
>> - ^ [self tempAt: 3 put: true. aBlock value]<br>
>> - ensure: [self tempAt: 3 put: false]!<br>
>><br>
>> Item was added:<br>
>> + ----- Method: Exception>>privHandlerContext (in category 'priv<br>
>> handling') -----<br>
>> + privHandlerContext<br>
>> +<br>
>> + ^handlerContext!<br>
>><br>
>> Item was removed:<br>
>> - ----- Method: Exception>>rearmHandlerDuring: (in category 'handling')<br>
>> -----<br>
>> - rearmHandlerDuring: aBlock<br>
>> - "Make the current error handler re-entrant while it is running aBlock.<br>
>> Only works in a closure-enabled image"<br>
>> -<br>
>> - ^ handlerContext rearmHandlerDuring: aBlock!<br>
>><br>
>> Item was removed:<br>
>> - ----- Method: MethodContext>>isHandlerContext (in category<br>
>> 'private-exceptions') -----<br>
>> - isHandlerContext<br>
>> - "is this context for method that is marked?"<br>
>> - ^method primitive = 199!<br>
>><br>
>> Item was added:<br>
>> + ----- Method: MethodContext>>isHandlerOrSignalingContext (in category<br>
>> 'private-exceptions') -----<br>
>> + isHandlerOrSignalingContext<br>
>> + "Both BlockClosure>>on:do: (handler) and<br>
>> ContextPart>>evaluateSignal: (signaling)<br>
>> + are marked with primitive 199."<br>
>> +<br>
>> + ^method primitive = 199!<br>
>><br>
>><br>
><br>
><br>
><br>
> --<br>
> best,<br>
> Eliot<br>
><br>
><br>
><br>
<br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br>best,<div>Eliot</div>
</div></div>