Convenient methods to build switch and try/finally in Classfile API

Brian Goetz brian.goetz at oracle.com
Fri May 19 14:07:55 UTC 2023


As I mentioned to Chen Liang, I would really like to place a moratorium 
on "new convenience methods" for a while, and I'd like to stop doing 
them one at a time.  Instead, let's gather a list of areas that 
potentially need improvement, and come back in a more organized way for 
a subsequent preview.

I have no objection to eventually improving the API for both switches 
and try, but both of these areas have some risk in them, so I don't want 
to treat these as the same sort of convenience as `aload_0`.  Switches 
have messy scoping (it's all one big scope, which means we don't create 
a new locals context the way we do with if/else) and control flow 
(break, continue).

We have an existing trying() construct but it doesn't handle finally.  
Having two constructs that look like they correspond to the same 
language construct may be confusing. (Also, I'm not convinced that our 
trying() builder handles local variable slot allocation correctly either 
-- I think the try block does, but I am pretty sure the cache handler 
doesn't.  But we don't have tests that cover the interaction of the 
various convenience builders with local allocation.

So let's put this on the list of things that need improvement, and 
meanwhile, continue to shore up basics.

On 5/19/2023 5:12 AM, Adam Sotona wrote:
>
> Hi,
>
> Classfile API provides convenient methods for if/then/else or 
> try/catch, however similar methods to build switch or try/finally are 
> missing.
>
> Here I would like to propose new|CodeBuilder|conveniences:
>
> ||
>
>   * |lookupswitch(Consumer<SwitchBuilder> switchHandler)|
>   * |tableswitch(Consumer<SwitchBuilder> switchHandler)|
>   * |tryWithFinalizer(Consumer<CodeBuilder> tryHandler,
>     Consumer<CodeBuilder> finalizerHandler, Label... externalLabels)|
>   * |tryWithFinalizer(Consumer<CodeBuilder> tryHandler,
>     Consumer<CodeBuilder> finalizerHandler, boolean compactForm,
>     Label... externalLabels)|
>
> and new|CodeBuilder.SwitchBuilder|interface with methods:
>
> ||
>
>   * |switchCase(int caseValue, Consumer<BlockCodeBuilder> caseHandler)|
>   * |switchCase(List<Integer> caseValues, Consumer<BlockCodeBuilder>
>     caseHandler)|
>   * |defaultCase(Consumer<BlockCodeBuilder> defaultHandler)|
>
> Sample use case (more can be seen in the tests at 
> https://github.com/openjdk/jdk/pull/14056/files):
>
> cob./lookupswitch/(swb -> swb
>
> ./switchCase/(1, b -> b./iinc/(0,1)./goto_/(b./breakLabel/()))
>
>         ./switchCase/(2, b -> b./iinc/(0,2)./goto_/(b./breakLabel/()))
>
>         ./switchCase/(3, b -> b./iinc/(0,3)./goto_/(b./breakLabel/()))
>
>         ./defaultCase/(b -> b./iinc/(0,100)./goto_/(b./breakLabel/()))
>
>         ./switchCase/(4, b -> b./iinc/(0,4)./goto_/(b./breakLabel/()))
>
>         ./switchCase/(5, b -> b./iinc/(0,5)./goto_/(b./breakLabel/()))
>
>         ./switchCase/(6, b -> b./iinc/(0,6)./goto_/(b./breakLabel/())))
>
> cob.tryWithFinalizer(
>         tryb -> tryb.goto_(externalLabel1),
>         finb -> finb.constantInstruction(42).ireturn(),
>         externalLabel1);
>
> The implementation work is in progress. I’m now fiddling with precise 
> placing of finalizers in all possible situations. Trying to do not 
> miss any exit from try block, do not produce dead code, do not fall to 
> double finalizer execution and all that with appropriate test coverage.
>
> The implementation of finalizers now offers two possible modes:
>
> ·expanded (as javac does now), where the code flow is unaffected and 
> finalizer block is copied before each exit from the try block
>
> ·compact, where identical exits are joined to common copy of the 
> finalizer block (for example all returns are merged into one finalizer 
> and return).
>
> Please let me know your comments and suggestions.
>
> Thanks,
>
> Adam
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/classfile-api-dev/attachments/20230519/1c895bef/attachment-0001.htm>


More information about the classfile-api-dev mailing list