> On Apr 20, 2017, at 5:36 PM, David Holmes <david.hol...@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 4.10.1.8 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.

—Dan

Reply via email to