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