[squeak-dev] The Inbox: Kernel-nice.857.mcz

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Fri Jun 6 15:55:46 UTC 2014


2014-06-06 12:43 GMT+02:00 Nicolas Cellier <
nicolas.cellier.aka.nice at gmail.com>:

>
>
> 2014-06-06 4:48 GMT+02:00 David T. Lewis <lewis at mail.msen.com>:
>
> The change behaves as described, fixing testHandlerFromAction and
>> introducing
>> the (now expected) failure into testHandlerRentrancy.
>>
>> I am not qualified to offer any more useful critique other than to say
>> that
>> is clear that Nicolas has put some serious thought into this issue and I
>> hope that others will take a close look at it.
>>
>> Dave
>>
>>
> Thanks David,
> Added wisdom: googling about usage of #rearmHandlerDuring: it seems
> required by Island mechanism in Tweak see
> https://code.google.com/p/pharo/issues/detail?id=2519
>
> Maybe there is another implementation possible in Tweak, but that's
> definitely the main usage of #rearmHandlerDuring:
>
> I also see this hack in VMMaker:
> http://forum.world.st/VM-Maker-VMMaker-oscog-eem-180-mcz-td4637135.html
> found after this thread:
> http://web.archiveorange.com/archive/v/kLJIkmCV2lbVUoHLbp3R
>
> I'll try and give a try to above Eliot's snippets
>
>
>
And good news, the new implementation of rearmHandlerDuring: is still work
on Eliot's snippets (#caught is correctly transcripted 5 times).
Though the count of second snippet is still 1.


