Convenient methods to build switch and try/finally in Classfile API
Adam Sotona
adam.sotona at oracle.com
Fri May 19 14:41:57 UTC 2023
OK, let’s postpone these.
From: Brian Goetz <brian.goetz at oracle.com>
Date: Friday, 19 May 2023 16:08
To: Adam Sotona <adam.sotona at oracle.com>, classfile-api-dev at openjdk.org <classfile-api-dev at openjdk.org>
Subject: Re: Convenient methods to build switch and try/finally in Classfile API
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:
1. lookupswitch(Consumer<SwitchBuilder> switchHandler)
2. tableswitch(Consumer<SwitchBuilder> switchHandler)
3. tryWithFinalizer(Consumer<CodeBuilder> tryHandler, Consumer<CodeBuilder> finalizerHandler, Label... externalLabels)
4. tryWithFinalizer(Consumer<CodeBuilder> tryHandler, Consumer<CodeBuilder> finalizerHandler, boolean compactForm, Label... externalLabels)
and new CodeBuilder.SwitchBuilder interface with methods:
1. switchCase(int caseValue, Consumer<BlockCodeBuilder> caseHandler)
2. switchCase(List<Integer> caseValues, Consumer<BlockCodeBuilder> caseHandler)
3. 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:
1. expanded (as javac does now), where the code flow is unaffected and finalizer block is copied before each exit from the try block
2. 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/43584db4/attachment-0001.htm>
More information about the classfile-api-dev
mailing list