Try/catch/finally builder

Brian Goetz brian.goetz at oracle.com
Thu Sep 1 17:32:18 UTC 2022



>> 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.

I think its fair to assume that users will either use TCB, or will build 
exception tables and inline finallys themselves, but not expect the 
interaction of the two to work automagically.  So let's confine 
ourselves to nested use of TCB for the time being.

It is quite likely that we may have indirect nesting: a try block inside 
an an if/else block inside a try block.  So in order to make the 
automagic finally-expansion work, we have to be prepared to walk the 
chain of parents back to the terminal builder, to find TCBs, even if the 
immediately enclosing block builder is not a TCB.

There are basically three paths here:

  - the automagic path, which we're exploring now -- retain enough 
information at run time to determine which "block" owns the branch 
target, and inline the finally blocks for the TCBs between the outermost 
block and the branch target block.

  - the totally manual path, where the user has to figure out which 
finally blocks to emit for any given branch, and maybe we give them a 
"BlockBuilder::emitFinally" to emit each one individually.

  - an intermediate path, where we don't try to guess at what block owns 
the target label, but instead let the user tell us what block owns the 
target label, with some sort of emitFinally(CodeBuilder 
thoughThisBuilder) method.

It feels like the automagic approach is almost there, so I suggest we 
continue pulling on this string for a bit.

> 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.

I'm a little unsure of these terms.  How does the root builder differ 
from the terminal builder?



More information about the classfile-api-dev mailing list