Path: blob/jdk8u272-b10-aarch32-20201026/nashorn/src/jdk/internal/dynalink/support/Lookup.java
48797 views
/*1* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425/*26* This file is available under and governed by the GNU General Public27* License version 2 only, as published by the Free Software Foundation.28* However, the following notice accompanied the original version of this29* file, and Oracle licenses the original version of this file under the BSD30* license:31*/32/*33Copyright 2009-2013 Attila Szegedi3435Licensed under both the Apache License, Version 2.0 (the "Apache License")36and the BSD License (the "BSD License"), with licensee being free to37choose either of the two at their discretion.3839You may not use this file except in compliance with either the Apache40License or the BSD License.4142If you choose to use this file in compliance with the Apache License, the43following notice applies to you:4445You may obtain a copy of the Apache License at4647http://www.apache.org/licenses/LICENSE-2.04849Unless required by applicable law or agreed to in writing, software50distributed under the License is distributed on an "AS IS" BASIS,51WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or52implied. See the License for the specific language governing53permissions and limitations under the License.5455If you choose to use this file in compliance with the BSD License, the56following notice applies to you:5758Redistribution and use in source and binary forms, with or without59modification, are permitted provided that the following conditions are60met:61* Redistributions of source code must retain the above copyright62notice, this list of conditions and the following disclaimer.63* Redistributions in binary form must reproduce the above copyright64notice, this list of conditions and the following disclaimer in the65documentation and/or other materials provided with the distribution.66* Neither the name of the copyright holder nor the names of67contributors may be used to endorse or promote products derived from68this software without specific prior written permission.6970THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS71IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED72TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A73PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER74BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR75CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF76SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR77BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,78WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR79OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF80ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.81*/8283package jdk.internal.dynalink.support;8485import java.lang.invoke.MethodHandle;86import java.lang.invoke.MethodHandles;87import java.lang.invoke.MethodType;88import java.lang.reflect.Constructor;89import java.lang.reflect.Field;90import java.lang.reflect.Method;9192/**93* A wrapper around MethodHandles.Lookup that masks checked exceptions in those cases when you're looking up methods94* within your own codebase (therefore it is an error if they are not present).95*96* @author Attila Szegedi97*/98public class Lookup {99private final MethodHandles.Lookup lookup;100101/**102* Creates a new instance, bound to an instance of {@link java.lang.invoke.MethodHandles.Lookup}.103*104* @param lookup the {@link java.lang.invoke.MethodHandles.Lookup} it delegates to.105*/106public Lookup(final MethodHandles.Lookup lookup) {107this.lookup = lookup;108}109110/**111* A canonical Lookup object that wraps {@link MethodHandles#publicLookup()}.112*/113public static final Lookup PUBLIC = new Lookup(MethodHandles.publicLookup());114115/**116* Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflect(Method)}, converting any encountered117* {@link IllegalAccessException} into an {@link IllegalAccessError}.118*119* @param m the method to unreflect120* @return the unreflected method handle.121*/122public MethodHandle unreflect(final Method m) {123return unreflect(lookup, m);124}125126/**127* Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflect(Method)}, converting any encountered128* {@link IllegalAccessException} into an {@link IllegalAccessError}.129*130* @param lookup the lookup used to unreflect131* @param m the method to unreflect132* @return the unreflected method handle.133*/134public static MethodHandle unreflect(final MethodHandles.Lookup lookup, final Method m) {135try {136return lookup.unreflect(m);137} catch(final IllegalAccessException e) {138final IllegalAccessError ee = new IllegalAccessError("Failed to unreflect method " + m);139ee.initCause(e);140throw ee;141}142}143144/**145* Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectGetter(Field)}, converting any encountered146* {@link IllegalAccessException} into an {@link IllegalAccessError}.147*148* @param f the field for which a getter is unreflected149* @return the unreflected field getter handle.150*/151public MethodHandle unreflectGetter(final Field f) {152try {153return lookup.unreflectGetter(f);154} catch(final IllegalAccessException e) {155final IllegalAccessError ee = new IllegalAccessError("Failed to unreflect getter for field " + f);156ee.initCause(e);157throw ee;158}159}160161/**162* Performs a {@link java.lang.invoke.MethodHandles.Lookup#findGetter(Class, String, Class)}, converting any163* encountered {@link IllegalAccessException} into an {@link IllegalAccessError} and {@link NoSuchFieldException}164* into a {@link NoSuchFieldError}.165*166* @param refc the class declaring the field167* @param name the name of the field168* @param type the type of the field169* @return the unreflected field getter handle.170* @throws IllegalAccessError if the field is inaccessible.171* @throws NoSuchFieldError if the field does not exist.172*/173public MethodHandle findGetter(final Class<?>refc, final String name, final Class<?> type) {174try {175return lookup.findGetter(refc, name, type);176} catch(final IllegalAccessException e) {177final IllegalAccessError ee = new IllegalAccessError("Failed to access getter for field " + refc.getName() +178"." + name + " of type " + type.getName());179ee.initCause(e);180throw ee;181} catch(final NoSuchFieldException e) {182final NoSuchFieldError ee = new NoSuchFieldError("Failed to find getter for field " + refc.getName() +183"." + name + " of type " + type.getName());184ee.initCause(e);185throw ee;186}187}188189/**190* Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectSetter(Field)}, converting any encountered191* {@link IllegalAccessException} into an {@link IllegalAccessError}.192*193* @param f the field for which a setter is unreflected194* @return the unreflected field setter handle.195*/196public MethodHandle unreflectSetter(final Field f) {197try {198return lookup.unreflectSetter(f);199} catch(final IllegalAccessException e) {200final IllegalAccessError ee = new IllegalAccessError("Failed to unreflect setter for field " + f);201ee.initCause(e);202throw ee;203}204}205206/**207* Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectConstructor(Constructor)}, converting any208* encountered {@link IllegalAccessException} into an {@link IllegalAccessError}.209*210* @param c the constructor to unreflect211* @return the unreflected constructor handle.212*/213public MethodHandle unreflectConstructor(final Constructor<?> c) {214return unreflectConstructor(lookup, c);215}216217/**218* Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectConstructor(Constructor)}, converting any219* encountered {@link IllegalAccessException} into an {@link IllegalAccessError}.220*221* @param lookup the lookup used to unreflect222* @param c the constructor to unreflect223* @return the unreflected constructor handle.224*/225public static MethodHandle unreflectConstructor(final MethodHandles.Lookup lookup, final Constructor<?> c) {226try {227return lookup.unreflectConstructor(c);228} catch(final IllegalAccessException e) {229final IllegalAccessError ee = new IllegalAccessError("Failed to unreflect constructor " + c);230ee.initCause(e);231throw ee;232}233}234235/**236* Performs a findSpecial on the underlying lookup. Converts any encountered {@link IllegalAccessException} into an237* {@link IllegalAccessError} and a {@link NoSuchMethodException} into a {@link NoSuchMethodError}.238*239* @param declaringClass class declaring the method240* @param name the name of the method241* @param type the type of the method242* @return a method handle for the method243* @throws IllegalAccessError if the method is inaccessible.244* @throws NoSuchMethodError if the method does not exist.245*/246public MethodHandle findSpecial(final Class<?> declaringClass, final String name, final MethodType type) {247try {248return lookup.findSpecial(declaringClass, name, type, declaringClass);249} catch(final IllegalAccessException e) {250final IllegalAccessError ee = new IllegalAccessError("Failed to access special method " + methodDescription(251declaringClass, name, type));252ee.initCause(e);253throw ee;254} catch(final NoSuchMethodException e) {255final NoSuchMethodError ee = new NoSuchMethodError("Failed to find special method " + methodDescription(256declaringClass, name, type));257ee.initCause(e);258throw ee;259}260}261262private static String methodDescription(final Class<?> declaringClass, final String name, final MethodType type) {263return declaringClass.getName() + "#" + name + type;264}265266/**267* Performs a findStatic on the underlying lookup. Converts any encountered {@link IllegalAccessException} into an268* {@link IllegalAccessError} and a {@link NoSuchMethodException} into a {@link NoSuchMethodError}.269*270* @param declaringClass class declaring the method271* @param name the name of the method272* @param type the type of the method273* @return a method handle for the method274* @throws IllegalAccessError if the method is inaccessible.275* @throws NoSuchMethodError if the method does not exist.276*/277public MethodHandle findStatic(final Class<?> declaringClass, final String name, final MethodType type) {278try {279return lookup.findStatic(declaringClass, name, type);280} catch(final IllegalAccessException e) {281final IllegalAccessError ee = new IllegalAccessError("Failed to access static method " + methodDescription(282declaringClass, name, type));283ee.initCause(e);284throw ee;285} catch(final NoSuchMethodException e) {286final NoSuchMethodError ee = new NoSuchMethodError("Failed to find static method " + methodDescription(287declaringClass, name, type));288ee.initCause(e);289throw ee;290}291}292293/**294* Performs a findVirtual on the underlying lookup. Converts any encountered {@link IllegalAccessException} into an295* {@link IllegalAccessError} and a {@link NoSuchMethodException} into a {@link NoSuchMethodError}.296*297* @param declaringClass class declaring the method298* @param name the name of the method299* @param type the type of the method300* @return a method handle for the method301* @throws IllegalAccessError if the method is inaccessible.302* @throws NoSuchMethodError if the method does not exist.303*/304public MethodHandle findVirtual(final Class<?> declaringClass, final String name, final MethodType type) {305try {306return lookup.findVirtual(declaringClass, name, type);307} catch(final IllegalAccessException e) {308final IllegalAccessError ee = new IllegalAccessError("Failed to access virtual method " + methodDescription(309declaringClass, name, type));310ee.initCause(e);311throw ee;312} catch(final NoSuchMethodException e) {313final NoSuchMethodError ee = new NoSuchMethodError("Failed to find virtual method " + methodDescription(314declaringClass, name, type));315ee.initCause(e);316throw ee;317}318}319320/**321* Given a lookup, finds using {@link #findSpecial(Class, String, MethodType)} a method on that lookup's class.322* Useful in classes' code for convenient linking to their own privates.323* @param lookup the lookup for the class324* @param name the name of the method325* @param rtype the return type of the method326* @param ptypes the parameter types of the method327* @return the method handle for the method328*/329public static MethodHandle findOwnSpecial(final MethodHandles.Lookup lookup, final String name, final Class<?> rtype, final Class<?>... ptypes) {330return new Lookup(lookup).findOwnSpecial(name, rtype, ptypes);331}332333334/**335* Finds using {@link #findSpecial(Class, String, MethodType)} a method on that lookup's class. Useful in classes'336* code for convenient linking to their own privates. It's easier to use than {@code findSpecial} in that you can337* just list the parameter types, and don't have to specify lookup class.338* @param name the name of the method339* @param rtype the return type of the method340* @param ptypes the parameter types of the method341* @return the method handle for the method342*/343public MethodHandle findOwnSpecial(final String name, final Class<?> rtype, final Class<?>... ptypes) {344return findSpecial(lookup.lookupClass(), name, MethodType.methodType(rtype, ptypes));345}346347/**348* Given a lookup, finds using {@link #findStatic(Class, String, MethodType)} a method on that lookup's class.349* Useful in classes' code for convenient linking to their own privates. It's easier to use than {@code findStatic}350* in that you can just list the parameter types, and don't have to specify lookup class.351* @param lookup the lookup for the class352* @param name the name of the method353* @param rtype the return type of the method354* @param ptypes the parameter types of the method355* @return the method handle for the method356*/357public static MethodHandle findOwnStatic(final MethodHandles.Lookup lookup, final String name, final Class<?> rtype, final Class<?>... ptypes) {358return new Lookup(lookup).findOwnStatic(name, rtype, ptypes);359}360361/**362* Finds using {@link #findStatic(Class, String, MethodType)} a method on that lookup's class. Useful in classes'363* code for convenient linking to their own privates. It's easier to use than {@code findStatic} in that you can364* just list the parameter types, and don't have to specify lookup class.365* @param name the name of the method366* @param rtype the return type of the method367* @param ptypes the parameter types of the method368* @return the method handle for the method369*/370public MethodHandle findOwnStatic(final String name, final Class<?> rtype, final Class<?>... ptypes) {371return findStatic(lookup.lookupClass(), name, MethodType.methodType(rtype, ptypes));372}373}374375376