Classfile API Synchronous Stack Tracking in CodeBuilder

Adam Sotona adam.sotona at oracle.com
Fri Aug 26 13:58:44 UTC 2022


Based on various optiona how to expose the StackTracker through the Classfile API I’ve decided to refactor the proposal in:
https://github.com/openjdk/jdk-sandbox/pull/34

Instead of embedded implementation and Classfile.Option here is a proposal to expose StackTracker as CodeTransform and implement CodeBuilder::transforming method:
/**
* Builds code fragment generated by the handler and synchronously transformed.
* @param transform the transform to apply to the code generated by the handler
* @param handler handler that receives a {@linkplain BlockCodeBuilder} to
* generate the code.
* @return this builder
*/
default CodeBuilder transforming(CodeTransform transform, Consumer<CodeBuilder> handler) {
    var resolved = transform.resolve(this);
    resolved.startHandler().run();
    handler.accept(new TransformingCodeBuilder(this, resolved.consumer()));
    resolved.endHandler().run();
    return this;
}

Modified usage of the StackTracker is reflected in the StackTrackerTest:


Classfile.build(ClassDesc.of("Foo"), clb ->

    clb.withMethodBody("m", MethodTypeDesc.of(ConstantDescs.CD_Void), 0, cob -> {

        var stackTracker = new StackTracker();

        cob.transforming(stackTracker, stcb -> {

            assertEquals(stackTracker.stack().get(), List.of());

            stcb.aload(0);

            assertEquals(stackTracker.stack().get(), List.of(ReferenceType));

            stcb.lconst_0();

            assertEquals(stackTracker.stack().get(), List.of(LongType, ReferenceType));

            stcb.trying(tryb -> {

                assertEquals(stackTracker.stack().get(), List.of(LongType, ReferenceType));

                tryb.iconst_1();

                assertEquals(stackTracker.stack().get(), List.of(IntType, LongType, ReferenceType));

                tryb.ifThen(thb -> {

                    assertEquals(stackTracker.stack().get(), List.of(LongType, ReferenceType));

                    thb.constantInstruction(ClassDesc.of("Phee"));

                    assertEquals(stackTracker.stack().get(), List.of(ReferenceType, LongType, ReferenceType));

                    thb.athrow();

                    assertFalse(stackTracker.stack().isPresent());

                });

                assertEquals(stackTracker.stack().get(), List.of(LongType, ReferenceType));

                tryb.return_();

                assertFalse(stackTracker.stack().isPresent());

            }, catchb -> catchb.catching(ClassDesc.of("Phee"), cb -> {

                assertEquals(stackTracker.stack().get(), List.of(ReferenceType));

                cb.athrow();

                assertFalse(stackTracker.stack().isPresent());

            }));

        });

        assertTrue(stackTracker.maxStackSize().isPresent());

        assertEquals((int)stackTracker.maxStackSize().get(), 4);

    }));

Thanks,
Adam
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/classfile-api-dev/attachments/20220826/338e19dc/attachment-0001.htm>


More information about the classfile-api-dev mailing list