The Inbox: Kernel-fbs.870.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

The Inbox: Kernel-fbs.870.mcz

commits-2
Frank Shearar uploaded a new version of Kernel to project The Inbox:
http://source.squeak.org/inbox/Kernel-fbs.870.mcz

==================== Summary ====================

Name: Kernel-fbs.870
Author: fbs
Time: 12 September 2014, 9:40:45.406 pm
UUID: 868e0d8a-5e9d-d34d-ba2d-688800331f5b
Ancestors: Kernel-eem.869

These are the changes Andres Valloud made to Cuis, to address a long-standing bug in Cuis, Squeak and Pharo, in ExceptionsTests >> #testHandlerFromAction.

However, it causes a regression in #testHandlerReentrancy, so as it stands it is NOT READY FOR MERGING.

Please take a look, and see if we can bend Andres' code slightly so that we get both the fix and don't break anything.

=============== Diff against Kernel-eem.869 ===============

Item was changed:
  ----- Method: BlockClosure>>on:do: (in category 'exceptions') -----
  on: exception do: handlerAction
+ "Evaluate the receiver in the scope of an exception handler.
+ The following primitive is just a marker used to find the error handling context.
+ See MethodContext>>#isHandlerOrSignalingContext. "
+ <primitive: 199>  
- "Evaluate the receiver in the scope of an exception handler."
-
- | handlerActive |
- <primitive: 199>  "just a marker, fail and execute the following"
- handlerActive := true.
  ^ self value!

Item was changed:
  ----- Method: BlockContext>>on:do: (in category 'exceptions') -----
  on: exception do: handlerAction
+ "Evaluate the receiver in the scope of an exception handler.
+ The following primitive is just a marker used to find the error handling context.
+ See MethodContext>>#isHandlerOrSignalingContext. "
+ <primitive: 199>  
+ ^ self value!
- "Evaluate the receiver in the scope of an exception handler."
- | handlerActive |
- <primitive: 199>
- handlerActive := true.
- ^self value!

Item was changed:
  ----- Method: ContextPart>>canHandleSignal: (in category 'private-exceptions') -----
  canHandleSignal: exception
  "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>>canHandleSignal:)"
 
+ ^ (self exceptionClass handles: exception)
+ or: [ self nextHandlerContext canHandleSignal: exception ].!
- ^ (((self tempAt: 1) handles: exception) and: [self tempAt: 3])
- or: [self nextHandlerContext canHandleSignal: exception].
- !

Item was added:
+ ----- Method: ContextPart>>evaluateSignal: (in category 'private-exceptions') -----
+ evaluateSignal: exception
+ "The following primitive is just a marker used to find the evaluation context.
+ See MethodContext>>#isHandlerOrSignalingContext. "
+
+ <primitive: 199>
+ | value |
+ exception privHandlerContext: self contextTag.
+ value := self exceptionHandlerBlock valueWithPossibleArgument: exception.
+ "return from self if not otherwise directed in handle block"
+ self return: value!

Item was added:
+ ----- Method: ContextPart>>exceptionClass (in category 'private-exceptions') -----
+ exceptionClass
+
+ ^self tempAt: 1!

Item was added:
+ ----- Method: ContextPart>>exceptionHandlerBlock (in category 'private-exceptions') -----
+ exceptionHandlerBlock
+ "handler context only. access temporaries from BlockClosure>>#on:do:"
+
+ ^self tempAt: 2!

Item was added:
+ ----- Method: ContextPart>>findNextHandlerContext (in category 'private-exceptions') -----
+ findNextHandlerContext
+ "Return the next handler marked context, returning nil if there is none.  Search starts with self and proceeds up to nil."
+
+ | context |
+ context := self findNextHandlerOrSignalingContext.
+ context isNil
+ ifTrue: [ ^ nil ].
+ context isHandlerContext
+ ifTrue: [ ^ context ]. "If it isn't a handler context, it must be a signaling context.
+ When we reach a signaling context we must skip over any handlers
+ that might be on the stack between the signaling context and the handler
+ context for that signal."
+ ^ context exceptionClass privHandlerContext nextHandlerContext!

Item was removed:
- ----- Method: ContextPart>>findNextHandlerContextStarting (in category 'private-exceptions') -----
- findNextHandlerContextStarting
- "Return the next handler marked context, returning nil if there is none.  Search starts with self and proceeds up to nil."
-
- | ctx |
- <primitive: 197>
- ctx := self.
- [ctx isHandlerContext ifTrue:[^ctx].
- (ctx := ctx sender) == nil ] whileFalse.
- ^nil!

Item was added:
+ ----- Method: ContextPart>>findNextHandlerOrSignalingContext (in category 'private-exceptions') -----
+ findNextHandlerOrSignalingContext
+ "Return the next handler/signaling marked context, answering nil if there is none.
+ Search starts with self and proceeds up to nil."
+
+ <primitive: 197>
+ | context |
+ context := self.
+ [
+ context isHandlerOrSignalingContext
+ ifTrue: [ ^ context ].
+ (context := context sender) == nil ] whileFalse.
+ ^ nil!

Item was changed:
  ----- Method: ContextPart>>handleSignal: (in category 'private-exceptions') -----
  handleSignal: exception
  "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's defaultAction (see nil>>handleSignal:)."
 
+ (self exceptionClass handles: exception)
+ ifFalse: [ ^ self nextHandlerContext handleSignal: exception ].
+ self evaluateSignal: exception!
- | val |
- (((self tempAt: 1) handles: exception) and: [self tempAt: 3]) ifFalse: [
- ^ self nextHandlerContext handleSignal: exception].
-
- exception privHandlerContext: self contextTag.
- self tempAt: 3 put: false.  "disable self while executing handle block"
- val := [(self tempAt: 2) cull: exception ]
- ensure: [self tempAt: 3 put: true].
- self return: val.  "return from self if not otherwise directed in handle block"
- !

Item was changed:
  ----- Method: ContextPart>>isHandlerContext (in category 'private-exceptions') -----
  isHandlerContext
