Try/catch/finally builder

Paul Sandoz paul.sandoz at oracle.com
Wed Aug 31 19:18:48 UTC 2022



> On Aug 30, 2022, at 2:59 PM, Brian Goetz <brian.goetz at oracle.com> wrote:
> 
> Is there any case where we would want to nest BBs but allow the nested BB to bind a label defined by the parent BB?  I don't think so; what we're basically saying is that if you define a label in a block, it should be (a) defined before you finish building the block and (b) can only be defined in that block, not in sub-blocks.  Since LabelTarget is part of the base API, we probably have to document this constraint on valid labels targets.  
> 

Yes.


> if we have nested trys, each with finally blocks, I think we have to walk the stack of BBs to get this right:
> 
>    Y: 
>    while (goop) {
>        try { 
>            X: 
>            while (blah) { 
>                try { 
>                    if (wah) continue X;
>                    // need A but not B here
>                    if (wooga) continue Y;
>                    // need A and B here
>                }
>                finally { A }
>        }
>        finally { B }
>     }
> 
> The first one uses a label defined in the outer try scope, so we only inline finally A here.  The second uses a label defined outside the outer try scope, so we have to inline A and B (in the right order) here.  
> 

Indeed it's complex. I think the test membership of block labels can work, since X is a member of the outer try’s label set, where as Y is not. But, we have to be careful how we propagate the branch instruction up the chain of builders.

At the moment it's a little messy (do we use parent or terminal etc?) and I need clear this up. We have three kinds of builder:

- the root builder, not an instance of BlockCodeBuilder.
- the terminal builder , an instance of TerminalCodeBuilder.
- the parent block builder, an instance of BlockCodeBuilder.

When a block builder is accepting code elements it can decide whether to propagate them directly to the root builder, skipping any intermediate parent block builders. Branch instructions can be propagated to the parent block builder if the target label is not a member of the block's label set.

So in your example the branch instruction for “continue X” gets propagated to the builder associated with the outer try, and then to the root builder, where as Y gets propagated all the way up.

Paul.




More information about the classfile-api-dev mailing list