This commit is contained in:
Alejandro Murillo 2015-03-03 06:23:50 -08:00
commit 1b7e7fdf70
2 changed files with 39 additions and 9 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -282,6 +282,7 @@ public class ObjectReferenceImpl extends ValueImpl
* implemented interface * implemented interface
*/ */
ReferenceTypeImpl declType = (ReferenceTypeImpl)method.declaringType(); ReferenceTypeImpl declType = (ReferenceTypeImpl)method.declaringType();
if (!declType.isAssignableFrom(this)) { if (!declType.isAssignableFrom(this)) {
throw new IllegalArgumentException("Invalid method"); throw new IllegalArgumentException("Invalid method");
} }
@ -311,7 +312,7 @@ public class ObjectReferenceImpl extends ValueImpl
/* /*
* For nonvirtual invokes, method must have a body * For nonvirtual invokes, method must have a body
*/ */
if ((options & INVOKE_NONVIRTUAL) != 0) { if (isNonVirtual(options)) {
if (method.isAbstract()) { if (method.isAbstract()) {
throw new IllegalArgumentException("Abstract method"); throw new IllegalArgumentException("Abstract method");
} }
@ -323,7 +324,7 @@ public class ObjectReferenceImpl extends ValueImpl
* method argument types. * method argument types.
*/ */
ClassTypeImpl invokedClass; ClassTypeImpl invokedClass;
if ((options & INVOKE_NONVIRTUAL) != 0) { if (isNonVirtual(options)) {
// No overrides in non-virtual invokes // No overrides in non-virtual invokes
invokedClass = clazz; invokedClass = clazz;
} else { } else {
@ -348,7 +349,7 @@ public class ObjectReferenceImpl extends ValueImpl
/* /*
* Only default methods allowed for nonvirtual invokes * Only default methods allowed for nonvirtual invokes
*/ */
if (!method.isDefault()) { if (isNonVirtual(options) && !method.isDefault()) {
throw new IllegalArgumentException("Not a default method"); throw new IllegalArgumentException("Not a default method");
} }
} }
@ -383,6 +384,7 @@ public class ObjectReferenceImpl extends ValueImpl
IncompatibleThreadStateException, IncompatibleThreadStateException,
InvocationException, InvocationException,
ClassNotLoadedException { ClassNotLoadedException {
validateMirror(threadIntf); validateMirror(threadIntf);
validateMirror(methodIntf); validateMirror(methodIntf);
validateMirrorsOrNulls(origArguments); validateMirrorsOrNulls(origArguments);
@ -624,4 +626,8 @@ public class ObjectReferenceImpl extends ValueImpl
byte typeValueKey() { byte typeValueKey() {
return JDWP.Tag.OBJECT; return JDWP.Tag.OBJECT;
} }
private static boolean isNonVirtual(int options) {
return (options & INVOKE_NONVIRTUAL) != 0;
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -24,6 +24,7 @@
/** /**
* @test * @test
* @bug 8031195 * @bug 8031195
* @bug 8071657
* @summary JDI: Add support for static and default methods in interfaces * @summary JDI: Add support for static and default methods in interfaces
* *
* @run build TestScaffold VMConnection TargetListener TargetAdapter * @run build TestScaffold VMConnection TargetListener TargetAdapter
@ -38,6 +39,7 @@ public class InterfaceMethodsTest extends TestScaffold {
private static final int RESULT_A = 1; private static final int RESULT_A = 1;
private static final int RESULT_B = 1; private static final int RESULT_B = 1;
private static final int RESULT_TARGET = 1; private static final int RESULT_TARGET = 1;
static interface InterfaceA { static interface InterfaceA {
static int staticMethodA() { static int staticMethodA() {
System.out.println("-InterfaceA: static interface method A-"); System.out.println("-InterfaceA: static interface method A-");
@ -202,6 +204,9 @@ public class InterfaceMethodsTest extends TestScaffold {
// try to invoke static method B on the instance // try to invoke static method B on the instance
testInvokePos(ifaceClass, ref, "staticMethodB", "()I", vm().mirrorOf(RESULT_A)); testInvokePos(ifaceClass, ref, "staticMethodB", "()I", vm().mirrorOf(RESULT_A));
// try to invoke a virtual method
testInvokePos(ifaceClass, ref, "implementedMethod", "()I", vm().mirrorOf(RESULT_A), true);
} }
private void testInterfaceB(ObjectReference ref) { private void testInterfaceB(ObjectReference ref) {
@ -302,9 +307,14 @@ public class InterfaceMethodsTest extends TestScaffold {
private void testInvokePos(ReferenceType targetClass, ObjectReference ref, String methodName, private void testInvokePos(ReferenceType targetClass, ObjectReference ref, String methodName,
String methodSig, Value value) { String methodSig, Value value) {
testInvokePos(targetClass, ref, methodName, methodSig, value, false);
}
private void testInvokePos(ReferenceType targetClass, ObjectReference ref, String methodName,
String methodSig, Value value, boolean virtual) {
logInvocation(ref, methodName, methodSig, targetClass); logInvocation(ref, methodName, methodSig, targetClass);
try { try {
invoke(targetClass, ref, methodName, methodSig, value); invoke(targetClass, ref, methodName, methodSig, value, virtual);
System.err.println("--- PASSED"); System.err.println("--- PASSED");
} catch (Exception e) { } catch (Exception e) {
System.err.println("--- FAILED"); System.err.println("--- FAILED");
@ -314,9 +324,14 @@ public class InterfaceMethodsTest extends TestScaffold {
private void testInvokeNeg(ReferenceType targetClass, ObjectReference ref, String methodName, private void testInvokeNeg(ReferenceType targetClass, ObjectReference ref, String methodName,
String methodSig, Value value, String msg) { String methodSig, Value value, String msg) {
testInvokeNeg(targetClass, ref, methodName, methodSig, value, msg, false);
}
private void testInvokeNeg(ReferenceType targetClass, ObjectReference ref, String methodName,
String methodSig, Value value, String msg, boolean virtual) {
logInvocation(ref, methodName, methodSig, targetClass); logInvocation(ref, methodName, methodSig, targetClass);
try { try {
invoke(targetClass, ref, methodName, methodSig, value); invoke(targetClass, ref, methodName, methodSig, value, virtual);
System.err.println("--- FAILED"); System.err.println("--- FAILED");
failure("FAILED: " + msg); failure("FAILED: " + msg);
} catch (Exception e) { } catch (Exception e) {
@ -326,7 +341,7 @@ public class InterfaceMethodsTest extends TestScaffold {
} }
private void invoke(ReferenceType targetClass, ObjectReference ref, String methodName, private void invoke(ReferenceType targetClass, ObjectReference ref, String methodName,
String methodSig, Value value) String methodSig, Value value, boolean virtual)
throws Exception { throws Exception {
Method method = getMethod(targetClass, methodName, methodSig); Method method = getMethod(targetClass, methodName, methodSig);
if (method == null) { if (method == null) {
@ -334,10 +349,15 @@ public class InterfaceMethodsTest extends TestScaffold {
} }
println("Invoking " + (method.isAbstract() ? "abstract " : " ") + "method: " + method); println("Invoking " + (method.isAbstract() ? "abstract " : " ") + "method: " + method);
println(method.declaringType().toString());
Value returnValue = null; Value returnValue = null;
if (ref != null) { if (ref != null) {
returnValue = invokeInstance(ref, method); if (virtual) {
returnValue = invokeVirtual(ref, method);
} else {
returnValue = invokeInstance(ref, method);
}
} else { } else {
returnValue = invokeStatic(targetClass, method); returnValue = invokeStatic(targetClass, method);
} }
@ -362,6 +382,10 @@ public class InterfaceMethodsTest extends TestScaffold {
return ref.invokeMethod(mainThread, method, Collections.emptyList(), ObjectReference.INVOKE_NONVIRTUAL); return ref.invokeMethod(mainThread, method, Collections.emptyList(), ObjectReference.INVOKE_NONVIRTUAL);
} }
private Value invokeVirtual(ObjectReference ref, Method method) throws Exception {
return ref.invokeMethod(mainThread, method, Collections.emptyList(), 0);
}
private Value invokeStatic(ReferenceType refType, Method method) throws Exception { private Value invokeStatic(ReferenceType refType, Method method) throws Exception {
if (refType instanceof ClassType) { if (refType instanceof ClassType) {
return ((ClassType)refType).invokeMethod(mainThread, method, Collections.emptyList(), ObjectReference.INVOKE_NONVIRTUAL); return ((ClassType)refType).invokeMethod(mainThread, method, Collections.emptyList(), ObjectReference.INVOKE_NONVIRTUAL);