[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