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 |
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 >> >> > > > |
Free forum by Nabble | Edit this page |