[External] : Re: Classfile API cleanup of labelToBci from CodeModel and CodeBuilder and removal of impl.LabelResolver

Adam Sotona adam.sotona at oracle.com
Fri Aug 19 05:58:44 UTC 2022


From: Michael van Acken <michael.van.acken at gmail.com<mailto:michael.van.acken at gmail.com>>

I have a single use of CodeBuilder.labelToBci(): decide whether the labels marking
the start and end of a try block refer to the same position, as a proxy for "enclosed
region is empty".  If this is the case, then no exceptionCatch can be installed and
all exception handlers become unreachable.

How can this scenario still be supported?

-- mva

It is not guaranteed to get the right bytecode indexes from CodeBuilder::labelToBci, the method is really an exposure of internal implementation.
Frequent common cases (like for example dropping exception handler when try block is empty) can be solved with CodeBuilder::trying support.
CodeBuilder::trying uses CodeBuilder::block and before further actions asks CodeBuilder.BlockCodeBuilder::isEmpty.
Now it throws an exception in case of an empty try block, however I can imagine it might skip all handlers instead:
    /**
     * Adds a "try-catch" block comprising one try block and zero or more catch blocks.
     * Exceptions thrown by instructions in the try block may be caught by catch blocks.
     *
     * @param tryHandler handler that receives a {@linkplain CodeBuilder} to
     *                   generate the body of the try block.
     * @param catchesHandler a handler that receives a {@linkplain CatchBuilder}
     *                       to generate bodies of catch blocks.
     * @return this builder
     * @see CatchBuilder
     */
    default CodeBuilder trying(Consumer<BlockCodeBuilder> tryHandler,
                               Consumer<CatchBuilder> catchesHandler) {
        Label tryCatchEnd = newLabel();

        // @@@ the tryHandler does not have access to tryCatchEnd
        BlockCodeBuilderImpl tryBlock = new BlockCodeBuilderImpl(this, tryCatchEnd);
        tryBlock.start();
        tryHandler.accept(tryBlock);
        tryBlock.end();

        // Check for empty try block
        if (!tryBlock.isEmpty()) {
            var catchBuilder = new CatchBuilderImpl(this, tryBlock, tryCatchEnd);
            catchesHandler.accept(catchBuilder);
            catchBuilder.finish();
        }

        return this;
    }



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/classfile-api-dev/attachments/20220819/f741d303/attachment-0001.htm>


More information about the classfile-api-dev mailing list