<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">
Here’s an update:
<div class=""><br class="">
</div>
<div class=""><a href="https://github.com/openjdk/jdk-sandbox/compare/classfile-api-branch...PaulSandoz:jdk-sandbox:try-catch-finally-builder?expand=1" class="">https://github.com/openjdk/jdk-sandbox/compare/classfile-api-branch...PaulSandoz:jdk-sandbox:try-catch-finally-builder?expand=1</a></div>
<div class="">
<pre style="background-color:#ffffff;color:#080808;font-family:'JetBrains Mono',monospace;font-size:9.8pt;" class=""><span style="color:#0033b3;" class="">sealed interface </span><span style="color:#000000;" class="">CatchFinallyBuilder </span><span style="color:#0033b3;" class="">permits </span><span style="color:#000000;" class="">CatchFinallyBuilderImpl </span>{<br class=""> <span style="color:#000000;" class="">CatchFinallyBuilder </span><span style="color:#00627a;" class="">catching</span>(<span style="color:#000000;" class="">ClassDesc </span>exceptionType, <span style="color:#000000;" class="">Consumer</span><<span style="color:#000000;" class="">BlockCodeBuilder</span>> catchHandler);<br class=""><br class=""> <span style="color:#0033b3;" class="">default void </span><span style="color:#00627a;" class="">finally_</span>(<span style="color:#000000;" class="">Consumer</span><<span style="color:#000000;" class="">BlockCodeBuilder</span>> finallyHandler) {<br class=""> finally_(<span style="color:#871094;font-style:italic;" class="">INLINE_FINALLY_ON_BREAK</span>, finallyHandler);<br class=""> }<br class=""><br class=""> <span style="color:#0033b3;" class="">void </span><span style="color:#00627a;" class="">finally_</span>(<span style="color:#000000;" class="">BiPredicate</span><<span style="color:#000000;" class="">BlockCodeBuilder</span>, <span style="color:#000000;" class="">BranchInstruction</span>> inlineFinallyTest,<br class=""> <span style="color:#000000;" class="">Consumer</span><<span style="color:#000000;" class="">BlockCodeBuilder</span>> finallyHandler);<br class=""><br class=""> <span style="color:#000000;" class="">BiPredicate</span><<span style="color:#000000;" class="">BlockCodeBuilder</span>, <span style="color:#000000;" class="">BranchInstruction</span>> <span style="color:#871094;font-style:italic;" class="">INLINE_FINALLY_ON_BREAK </span>=<br class=""> (b, i) -> b.breakLabel() == i.target();<br class="">}<br class=""></pre>
<div class="">The terminal finally_ builder method accepts an optional predicate.</div>
<div class=""><br class="">
</div>
<div class="">Paul. </div>
<br class="">
<blockquote type="cite" class="">On Aug 24, 2022, at 10:57 AM, Paul Sandoz <<a href="mailto:paul.sandoz@oracle.com" class="">paul.sandoz@oracle.com</a>> wrote:<br class="">
<br class="">
Or, alternatively, the user can provide an optional BiPredicate<BlockCodeBuilder, BranchInstruction>, which is called for every branch instruction of a try or catch block, and returns true if the branches target is known to exit the block and therefore the
finally blocks need to be inlined before it. The default implementation is specified to behave as it does in the prototype, and can be composed.<br class="">
<br class="">
That seems to give the developer the control they need without explicitly emitting finally blocks, which could get more complex when nesting trying builders.<br class="">
<br class="">
Paul.<br class="">
<br class="">
<blockquote type="cite" class="">On Aug 23, 2022, at 6:12 PM, Brian Goetz <<a href="mailto:brian.goetz@oracle.com" class="">brian.goetz@oracle.com</a>> wrote:<br class="">
<br class="">
Maybe the TCB should have an “emit finally” method that causes the finally lambda to be called at that point?<br class="">
<br class="">
Sent from my MacBook Wheel<br class="">
<br class="">
<blockquote type="cite" class="">On Aug 23, 2022, at 6:39 PM, Paul Sandoz <<a href="mailto:paul.sandoz@oracle.com" class="">paul.sandoz@oracle.com</a>> wrote:<br class="">
<br class="">
Hi,<br class="">
<br class="">
Here’s a prototype of a try/catch/finally builder (that should replace the current approach):<br class="">
<br class="">
<a href="https://github.com/openjdk/jdk-sandbox/compare/classfile-api-branch...PaulSandoz:jdk-sandbox:try-catch-finally-builder?expand=1" class="">https://github.com/openjdk/jdk-sandbox/compare/classfile-api-branch...PaulSandoz:jdk-sandbox:try-catch-finally-builder?expand=1</a><br class="">
<br class="">
So far it all seems to work and produces correct code for nested building, generating similar code as the source compiler produces.<br class="">
<br class="">
I need to do more thorough testing and commit unit tests.<br class="">
<br class="">
—<br class="">
<br class="">
One challenge is determining when a block exits. A branching instruction that exits the block should result in inlining of the finally code before the instruction, but it's hard to precisely determine if the branch target is within or outside of the block.
At the moment I hard code to checking if the target is the break label of the block, otherwise it is assumed the branch does not exit the block. I don’t think this is generally decidable unless all block instructions are first buffered.<br class="">
<br class="">
Paul.<br class="">
</blockquote>
</blockquote>
<br class="">
</blockquote>
<br class="">
</div>
</body>
</html>