<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <br>
    <br>
    <blockquote type="cite" cite="mid:CY4PR1001MB2150BF5CCB1E062DBA8D16268C7C9@CY4PR1001MB2150.namprd10.prod.outlook.com">
      
      <meta name="Generator" content="Microsoft Word 15 (filtered
        medium)">
      <style>@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;}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;}div.WordSection1
        {page:WordSection1;}</style>
      <div class="WordSection1">
        <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="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?</span></p>
      </div>
    </blockquote>
    <br>
    It means certain operations are, well, contextual.  If you ask a
    context to generate a class, it will do so with the options of that
    context.  So if you generate the same class twice with different
    contexts, you get different results.  <br>
    <br>
    It also means some entities might drag parts of their creating
    context with them.  For example, suppose we parse a classfile using
    context A, which has a mapper for attribute "Foo".  Then we adapt it
    using context B, that doens't know about Foo.  Well, B may not know
    about Foo, but the FooAttribute will have a reference to its
    creating AttributeMapper.  That's fine too (well, if different
    contexts have radically different ideas of how a FooAttribute is
    laid out, maybe not, but in that case we have bigger problems.)<br>
    <br>
    <br>
    <blockquote type="cite" cite="mid:CY4PR1001MB2150BF5CCB1E062DBA8D16268C7C9@CY4PR1001MB2150.namprd10.prod.outlook.com">
      <div class="WordSection1">
        <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US"><o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US">Some of the options already behave that way and
            are quite flexible (</span><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US">processDebug, generateStackmap,
            constantPoolSharing, fixShortJumps, patchDeadCode,
            classHierarchyResolver, filterDeadLabels) and some can be
            fixed to do so (processLineNumbers).</span></p>
      </div>
    </blockquote>
    <br>
    I think its been a while since we took a good look at our options
    and asked "is this the way we want it"; now is a good time to review
    this.  <br>
    <br>
    <blockquote type="cite" cite="mid:CY4PR1001MB2150BF5CCB1E062DBA8D16268C7C9@CY4PR1001MB2150.namprd10.prod.outlook.com">
      <div class="WordSection1">
        <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US"><o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="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?)</span></p>
      </div>
    </blockquote>
    <br>
    I think this is a place where we have to lean on existing design
    constraints of backward compatibility.  We can parse the attribute
    with the mapper found at parse time, and we can write it with either
    that mapper or the one we find at generation time.  <br>
    <br>
    <blockquote type="cite" cite="mid:CY4PR1001MB2150BF5CCB1E062DBA8D16268C7C9@CY4PR1001MB2150.namprd10.prod.outlook.com">
      <div class="WordSection1">
        <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US"><o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="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 style="font-size:11.0pt;mso-fareast-language:EN-US" lang="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.</span></p>
      </div>
    </blockquote>
    <br>
    Correct, this is part of what I mean by the "let's review our
    options and make sure they mean what we think, and write that down"
    above.  <br>
    <br>
    <blockquote type="cite" cite="mid:CY4PR1001MB2150BF5CCB1E062DBA8D16268C7C9@CY4PR1001MB2150.namprd10.prod.outlook.com">
      <div class="WordSection1">
        <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US"><o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US">While
          </span><span style="font-size:11.0pt;mso-fareast-language:EN-US">DROP_DEBUG_ON_READ</span><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="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 style="font-size:11.0pt;mso-fareast-language:EN-US" lang="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 style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="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 style="font-size:13.5pt;font-family:"Courier
            New",serif" lang="EN-US">).</span><span style="font-size:13.5pt;font-family:"Courier
            New",serif">parse(bytes);<br>
                CC.of(</span><span style="font-size:13.5pt;font-family:"Courier
            New",serif" lang="EN-US">do not
          </span><span style="font-size:13.5pt;font-family:"Courier
            New",serif">DROP_DEBUG).transform(cm, transform);<br>
          </span></p>
      </div>
    </blockquote>
    <br>
    So, what happens here is that on reading, we drop the debug
    information, so the ClassModel has no debug information.  When we
    use that as a source, there's no debug information in the source but
    any debug information added by the transform is not dropped.<br>
    <br>
    <blockquote type="cite" cite="mid:CY4PR1001MB2150BF5CCB1E062DBA8D16268C7C9@CY4PR1001MB2150.namprd10.prod.outlook.com">
      <div class="WordSection1">
        <p class="MsoNormal"><span style="font-size:13.5pt;font-family:"Courier
            New",serif">
                </span><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="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 <a class="moz-txt-link-rfc2396E" href="mailto:brian.goetz@oracle.com"><brian.goetz@oracle.com></a><br>
              <b>Date: </b>Friday, 19 May 2023 16:15<br>
              <b>To: </b>Adam Sotona <a class="moz-txt-link-rfc2396E" href="mailto:adam.sotona@oracle.com"><adam.sotona@oracle.com></a>,
              <a class="moz-txt-link-abbreviated" href="mailto:liangchenblue@gmail.com">liangchenblue@gmail.com</a> <a class="moz-txt-link-rfc2396E" href="mailto:liangchenblue@gmail.com"><liangchenblue@gmail.com></a>,
              classfile-api-dev <a class="moz-txt-link-rfc2396E" href="mailto:classfile-api-dev@openjdk.org"><classfile-api-dev@openjdk.org></a><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 style="font-size:11.0pt;mso-fareast-language:EN-US" lang="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 style="font-size:11.0pt;mso-fareast-language:EN-US" lang="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 style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US"> </span></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US">var options =
              List.of(Option.classHierarchyResolver(resolver),
            </span></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US">                      Option.attributeMapper(mapper));</span></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US"> </span></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US">Classfile.build(clsDesc, options, handler);</span></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US">Classfile.parse(bytes, options); //here we
              have only vararg now</span></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US"> </span></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="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 style="font-size:11.0pt;mso-fareast-language:EN-US" lang="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 style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US"> </span></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US">Classfile.parse(bytes,
              options1).transform(classTransform1);</span></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US">Classfile.parse(bytes,
              options2).transform(classTransform2);</span></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US"> </span></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US">Instead of simple:</span></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US">var clm = Classfile.parse(bytes);</span></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US">clm.transform(classTransform1, options1);</span></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US">clm.transform(classTransform2, options2);</span></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US"> </span></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US">Or maybe:</span></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US">var clm = Classfile.parse(bytes, options1);</span></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US">clm.transform(classTransform1);</span></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US">clm.setOptions(options2);</span></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US">clm.transform(classTransform2);</span></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US"> </span></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="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 style="font-size:11.0pt;mso-fareast-language:EN-US" lang="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 style="font-size:11.0pt;mso-fareast-language:EN-US" lang="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 style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US"> </span></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="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 style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US"> </span></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US">Thanks,</span></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US">Adam</span></p>
          <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="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" moz-do-not-send="true"><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" moz-do-not-send="true"><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" moz-do-not-send="true"><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" moz-do-not-send="true"><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" moz-do-not-send="true"><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>
    </blockquote>
    <br>
  </body>
</html>