Generation of synthesized parameters
Alex Buckley
alex.buckley at oracle.com
Fri Feb 1 15:42:48 PST 2013
On 2/1/2013 2:50 PM, Peter Jensen wrote:
> I have a hard time seeing this as an offer to "the joint JLS and Java SE
> API spec". Unless, by "joint" you mean "joint by a hypothetical compiler
> spec (or concrete implementation)".
> I think these flags are offered to a compiler spec (or implementer),
> which may use it to map a concept of "implicit" in an implemented
> language specification, to ACC_MANDATED in the VM specification.
The JLS and SE API spec both believe that there exist "implicitly
declared" constructs in Java programs. How should "implicitly declared"
be reified at compile-time for use at runtime? That is certainly an
answer for a compiler spec.
But since we do not have a compiler spec, all I can say in the JLS is
that a compiler must "mark" certain constructs. I want to say nothing
about what a mark physically looks like. Still, the author of a Java
compiler which emits class files will find the ACC_SYNTHETIC and
ACC_MANDATED flags very useful.
> As far as I can tell, ACC_SYNTHETIC/ACC_MANDATED has
> - no semantics in the VM
True.
> - no semantics in the JLS
Not exactly. Consider the formal parameters of a method. ACC_SYNTHETIC
and ACC_MANDATED are, in the entire ClassFile chapter of the JVMS, the
only mechanism for reifying certain concepts about formal parameters. So
here comes the JLS with its talk of explicitly/implicitly declared
constructs, telling a compiler to reify those concepts. If the compiler
emits class files,, the ClassFile chapter conveniently offers a
MethodParameters attribute to record parameter information with just the
right flag bits to reify implicitly declared parameters. Technically,
the flag bits are not referenced by the JLS, but the JLS "knows" that
what it demands of a compiler can be achieved by reading JVMS 4.7.22.
> - no semantics in core reflection (They are just values. They have no
> impact on reflected parameter names, and generally no meaning without
> assumptions about the class file origin).
The phrase "no semantics in core reflection" must be read in a certain
light to get your real meaning, but fundamentally: yes, the values
0x1000 and 0x8000 are not inherently critical.
> basically, anyone relying on the synthetic/mandated flags to mean
> anything must trust the provenance of the class file.
Yes.
> So, the important question for me is, what is the the intended use of
> these flags by javac (i.e. what does the javac compiler specification say).
Read JLS 13.1 in the spec PDF, then JVMS 4.7.22. It's pretty obvious
what any Java compiler must do.
> Writing test for this, I assumed something along the lines of:
>
> - Non-synthetic methods with declared arguments must have the
> MethodParameters attribute. (all assuming -parameters of, course)
Yes.
> - Synthetics may have one (allowances for lambdas, which happens to have
> perfectly good explicitly declared parameter names)
I know nothing of methods which are not explicitly or implicitly
declared, other than they must be marked as such in a class file. The
arguments of a so-marked (with ACC_SYNTHETIC) method in a class file are
javac's private business.
> - Expect 2 leading mandated arguments for an enum constructor.
I failed to observe in JLS 8.9.2 that a private no-args constructor is
really implicitly declared for an enum type. I will add this to the
enhanced-metadata spec.
Since it's no-args, any arguments that you are seeing are not explicitly
or implicitly declared and must therefore be marked appropriately - that
would be ACC_SYNTHETIC in the class file.
> - Expect one leading mandated or synthetic argument for non-static
> member classes, local classes and anon inner classes. (couldn't figure
> out precisely
> when to expect mandated and when it's merely synthetic. I thin Alex
> clarified that).
JLS 13.1 now says the constructor of a non-private inner member class
has an implicitly declared parameter, so reflection should reveal that a
Parameter object for which isImplicit() is true.
That's it. Other kinds of classes do not have implicitly declared
parameters in their constructors. A compiler may choose to add
parameters in their constructors, but since those parameters will not be
explicitly or implicitly declared, they must be marked appropriately.
> - For synthetic or mandated parameters, the compiler generates names on
> the form "argI", except when the specification names the
> implied parameter for an enum valueOf(). The JLS give the parameter
> name as "name" (maybe by accident, but nevertheless, it's there).
The JLS imposes no constraints on the names of parameters which are
implicitly declared. The JLS doesn't care at all about parameters which
are not explicitly OR implicitly declared. So a Java compiler has a lot
of freedom with names here. Where are you seeing "name" in the JLS?
Section 2.3 of the enhanced-metadata spec requires name generation by
core reflection, but that's "arg".
Finally, please start a new thread for non-parameter constructs.
Alex
More information about the compiler-dev
mailing list