Re: [Seaside-dev] Seaside and exception behaviour

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

Re: [Seaside-dev] Seaside and exception behaviour

Julian Fitzell-2
On Wed, Jan 5, 2011 at 8:15 AM, Paolo Bonzini <[hidden email]> wrote:

> On 01/05/2011 04:58 PM, [hidden email] wrote:
>>
>> > >  Here's maybe a bit more concise example. If you run the thing below
>> > > in a workspace,
>> > >  it returns 'Squeak' in Squeak and 'VW' in VW
>> > >
>> > >  [  [       [       self error: 'trigger error'
>> > >             ] on: ZeroDivide do: [ :ex | 'Squeak' ]
>> > >     ] on: Error do: [ :ex | 3 / 0 ]
>> > >  ] on: ZeroDivide do: [ :ex | 'VW' ]
>> >
>> >  It returns 'Squeak' on GNU Smalltalk.  This is consistent with my
>> >  analysis of Alan's snippet.  Unfortunately I don't have at hand my copy
>> >  of the standard.
>>
>> FWIW, Smalltalk/X returns 'VW'
>
> That's the correct behavior.  The standard says the search should proceed
> from the last exception handler that was created up to the oldest.

Agreed.  The ANSI standard seems quite clear about that:

5.4.3.3: "If signaling of an exception results in evaluation of action
the evaluation will occur in the context of the handler environment."

5.5.2.1: "If a matching handler is found, the exception action of the
handler is evaluated in the exception environment that was current
when the handler was created and the state of the current exception
environment is preserved as the signaling environment."

> (That said, Squeak/gst's behavior is quite easy to justify, as stack
> unwinding hasn't happened yet.  I'll wait for this thread to settle before
> changing it in gst).

But stack unwinding shouldn't need to happen until one of the #on:do:
calls is actually ready to return. Until then, its all just searching.

I think Squeak/Pharo's problem is that it doesn't maintain a first
class "exception environment" as described by the glossary in the ANSI
standard: "An abstract entity that is a LIFO list of exception
handlers. An exception environment may be logically searched starting
from the most recently "pushed" exception handler."

Squeak/Pharo simply (ab)uses the context chain, walking it looking for
the next handler (see the implementation of #signal, which always
starts searching from thisContext). This works fine most of the time
but not when you need to temporarily restore a previous exception
environment. #handleSignal: does go to the effort of setting a
handlerContext on the signaled exception before calling the action
block. This is necessary to implement #pass, #isNested, and so on but
would also need to be put somewhere that #signal could get at it to
use as a starting point for the search.

This seems like a squeak/pharo bug to me. I don't much feel like
fixing it in Grease given that Grease is supposed to assume correct
ANSI implementation as a pre-requisite. Perhaps we can broker a deal
where Squeak/Pharo will fix this and VW (finally) fixes its signaling
behaviour so we can drop GRError, etc. entirely.

In the meantime, though, how would we fix the Seaside code assuming we
had ANSI-correct exception handling implementations?

Julian

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: [Seaside-dev] Seaside and exception behaviour

Julian Fitzell-2
Hi Andreas,

A neat approach, but I don't think it quite works (yet, anyway).
Although it has the correct behaviour when the exception action is
invoked, it doesn't behave correctly for #defaultAction. According to
5.5.2.1 in the spec, "The #defaultAction method is executed in the
context of the signaling environment."

So, taking an example of an existing #defaultAction method that
signals an exception:

[ Error signal ] on: UnhandledError do: [ :ex | 'ANSI says so' ]

returns 'ANSI says so' without your change but brings up a debugger with it.

Julian

On Sat, Jan 8, 2011 at 7:34 PM, Andreas Raab <[hidden email]> wrote:

> Thanks for the test case. I've posted a possible fix for Squeak to the inbox
> (Kernel-ar.540) but I'd like people to review the change first since it's a
> fairly critical part of the system. I'd appreciate if someone could look at
> the fix and comment on whether that's the sensible thing to do.
>
> Cheers,
>  - Andreas
>
> On 1/8/2011 6:02 PM, Julian Fitzell wrote:
>>
>> On Wed, Jan 5, 2011 at 8:15 AM, Paolo Bonzini<[hidden email]>  wrote:
>>>
>>> On 01/05/2011 04:58 PM, [hidden email] wrote:
>>>>
>>>>>>  Here's maybe a bit more concise example. If you run the thing below
>>>>>> in a workspace,
>>>>>>  it returns 'Squeak' in Squeak and 'VW' in VW
>>>>>>
>>>>>>  [  [       [       self error: 'trigger error'
>>>>>>             ] on: ZeroDivide do: [ :ex | 'Squeak' ]
>>>>>>     ] on: Error do: [ :ex | 3 / 0 ]
>>>>>>  ] on: ZeroDivide do: [ :ex | 'VW' ]
>>>>>
>>>>>  It returns 'Squeak' on GNU Smalltalk.  This is consistent with my
>>>>>  analysis of Alan's snippet.  Unfortunately I don't have at hand my
>>>>> copy
>>>>>  of the standard.
>>>>
>>>> FWIW, Smalltalk/X returns 'VW'
>>>
>>> That's the correct behavior.  The standard says the search should proceed
>>> from the last exception handler that was created up to the oldest.
>>
>> Agreed.  The ANSI standard seems quite clear about that:
>>
>> 5.4.3.3: "If signaling of an exception results in evaluation of action
>> the evaluation will occur in the context of the handler environment."
>>
>> 5.5.2.1: "If a matching handler is found, the exception action of the
>> handler is evaluated in the exception environment that was current
>> when the handler was created and the state of the current exception
>> environment is preserved as the signaling environment."
>>
>>> (That said, Squeak/gst's behavior is quite easy to justify, as stack
>>> unwinding hasn't happened yet.  I'll wait for this thread to settle
>>> before
>>> changing it in gst).
>>
>> But stack unwinding shouldn't need to happen until one of the #on:do:
>> calls is actually ready to return. Until then, its all just searching.
>>
>> I think Squeak/Pharo's problem is that it doesn't maintain a first
>> class "exception environment" as described by the glossary in the ANSI
>> standard: "An abstract entity that is a LIFO list of exception
>> handlers. An exception environment may be logically searched starting
>> from the most recently "pushed" exception handler."
>>
>> Squeak/Pharo simply (ab)uses the context chain, walking it looking for
>> the next handler (see the implementation of #signal, which always
>> starts searching from thisContext). This works fine most of the time
>> but not when you need to temporarily restore a previous exception
>> environment. #handleSignal: does go to the effort of setting a
>> handlerContext on the signaled exception before calling the action
>> block. This is necessary to implement #pass, #isNested, and so on but
>> would also need to be put somewhere that #signal could get at it to
>> use as a starting point for the search.
>>
>> This seems like a squeak/pharo bug to me. I don't much feel like
>> fixing it in Grease given that Grease is supposed to assume correct
>> ANSI implementation as a pre-requisite. Perhaps we can broker a deal
>> where Squeak/Pharo will fix this and VW (finally) fixes its signaling
>> behaviour so we can drop GRError, etc. entirely.
>>
>> In the meantime, though, how would we fix the Seaside code assuming we
>> had ANSI-correct exception handling implementations?
>>
>> Julian
>>
>>
>
>
>