Try/catch/finally builder

Paul Sandoz paul.sandoz at oracle.com
Thu Sep 1 18:20:08 UTC 2022



> On Sep 1, 2022, at 10:32 AM, Brian Goetz <brian.goetz at oracle.com> wrote:
> 
> 
> 
>>> 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.
> 

Yes.


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

Agreed, it looks possible.

(Separately we need to add some loop support, plus perhaps a way to model lambda expressions, which interestingly will build synthetic methods.) 


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

The root builder is that passed by the MethodBuilder::withCode method to its consumer argument.

I am still uncertain how code transformers layer in. I think they interject a form of builder in the builder chain but I am currently unsure of any impact related to TCB.

Paul.


More information about the classfile-api-dev mailing list