jdk/src/share/classes/sun/dyn/AdapterMethodHandle.java
changeset 7554 8a0ad9757002
parent 5725 16c1792b2ee6
child 7555 a279ebc3b25c
--- a/jdk/src/share/classes/sun/dyn/AdapterMethodHandle.java	Tue Sep 14 01:42:03 2010 -0700
+++ b/jdk/src/share/classes/sun/dyn/AdapterMethodHandle.java	Sat Oct 30 21:02:30 2010 -0700
@@ -478,6 +478,39 @@
         return new AdapterMethodHandle(target, newType, makeConv(raw ? OP_RETYPE_RAW : OP_RETYPE_ONLY));
     }
 
+    static MethodHandle makeTypeHandler(Access token,
+                MethodHandle target, MethodHandle typeHandler) {
+        Access.check(token);
+        return new WithTypeHandler(target, typeHandler);
+    }
+
+    static class WithTypeHandler extends AdapterMethodHandle {
+        final MethodHandle target, typeHandler;
+        WithTypeHandler(MethodHandle target, MethodHandle typeHandler) {
+            super(target, target.type(), OP_RETYPE_ONLY);
+            this.target = target;
+            this.typeHandler = typeHandler.asType(TYPE_HANDLER_TYPE);
+        }
+
+        public MethodHandle asType(MethodType newType) {
+            if (this.type() == newType)
+                return this;
+            try {
+                MethodHandle retyped = (MethodHandle) typeHandler.<MethodHandle>invokeExact(target, newType);
+                // Contract:  Must return the desired type, or throw WMT
+                if (retyped.type() != newType)
+                    throw new WrongMethodTypeException(retyped.toString());
+                return retyped;
+            } catch (Throwable ex) {
+                if (ex instanceof Error)  throw (Error)ex;
+                if (ex instanceof RuntimeException)  throw (RuntimeException)ex;
+                throw new RuntimeException(ex);
+            }
+        }
+        private static final MethodType TYPE_HANDLER_TYPE
+            = MethodType.methodType(MethodHandle.class, MethodHandle.class, MethodType.class);
+    }
+
     /** Can a checkcast adapter validly convert the target to newType?
      *  The JVM supports all kind of reference casts, even silly ones.
      */