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 }