<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:Consolas;
panose-1:2 11 6 9 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
font-size:10.0pt;
font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
pre
{mso-style-priority:99;
mso-style-link:"HTML Preformatted Char";
margin:0cm;
margin-bottom:.0001pt;
font-size:10.0pt;
font-family:"Courier New",serif;}
span.HTMLPreformattedChar
{mso-style-name:"HTML Preformatted Char";
mso-style-priority:99;
mso-style-link:"HTML Preformatted";
font-family:Consolas;}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;
mso-ligatures:none;}
@page WordSection1
{size:612.0pt 792.0pt;
margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
{page:WordSection1;}
--></style>
</head>
<body lang="en-CZ" link="blue" vlink="purple" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">I like the idea when the whole “context” is out of the ClassModel, so using it with a different context will do the job differently. However doesn’t it mean they are
rather mutable, when you get different content based on context?<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">Some of the options already behave that way and are quite flexible (</span><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">processDebug, generateStackmap,
constantPoolSharing, fixShortJumps, patchDeadCode, classHierarchyResolver, filterDeadLabels) and some can be fixed to do so (processLineNumbers).<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">However for example attributeMapper is closely tied with the parsed model and it would require to re-parse when. Also the last used context would have to be stored with
the model to know if any reset of already expanded model is needed (for example did we skipped parsing line numbers or are they just missing?)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">Another confusion we are already facing is when the actual option become effective.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">For example generateStackmap(false) does not implicitly mean they will be dropped by the transformation (unless we expand each Code attribute). The same for processDebug,
processLineNumbers and patchDeadCode.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">While
</span><span style="font-size:11.0pt;mso-fareast-language:EN-US">DROP_DEBUG_ON_READ</span><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> is clearly an option,
</span><span style="font-size:11.0pt;mso-fareast-language:EN-US">DROP_DEBUG_ON_WRITE</span><span style="font-size:11.0pt;mso-fareast-language:EN-US">
<span lang="EN-US">suppose to be rather a CodeTransform, because by setting the option we do not say it will be effective.<o:p></o:p></span></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">All attributes attached to code have very specific position, as we must expand the whole code when we want just filter them out.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">To your example I’m not quite sure what to expect from:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:13.5pt;font-family:"Courier New",serif"> ClassModel cm = CC.of(DROP_DEBUG</span><span lang="EN-US" style="font-size:13.5pt;font-family:"Courier New",serif">).</span><span style="font-size:13.5pt;font-family:"Courier New",serif">parse(bytes);<br>
CC.of(</span><span lang="EN-US" style="font-size:13.5pt;font-family:"Courier New",serif">do not
</span><span style="font-size:13.5pt;font-family:"Courier New",serif">DROP_DEBUG).transform(cm, transform);<br>
</span><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal" style="margin-bottom:12.0pt"><b><span style="font-size:12.0pt;color:black">From:
</span></b><span style="font-size:12.0pt;color:black">Brian Goetz <brian.goetz@oracle.com><br>
<b>Date: </b>Friday, 19 May 2023 16:15<br>
<b>To: </b>Adam Sotona <adam.sotona@oracle.com>, liangchenblue@gmail.com <liangchenblue@gmail.com>, classfile-api-dev <classfile-api-dev@openjdk.org><br>
<b>Subject: </b>Re: Planned features of a classfile context object<o:p></o:p></span></p>
</div>
<p class="MsoNormal" style="margin-bottom:12.0pt"><span style="font-size:13.5pt;font-family:"Courier New",serif">I agree that much of what such a context would manage is options. But I think we can also agree that the current treatment, where we stash Options
in the CPBuilder, isn't right either. <br>
<br>
I can buy that sometimes we want to parse with different options than we generate with. We can add this in as as goal for rationalizing the classfile context. I suspect also that part of the problem is that our options are too granular: "process debug" is
just a boolean, which could be broken down further. As a not-entirely-serious suggestion:
<br>
<br>
enum ProcessDebugOptions implements Option { <br>
DROP_DEBUG, DROP_DEBUG_ON_READ, DROP_DEBUG_ON_WRITE;<br>
}<br>
<br>
Originally all our options were booleans, and we've moved past that structurally, but haven't really reexamined all the options we defined.<br>
<br>
I think the problem with "can't transform with different options" stems from the fact that transform lives only on the model, not on the context. This would let you do what you want as:<br>
<br>
ClassModel cm = CC.of(opts1).parse(bytes);<br>
CC.of(opts2).transform(cm, transform);<br>
CC.of(opts3).transform(cm, transform);<br>
<br>
This derives from the principle that all classfile entities are immutable and can be used in any context; no need to re-parse.
<br>
<br>
<br>
<br>
</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">On 5/19/2023 3:52 AM, Adam Sotona wrote:<o:p></o:p></span></p>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">I think our current Classfile.Option is already not so far from the proposed global context holder approach.</span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">The most significant use cases to persist (class hierarchy resolution and custom attributes) can be very well cached by keeping the Classfile.Option instances and re-using
them as many times as user needs.</span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US">var options = List.of(Option.classHierarchyResolver(resolver),
</span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US"> Option.attributeMapper(mapper));</span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US">Classfile.build(clsDesc, options, handler);</span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US">Classfile.parse(bytes, options); //here we have only vararg now</span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">What I’m missing much much more than “global options holder” is per-transformation options (or even option change for transformed method).
</span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">For example I would like to use one class model to transform into multiple classes with different options, and I have to write:</span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US">Classfile.parse(bytes, options1).transform(classTransform1);</span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US">Classfile.parse(bytes, options2).transform(classTransform2);</span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">Instead of simple:</span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US">var clm = Classfile.parse(bytes);</span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US">clm.transform(classTransform1, options1);</span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US">clm.transform(classTransform2, options2);</span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">Or maybe:</span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US">var clm = Classfile.parse(bytes, options1);</span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US">clm.transform(classTransform1);</span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US">clm.setOptions(options2);</span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US">clm.transform(classTransform2);</span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">However it raises the main question about what options are really tied to model parsing (I think it is only attributeMapper).</span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">And what options can be safely changed later. For example can I change processDebug, processLineNumbers or processUnknownAttributes on already parsed class model to
get different results of the following model traversal?</span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">And there are majority of options unrelated to the parsed class model but affecting only building and transformations (generateStackmap, constantPoolSharing, fixShortJumps,
patchDeadCode, classHierarchyResolver, filterDeadLabels).</span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">I think we should make more clear which options affect what actions (parsing, building, transformation) and give more flexibility to change them on the fly.</span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">Thanks,</span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">Adam</span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"> </span></p>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal" style="margin-bottom:12.0pt"><b><span style="font-size:12.0pt;color:black">From:
</span></b><span style="font-size:12.0pt;color:black">classfile-api-dev </span><a href="mailto:classfile-api-dev-retn@openjdk.org"><span style="font-size:12.0pt"><classfile-api-dev-retn@openjdk.org></span></a><span style="font-size:12.0pt;color:black"> on behalf
of Brian Goetz </span><a href="mailto:brian.goetz@oracle.com"><span style="font-size:12.0pt"><brian.goetz@oracle.com></span></a><span style="font-size:12.0pt;color:black"><br>
<b>Date: </b>Thursday, 18 May 2023 16:16<br>
<b>To: </b></span><a href="mailto:liangchenblue@gmail.com"><span style="font-size:12.0pt">liangchenblue@gmail.com</span></a><span style="font-size:12.0pt;color:black">
</span><a href="mailto:liangchenblue@gmail.com"><span style="font-size:12.0pt"><liangchenblue@gmail.com></span></a><span style="font-size:12.0pt;color:black">, classfile-api-dev
</span><a href="mailto:classfile-api-dev@openjdk.org"><span style="font-size:12.0pt"><classfile-api-dev@openjdk.org></span></a><span style="font-size:12.0pt;color:black"><br>
<b>Subject: </b>Re: Planned features of a classfile context object</span></p>
</div>
<p class="MsoNormal" style="margin-bottom:12.0pt"><span style="font-size:13.5pt;font-family:"Courier New",serif">Currently the ConstantPoolBuilder is another place we we attach options. This was more of a sin of convenience than anything else; the theory was
that if we are transforming a class, we'll parse it with a set of options, and then generate a new class which shares its CP, and the options came along for the ride.
<br>
<br>
Searching for a better name that ClassfileContext. The name Classfile is too good to waste, but it doesn't represent a classfile (that's ClassModel), so calling the new thing Classfile would likely be weird. Also ClassfileContext would make it harder to discover
the key entry points (build/parse). Classfile.Context is better in that it is more discoverable at least.
<br>
<br>
Classfile{Parser,Generator} are more discoverable but only tell half the story, and there's no obvious "first half" of the story. ClassfileReaderWriter is discoverable and honest but long. Classfile{Broker,Manager,Mediator} sound like parodies of the Design
Patterns era. <br>
<br>
A slightly cheeky but possibly viable option is "Classfiles"; while not a collection of classfiles, it is a collection of behaviors _about_ classfiles.
<br>
<br>
Classfiles.of(options).parse(bytes)<br>
Classfiles.of(options).generate(handler)<br>
<br>
<br>
<br>
<br>
<br>
</span></p>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">On 5/17/2023 11:21 AM, Brian Goetz wrote:</span></p>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal" style="margin-bottom:12.0pt"><span style="font-size:13.5pt;font-family:"Courier New",serif">These are basically what is on my list, though I had in mind to move _all_ option information to the context, and leave it out of individual processing
decisions. </span></p>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">On 5/17/2023 9:59 AM, - wrote:</span></p>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<pre>Hi,</pre>
<pre>In the discussions a few weeks ago, we envisioned a Classfile context</pre>
<pre>object shared across multiple Classfile processing scenarios, mainly</pre>
<pre>for Class hierarchy information caching.</pre>
<pre> </pre>
<pre>I want to confirm that these are contents of the object, mainly</pre>
<pre>promoted from individual options:</pre>
<pre> - Class Hierarchy information caching</pre>
<pre> - Custom attribute processing</pre>
<pre> - A set of default options, propagated to individual processing (may</pre>
<pre>be overridden classfile-wise)</pre>
<pre> </pre>
<pre>What else is planned for the context object currently? Please don't</pre>
<pre>hesitate to propose. Thanks!</pre>
<pre> </pre>
<pre>Chen Liang</pre>
</blockquote>
<p class="MsoNormal"><span style="font-size:11.0pt"> </span></p>
</blockquote>
<p class="MsoNormal"><span style="font-size:11.0pt"> </span></p>
</blockquote>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
</div>
</body>
</html>