# HG changeset patch # User Gilles Duboscq # Date 1434642287 -7200 # Node ID 53b4acee50f15a0b3596577bf9f22f7a43382b08 # Parent 4c9d4fe1cbd8d369dc9b89c523552d2979bcfa83 Add ResolvedJavaMethod.isSignaturePolymorphic and ResolvedJavaType.findMethod diff -r 4c9d4fe1cbd8 -r 53b4acee50f1 jvmci/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/ResolvedJavaMethod.java --- a/jvmci/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/ResolvedJavaMethod.java Thu Jun 18 17:51:05 2015 +0200 +++ b/jvmci/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/ResolvedJavaMethod.java Thu Jun 18 17:44:47 2015 +0200 @@ -338,4 +338,22 @@ } SpeculationLog getSpeculationLog(); + + /** + * Determines if the method identified by its holder and name is a signature + * polymorphic method. + */ + static boolean isSignaturePolymorphic(JavaType holder, String name, MetaAccessProvider metaAccess) { + if (!holder.getName().equals("Ljava/lang/invoke/MethodHandle;")) { + return false; + } + ResolvedJavaType methodHandleType = metaAccess.lookupJavaType(MethodHandle.class); + Signature signature = metaAccess.parseMethodDescriptor("([Ljava/lang/Object;)Ljava/lang/Object;"); + ResolvedJavaMethod method = methodHandleType.findMethod(name, signature); + if (method == null) { + return false; + } + return method.isNative() && method.isVarArgs(); + } } diff -r 4c9d4fe1cbd8 -r 53b4acee50f1 jvmci/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/ResolvedJavaType.java --- a/jvmci/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/ResolvedJavaType.java Thu Jun 18 17:51:05 2015 +0200 +++ b/jvmci/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/ResolvedJavaType.java Thu Jun 18 17:44:47 2015 +0200 @@ -351,4 +351,13 @@ * where the JVM verifier would not give any guarantees other than {@link Object}. */ boolean isTrustedInterfaceType(); + + default ResolvedJavaMethod findMethod(String name, Signature signature) { + for (ResolvedJavaMethod method : getDeclaredMethods()) { + if (method.getName().equals(name) && method.getSignature().equals(signature)) { + return method; + } + } + return null; + } } diff -r 4c9d4fe1cbd8 -r 53b4acee50f1 jvmci/com.oracle.jvmci.runtime.test/src/com/oracle/jvmci/runtime/test/TestResolvedJavaMethod.java --- a/jvmci/com.oracle.jvmci.runtime.test/src/com/oracle/jvmci/runtime/test/TestResolvedJavaMethod.java Thu Jun 18 17:51:05 2015 +0200 +++ b/jvmci/com.oracle.jvmci.runtime.test/src/com/oracle/jvmci/runtime/test/TestResolvedJavaMethod.java Thu Jun 18 17:44:47 2015 +0200 @@ -25,6 +25,7 @@ import static org.junit.Assert.*; import java.lang.annotation.*; +import java.lang.invoke.*; import java.lang.reflect.*; import java.util.*; @@ -361,6 +362,20 @@ } } + @Test + public void isSignaturePolymorphicTest() { + ResolvedJavaType methodHandleType = metaAccess.lookupJavaType(MethodHandle.class); + assertTrue(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "invokeExact", metaAccess)); + assertTrue(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "invoke", metaAccess)); + assertTrue(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "invokeBasic", metaAccess)); + assertTrue(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "linkToVirtual", metaAccess)); + assertTrue(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "linkToStatic", metaAccess)); + assertTrue(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "linkToSpecial", metaAccess)); + assertTrue(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "linkToInterface", metaAccess)); + assertFalse(ResolvedJavaMethod.isSignaturePolymorphic(methodHandleType, "type", metaAccess)); + assertFalse(ResolvedJavaMethod.isSignaturePolymorphic(metaAccess.lookupJavaType(Object.class), "toString", metaAccess)); + } + private Method findTestMethod(Method apiMethod) { String testName = apiMethod.getName() + "Test"; for (Method m : getClass().getDeclaredMethods()) { @@ -400,6 +415,9 @@ public void testCoverage() { Set known = new HashSet<>(Arrays.asList(untestedApiMethods)); for (Method m : ResolvedJavaMethod.class.getDeclaredMethods()) { + if (Modifier.isStatic(m.getModifiers())) { + continue; + } if (findTestMethod(m) == null) { assertTrue("test missing for " + m, known.contains(m.getName())); } else { diff -r 4c9d4fe1cbd8 -r 53b4acee50f1 jvmci/com.oracle.jvmci.runtime.test/src/com/oracle/jvmci/runtime/test/TestResolvedJavaType.java --- a/jvmci/com.oracle.jvmci.runtime.test/src/com/oracle/jvmci/runtime/test/TestResolvedJavaType.java Thu Jun 18 17:51:05 2015 +0200 +++ b/jvmci/com.oracle.jvmci.runtime.test/src/com/oracle/jvmci/runtime/test/TestResolvedJavaType.java Thu Jun 18 17:44:47 2015 +0200 @@ -771,6 +771,10 @@ } } + static class SubD extends D { + + } + @Test public void getClassInitializerTest() { assertNotNull(metaAccess.lookupJavaType(A.class).getClassInitializer()); @@ -833,6 +837,29 @@ } } + @Test + public void findMethodTest() { + try { + ResolvedJavaMethod findFoo = metaAccess.lookupJavaType(D.class).findMethod("foo", metaAccess.parseMethodDescriptor("()V")); + ResolvedJavaMethod expectedFoo = metaAccess.lookupJavaMethod(D.class.getDeclaredMethod("foo")); + assertEquals(expectedFoo, findFoo); + + ResolvedJavaMethod wrongReturnTypeFoo = metaAccess.lookupJavaType(D.class).findMethod("foo", metaAccess.parseMethodDescriptor("()I")); + assertNull(wrongReturnTypeFoo); + + ResolvedJavaMethod wrongArgumentsFoo = metaAccess.lookupJavaType(D.class).findMethod("foo", metaAccess.parseMethodDescriptor("(I)V")); + assertNull(wrongArgumentsFoo); + + ResolvedJavaMethod wrongNameFoo = metaAccess.lookupJavaType(D.class).findMethod("bar", metaAccess.parseMethodDescriptor("()V")); + assertNull(wrongNameFoo); + + ResolvedJavaMethod wrongClassFoo = metaAccess.lookupJavaType(SubD.class).findMethod("foo", metaAccess.parseMethodDescriptor("()V")); + assertNull(wrongClassFoo); + } catch (NoSuchMethodException | SecurityException e) { + throw new RuntimeException(e); + } + } + private Method findTestMethod(Method apiMethod) { String testName = apiMethod.getName() + "Test"; for (Method m : getClass().getDeclaredMethods()) {