>> On Fri, Jun 06, 2014 at 04:13:39AM +0200, Nicolas Cellier wrote:
>> > Though I'm pretty happy with this solution, this late coding definitely
>> > needs more eyes, more tests and advice for rearmHandlerDuring:
>> >
>> >
>> > 2014-06-06 3:57 GMT+02:00 <commits at source.squeak.org>:
>> >
>> > > A new version of Kernel was added to project The Inbox:
>> > > http://source.squeak.org/inbox/Kernel-nice.857.mcz
>> > >
>> > > ==================== Summary ====================
>> > >
>> > > Name: Kernel-nice.857
>> > > Author: nice
>> > > Time: 6 June 2014, 3:56:46.41 am
>> > > UUID: 58fb31c3-1c03-4cf6-80d3-1f51f41f6d95
>> > > Ancestors: Kernel-cmm.855
>> > >
>> > > Resolve ExceptionTests>>testHandlerFromAction.
>> > >
>> > > Implementation details:
>> > >
>> > > Do so by intercepting any exception raised by the handle block in the
>> > > context which is invoking this block (see #handleSignal:) and by
>> allways
>> > > propagating this new exception to a previously recorded outerHandler
>> (temp
>> > > at: 3). Since this context is above the handlers (on:do:) on the
>> stack, it
>> > > just has to be marked as a fake handler (<primitive: 199>) to do its
>> > > interceptor/propagator job.
>> > >
>> > > Do not use (temp at: 3) of handler (on:do:) as a marker of enablement
>> > > (true) or temporary disablement (false) during handle block execution,
>> > > since this is completely superseded by above mechanism. We should
>> rather
>> > > rename the (temp at: 3) as outerHandler and set it to nil.
>> > > Since load order counts, and since some #on:do: context down the
>> processes
>> > > stacks are not going to die soon, we have equipped #handleSignal:
>> with a
>> > > workaround, so this change can wait.
>> > >
>> > > Attempt to preserve the possibility for an exception to
>> > > rearmHandlerDuring: aBlock by temporarily resetting the outerHandler
>> temp
>> > > in the interceptorContext (which must be a new inst.var. recorded by
>> the
>> > > Exception).
>> > >
>> > > Alas, the #testHandlerReentrancy is now failing, because it expects an
>> > > inner handler to be triggered by an exception raised from an outer
>> handle
>> > > block, which is forbidden by above implementation. This test is hardly
>> > > compatible with testHandlerFromAction.
>> > >
>> > > I suggest adding an expected failure to document the change of
>> behavior,
>> > > and creating a new test demonstrating how rearmHandlerDuring: could
>> be used.
>> > > If we don't find a real interest in this message now that it cannot
>> pass
>> > > then intercept, we can as well deprecate it.
>> > >
>> > > =============== Diff against Kernel-cmm.855 ===============
>> > >
>> > > 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 tempAt: 1) handles: exception))
>> > > -       ^ (((self tempAt: 1) handles: exception) and: [self tempAt:
>> 3])
>> > >                 or: [self nextHandlerContext canHandleSignal:
>> exception].
>> > >   !
>> > >
>> > > Item was changed:
>> > >   ----- Method: ContextPart>>handleSignal: (in category
>> > > 'private-exceptions') -----
>> > >   handleSignal: exception
>> > > +       "Sent to handler (on:do:) and propagator (handleSignal:)
>> contexts
>> > > only.
>> > > +       If I am a handler (on:do:), and 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:).
>> > > +       If I am a propagator (handleSignal:) I just forward the
>> handling
>> > > to the outerHandler (temp at: 3). The propagator is allways above the
>> > > handlers on the stack. If an exception occurs while executing the
>> handle
>> > > block, it will be intercepted by the propagator and redirected to the
>> > > previously recorded outer handler, effectively bypassing all inner and
>> > > current handler."
>> > > -       "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:)."
>> > >
>> > > +       | val outerHandler |
>> > > +       <primitive: 199>
>> > > +       (self tempAt: 3) == true ifTrue: [self tempAt: 3 put: nil].
>> > > "preserve compatibility with old handlerContext"
>> > > +       ((self tempAt: 1) handles: exception) ifFalse: [
>> > > +               ^((self tempAt: 3) ifNil: [self nextHandlerContext])
>> > > handleSignal: exception].
>> > > +
>> > > +       exception privHandlerContext: self contextTag from:
>> thisContext
>> > > contextTag.
>> > > +       outerHandler := self nextHandlerContext.  "disable self and
>> all
>> > > inner handlers while executing handle block"
>> > > +       val := (self tempAt: 2) cull: 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 added:
>> > > + ----- Method: ContextPart>>rearmHandler:during: (in category
>> > > 'private-exceptions') -----
>> > > + rearmHandler: aHandlerContext during: aBlock
>> > > +       "Sent to interceptor (handleSignal:) contexts only, with a
>> handler
>> > > context (on:do:) parameter.
>> > > +       Makes aHandlerContext re-entrant for the duration of aBlock.
>> Only
>> > > works in a closure-enabled image"
>> > > +
>> > > +       | oldHandler |
>> > > +       oldHandler := self tempAt: 3.
>> > > +       ^ [self tempAt: 3 put: aHandlerContext. aBlock value]
>> > > +               ensure: [self tempAt: 3 put: oldHandler]!
>> > >
>> > > 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 changed:
>> > >   Object subclass: #Exception
>> > > +       instanceVariableNames: 'messageText tag signalContext
>> > > handlerContext outerContext interceptorContext'
>> > > -       instanceVariableNames: 'messageText tag signalContext
>> > > handlerContext outerContext'
>> > >         classVariableNames: ''
>> > >         poolDictionaries: ''
>> > >         category: 'Kernel-Exceptions-Kernel'!
>> > >
>> > >   !Exception commentStamp: '<historical>' prior: 0!
>> > >   This is the main class used to implement the exception handling
>> system
>> > > (EHS).  It plays two distinct roles:  that of the exception, and that
>> of
>> > > the exception handler.  More specifically, it implements the bulk of
>> the
>> > > protocols laid out in the ANSI specification - those protocol names
>> are
>> > > reflected in the message categories.
>> > >
>> > >   Exception is an abstract class.  Instances should neither be
>> created nor
>> > > trapped.  In most cases, subclasses should inherit from Error or
>> > > Notification rather than directly from Exception.
>> > >
>> > >   In implementing this EHS, The Fourth Estate Inc. incorporated some
>> ideas
>> > > and code from Craig Latta's EHS.  His insights were crucial in
>> allowing us
>> > > to implement BlockContext>>valueUninterruptably (and by extension,
>> #ensure:
>> > > and #ifCurtailed:), and we imported the following methods with little
>> or no
>> > > modification:
>> > >
>> > >   ContextPart>>terminateTo:
>> > >   ContextPart>>terminate
>> > >   MethodContext>>receiver:
>> > >   MethodContext>>answer:
>> > >
>> > >   Thanks, Craig!!!
>> > >
>> > > Item was removed:
>> > > - ----- Method: Exception>>privHandlerContext: (in category 'priv
>> > > handling') -----
>> > > - privHandlerContext: aContextTag
>> > > -
>> > > -       handlerContext := aContextTag!
>> > >
>> > > Item was added:
>> > > + ----- Method: Exception>>privHandlerContext:from: (in category 'priv
>> > > handling') -----
>> > > + privHandlerContext: aContextTag from: anotherContextTag
>> > > +
>> > > +       handlerContext := aContextTag.
>> > > +       interceptorContext := anotherContextTag!
>> > >
>> > > Item was changed:
>> > >   ----- 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"
>> > >
>> > > +       ^ interceptorContext rearmHandler: handlerContext during:
>> aBlock!
>> > > -       ^ handlerContext rearmHandlerDuring: aBlock!
>> > >
>> > >
>> > >
>>
>> >
>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20140606/a797333e/attachment.htm


More information about the Squeak-dev mailing list