Path: blob/master/src/java.base/share/classes/sun/invoke/util/BytecodeDescriptor.java
41159 views
/*1* Copyright (c) 2008, 2015, 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*/2425package sun.invoke.util;2627import java.lang.invoke.MethodType;28import java.util.ArrayList;29import java.util.List;3031/**32* Utility routines for dealing with bytecode-level signatures.33* @author jrose34*/35public class BytecodeDescriptor {3637private BytecodeDescriptor() { } // cannot instantiate3839/**40* @param loader the class loader in which to look up the types (null means41* bootstrap class loader)42*/43public static List<Class<?>> parseMethod(String bytecodeSignature, ClassLoader loader) {44return parseMethod(bytecodeSignature, 0, bytecodeSignature.length(), loader);45}4647/**48* @param loader the class loader in which to look up the types (null means49* bootstrap class loader)50*/51static List<Class<?>> parseMethod(String bytecodeSignature,52int start, int end, ClassLoader loader) {53String str = bytecodeSignature;54int[] i = {start};55ArrayList<Class<?>> ptypes = new ArrayList<Class<?>>();56if (i[0] < end && str.charAt(i[0]) == '(') {57++i[0]; // skip '('58while (i[0] < end && str.charAt(i[0]) != ')') {59Class<?> pt = parseSig(str, i, end, loader);60if (pt == null || pt == void.class)61parseError(str, "bad argument type");62ptypes.add(pt);63}64++i[0]; // skip ')'65} else {66parseError(str, "not a method type");67}68Class<?> rtype = parseSig(str, i, end, loader);69if (rtype == null || i[0] != end)70parseError(str, "bad return type");71ptypes.add(rtype);72return ptypes;73}7475private static void parseError(String str, String msg) {76throw new IllegalArgumentException("bad signature: "+str+": "+msg);77}7879/**80* @param loader the class loader in which to look up the types (null means81* bootstrap class loader)82*/83private static Class<?> parseSig(String str, int[] i, int end, ClassLoader loader) {84if (i[0] == end) return null;85char c = str.charAt(i[0]++);86if (c == 'L') {87int begc = i[0], endc = str.indexOf(';', begc);88if (endc < 0) return null;89i[0] = endc+1;90String name = str.substring(begc, endc).replace('/', '.');91try {92return Class.forName(name, false, loader);93} catch (ClassNotFoundException ex) {94throw new TypeNotPresentException(name, ex);95}96} else if (c == '[') {97Class<?> t = parseSig(str, i, end, loader);98if (t != null)99t = java.lang.reflect.Array.newInstance(t, 0).getClass();100return t;101} else {102return Wrapper.forBasicType(c).primitiveType();103}104}105106public static String unparse(Class<?> type) {107if (type == Object.class) {108return "Ljava/lang/Object;";109} else if (type == int.class) {110return "I";111}112return type.descriptorString();113}114115public static String unparse(MethodType type) {116return unparseMethod(type.returnType(), type.parameterArray());117}118119public static String unparse(Object type) {120if (type instanceof Class<?>)121return unparse((Class<?>) type);122if (type instanceof MethodType)123return unparse((MethodType) type);124return (String) type;125}126127public static String unparseMethod(Class<?> rtype, List<Class<?>> ptypes) {128StringBuilder sb = new StringBuilder();129sb.append('(');130for (Class<?> pt : ptypes)131unparseSig(pt, sb);132sb.append(')');133unparseSig(rtype, sb);134return sb.toString();135}136137public static String unparseMethod(Class<?> rtype, Class<?>[] ptypes) {138StringBuilder sb = new StringBuilder();139sb.append('(');140for (Class<?> pt : ptypes)141unparseSig(pt, sb);142sb.append(')');143unparseSig(rtype, sb);144return sb.toString();145}146147private static void unparseSig(Class<?> t, StringBuilder sb) {148char c = Wrapper.forBasicType(t).basicTypeChar();149if (c != 'L') {150sb.append(c);151} else if (t == Object.class) {152sb.append("Ljava/lang/Object;");153} else {154sb.append(t.descriptorString());155}156}157}158159160