Draft JVMS changes for Nestmates
daniel.smith at oracle.com
Fri Apr 21 16:54:39 UTC 2017
> On Apr 20, 2017, at 5:36 PM, David Holmes <David.Holmes at oracle.com> wrote:
>> The rule is:
>> 1) if the referenced method name is not <init> (cheap), and
>> 2) if the referenced class name is the name of a superclass or direct superinterface (cheap—superclass chain is already loaded), and
>> 3) if the loaded referenced class actually is a superclass or direct superinterface (almost always true and cheap, unless there's a name clash), and
>> 4) if the resolved method is not private (pretty cheap, because referenced class is already loaded)
>> *then* check that the stack type is assignable to the current class type.
>> This is, essentially, the same logic being employed by the old protected check: if the reference is to a superclass, find the field/method and decide if it's protected; if the reference is to some other class, don't worry about it.
> So here's the problem, in the spec 5.4 states:
> "Linking a class or interface involves verifying and preparing that class or interface, its direct superclass, its direct superinterfaces, and its element type (if it is an array type), if necessary. Resolution of symbolic references in the class or interface is an optional part of linking."
> So resolution is _optional_ at link time! But your updated spec requires resolution to happen before we can complete verification!
> When we do the verification of invokespecial in the VM it is before resolution and we do not know if the target method is private or not.
In the narrow case of an invokespecial in which (1), (2), and (3) are true, yes, step (4) requires the verifier to find the declaration that is being referenced and decide if it is 'private'.
This is the same as what the old 188.8.131.52 check has always required for every invokevirtual, getfield, and putfield: in narrow circumstances, track down the declared method and decide if it is <protected in another package> or not.
I've tried to be careful not to claim this process is actually resolution. It could be, but it could also be a simulation of resolution that just tells you what method would be found if resolution occurred. Specific text (tweaked slightly since published version): "Given a symbolic reference to a field or method in class _ReferencedClass_ named _MemberName_ with descriptor _MemberDescriptor_, identifies the field or method _Member_ declared in class _DeclaringClass_ that would be produced by resolution, as specified in [5.4.3]."
I am curious about the actual implemented details of this in the protected check. I'm happy to make adjustments to the spec to align with how we actually do this.
More information about the valhalla-spec-observers