enhanced-metadata-spec-discuss Digest, Vol 12, Issue 4
Alex Buckley
alex.buckley at oracle.com
Mon Aug 26 13:07:35 PDT 2013
Hi Srikanth,
Many thanks for trying out javac in the JDK 8 builds. Answers below.
On 8/26/2013 11:56 AM, Srikanth S Adayapalam wrote:
> (1) For the following case:
>
> // --
> public class X {
> void foo() {
> class Local {
> }
> }
> }
> // --
>
> why would javac emit a mandated formal parameter as in
>
> X$1Local(X);
> descriptor: (LX;)V
> flags:
> Code:
> stack=2, locals=2, args_size=2
> 0: aload_0
> 1: aload_1
> 2: putfield #1 // Field this$0:LX;
> 5: aload_0
> 6: invokespecial #2 // Method
> java/lang/Object."<init>
> :()V
> 9: return
> LineNumberTable:
> line 3: 0
> MethodParameters:
> Name Flags
> this$0 final mandated
>
> // --
>
> I would think this is covered by "The local/
> anonymous class is necessarily emitted by the same compiler as the class
> instance creation
> expression. That compiler can represent the immediately enclosing instance
> how ever
> it wishes. There is no need for the Java programming language to
> implicitly declare a
> parameter in the local/anonymous class's constructor."
>
> and so the parameter need not be mandated ?
I agree. This is a known bug in javac which was identified by unit tests
on compiler-dev last week. (For those who can read GPL'd lists, it's
http://mail.openjdk.java.net/pipermail/compiler-dev/2013-August/007190.html.)
> However, per 13.1 we have:
>
> A construct emitted by a Java compiler must be marked as mandated if it
> corresponds to a formal parameter declared implicitly in source code
> (§8.8.9,
> §8.9.2, §15.9.5.1) and per a reading of 15.9.5.1. seems to imply that
> this$0 above should be mandated, since class Local is not
> occurring in a static context.
Not quite. 15.9.5.1 is about constructors of anonymous classes, and
there is no anonymous class in class X above, so there is nothing in any
current or future JLS text to say that class Local has an implicitly
declared formal parameter.
The interesting case is when an anonymous class has a direct superclass
(the 'S' in 15.9.5.1) which is "special" in some way - private, or local
in a static context. Per the compiler-dev thread above, I am due to
update the enhanced metadata spec ASAP to fully enumerate these
situations in order to completely specify when ctor formal parameters
are implicitly declared.
> (2) 8.8.9 point 3) reads:
>
> In a class instance creation expression for an anonymous class, and where
> the anonymous
> class's superclass is inner, §15.9.2 specifies the immediately enclosing
> instance with respect
> to the superclass. Similar to (1), the superclass may have been emitted by
> a compiler which
> is different than the compiler of the class instance creation expression.
> Therefore, there
> must be a standard way for the compiler of the creation expression to pass
> a reference
> (representing the immediately enclosing instance with respect to the
> superclass) to the
> superclass's constructor. Consequently, the Java programming language
> deems that an
> anonymous class's constructor implicitly declares an initial parameter for
> the immediately
> enclosing instance with respect to the superclass.
>
>
> 8b100's behavior is confusing on the following code:
>
> // --
> public class X {
> void foo() {
> new Y().new Z() {
> };
> }
> }
> class Y {
> class Z {}
> }
> // --
>
> final X this$0;
> descriptor: LX;
> flags: ACC_FINAL, ACC_SYNTHETIC
>
> X$1(X, Y);
> descriptor: (LX;LY;)V
> flags:
> Code:
> stack=3, locals=3, args_size=3
> 0: aload_0
> 1: aload_1
> 2: putfield #1 // Field this$0:LX;
> 5: aload_0
> 6: aload_2
> 7: dup
> 8: invokevirtual #2 // Method
> java/lang/Object.getClas
> s:()Ljava/lang/Class;
> 11: pop
> 12: invokespecial #3 // Method
> Y$Z."<init>":(LY;)V
> 15: return
> LineNumberTable:
> line 3: 0
> MethodParameters:
> Name Flags
> this$0 final mandated
> x0
>
> Why would the anonymous class's own enclosing instances be mandated
> while "x0" which I presume is the super classes enclosing instance
> be flag less ?
There seem to be two javac (or maybe javap) bugs here:
- The this$0 field and the this$0 formal parameter which supplies it are
concerned with the immediately enclosing instance of the anonymous
class's instance. Transmitting this instance to the anonymous class's
instance is covered by point 2 in 8.8.9. Basically, it's not specified.
As such, the this$0 field has been ACC_SYNTHETIC since forever, and
that's a big hint that the this$0 formal parameter should be
ACC_SYNTHETIC too.
- The x0 formal parameter is implicitly declared by 15.9.5.1 as having
type Y, because the direct superclass Z of the anonymous class is inner.
So, x0 should be flagged and displayed as mandated.
Alex
More information about the enhanced-metadata-spec-discuss
mailing list