Mercurial > hg > openjdk > aarch64-port > jdk
changeset 10680:aa2770d3ff19
8071657: JDI ObjectReferenceImpl.invokeMethod() validation fails for virtual invocations of method with declaring type being an interface
Reviewed-by: sspitsyn, sla
author | jbachorik |
---|---|
date | Wed, 18 Feb 2015 17:50:41 +0100 |
parents | 650385b989cf |
children | a810f93ace76 |
files | src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java test/com/sun/jdi/InterfaceMethodsTest.java |
diffstat | 2 files changed, 37 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java Wed Mar 11 18:12:25 2015 +0900 +++ b/src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java Wed Feb 18 17:50:41 2015 +0100 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -311,7 +311,7 @@ /* * For nonvirtual invokes, method must have a body */ - if ((options & INVOKE_NONVIRTUAL) != 0) { + if (isNonVirtual(options)) { if (method.isAbstract()) { throw new IllegalArgumentException("Abstract method"); } @@ -323,7 +323,7 @@ * method argument types. */ ClassTypeImpl invokedClass; - if ((options & INVOKE_NONVIRTUAL) != 0) { + if (isNonVirtual(options)) { // No overrides in non-virtual invokes invokedClass = clazz; } else { @@ -348,7 +348,7 @@ /* * Only default methods allowed for nonvirtual invokes */ - if (!method.isDefault()) { + if (isNonVirtual(options) && !method.isDefault()) { throw new IllegalArgumentException("Not a default method"); } } @@ -624,4 +624,8 @@ byte typeValueKey() { return JDWP.Tag.OBJECT; } + + private static boolean isNonVirtual(int options) { + return (options & INVOKE_NONVIRTUAL) != 0; + } }
--- a/test/com/sun/jdi/InterfaceMethodsTest.java Wed Mar 11 18:12:25 2015 +0900 +++ b/test/com/sun/jdi/InterfaceMethodsTest.java Wed Feb 18 17:50:41 2015 +0100 @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -24,6 +24,7 @@ /** * @test * @bug 8031195 + * @bug 8071657 * @summary JDI: Add support for static and default methods in interfaces * * @run build TestScaffold VMConnection TargetListener TargetAdapter @@ -38,6 +39,7 @@ private static final int RESULT_A = 1; private static final int RESULT_B = 1; private static final int RESULT_TARGET = 1; + static interface InterfaceA { static int staticMethodA() { System.out.println("-InterfaceA: static interface method A-"); @@ -202,6 +204,9 @@ // try to invoke static method B on the instance 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) { @@ -302,9 +307,14 @@ private void testInvokePos(ReferenceType targetClass, ObjectReference ref, String methodName, 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); try { - invoke(targetClass, ref, methodName, methodSig, value); + invoke(targetClass, ref, methodName, methodSig, value, virtual); System.err.println("--- PASSED"); } catch (Exception e) { System.err.println("--- FAILED"); @@ -314,9 +324,14 @@ private void testInvokeNeg(ReferenceType targetClass, ObjectReference ref, String methodName, 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); try { - invoke(targetClass, ref, methodName, methodSig, value); + invoke(targetClass, ref, methodName, methodSig, value, virtual); System.err.println("--- FAILED"); failure("FAILED: " + msg); } catch (Exception e) { @@ -326,7 +341,7 @@ } private void invoke(ReferenceType targetClass, ObjectReference ref, String methodName, - String methodSig, Value value) + String methodSig, Value value, boolean virtual) throws Exception { Method method = getMethod(targetClass, methodName, methodSig); if (method == null) { @@ -334,10 +349,15 @@ } println("Invoking " + (method.isAbstract() ? "abstract " : " ") + "method: " + method); + println(method.declaringType().toString()); Value returnValue = null; if (ref != null) { - returnValue = invokeInstance(ref, method); + if (virtual) { + returnValue = invokeVirtual(ref, method); + } else { + returnValue = invokeInstance(ref, method); + } } else { returnValue = invokeStatic(targetClass, method); } @@ -362,6 +382,10 @@ 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 { if (refType instanceof ClassType) { return ((ClassType)refType).invokeMethod(mainThread, method, Collections.emptyList(), ObjectReference.INVOKE_NONVIRTUAL);