Hi,

the Java VM spec tells you the following how to "detect" signature polymorphic 
methods in bytecode:

===
A method is signature polymorphic if and only if all of the following 
conditions hold :
- It is declared in the java.lang.invoke.MethodHandle class.
- It has a single formal parameter of type Object[].
- It has a return type of Object.
- It has the ACC_VARARGS and ACC_NATIVE flags set.

In Java SE 7, the only signature polymorphic methods are the invoke and 
invokeExact methods of the class java.lang.invoke.MethodHandle.

The Java Virtual Machine gives special treatment to signature polymorphic 
methods in the invokevirtual instruction (§invokevirtual), in order to effect 
invocation of a method handle. A method handle is a typed, directly executable 
reference to an underlying method, constructor, field, or similar low-level 
operation (§5.4.3.5), with optional transformations of arguments or return 
values. These transformations are quite general, and include such patterns as 
conversion, insertion, deletion, and substitution. See the java.lang.invoke 
package in the Java SE platform API for more information.
===

Now the question is: In java 9 the MethodHandle class is not the only one, it 
also added VerHandle to the list of classes that use signature polymorphic!

Now the problem I have: In the Javadocs it says: "Bytecode generators, 
including the compiler back end, are required to emit untransformed symbolic 
type descriptors for these methods. Tools which determine symbolic linkage are 
required to accept such untransformed descriptors, without reporting linkage 
errors."

I am writing a bytecode analysis tool that needs to detect signature 
polymorphic methods to have a special treatment with them when invoked in 
bytecode. In my opinion, the above spec is fine for Java 7 and Java 8, but 
breaks for Java 9, because also VarHandle was added. I think the spec should be 
a bit more clear how to detect those methods:
- Add a reflective getter on Method to check if its signature polymorphic
- Make the annotation in MethodHandle public and document it. Also change the 
spec to say: All native varargs methods with the *public* annotation on it are 
signature polymorphic.
- Change the spec to say: The above described flags and method desriptor are 
used to detect (no change), but anything below java.lang.invoke is also 
required. I don't really like that spec, because it may break again in future.

I don't like the first part of the spec that says: this signature + ACC_VARARGS 
+ ACC_NATIVE. A 3rd party tool could create a method with exactly that 
signature outside the JDK code, so I have to limit the package name. Or use the 
annotations! That’s my problem with the spec!

Whats the plan for the VM spec and "what's" the best way to detect if a method 
is signature polymorphic - that is also future proof?

In my code of forbiddenapis, see 
https://github.com/policeman-tools/forbidden-apis/pull/106, I implemented 
purely the Java VM 8 spec, just extending the class name matcher to "everything 
below java.lang.invoke", so it also works for VarHandles. But as said, this 
does not look like "future-proof".

Uwe

-----
Uwe Schindler
uschind...@apache.org 
ASF Member, Apache Lucene PMC / Committer
Bremen, Germany
http://lucene.apache.org/


Reply via email to