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