+ "is this context for #on:do:?"
+ ^self isHandlerOrSignalingContext and: [ self selector == #on:do: ]!
- ^false!

Item was added:
+ ----- Method: ContextPart>>isHandlerOrSignalingContext (in category 'private-exceptions') -----
+ isHandlerOrSignalingContext
+ "Both BlockClosure>>on:do: (handler) and ContextPart>>evaluateSignal: (signaling)
+ are marked with primitive 199."
+
+ ^false!

Item was changed:
  ----- Method: ContextPart>>nextHandlerContext (in category 'private-exceptions') -----
  nextHandlerContext
 
+ ^ self sender findNextHandlerContext!
- ^ self sender findNextHandlerContextStarting!

Item was removed:
- ----- Method: ContextPart>>rearmHandlerDuring: (in category 'private-exceptions') -----
- rearmHandlerDuring: aBlock
- "Sent to handler (on:do:) contexts only. Makes me re-entrant for the duration of aBlock. Only works in a closure-enabled image"
-
- ^ [self tempAt: 3 put: true. aBlock value]
- ensure: [self tempAt: 3 put: false]!

Item was added:
+ ----- Method: Exception>>privHandlerContext (in category 'priv handling') -----
+ privHandlerContext
+
+ ^handlerContext!

Item was removed:
- ----- Method: Exception>>rearmHandlerDuring: (in category 'handling') -----
- rearmHandlerDuring: aBlock
- "Make the current error handler re-entrant while it is running aBlock. Only works in a closure-enabled image"
-
- ^ handlerContext rearmHandlerDuring: aBlock!

Item was removed:
- ----- Method: MethodContext>>isHandlerContext (in category 'private-exceptions') -----
- isHandlerContext
- "is this context for  method that is marked?"
- ^method primitive = 199!

Item was added:
+ ----- Method: MethodContext>>isHandlerOrSignalingContext (in category 'private-exceptions') -----
+ isHandlerOrSignalingContext
+ "Both BlockClosure>>on:do: (handler) and ContextPart>>evaluateSignal: (signaling)
+ are marked with primitive 199."
+
+ ^method primitive = 199!


Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Kernel-fbs.870.mcz

Eliot Miranda-2
Hi Frank,

    I'd rather see

on: exception do: handlerAction
       "Evaluate the receiver in the scope of an exception handler.
       The following primitive is just a marker used to find the error handling context.
       See MethodContext>>#isHandlerOrSignalingContext. "
       <primitive: 199>
       <handler>
       ^ self value!


isHandlerContext
       "is this context for #on:do:?"
       ^self isHandlerOrSignalingContext and: [ (self method pragmaAt: #handler) notNil: ]

etc, rather than testing the selector.  I'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.

On Fri, Sep 12, 2014 at 1:40 PM, <[hidden email]> wrote:
Frank Shearar uploaded a new version of Kernel to project The Inbox:
http://source.squeak.org/inbox/Kernel-fbs.870.mcz

==================== Summary ====================

Name: Kernel-fbs.870
Author: fbs
Time: 12 September 2014, 9:40:45.406 pm
UUID: 868e0d8a-5e9d-d34d-ba2d-688800331f5b
Ancestors: Kernel-eem.869

These are the changes Andres Valloud made to Cuis, to address a long-standing bug in Cuis, Squeak and Pharo, in ExceptionsTests >> #testHandlerFromAction.

However, it causes a regression in #testHandlerReentrancy, so as it stands it is NOT READY FOR MERGING.

Please take a look, and see if we can bend Andres' code slightly so that we get both the fix and don't break anything.

=============== Diff against Kernel-eem.869 ===============

Item was changed:
  ----- Method: BlockClosure>>on:do: (in category 'exceptions') -----
  on: exception do: handlerAction
+       "Evaluate the receiver in the scope of an exception handler.
+       The following primitive is just a marker used to find the error handling context.
+       See MethodContext>>#isHandlerOrSignalingContext. "
+       <primitive: 199>
-       "Evaluate the receiver in the scope of an exception handler."
-
-       | handlerActive |
-       <primitive: 199>  "just a marker, fail and execute the following"
-       handlerActive := true.
        ^ self value!

Item was changed:
  ----- Method: BlockContext>>on:do: (in category 'exceptions') -----
  on: exception do: handlerAction
+       "Evaluate the receiver in the scope of an exception handler.
+       The following primitive is just a marker used to find the error handling context.
+       See MethodContext>>#isHandlerOrSignalingContext. "
+       <primitive: 199>
+       ^ self value!
-       "Evaluate the receiver in the scope of an exception handler."
-       | handlerActive |
-       <primitive: 199>
-       handlerActive := true.
-       ^self value!

Item was changed:
  ----- Method: ContextPart>>canHandleSignal: (in category 'private-exceptions') -----
  canHandleSignal: exception
        "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>>canHandleSignal:)"

+       ^ (self exceptionClass handles: exception)
+               or: [ self nextHandlerContext canHandleSignal: exception ].!
-       ^ (((self tempAt: 1) handles: exception) and: [self tempAt: 3])
-               or: [self nextHandlerContext canHandleSignal: exception].
- !

Item was added:
+ ----- Method: ContextPart>>evaluateSignal: (in category 'private-exceptions') -----
+ evaluateSignal: exception
+       "The following primitive is just a marker used to find the evaluation context.
+       See MethodContext>>#isHandlerOrSignalingContext. "
+
+       <primitive: 199>
+       | value |
+       exception privHandlerContext: self contextTag.
+       value := self exceptionHandlerBlock valueWithPossibleArgument: exception.
+       "return from self if not otherwise directed in handle block"
+       self return: value!

Item was added:
+ ----- Method: ContextPart>>exceptionClass (in category 'private-exceptions') -----
+ exceptionClass
+
+       ^self tempAt: 1!

Item was added:
+ ----- Method: ContextPart>>exceptionHandlerBlock (in category 'private-exceptions') -----
+ exceptionHandlerBlock
+       "handler context only. access temporaries from BlockClosure>>#on:do:"
+
+       ^self tempAt: 2!

Item was added:
+ ----- Method: ContextPart>>findNextHandlerContext (in category 'private-exceptions') -----
+ findNextHandlerContext
+       "Return the next handler marked context, returning nil if there is none.  Search starts with self and proceeds up to nil."
+
+       | context |
+       context := self findNextHandlerOrSignalingContext.
+       context isNil
+               ifTrue: [ ^ nil ].
+       context isHandlerContext
+               ifTrue: [ ^ context ].  "If it isn't a handler context, it must be a signaling context.
+       When we reach a signaling context we must skip over any handlers
+       that might be on the stack between the signaling context and the handler
+       context for that signal."
+       ^ context exceptionClass privHandlerContext nextHandlerContext!

Item was removed:
- ----- Method: ContextPart>>findNextHandlerContextStarting (in category 'private-exceptions') -----
- findNextHandlerContextStarting
-       "Return the next handler marked context, returning nil if there is none.  Search starts with self and proceeds up to nil."
-
-       | ctx |
-       <primitive: 197>
-       ctx := self.
-               [ctx isHandlerContext ifTrue:[^ctx].
-               (ctx := ctx sender) == nil ] whileFalse.
-       ^nil!

Item was added:
+ ----- Method: ContextPart>>findNextHandlerOrSignalingContext (in category 'private-exceptions') -----
+ findNextHandlerOrSignalingContext
+       "Return the next handler/signaling marked context, answering nil if there is none.
+       Search starts with self and proceeds up to nil."
+
+       <primitive: 197>
+       | context |
+       context := self.
+       [
+       context isHandlerOrSignalingContext
+               ifTrue: [ ^ context ].
+       (context := context sender) == nil ] whileFalse.
+       ^ nil!

Item was changed:
  ----- Method: ContextPart>>handleSignal: (in category 'private-exceptions') -----
  handleSignal: exception
        "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's defaultAction (see nil>>handleSignal:)."

+       (self exceptionClass handles: exception)
+               ifFalse: [ ^ self nextHandlerContext handleSignal: exception ].
+       self evaluateSignal: exception!
-       | val |
-       (((self tempAt: 1) handles: exception) and: [self tempAt: 3]) ifFalse: [
-               ^ self nextHandlerContext handleSignal: exception].
-
-       exception privHandlerContext: self contextTag.
-       self tempAt: 3 put: false.  "disable self while executing handle block"
-       val := [(self tempAt: 2) cull: exception ]
-               ensure: [self tempAt: 3 put: true].
-       self return: val.  "return from self if not otherwise directed in handle block"
- !

Item was changed:
  ----- Method: ContextPart>>isHandlerContext (in category 'private-exceptions') -----
  isHandlerContext
+       "is this context for #on:do:?"
+       ^self isHandlerOrSignalingContext and: [ self selector == #on:do: ]!
-       ^false!

Item was added:
+ ----- Method: ContextPart>>isHandlerOrSignalingContext (in category 'private-exceptions') -----
+ isHandlerOrSignalingContext
+       "Both BlockClosure>>on:do: (handler) and ContextPart>>evaluateSignal: (signaling)
+       are marked with primitive 199."
+
+       ^false!

Item was changed:
  ----- Method: ContextPart>>nextHandlerContext (in category 'private-exceptions') -----
  nextHandlerContext

+       ^ self sender findNextHandlerContext!
-       ^ self sender findNextHandlerContextStarting!

Item was removed:
- ----- Method: ContextPart>>rearmHandlerDuring: (in category 'private-exceptions') -----
- rearmHandlerDuring: aBlock
-       "Sent to handler (on:do:) contexts only. Makes me re-entrant for the duration of aBlock. Only works in a closure-enabled image"
-
-       ^ [self tempAt: 3 put: true. aBlock value]
-               ensure: [self tempAt: 3 put: false]!

Item was added:
+ ----- Method: Exception>>privHandlerContext (in category 'priv handling') -----
+ privHandlerContext
+
+       ^handlerContext!

Item was removed:
- ----- Method: Exception>>rearmHandlerDuring: (in category 'handling') -----
- rearmHandlerDuring: aBlock
- "Make the current error handler re-entrant while it is running aBlock. Only works in a closure-enabled image"
-
-       ^ handlerContext rearmHandlerDuring: aBlock!

Item was removed:
- ----- Method: MethodContext>>isHandlerContext (in category 'private-exceptions') -----
- isHandlerContext
- "is this context for  method that is marked?"
-       ^method primitive = 199!

Item was added:
+ ----- Method: MethodContext>>isHandlerOrSignalingContext (in category 'private-exceptions') -----
+ isHandlerOrSignalingContext
+       "Both BlockClosure>>on:do: (handler) and ContextPart>>evaluateSignal: (signaling)
+       are marked with primitive 199."
+
+       ^method primitive = 199!





--
best,
Eliot


Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Kernel-fbs.870.mcz

Frank Shearar-3
On 12 September 2014 21:49, Eliot Miranda <[hidden email]> wrote:

> Hi Frank,
>
>     I'd rather see
>
> on: exception do: handlerAction
>        "Evaluate the receiver in the scope of an exception handler.
>        The following primitive is just a marker used to find the error
> handling context.
>        See MethodContext>>#isHandlerOrSignalingContext. "
>        <primitive: 199>
>        <handler>
>        ^ self value!
>
> isHandlerContext
>        "is this context for #on:do:?"
>        ^self isHandlerOrSignalingContext and: [ (self method pragmaAt:
> #handler) notNil: ]
>
> etc, rather than testing the selector.

OK, I see what you're doing there. I guess the only worry I have is
that <handler> doesn't seem terribly specific to me.

One thing I don't get is the tempAt: 3 stuff. This code removes it,
and that seems to be the root of why #testHandlerReentrancy fails. But
this is beyond my depth (which is most of why I made Andres' code more
available for those for home this is _not_ out of depth).

>  I'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.

Right, because BlockContext has been marked for death? (Because
MethodContext has a closureOrNil instvar, which disambiguates between
MethodContexts-for-block-activations and
MethodContexts-for-method-activations.)

But since at some point we're going to merge MethodContext and
ContextPart, why not just leave the code where it is? I guess it just
depends on whether we merge MethodContext -> ContextPart, or
ContextPart -> MethodContext.

frank

> On Fri, Sep 12, 2014 at 1:40 PM, <[hidden email]> wrote:
>>
>> Frank Shearar uploaded a new version of Kernel to project The Inbox:
>> http://source.squeak.org/inbox/Kernel-fbs.870.mcz
>>
>> ==================== Summary ====================
>>
>> Name: Kernel-fbs.870
>> Author: fbs
>> Time: 12 September 2014, 9:40:45.406 pm
>> UUID: 868e0d8a-5e9d-d34d-ba2d-688800331f5b
>> Ancestors: Kernel-eem.869
>>
>> These are the changes Andres Valloud made to Cuis, to address a
>> long-standing bug in Cuis, Squeak and Pharo, in ExceptionsTests >>
>> #testHandlerFromAction.
>>
>> However, it causes a regression in #testHandlerReentrancy, so as it stands
>> it is NOT READY FOR MERGING.
>>
>> Please take a look, and see if we can bend Andres' code slightly so that
>> we get both the fix and don't break anything.
>>
>> =============== Diff against Kernel-eem.869 ===============
>>
>> Item was changed:
>>   ----- Method: BlockClosure>>on:do: (in category 'exceptions') -----
>>   on: exception do: handlerAction
>> +       "Evaluate the receiver in the scope of an exception handler.
>> +       The following primitive is just a marker used to find the error
>> handling context.
>> +       See MethodContext>>#isHandlerOrSignalingContext. "
>> +       <primitive: 199>
>> -       "Evaluate the receiver in the scope of an exception handler."
>> -
>> -       | handlerActive |
>> -       <primitive: 199>  "just a marker, fail and execute the following"
>> -       handlerActive := true.
>>         ^ self value!
>>
>> Item was changed:
>>   ----- Method: BlockContext>>on:do: (in category 'exceptions') -----
>>   on: exception do: handlerAction
>> +       "Evaluate the receiver in the scope of an exception handler.
>> +       The following primitive is just a marker used to find the error
>> handling context.
>> +       See MethodContext>>#isHandlerOrSignalingContext. "
>> +       <primitive: 199>
>> +       ^ self value!
>> -       "Evaluate the receiver in the scope of an exception handler."
>> -       | handlerActive |
>> -       <primitive: 199>
>> -       handlerActive := true.
>> -       ^self value!
>>
>> Item was changed:
>>   ----- Method: ContextPart>>canHandleSignal: (in category
>> 'private-exceptions') -----
>>   canHandleSignal: exception
>>         "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>>canHandleSignal:)"
>>
>> +       ^ (self exceptionClass handles: exception)
>> +               or: [ self nextHandlerContext canHandleSignal: exception
>> ].!
>> -       ^ (((self tempAt: 1) handles: exception) and: [self tempAt: 3])
>> -               or: [self nextHandlerContext canHandleSignal: exception].
>> - !
>>
>> Item was added:
>> + ----- Method: ContextPart>>evaluateSignal: (in category
>> 'private-exceptions') -----
>> + evaluateSignal: exception
>> +       "The following primitive is just a marker used to find the
>> evaluation context.
>> +       See MethodContext>>#isHandlerOrSignalingContext. "
>> +
>> +       <primitive: 199>
>> +       | value |
>> +       exception privHandlerContext: self contextTag.
>> +       value := self exceptionHandlerBlock valueWithPossibleArgument:
>> exception.
>> +       "return from self if not otherwise directed in handle block"
>> +       self return: value!
>>
>> Item was added:
>> + ----- Method: ContextPart>>exceptionClass (in category
>> 'private-exceptions') -----
>> + exceptionClass
>> +
>> +       ^self tempAt: 1!
>>
>> Item was added:
>> + ----- Method: ContextPart>>exceptionHandlerBlock (in category
>> 'private-exceptions') -----
>> + exceptionHandlerBlock
>> +       "handler context only. access temporaries from
>> BlockClosure>>#on:do:"
>> +
>> +       ^self tempAt: 2!
>>
>> Item was added:
>> + ----- Method: ContextPart>>findNextHandlerContext (in category
>> 'private-exceptions') -----
>> + findNextHandlerContext
>> +       "Return the next handler marked context, returning nil if there is
>> none.  Search starts with self and proceeds up to nil."
>> +
>> +       | context |
>> +       context := self findNextHandlerOrSignalingContext.
>> +       context isNil
>> +               ifTrue: [ ^ nil ].
>> +       context isHandlerContext
>> +               ifTrue: [ ^ context ].  "If it isn't a handler context, it
>> must be a signaling context.
>> +       When we reach a signaling context we must skip over any handlers
>> +       that might be on the stack between the signaling context and the
>> handler
>> +       context for that signal."
>> +       ^ context exceptionClass privHandlerContext nextHandlerContext!
>>
>> Item was removed:
>> - ----- Method: ContextPart>>findNextHandlerContextStarting (in category
>> 'private-exceptions') -----
>> - findNextHandlerContextStarting
>> -       "Return the next handler marked context, returning nil if there is
>> none.  Search starts with self and proceeds up to nil."
>> -
>> -       | ctx |
>> -       <primitive: 197>
>> -       ctx := self.
>> -               [ctx isHandlerContext ifTrue:[^ctx].
>> -               (ctx := ctx sender) == nil ] whileFalse.
>> -       ^nil!
>>
>> Item was added:
>> + ----- Method: ContextPart>>findNextHandlerOrSignalingContext (in
>> category 'private-exceptions') -----
>> + findNextHandlerOrSignalingContext
>> +       "Return the next handler/signaling marked context, answering nil
>> if there is none.
>> +       Search starts with self and proceeds up to nil."
>> +
>> +       <primitive: 197>
>> +       | context |
>> +       context := self.
>> +       [
>> +       context isHandlerOrSignalingContext
>> +               ifTrue: [ ^ context ].
>> +       (context := context sender) == nil ] whileFalse.
>> +       ^ nil!
>>
>> Item was changed:
>>   ----- Method: ContextPart>>handleSignal: (in category
>> 'private-exceptions') -----
>>   handleSignal: exception
>>         "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's defaultAction (see nil>>handleSignal:)."
>>
>> +       (self exceptionClass handles: exception)
>> +               ifFalse: [ ^ self nextHandlerContext handleSignal:
>> exception ].
>> +       self evaluateSignal: exception!
>> -       | val |
>> -       (((self tempAt: 1) handles: exception) and: [self tempAt: 3])
>> ifFalse: [
>> -               ^ self nextHandlerContext handleSignal: exception].
>> -
>> -       exception privHandlerContext: self contextTag.
>> -       self tempAt: 3 put: false.  "disable self while executing handle
>> block"
>> -       val := [(self tempAt: 2) cull: exception ]
>> -               ensure: [self tempAt: 3 put: true].
>> -       self return: val.  "return from self if not otherwise directed in
>> handle block"
>> - !
>>
>> Item was changed:
>>   ----- Method: ContextPart>>isHandlerContext (in category
>> 'private-exceptions') -----
>>   isHandlerContext
>> +       "is this context for #on:do:?"
>> +       ^self isHandlerOrSignalingContext and: [ self selector == #on:do:
>> ]!
>> -       ^false!
>>
>> Item was added:
>> + ----- Method: ContextPart>>isHandlerOrSignalingContext (in category
>> 'private-exceptions') -----
>> + isHandlerOrSignalingContext
>> +       "Both BlockClosure>>on:do: (handler) and
>> ContextPart>>evaluateSignal: (signaling)
>> +       are marked with primitive 199."
>> +
>> +       ^false!
>>
>> Item was changed:
>>   ----- Method: ContextPart>>nextHandlerContext (in category
>> 'private-exceptions') -----
>>   nextHandlerContext
>>
>> +       ^ self sender findNextHandlerContext!
>> -       ^ self sender findNextHandlerContextStarting!
>>
>> Item was removed:
>> - ----- Method: ContextPart>>rearmHandlerDuring: (in category
>> 'private-exceptions') -----
>> - rearmHandlerDuring: aBlock
>> -       "Sent to handler (on:do:) contexts only. Makes me re-entrant for
>> the duration of aBlock. Only works in a closure-enabled image"
>> -
>> -       ^ [self tempAt: 3 put: true. aBlock value]
>> -               ensure: [self tempAt: 3 put: false]!
>>
>> Item was added:
>> + ----- Method: Exception>>privHandlerContext (in category 'priv
>> handling') -----
>> + privHandlerContext
>> +
>> +       ^handlerContext!
>>
>> Item was removed:
>> - ----- Method: Exception>>rearmHandlerDuring: (in category 'handling')
>> -----
>> - rearmHandlerDuring: aBlock
>> - "Make the current error handler re-entrant while it is running aBlock.
>> Only works in a closure-enabled image"
>> -
>> -       ^ handlerContext rearmHandlerDuring: aBlock!
>>
>> Item was removed:
>> - ----- Method: MethodContext>>isHandlerContext (in category
>> 'private-exceptions') -----
>> - isHandlerContext
>> - "is this context for  method that is marked?"
>> -       ^method primitive = 199!
>>
>> Item was added:
>> + ----- Method: MethodContext>>isHandlerOrSignalingContext (in category
>> 'private-exceptions') -----
>> + isHandlerOrSignalingContext
>> +       "Both BlockClosure>>on:do: (handler) and
>> ContextPart>>evaluateSignal: (signaling)
>> +       are marked with primitive 199."
>> +
>> +       ^method primitive = 199!
>>
>>
>
>
>
> --
> best,
> Eliot
>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Kernel-fbs.870.mcz

Eliot Miranda-2


On Fri, Sep 12, 2014 at 2:12 PM, Frank Shearar <[hidden email]> wrote:
On 12 September 2014 21:49, Eliot Miranda <[hidden email]> wrote:
> Hi Frank,
>
>     I'd rather see
>
> on: exception do: handlerAction
>        "Evaluate the receiver in the scope of an exception handler.
>        The following primitive is just a marker used to find the error
> handling context.
>        See MethodContext>>#isHandlerOrSignalingContext. "
>        <primitive: 199>
>        <handler>
>        ^ self value!
>
> isHandlerContext
>        "is this context for #on:do:?"
>        ^self isHandlerOrSignalingContext and: [ (self method pragmaAt:
> #handler) notNil: ]
>
> etc, rather than testing the selector.

OK, I see what you're doing there. I guess the only worry I have is
that <handler> doesn't seem terribly specific to me.

it can be as specific a label as you'd like.


One thing I don't get is the tempAt: 3 stuff. This code removes it,
and that seems to be the root of why #testHandlerReentrancy fails. But
this is beyond my depth (which is most of why I made Andres' code more
available for those for home this is _not_ out of depth).

I hear you.

>  I'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.

Right, because BlockContext has been marked for death? (Because
MethodContext has a closureOrNil instvar, which disambiguates between
MethodContexts-for-block-activations and
MethodContexts-for-method-activations.)

Right.  BlockCOntext is obsolete and unused.

But since at some point we're going to merge MethodContext and
ContextPart, why not just leave the code where it is? I guess it just
depends on whether we merge MethodContext -> ContextPart, or
ContextPart -> MethodContext.

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.


frank

> On Fri, Sep 12, 2014 at 1:40 PM, <[hidden email]> wrote:
>>
>> Frank Shearar uploaded a new version of Kernel to project The Inbox:
>> http://source.squeak.org/inbox/Kernel-fbs.870.mcz
>>
>> ==================== Summary ====================
>>
>> Name: Kernel-fbs.870
>> Author: fbs
>> Time: 12 September 2014, 9:40:45.406 pm
>> UUID: 868e0d8a-5e9d-d34d-ba2d-688800331f5b
>> Ancestors: Kernel-eem.869
>>
>> These are the changes Andres Valloud made to Cuis, to address a
>> long-standing bug in Cuis, Squeak and Pharo, in ExceptionsTests >>
>> #testHandlerFromAction.
>>
>> However, it causes a regression in #testHandlerReentrancy, so as it stands
>> it is NOT READY FOR MERGING.
>>
>> Please take a look, and see if we can bend Andres' code slightly so that
>> we get both the fix and don't break anything.
>>
>> =============== Diff against Kernel-eem.869 ===============
>>
>> Item was changed:
>>   ----- Method: BlockClosure>>on:do: (in category 'exceptions') -----
>>   on: exception do: handlerAction
>> +       "Evaluate the receiver in the scope of an exception handler.
>> +       The following primitive is just a marker used to find the error
>> handling context.
>> +       See MethodContext>>#isHandlerOrSignalingContext. "
>> +       <primitive: 199>
>> -       "Evaluate the receiver in the scope of an exception handler."
>> -
>> -       | handlerActive |
>> -       <primitive: 199>  "just a marker, fail and execute the following"
>> -       handlerActive := true.
>>         ^ self value!
>>
>> Item was changed:
>>   ----- Method: BlockContext>>on:do: (in category 'exceptions') -----
>>   on: exception do: handlerAction
>> +       "Evaluate the receiver in the scope of an exception handler.
>> +       The following primitive is just a marker used to find the error
>> handling context.
>> +       See MethodContext>>#isHandlerOrSignalingContext. "
>> +       <primitive: 199>
>> +       ^ self value!
>> -       "Evaluate the receiver in the scope of an exception handler."
>> -       | handlerActive |
>> -       <primitive: 199>
>> -       handlerActive := true.
>> -       ^self value!
>>
>> Item was changed:
>>   ----- Method: ContextPart>>canHandleSignal: (in category
>> 'private-exceptions') -----
>>   canHandleSignal: exception
>>         "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>>canHandleSignal:)"
>>
>> +       ^ (self exceptionClass handles: exception)
>> +               or: [ self nextHandlerContext canHandleSignal: exception
>> ].!
>> -       ^ (((self tempAt: 1) handles: exception) and: [self tempAt: 3])
>> -               or: [self nextHandlerContext canHandleSignal: exception].
>> - !
>>
>> Item was added:
>> + ----- Method: ContextPart>>evaluateSignal: (in category
>> 'private-exceptions') -----
>> + evaluateSignal: exception
>> +       "The following primitive is just a marker used to find the
>> evaluation context.
>> +       See MethodContext>>#isHandlerOrSignalingContext. "
>> +
>> +       <primitive: 199>
>> +       | value |
>> +       exception privHandlerContext: self contextTag.
>> +       value := self exceptionHandlerBlock valueWithPossibleArgument:
>> exception.
>> +       "return from self if not otherwise directed in handle block"
>> +       self return: value!
>>
>> Item was added:
>> + ----- Method: ContextPart>>exceptionClass (in category
>> 'private-exceptions') -----
>> + exceptionClass
>> +
>> +       ^self tempAt: 1!
>>
>> Item was added:
>> + ----- Method: ContextPart>>exceptionHandlerBlock (in category
>> 'private-exceptions') -----
>> + exceptionHandlerBlock
>> +       "handler context only. access temporaries from
>> BlockClosure>>#on:do:"
>> +
>> +       ^self tempAt: 2!
>>
>> Item was added:
>> + ----- Method: ContextPart>>findNextHandlerContext (in category
>> 'private-exceptions') -----
>> + findNextHandlerContext
>> +       "Return the next handler marked context, returning nil if there is
>> none.  Search starts with self and proceeds up to nil."
>> +
>> +       | context |
>> +       context := self findNextHandlerOrSignalingContext.
>> +       context isNil
>> +               ifTrue: [ ^ nil ].
>> +       context isHandlerContext
>> +               ifTrue: [ ^ context ].  "If it isn't a handler context, it
>> must be a signaling context.
>> +       When we reach a signaling context we must skip over any handlers
>> +       that might be on the stack between the signaling context and the
>> handler
>> +       context for that signal."
>> +       ^ context exceptionClass privHandlerContext nextHandlerContext!
>>
>> Item was removed:
>> - ----- Method: ContextPart>>findNextHandlerContextStarting (in category
>> 'private-exceptions') -----
>> - findNextHandlerContextStarting
>> -       "Return the next handler marked context, returning nil if there is
>> none.  Search starts with self and proceeds up to nil."
>> -
>> -       | ctx |
>> -       <primitive: 197>
>> -       ctx := self.
>> -               [ctx isHandlerContext ifTrue:[^ctx].
>> -               (ctx := ctx sender) == nil ] whileFalse.
>> -       ^nil!
>>
>> Item was added:
>> + ----- Method: ContextPart>>findNextHandlerOrSignalingContext (in
>> category 'private-exceptions') -----
>> + findNextHandlerOrSignalingContext
>> +       "Return the next handler/signaling marked context, answering nil
>> if there is none.
>> +       Search starts with self and proceeds up to nil."
>> +
>> +       <primitive: 197>
>> +       | context |
>> +       context := self.
>> +       [
>> +       context isHandlerOrSignalingContext
>> +               ifTrue: [ ^ context ].
>> +       (context := context sender) == nil ] whileFalse.
>> +       ^ nil!
>>
>> Item was changed:
>>   ----- Method: ContextPart>>handleSignal: (in category
>> 'private-exceptions') -----
>>   handleSignal: exception
>>         "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's defaultAction (see nil>>handleSignal:)."
>>
>> +       (self exceptionClass handles: exception)
>> +               ifFalse: [ ^ self nextHandlerContext handleSignal:
>> exception ].
>> +       self evaluateSignal: exception!
>> -       | val |
>> -       (((self tempAt: 1) handles: exception) and: [self tempAt: 3])
>> ifFalse: [
>> -               ^ self nextHandlerContext handleSignal: exception].
>> -
>> -       exception privHandlerContext: self contextTag.
>> -       self tempAt: 3 put: false.  "disable self while executing handle
>> block"
>> -       val := [(self tempAt: 2) cull: exception ]
>> -               ensure: [self tempAt: 3 put: true].
>> -       self return: val.  "return from self if not otherwise directed in
>> handle block"
>> - !
>>
>> Item was changed:
>>   ----- Method: ContextPart>>isHandlerContext (in category
>> 'private-exceptions') -----
>>   isHandlerContext
>> +       "is this context for #on:do:?"
>> +       ^self isHandlerOrSignalingContext and: [ self selector == #on:do:
>> ]!
>> -       ^false!
>>
>> Item was added:
>> + ----- Method: ContextPart>>isHandlerOrSignalingContext (in category
>> 'private-exceptions') -----
>> + isHandlerOrSignalingContext
>> +       "Both BlockClosure>>on:do: (handler) and
>> ContextPart>>evaluateSignal: (signaling)
>> +       are marked with primitive 199."
>> +
>> +       ^false!
>>
>> Item was changed:
>>   ----- Method: ContextPart>>nextHandlerContext (in category
>> 'private-exceptions') -----
>>   nextHandlerContext
>>
>> +       ^ self sender findNextHandlerContext!
>> -       ^ self sender findNextHandlerContextStarting!
>>
>> Item was removed:
>> - ----- Method: ContextPart>>rearmHandlerDuring: (in category
>> 'private-exceptions') -----
>> - rearmHandlerDuring: aBlock
>> -       "Sent to handler (on:do:) contexts only. Makes me re-entrant for
>> the duration of aBlock. Only works in a closure-enabled image"
>> -
>> -       ^ [self tempAt: 3 put: true. aBlock value]
>> -               ensure: [self tempAt: 3 put: false]!
>>
>> Item was added:
>> + ----- Method: Exception>>privHandlerContext (in category 'priv
>> handling') -----
>> + privHandlerContext
>> +
>> +       ^handlerContext!
>>
>> Item was removed:
>> - ----- Method: Exception>>rearmHandlerDuring: (in category 'handling')
>> -----
>> - rearmHandlerDuring: aBlock
>> - "Make the current error handler re-entrant while it is running aBlock.
>> Only works in a closure-enabled image"
>> -
>> -       ^ handlerContext rearmHandlerDuring: aBlock!
>>
>> Item was removed:
>> - ----- Method: MethodContext>>isHandlerContext (in category
>> 'private-exceptions') -----
>> - isHandlerContext
>> - "is this context for  method that is marked?"
>> -       ^method primitive = 199!
>>
>> Item was added:
>> + ----- Method: MethodContext>>isHandlerOrSignalingContext (in category
>> 'private-exceptions') -----
>> + isHandlerOrSignalingContext
>> +       "Both BlockClosure>>on:do: (handler) and
>> ContextPart>>evaluateSignal: (signaling)
>> +       are marked with primitive 199."
>> +
>> +       ^method primitive = 199!
>>
>>
>
>
>
> --
> best,
> Eliot
>
>
>




--
best,
Eliot


Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Kernel-fbs.870.mcz

Andres Valloud-4
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'd like to keep Cuis in the loop.

On 9/12/14 17:14 , Eliot Miranda wrote:

>
>
> On Fri, Sep 12, 2014 at 2:12 PM, Frank Shearar <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     On 12 September 2014 21:49, Eliot Miranda <[hidden email]
>     <mailto:[hidden email]>> wrote:
>     > Hi Frank,
>     >
>     >     I'd rather see
>     >
>     > on: exception do: handlerAction
>     >        "Evaluate the receiver in the scope of an exception handler.
>     >        The following primitive is just a marker used to find the error
>     > handling context.
>     >        See MethodContext>>#isHandlerOrSignalingContext. "
>     >        <primitive: 199>
>     >        <handler>
>     >        ^ self value!
>     >
>     > isHandlerContext
>     >        "is this context for #on:do:?"
>     >        ^self isHandlerOrSignalingContext and: [ (self method pragmaAt:
>     > #handler) notNil: ]
>     >
>     > etc, rather than testing the selector.
>
>     OK, I see what you're doing there. I guess the only worry I have is
>     that <handler> doesn't seem terribly specific to me.
>
>
> it can be as specific a label as you'd like.
>
>
>     One thing I don't get is the tempAt: 3 stuff. This code removes it,
>     and that seems to be the root of why #testHandlerReentrancy fails. But
>     this is beyond my depth (which is most of why I made Andres' code more
>     available for those for home this is _not_ out of depth).
>
>
> I hear you.
>
>     >  I'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.
>
>     Right, because BlockContext has been marked for death? (Because
>     MethodContext has a closureOrNil instvar, which disambiguates between
>     MethodContexts-for-block-activations and
>     MethodContexts-for-method-activations.)
>
>
> Right.  BlockCOntext is obsolete and unused.
>
>     But since at some point we're going to merge MethodContext and
>     ContextPart, why not just leave the code where it is? I guess it just
>     depends on whether we merge MethodContext -> ContextPart, or
>     ContextPart -> MethodContext.
>
>
> 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.
>
>
>     frank
>
>      > On Fri, Sep 12, 2014 at 1:40 PM, <[hidden email]
>     <mailto:[hidden email]>> wrote:
>      >>
>      >> Frank Shearar uploaded a new version of Kernel to project The Inbox:
>      >> http://source.squeak.org/inbox/Kernel-fbs.870.mcz
>      >>
>      >> ==================== Summary ====================
>      >>
>      >> Name: Kernel-fbs.870
>      >> Author: fbs
>      >> Time: 12 September 2014, 9:40:45.406 pm
>      >> UUID: 868e0d8a-5e9d-d34d-ba2d-688800331f5b
>      >> Ancestors: Kernel-eem.869
>      >>
>      >> These are the changes Andres Valloud made to Cuis, to address a
>      >> long-standing bug in Cuis, Squeak and Pharo, in ExceptionsTests >>
>      >> #testHandlerFromAction.
>      >>
>      >> However, it causes a regression in #testHandlerReentrancy, so as
>     it stands
>      >> it is NOT READY FOR MERGING.
>      >>
>      >> Please take a look, and see if we can bend Andres' code slightly
>     so that
>      >> we get both the fix and don't break anything.
>      >>
>      >> =============== Diff against Kernel-eem.869 ===============
>      >>
>      >> Item was changed:
>      >>   ----- Method: BlockClosure>>on:do: (in category 'exceptions')
>     -----
>      >>   on: exception do: handlerAction
>      >> +       "Evaluate the receiver in the scope of an exception handler.
>      >> +       The following primitive is just a marker used to find
>     the error
>      >> handling context.
>      >> +       See MethodContext>>#isHandlerOrSignalingContext. "
>      >> +       <primitive: 199>
>      >> -       "Evaluate the receiver in the scope of an exception
>     handler."
>      >> -
>      >> -       | handlerActive |
>      >> -       <primitive: 199>  "just a marker, fail and execute the
>     following"
>      >> -       handlerActive := true.
>      >>         ^ self value!
>      >>
>      >> Item was changed:
>      >>   ----- Method: BlockContext>>on:do: (in category 'exceptions')
>     -----
>      >>   on: exception do: handlerAction
>      >> +       "Evaluate the receiver in the scope of an exception handler.
>      >> +       The following primitive is just a marker used to find
>     the error
>      >> handling context.
>      >> +       See MethodContext>>#isHandlerOrSignalingContext. "
>      >> +       <primitive: 199>
>      >> +       ^ self value!
>      >> -       "Evaluate the receiver in the scope of an exception
>     handler."
>      >> -       | handlerActive |
>      >> -       <primitive: 199>
>      >> -       handlerActive := true.
>      >> -       ^self value!
>      >>
>      >> Item was changed:
>      >>   ----- Method: ContextPart>>canHandleSignal: (in category
>      >> 'private-exceptions') -----
>      >>   canHandleSignal: exception
>      >>         "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>>canHandleSignal:)"
>      >>
>      >> +       ^ (self exceptionClass handles: exception)
>      >> +               or: [ self nextHandlerContext canHandleSignal:
>     exception
>      >> ].!
>      >> -       ^ (((self tempAt: 1) handles: exception) and: [self
>     tempAt: 3])
>      >> -               or: [self nextHandlerContext canHandleSignal:
>     exception].
>      >> - !
>      >>
>      >> Item was added:
>      >> + ----- Method: ContextPart>>evaluateSignal: (in category
>      >> 'private-exceptions') -----
>      >> + evaluateSignal: exception
>      >> +       "The following primitive is just a marker used to find the
>      >> evaluation context.
>      >> +       See MethodContext>>#isHandlerOrSignalingContext. "
>      >> +
>      >> +       <primitive: 199>
>      >> +       | value |
>      >> +       exception privHandlerContext: self contextTag.
>      >> +       value := self exceptionHandlerBlock
>     valueWithPossibleArgument:
>      >> exception.
>      >> +       "return from self if not otherwise directed in handle block"
>      >> +       self return: value!
>      >>
>      >> Item was added:
>      >> + ----- Method: ContextPart>>exceptionClass (in category
>      >> 'private-exceptions') -----
>      >> + exceptionClass
>      >> +
>      >> +       ^self tempAt: 1!
>      >>
>      >> Item was added:
>      >> + ----- Method: ContextPart>>exceptionHandlerBlock (in category
>      >> 'private-exceptions') -----
>      >> + exceptionHandlerBlock
>      >> +       "handler context only. access temporaries from
>      >> BlockClosure>>#on:do:"
>      >> +
>      >> +       ^self tempAt: 2!
>      >>
>      >> Item was added:
>      >> + ----- Method: ContextPart>>findNextHandlerContext (in category
>      >> 'private-exceptions') -----
>      >> + findNextHandlerContext
>      >> +       "Return the next handler marked context, returning nil
>     if there is
>      >> none.  Search starts with self and proceeds up to nil."
>      >> +
>      >> +       | context |
>      >> +       context := self findNextHandlerOrSignalingContext.
>      >> +       context isNil
>      >> +               ifTrue: [ ^ nil ].
>      >> +       context isHandlerContext
>      >> +               ifTrue: [ ^ context ].  "If it isn't a handler
>     context, it
>      >> must be a signaling context.
>      >> +       When we reach a signaling context we must skip over any
>     handlers
>      >> +       that might be on the stack between the signaling context
>     and the
>      >> handler
>      >> +       context for that signal."
>      >> +       ^ context exceptionClass privHandlerContext
>     nextHandlerContext!
>      >>
>      >> Item was removed:
>      >> - ----- Method: ContextPart>>findNextHandlerContextStarting (in
>     category
>      >> 'private-exceptions') -----
>      >> - findNextHandlerContextStarting
>      >> -       "Return the next handler marked context, returning nil
>     if there is
>      >> none.  Search starts with self and proceeds up to nil."
>      >> -
>      >> -       | ctx |
>      >> -       <primitive: 197>
>      >> -       ctx := self.
>      >> -               [ctx isHandlerContext ifTrue:[^ctx].
>      >> -               (ctx := ctx sender) == nil ] whileFalse.
>      >> -       ^nil!
>      >>
>      >> Item was added:
>      >> + ----- Method: ContextPart>>findNextHandlerOrSignalingContext (in
>      >> category 'private-exceptions') -----
>      >> + findNextHandlerOrSignalingContext
>      >> +       "Return the next handler/signaling marked context,
>     answering nil
>      >> if there is none.
>      >> +       Search starts with self and proceeds up to nil."
>      >> +
>      >> +       <primitive: 197>
>      >> +       | context |
>      >> +       context := self.
>      >> +       [
>      >> +       context isHandlerOrSignalingContext
>      >> +               ifTrue: [ ^ context ].
>      >> +       (context := context sender) == nil ] whileFalse.
>      >> +       ^ nil!
>      >>
>      >> Item was changed:
>      >>   ----- Method: ContextPart>>handleSignal: (in category
>      >> 'private-exceptions') -----
>      >>   handleSignal: exception
>      >>         "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's defaultAction (see nil>>handleSignal:)."
>      >>
>      >> +       (self exceptionClass handles: exception)
>      >> +               ifFalse: [ ^ self nextHandlerContext handleSignal:
>      >> exception ].
>      >> +       self evaluateSignal: exception!
>      >> -       | val |
>      >> -       (((self tempAt: 1) handles: exception) and: [self
>     tempAt: 3])
>      >> ifFalse: [
>      >> -               ^ self nextHandlerContext handleSignal: exception].
>      >> -
>      >> -       exception privHandlerContext: self contextTag.
>      >> -       self tempAt: 3 put: false.  "disable self while
>     executing handle
>      >> block"
>      >> -       val := [(self tempAt: 2) cull: exception ]
>      >> -               ensure: [self tempAt: 3 put: true].
>      >> -       self return: val.  "return from self if not otherwise
>     directed in
>      >> handle block"
>      >> - !
>      >>
>      >> Item was changed:
>      >>   ----- Method: ContextPart>>isHandlerContext (in category
>      >> 'private-exceptions') -----
>      >>   isHandlerContext
>      >> +       "is this context for #on:do:?"
>      >> +       ^self isHandlerOrSignalingContext and: [ self selector
>     == #on:do:
>      >> ]!
>      >> -       ^false!
>      >>
>      >> Item was added:
>      >> + ----- Method: ContextPart>>isHandlerOrSignalingContext (in
>     category
>      >> 'private-exceptions') -----
>      >> + isHandlerOrSignalingContext
>      >> +       "Both BlockClosure>>on:do: (handler) and
>      >> ContextPart>>evaluateSignal: (signaling)
>      >> +       are marked with primitive 199."
>      >> +
>      >> +       ^false!
>      >>
>      >> Item was changed:
>      >>   ----- Method: ContextPart>>nextHandlerContext (in category
>      >> 'private-exceptions') -----
>      >>   nextHandlerContext
>      >>
>      >> +       ^ self sender findNextHandlerContext!
>      >> -       ^ self sender findNextHandlerContextStarting!
>      >>
>      >> Item was removed:
>      >> - ----- Method: ContextPart>>rearmHandlerDuring: (in category
>      >> 'private-exceptions') -----
>      >> - rearmHandlerDuring: aBlock
>      >> -       "Sent to handler (on:do:) contexts only. Makes me
>     re-entrant for
>      >> the duration of aBlock. Only works in a closure-enabled image"
>      >> -
>      >> -       ^ [self tempAt: 3 put: true. aBlock value]
>      >> -               ensure: [self tempAt: 3 put: false]!
>      >>
>      >> Item was added:
>      >> + ----- Method: Exception>>privHandlerContext (in category 'priv
>      >> handling') -----
>      >> + privHandlerContext
>      >> +
>      >> +       ^handlerContext!
>      >>
>      >> Item was removed:
>      >> - ----- Method: Exception>>rearmHandlerDuring: (in category
>     'handling')
>      >> -----
>      >> - rearmHandlerDuring: aBlock
>      >> - "Make the current error handler re-entrant while it is running
>     aBlock.
>      >> Only works in a closure-enabled image"
>      >> -
>      >> -       ^ handlerContext rearmHandlerDuring: aBlock!
>      >>
>      >> Item was removed:
>      >> - ----- Method: MethodContext>>isHandlerContext (in category
>      >> 'private-exceptions') -----
>      >> - isHandlerContext
>      >> - "is this context for  method that is marked?"
>      >> -       ^method primitive = 199!
>      >>
>      >> Item was added:
>      >> + ----- Method: MethodContext>>isHandlerOrSignalingContext (in
>     category
>      >> 'private-exceptions') -----
>      >> + isHandlerOrSignalingContext
>      >> +       "Both BlockClosure>>on:do: (handler) and
>      >> ContextPart>>evaluateSignal: (signaling)
>      >> +       are marked with primitive 199."
>      >> +
>      >> +       ^method primitive = 199!
>      >>
>      >>
>      >
>      >
>      >
>      > --
>      > best,
>      > Eliot
>      >
>      >
>      >
>
>
>
>
> --
> best,
> Eliot
>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Kernel-fbs.870.mcz

Nicolas Cellier
So I tried to preserve it.

IMO testHandlerReentrancy is fallacy.
It's just that it seems to be used by Island mechanism in latest versions of in Tweak see https://code.google.com/p/pharo/issues/detail?id=2519

Note that Andres' code still use tempAt: 1 & 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...

2014-09-13 2:57 GMT+02:00 Andres Valloud <[hidden email]>:
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'd like to keep Cuis in the loop.

On 9/12/14 17:14 , Eliot Miranda wrote:


On Fri, Sep 12, 2014 at 2:12 PM, Frank Shearar <[hidden email]
<mailto:[hidden email]>> wrote:

    On 12 September 2014 21:49, Eliot Miranda <[hidden email]
    <mailto:[hidden email]>> wrote:
    > Hi Frank,
    >
    >     I'd rather see
    >
    > on: exception do: handlerAction
    >        "Evaluate the receiver in the scope of an exception handler.
    >        The following primitive is just a marker used to find the error
    > handling context.
    >        See MethodContext>>#isHandlerOrSignalingContext. "
    >        <primitive: 199>
    >        <handler>
    >        ^ self value!
    >
    > isHandlerContext
    >        "is this context for #on:do:?"
    >        ^self isHandlerOrSignalingContext and: [ (self method pragmaAt:
    > #handler) notNil: ]
    >
    > etc, rather than testing the selector.

    OK, I see what you're doing there. I guess the only worry I have is
    that <handler> doesn't seem terribly specific to me.


it can be as specific a label as you'd like.


    One thing I don't get is the tempAt: 3 stuff. This code removes it,
    and that seems to be the root of why #testHandlerReentrancy fails. But
    this is beyond my depth (which is most of why I made Andres' code more
    available for those for home this is _not_ out of depth).


I hear you.

    >  I'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.

    Right, because BlockContext has been marked for death? (Because
    MethodContext has a closureOrNil instvar, which disambiguates between
    MethodContexts-for-block-activations and
    MethodContexts-for-method-activations.)


Right.  BlockCOntext is obsolete and unused.

    But since at some point we're going to merge MethodContext and
    ContextPart, why not just leave the code where it is? I guess it just
    depends on whether we merge MethodContext -> ContextPart, or
    ContextPart -> MethodContext.


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.


    frank

     > On Fri, Sep 12, 2014 at 1:40 PM, <[hidden email]
    <mailto:[hidden email]>> wrote:
     >>
     >> Frank Shearar uploaded a new version of Kernel to project The Inbox:
     >> http://source.squeak.org/inbox/Kernel-fbs.870.mcz
     >>
     >> ==================== Summary ====================
     >>
     >> Name: Kernel-fbs.870
     >> Author: fbs
     >> Time: 12 September 2014, 9:40:45.406 pm
     >> UUID: 868e0d8a-5e9d-d34d-ba2d-688800331f5b
     >> Ancestors: Kernel-eem.869
     >>
     >> These are the changes Andres Valloud made to Cuis, to address a
     >> long-standing bug in Cuis, Squeak and Pharo, in ExceptionsTests >>
     >> #testHandlerFromAction.
     >>
     >> However, it causes a regression in #testHandlerReentrancy, so as
    it stands
     >> it is NOT READY FOR MERGING.
     >>
     >> Please take a look, and see if we can bend Andres' code slightly
    so that
     >> we get both the fix and don't break anything.
     >>
     >> =============== Diff against Kernel-eem.869 ===============
     >>
     >> Item was changed:
     >>   ----- Method: BlockClosure>>on:do: (in category 'exceptions')
    -----
     >>   on: exception do: handlerAction
     >> +       "Evaluate the receiver in the scope of an exception handler.
     >> +       The following primitive is just a marker used to find
    the error
     >> handling context.
     >> +       See MethodContext>>#isHandlerOrSignalingContext. "
     >> +       <primitive: 199>
     >> -       "Evaluate the receiver in the scope of an exception
    handler."
     >> -
     >> -       | handlerActive |
     >> -       <primitive: 199>  "just a marker, fail and execute the
    following"
     >> -       handlerActive := true.
     >>         ^ self value!
     >>
     >> Item was changed:
     >>   ----- Method: BlockContext>>on:do: (in category 'exceptions')
    -----
     >>   on: exception do: handlerAction
     >> +       "Evaluate the receiver in the scope of an exception handler.
     >> +       The following primitive is just a marker used to find
    the error
     >> handling context.
     >> +       See MethodContext>>#isHandlerOrSignalingContext. "
     >> +       <primitive: 199>
     >> +       ^ self value!
     >> -       "Evaluate the receiver in the scope of an exception
    handler."
     >> -       | handlerActive |
     >> -       <primitive: 199>
     >> -       handlerActive := true.
     >> -       ^self value!
     >>
     >> Item was changed:
     >>   ----- Method: ContextPart>>canHandleSignal: (in category
     >> 'private-exceptions') -----
     >>   canHandleSignal: exception
     >>         "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>>canHandleSignal:)"
     >>
     >> +       ^ (self exceptionClass handles: exception)
     >> +               or: [ self nextHandlerContext canHandleSignal:
    exception
     >> ].!
     >> -       ^ (((self tempAt: 1) handles: exception) and: [self
    tempAt: 3])
     >> -               or: [self nextHandlerContext canHandleSignal:
    exception].
     >> - !
     >>
     >> Item was added:
     >> + ----- Method: ContextPart>>evaluateSignal: (in category
     >> 'private-exceptions') -----
     >> + evaluateSignal: exception
     >> +       "The following primitive is just a marker used to find the
     >> evaluation context.
     >> +       See MethodContext>>#isHandlerOrSignalingContext. "
     >> +
     >> +       <primitive: 199>
     >> +       | value |
     >> +       exception privHandlerContext: self contextTag.
     >> +       value := self exceptionHandlerBlock
    valueWithPossibleArgument:
     >> exception.
     >> +       "return from self if not otherwise directed in handle block"
     >> +       self return: value!
     >>
     >> Item was added:
     >> + ----- Method: ContextPart>>exceptionClass (in category
     >> 'private-exceptions') -----
     >> + exceptionClass
     >> +
     >> +       ^self tempAt: 1!
     >>
     >> Item was added:
     >> + ----- Method: ContextPart>>exceptionHandlerBlock (in category
     >> 'private-exceptions') -----
     >> + exceptionHandlerBlock
     >> +       "handler context only. access temporaries from
     >> BlockClosure>>#on:do:"
     >> +
     >> +       ^self tempAt: 2!
     >>
     >> Item was added:
     >> + ----- Method: ContextPart>>findNextHandlerContext (in category
     >> 'private-exceptions') -----
     >> + findNextHandlerContext
     >> +       "Return the next handler marked context, returning nil
    if there is
     >> none.  Search starts with self and proceeds up to nil."
     >> +
     >> +       | context |
     >> +       context := self findNextHandlerOrSignalingContext.
     >> +       context isNil
     >> +               ifTrue: [ ^ nil ].
     >> +       context isHandlerContext
     >> +               ifTrue: [ ^ context ].  "If it isn't a handler
    context, it
     >> must be a signaling context.
     >> +       When we reach a signaling context we must skip over any
    handlers
     >> +       that might be on the stack between the signaling context
    and the
     >> handler
     >> +       context for that signal."
     >> +       ^ context exceptionClass privHandlerContext
    nextHandlerContext!
     >>
     >> Item was removed:
     >> - ----- Method: ContextPart>>findNextHandlerContextStarting (in
    category
     >> 'private-exceptions') -----
     >> - findNextHandlerContextStarting
     >> -       "Return the next handler marked context, returning nil
    if there is
     >> none.  Search starts with self and proceeds up to nil."
     >> -
     >> -       | ctx |
     >> -       <primitive: 197>
     >> -       ctx := self.
     >> -               [ctx isHandlerContext ifTrue:[^ctx].
     >> -               (ctx := ctx sender) == nil ] whileFalse.
     >> -       ^nil!
     >>
     >> Item was added:
     >> + ----- Method: ContextPart>>findNextHandlerOrSignalingContext (in
     >> category 'private-exceptions') -----
     >> + findNextHandlerOrSignalingContext
     >> +       "Return the next handler/signaling marked context,
    answering nil
     >> if there is none.
     >> +       Search starts with self and proceeds up to nil."
     >> +
     >> +       <primitive: 197>
     >> +       | context |
     >> +       context := self.
     >> +       [
     >> +       context isHandlerOrSignalingContext
     >> +               ifTrue: [ ^ context ].
     >> +       (context := context sender) == nil ] whileFalse.
     >> +       ^ nil!
     >>
     >> Item was changed:
     >>   ----- Method: ContextPart>>handleSignal: (in category
     >> 'private-exceptions') -----
     >>   handleSignal: exception
     >>         "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's defaultAction (see nil>>handleSignal:)."
     >>
     >> +       (self exceptionClass handles: exception)
     >> +               ifFalse: [ ^ self nextHandlerContext handleSignal:
     >> exception ].
     >> +       self evaluateSignal: exception!
     >> -       | val |
     >> -       (((self tempAt: 1) handles: exception) and: [self
    tempAt: 3])
     >> ifFalse: [
     >> -               ^ self nextHandlerContext handleSignal: exception].
     >> -
     >> -       exception privHandlerContext: self contextTag.
     >> -       self tempAt: 3 put: false.  "disable self while
    executing handle
     >> block"
     >> -       val := [(self tempAt: 2) cull: exception ]
     >> -               ensure: [self tempAt: 3 put: true].
     >> -       self return: val.  "return from self if not otherwise
    directed in
     >> handle block"
     >> - !
     >>
     >> Item was changed:
     >>   ----- Method: ContextPart>>isHandlerContext (in category
     >> 'private-exceptions') -----
     >>   isHandlerContext
     >> +       "is this context for #on:do:?"
     >> +       ^self isHandlerOrSignalingContext and: [ self selector
    == #on:do:
     >> ]!
     >> -       ^false!
     >>
     >> Item was added:
     >> + ----- Method: ContextPart>>isHandlerOrSignalingContext (in
    category
     >> 'private-exceptions') -----
     >> + isHandlerOrSignalingContext
     >> +       "Both BlockClosure>>on:do: (handler) and
     >> ContextPart>>evaluateSignal: (signaling)
     >> +       are marked with primitive 199."
     >> +
     >> +       ^false!
     >>
     >> Item was changed:
     >>   ----- Method: ContextPart>>nextHandlerContext (in category
     >> 'private-exceptions') -----
     >>   nextHandlerContext
     >>
     >> +       ^ self sender findNextHandlerContext!
     >> -       ^ self sender findNextHandlerContextStarting!
     >>
     >> Item was removed:
     >> - ----- Method: ContextPart>>rearmHandlerDuring: (in category
     >> 'private-exceptions') -----
     >> - rearmHandlerDuring: aBlock
     >> -       "Sent to handler (on:do:) contexts only. Makes me
    re-entrant for
     >> the duration of aBlock. Only works in a closure-enabled image"
     >> -
     >> -       ^ [self tempAt: 3 put: true. aBlock value]
     >> -               ensure: [self tempAt: 3 put: false]!
     >>
     >> Item was added:
     >> + ----- Method: Exception>>privHandlerContext (in category 'priv
     >> handling') -----
     >> + privHandlerContext
     >> +
     >> +       ^handlerContext!
     >>
     >> Item was removed:
     >> - ----- Method: Exception>>rearmHandlerDuring: (in category
    'handling')
     >> -----
     >> - rearmHandlerDuring: aBlock
     >> - "Make the current error handler re-entrant while it is running
    aBlock.
     >> Only works in a closure-enabled image"
     >> -
     >> -       ^ handlerContext rearmHandlerDuring: aBlock!
     >>
     >> Item was removed:
     >> - ----- Method: MethodContext>>isHandlerContext (in category
     >> 'private-exceptions') -----
     >> - isHandlerContext
     >> - "is this context for  method that is marked?"
     >> -       ^method primitive = 199!
     >>
     >> Item was added:
     >> + ----- Method: MethodContext>>isHandlerOrSignalingContext (in
    category
     >> 'private-exceptions') -----
     >> + isHandlerOrSignalingContext
     >> +       "Both BlockClosure>>on:do: (handler) and
     >> ContextPart>>evaluateSignal: (signaling)
     >> +       are marked with primitive 199."
     >> +
     >> +       ^method primitive = 199!
     >>
     >>
     >
     >
     >
     > --
     > best,
     > Eliot
     >
     >
     >




--
best,
Eliot