On Aug 30, 2012, at 6:35 AM, Remi Forax wrote:
> "<init>" should be possible, but I don't think the EG discuss this corner
> case.
I don't remember discussing this either, but I'm sure we covered it at some
point, since it is covered in the JVMS. Maybe we just have to thank Alex
Buckley for filling in the correct rule.
A non-normative footnote in JVMS 4.2.2 implies that <init> is not usable with
invokedynamic:
> Note that a field name or interface method name may be <init> or <clinit>,
> but no method invocation instruction may reference <clinit> and only the
> invokespecial instruction (§invokespecial) may reference <init>.
JVMS 4.4.2 says (as Doug Simon observed) that <init> must always be associated
with a void return type, whenever it is mentioned in a CONSTANT_NameAndType
that is part of a CONSTANT_Methodref_info. But an invokedynamic instruction
does not use CONSTANT_Methodref_info, but refers to a CONSTANT_NameAndType
which is not governed by the constraint on return type of <init>.
The CONSTANT_NameAndType constant (JVMS 4.4.6) says explicitly that <init> is
allowed, in general. It also references 4.2.2 which in turn allows both <init>
and <clinit>, so I suppose <clinit> is allowed too, in a CONSTANT_NameAndType.
But the uses of CONSTANT_NameAndType constants are further constrained
elsewhere, so as to disallow most occurrences of <init> and <clinit>.
The specific discussion of the invokedynamic instruction in 4.10.1.4 provides
the final word on these considerations:
> An invokedynamic instruction is type safe iff all of the following conditions
> hold:
>
> • Its first operand, CP, refers to a constant pool entry denoting an
> dynamic call site with
>
> name CallSiteName with descriptor Descriptor.
>
> • CallSiteName is not <init>.
>
> • CallSiteName is not <clinit>.
>
> • One can validly replace types matching the argument types given in
> Descriptor on the incoming operand stack with the return type given in
> Descriptor, yielding the outgoing type state.
So if you want your code to pass the verifier, avoid <init> (and <clinit>).
— John
P.S. Value types (see my blog) will need to make <init> be private, since the
new & invokespecial <init> idiom is totally incompatible with value types. If
we bake them into the class file format (which I don't advocate at present) we
would have to define a syntax for building value-type instances that does not
mention <init>; this leads to ideas like canonical factory methods, of which
the obvious name is <new>. For now, I'm just proposing a design pattern
(public static factory methods, which internally use private new & <init>) that
the JVM internally rewrites.
_______________________________________________
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev