On 11/22/19 12:02, Dan Smith wrote:
On Nov 22, 2019, at 12:22 PM, Leonid Kuskov <[email protected]> wrote:

So specification allows RI  to mark final fields associated with components and some methods by 
ACC_MANDATED flag (0x8000). The latest JVMS specification 
(https://docs.oracle.com/javase/specs/jvms/se13/html/index.html) permits this flag only for 2 
attributes:  MethodParameters_attribute, Module_attribute . The flag is not mentioned in both 
tables: Table 4.5-A. "Field access and property flags", Table 4.6-A. "Method access 
and property flags".
Does it make sense to add a definition of ACC_MANDATED to the tables?
To clarify: are you saying javac is using the 0x8000 flags on fields and 
methods, despite this flag being undefined in these contexts? Or are you saying 
that you think we should *start* using the flag on fields and methods, with 
supporting changes to the spec?
I'm saying javac is using the ACC_MANDATED flag on fields and methods and VM doesn't throw an exception although the spec does not permit this. Please see the example below.

(The first would be a bug, the second would be a minor new feature.)

Now names of methods are removed and the more loose statement "mandated members of enums and 
records" is used. Does it mean that spec won't enumerate "mandated" methods anymore? 
And the setting of this flag will be implementation-specific? From my point of view, it might break 
the unambiguity of the signature tests.
I don't like putting highly specific compilation details in the JVMS 
description of an attribute. I don't think it's the appropriate place for those 
kinds of rules.
I don't like this too.
It is a good idea to define "mandated" members in JVMS through implicitly declared members stated in the JLS. But JVMS doesn't interact with JLS in a definition of any members at all. Could it be clarified in the VM spec?

I *do* think we have a reasonable definition of "mandated" based on the 
specification of the flag, combined with what the JLS has to say about implicit 
declarations (see, for example, JLS 8.9.3).

(JLS doesn't use that particular term, so depending on the answer to your first question, maybe it 
makes sense to rephrase this rule to talk about "implicit" members rather than 
"mandated" members.)

I agree.

BTW, JLS for Records* (chapter 13.1 Binary compatibility) states

   For reference, the following constructs are declared implicitly in
   source code, but are not marked as mandated because only formal
   parameters can be so marked in a|class|file (JVMS §4.7.24):

     *

       Default constructors of classes and enum types (8.8.9
       
<https://docs.oracle.com/javase/specs/jls/se11/html/jls-8.html#jls-8.8.9>,8.9.2
       
<https://docs.oracle.com/javase/specs/jls/se11/html/jls-8.html#jls-8.9.2>)

     *

       *Canonical constructors of record types (8.10.4
       
<http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html#jls-8.10.4>)*

     *

       Anonymous constructors (15.9.5.1
       
<https://docs.oracle.com/javase/specs/jls/se11/html/jls-15.html#jls-15.9.5.1>)

     *

       The|values|and|valueOf|methods of enum types (8.9.3
       
<https://docs.oracle.com/javase/specs/jls/se11/html/jls-8.html#jls-8.9.3>)

     *

       Certain|public|fields of enum types (8.9.3
       
<https://docs.oracle.com/javase/specs/jls/se11/html/jls-8.html#jls-8.9.3>)

     *

       *Certain|private|fields and|public|methods of record types
       (8.10.3
       
<http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html#jls-8.10.3>)*

     *

       Certain|public|methods of interfaces (9.2
       <https://docs.oracle.com/javase/specs/jls/se11/html/jls-9.html#jls-9.2>)

     *

       Container annotations (9.7.5
       
<https://docs.oracle.com/javase/specs/jls/se11/html/jls-9.html#jls-9.7.5>)

It is an extra place where implicit members don't match "mandated" members from the JVMS point of view. It would be good to be able to identify a list of implicit/mandated methods for each class/interface.

For example, the record:

public record Complex(double re, double im) {
  @Override
  public String toString() { ... }
}

is compiled to :

super public final class Complex extends java/lang/Record version 58:65535
{

private final mandated Field re:D;
private final mandated Field im:D;

public Method "<init>":"(DD)V"
    stack 3 locals 5
    0: #{re mandated}
    1: #{im mandated}
{}

public Method toString:"()Ljava/lang/String;"{}
public final mandated Method hashCode:"()I" {}
public final mandated Method equals:"(Ljava/lang/Object;)Z" {}
public mandated Method re:"()D"
public mandated Method im:"()D"

Record
 re:D,
 im:D;

}

Thanks,
Leonid

*) http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html

Reply via email to