Classfile API Synchronous Stack Tracking in CodeBuilder
Brian Goetz
brian.goetz at oracle.com
Fri Aug 26 14:12:50 UTC 2022
I like how this leans on the existing Transform abstraction -- and it is
useful beyond just tracking -- it means existing transforms can be
combined with generation if that is convenient.
If the user wants to chain some transforms together *and* wants to
retain references to each element in the chain -- which they will
probably want to do if there are multiple kinds of "trackers" here, such
as tracking stack + tracking locals -- then there is a little trickiness
to setting the pipeline up right. The user will have to do something like:
withMethodBody(b -> {
StackTracker st = StackTracker.of();
LocalTracker lt = LocalTracker.of();
transforming(st.andThen(lt), cb -> { ... build here, can use
st/lt ... });
});
What's happening here is that the transforms are stateful, but the user
is creating the transform instances directly, rather than through a
factory, so they can retain references to them. This is totally OK, as
long as the user doesn't try to reuse the same StackTracker instance
across multiple methods at the same time.
The spec for StackTracker and friends will probably need some extensive
examples to guide users to the right idiom.
On 8/26/2022 9:58 AM, Adam Sotona wrote:
>
> 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 thetransformtoapplytothecodegeneratedbythehandler
>
> * *@param*handler handlerthatreceivesa {*@linkplain*BlockCodeBuilder} to
>
> * generatethecode.
>
> * *@return*thisbuilder
>
> */
>
> defaultCodeBuilder *transforming*(CodeTransform transform,
> Consumer<CodeBuilder> handler) {
>
> varresolved = transform.resolve(this);
>
> resolved.startHandler().run();
>
> handler.accept(newTransformingCodeBuilder(this, resolved.consumer()));
>
> resolved.endHandler().run();
>
> returnthis;
>
> }
>
> 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 -> {
> varstackTracker = newStackTracker();
> 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/94305bc7/attachment-0001.htm>
More information about the classfile-api-dev
mailing list