changeset 655:d66149a0e03c

Object methods are not dispatched correctly by the ProxyHelper class.
author mcimadamore
date Wed, 25 Aug 2010 10:34:46 +0100
parents 1bb5b46bb326
children 5b1354e63ad9
files src/share/classes/com/sun/runtime/ProxyHelper.java test/tools/javac/lambda/MethodReference11.java test/tools/javac/lambda/MethodReference12.java
diffstat 3 files changed, 93 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/runtime/ProxyHelper.java	Mon Aug 23 13:48:15 2010 +0100
+++ b/src/share/classes/com/sun/runtime/ProxyHelper.java	Wed Aug 25 10:34:46 2010 +0100
@@ -36,25 +36,47 @@
  */
 public class ProxyHelper {
     @SuppressWarnings("unchecked")
-    public static <T> T makeProxy(final MethodHandle mh, Class<T> sam, final boolean passMH) {
+    public static <T> T makeProxy(final MethodHandle mh, final Class<T> sam, final boolean passMH) {
         return (T)Proxy.newProxyInstance(sam.getClassLoader(), new Class<?>[]{sam}, new InvocationHandler() {
             @Override
             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-                Object[] args1 = null;
-                if (passMH) {
-                    //prepend proxy to list arg list
-                    int len = args != null ?
-                        args.length :
-                        0;
-                    args1 = new Object[len + 1];
-                    if (len != 0)
-                        System.arraycopy(args, 0, args1, 1, len);
-                    args1[0] = proxy;
+                if (method.getDeclaringClass() == Object.class) {
+                    return dispatchObjectMethod(method, args);
                 }
                 else {
-                    args1 = args;
+                    Object[] args1 = null;
+                    if (passMH) {
+                        //prepend proxy to list arg list
+                        int len = args != null ?
+                            args.length :
+                            0;
+                        args1 = new Object[len + 1];
+                        if (len != 0)
+                            System.arraycopy(args, 0, args1, 1, len);
+                        args1[0] = proxy;
+                    }
+                    else {
+                        args1 = args;
+                    }
+                    return mh.invokeVarargs(args1);
                 }
-                return mh.invokeVarargs(args1);
+            }
+
+            Object dispatchObjectMethod(Method method, Object... args) throws Throwable {
+                switch(method.getName()) {
+                    case "clone": return clone();
+                    case "equals": return equals(args[0]);
+                    case "finalize": finalize(); return null;
+                    case "getClass": return getClass();
+                    case "hashCode": return hashCode();
+                    case "notify": notify(); return null;
+                    case "notifyAll": notifyAll(); return null;
+                    case "toString": return toString();
+                    case "wait0": wait(); return null;
+                    case "wait1": wait((Long)args[0]); return null;
+                    case "wait2": wait((Long)args[0], (Integer)args[1]); return null;
+                    default: throw new AssertionError("Bad Object method " + method);
+                }
             }
         });
     }
--- a/test/tools/javac/lambda/MethodReference11.java	Mon Aug 23 13:48:15 2010 +0100
+++ b/test/tools/javac/lambda/MethodReference11.java	Wed Aug 25 10:34:46 2010 +0100
@@ -25,19 +25,19 @@
  * @test
  * @summary check that static vs. non-static selection logic in method references works
  * @author  Maurizio Cimadamore
- * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles MethodReference06
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles MethodReference11
  */
 
 import java.util.*;
 
-class Test {
+public class MethodReference11 {
     public static void main(String[] args) {
         String[] strings = new String[] { "D", "C", "B", "A" };
         Arrays.sort( strings, String.CASE_INSENSITIVE_ORDER#compare( String, String ) );
         String last = "1";
-        for String s : strings) {
+        for (String s : strings) {
             if (String.CASE_INSENSITIVE_ORDER.compare(last, s) > 0) {
-                throws new AssertionError();
+                throw new AssertionError();
             }
         }
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MethodReference12.java	Wed Aug 25 10:34:46 2010 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary check that Object methods are dispatched accordingly
+ * @author  Maurizio Cimadamore
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles MethodReference12
+ */
+
+public class MethodReference12 {
+
+    interface SAM { void foo(int i); }
+
+    static void print(int i) {
+        System.out.println(i);
+    }
+
+    public static void main(String[] args) {
+        try {
+            test(MethodReference12#print(int));
+            test(#(i) { System.out.println(i); } );
+        }
+        catch (Throwable t) {
+            t.printStackTrace();
+            throw new AssertionError("An error occurred");
+        }
+    }
+
+    static void test(SAM s) throws Throwable {
+        s.equals(null);
+        s.toString();
+    }
+}