blob: eddd437a5d54a30179ac31267db271949346f827 [file] [log] [blame]
John R Rosefb6164c2009-05-05 22:40:09 -07001/*
2 * Copyright 2008-2009 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.dyn;
27
28import java.dyn.MethodHandle;
29import java.dyn.MethodHandles;
30import java.dyn.MethodType;
31
32
33/**
34 * Construction and caching of often-used invokers.
35 * @author jrose
36 */
37public class Invokers {
38 // exact type (sans leading taget MH) for the outgoing call
39 private final MethodType targetType;
40
41 // exact invoker for the outgoing call
42 private /*lazy*/ MethodHandle exactInvoker;
43
44 // generic (untyped) invoker for the outgoing call
45 private /*lazy*/ MethodHandle genericInvoker;
46
47 /** Compute and cache information common to all collecting adapters
48 * that implement members of the erasure-family of the given erased type.
49 */
50 public Invokers(Access token, MethodType targetType) {
51 Access.check(token);
52 this.targetType = targetType;
53 }
54
55 public static MethodType invokerType(MethodType targetType) {
56 return targetType.insertParameterType(0, MethodHandle.class);
57 }
58
59 public MethodHandle exactInvoker() {
60 MethodHandle invoker = exactInvoker;
61 if (invoker != null) return invoker;
62 invoker = MethodHandleImpl.IMPL_LOOKUP.findVirtual(MethodHandle.class, "invoke", targetType);
63 if (invoker == null) throw new InternalError("JVM cannot find invoker for "+targetType);
64 assert(invokerType(targetType) == invoker.type());
65 exactInvoker = invoker;
66 return invoker;
67 }
68
69 public MethodHandle genericInvoker() {
70 MethodHandle invoker1 = exactInvoker();
71 MethodHandle invoker = genericInvoker;
72 if (invoker != null) return invoker;
73 MethodType genericType = targetType.generic();
74 invoker = MethodHandles.convertArguments(invoker1, invokerType(genericType));
75 genericInvoker = invoker;
76 return invoker;
77 }
78
79 public MethodHandle varargsInvoker() {
80 throw new UnsupportedOperationException("NYI");
81 }
82
83 public String toString() {
84 return "Invokers"+targetType;
85 }
86}