1 /*
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
26 package impl.java.dyn;
27
28 import java.dyn.*;
29
30 /**
31 * The flavor of method handle which emulates an invoke instruction
32 * on a predetermined argument. The JVM dispatches to the correct method
33 * when the handle is created, not when it is invoked.
34 * @author jrose
35 */
36 public class BoundMethodHandle extends MethodHandle {
37 //MethodHandle vmtarget; // next BMH or final DMH or methodOop
38 private final Object argument; // argument to insert
39 private final int vmargslot; // position at which it is inserted
40
41 // Constructors in this class *must* be package scoped or private.
42
43 /** Bind a direct MH to its receiver (or first ref. argument).
44 * The JVM will pre-dispatch the MH if it is not already static.
45 */
46 BoundMethodHandle(DirectMethodHandle mh, Object argument) {
47 super(Access.TOKEN, mh.type().deleteParameterType(0));
48 // check the type now, once for all:
49 this.argument = mh.type().parameterType(0).cast(argument);
50 this.vmargslot = this.type().parameterSlotCount();
51 if (MethodHandleNatives.JVM_SUPPORT) {
52 this.vmtarget = null; // maybe updated by JVM
53 MethodHandleNatives.init(this, mh, 0);
54 } else {
55 this.vmtarget = mh;
56 }
57 }
58
59 /** Insert an argument into an arbitrary method handle.
60 * If argnum is zero, inserts the first argument, etc.
61 */
62 BoundMethodHandle(MethodHandle mh, Object argument, int argnum) {
63 super(Access.TOKEN, mh.type().deleteParameterType(argnum));
64 this.argument = mh.type().parameterType(argnum).cast(argument);
65 this.vmargslot = this.type().parameterSlot(argnum-1);
66 System.out.println("init BMH type="+type()+" argnum="+argnum+" vmargslot="+vmargslot);
67 if (MethodHandleNatives.JVM_SUPPORT) {
68 this.vmtarget = null; // maybe updated by JVM
69 MethodHandleNatives.init(this, mh, argnum);
70 } else {
71 this.vmtarget = mh;
72 }
73 }
74
75 /** For subclasses only.
76 */
77 BoundMethodHandle(MethodType type, Object argument, int vmargslot) {
78 super(Access.TOKEN, type);
79 this.argument = argument;
80 this.vmargslot = vmargslot;
81 assert(this.getClass() != BoundMethodHandle.class);
82 }
83
84 @Override
85 public String toString() {
86 return "Bound[" + super.toString() + "]";
87 }
88 }