[D-runtime] druntime commit, revision 459

Sean Kelly sean at invisibleduck.org
Tue Dec 28 10:34:42 PST 2010


This one was discussed a while ago in private email and stalled for lack of an executive decision.  I'll paste some pertinent bits of the discussion below (all stuff I said).  The rest of this message is pasted from various old emails.

----------

On Sep 2, 2010, at 3:44 PM, Sean Kelly wrote:

> I spent some time investigating the test suite failures that caused Walter to revert the chaining code and ran into an interesting problem.  Consider this (from test4.d test55):
> 
> void funcA()
> {
>   try {
>       try {
>           throw new Exception( "A" );
>       } finally {
>           funcB();
>       }
>   } catch( Exception e ) {
>       assert( e.msg == "A" );
>   }
> }
> 
> void funcB()
> {
>   try {
>       throw new Exception( "B" );
>   } catch( Exception e ) {
>       assert( e.msg == "B" );
>   }
> }
> 
> In this case, the assertion in funcB() will fail because exception A is already in flight so exception B will be considered collateral damage and be chained to the existing exception A.  In an ideal world, proper behavior would probably be to make exception chaining scope-aware so an exception is only considered collateral if it escapes the top finally block called during stack unwinding.  Practically speaking however, this seems like it could be a very complicated thing to actually do.  What are the alternatives?  As it is, I don't feel comfortable rolling the chaining code back in.

Okay, I think this could be done without too much work, but it would require adding a pointer to the handler table for each stack frame (for the current exception).  I'm unsure whether the chaining behavior is worth it... thoughts?

On Sep 21, 2010, at 3:43 PM, Sean Kelly wrote:
> 
>> On 9/21/10 17:01 CDT, Sean Kelly wrote:
>> 
>>> What's really convinced me that the simple TDPL approach isn't
>>> sufficient is that it can violate the nothrow guarantee.  You'd think
>>> it should be safe to put a nothrow label on funcB(), right?  But with
>>> the previously implemented TDPL model, the exception "thrown" out of
>>> funcB() is exception A because exception B is considered collateral
>>> damage.  I think you're right that the language in TDPL isn't wrong
>>> though.  It's just that a naive implementation of the described TDPL
>>> model (as I did before) doesn't work.
> 
> I think doing so will require either a codegen change to add a void* to the DHandlerInfo struct (for saving a reference to the in-flight exception that caused the handler to be called), or a dynamic stack to store this info.

I realized last night that the dynamic stack can be a linked-list of structs on the stack, so no need for DMA.  So store the Throwable reference and a pointer to the finally block being called or perhaps a stack position.  I'll experiment with it today.  The details are still fuzzy but I'm reasonably certain it will work.


More information about the D-runtime mailing list