Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/invoke/util/BytecodeDescriptor.java
38918 views
/*1* Copyright (c) 2008, 2011, 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 instantiate3839public static List<Class<?>> parseMethod(String bytecodeSignature, ClassLoader loader) {40return parseMethod(bytecodeSignature, 0, bytecodeSignature.length(), loader);41}4243static List<Class<?>> parseMethod(String bytecodeSignature,44int start, int end, ClassLoader loader) {45if (loader == null)46loader = ClassLoader.getSystemClassLoader();47String str = bytecodeSignature;48int[] i = {start};49ArrayList<Class<?>> ptypes = new ArrayList<Class<?>>();50if (i[0] < end && str.charAt(i[0]) == '(') {51++i[0]; // skip '('52while (i[0] < end && str.charAt(i[0]) != ')') {53Class<?> pt = parseSig(str, i, end, loader);54if (pt == null || pt == void.class)55parseError(str, "bad argument type");56ptypes.add(pt);57}58++i[0]; // skip ')'59} else {60parseError(str, "not a method type");61}62Class<?> rtype = parseSig(str, i, end, loader);63if (rtype == null || i[0] != end)64parseError(str, "bad return type");65ptypes.add(rtype);66return ptypes;67}6869static private void parseError(String str, String msg) {70throw new IllegalArgumentException("bad signature: "+str+": "+msg);71}7273static private Class<?> parseSig(String str, int[] i, int end, ClassLoader loader) {74if (i[0] == end) return null;75char c = str.charAt(i[0]++);76if (c == 'L') {77int begc = i[0], endc = str.indexOf(';', begc);78if (endc < 0) return null;79i[0] = endc+1;80String name = str.substring(begc, endc).replace('/', '.');81try {82return loader.loadClass(name);83} catch (ClassNotFoundException ex) {84throw new TypeNotPresentException(name, ex);85}86} else if (c == '[') {87Class<?> t = parseSig(str, i, end, loader);88if (t != null)89t = java.lang.reflect.Array.newInstance(t, 0).getClass();90return t;91} else {92return Wrapper.forBasicType(c).primitiveType();93}94}9596public static String unparse(Class<?> type) {97StringBuilder sb = new StringBuilder();98unparseSig(type, sb);99return sb.toString();100}101102public static String unparse(MethodType type) {103return unparseMethod(type.returnType(), type.parameterList());104}105106public static String unparse(Object type) {107if (type instanceof Class<?>)108return unparse((Class<?>) type);109if (type instanceof MethodType)110return unparse((MethodType) type);111return (String) type;112}113114public static String unparseMethod(Class<?> rtype, List<Class<?>> ptypes) {115StringBuilder sb = new StringBuilder();116sb.append('(');117for (Class<?> pt : ptypes)118unparseSig(pt, sb);119sb.append(')');120unparseSig(rtype, sb);121return sb.toString();122}123124static private void unparseSig(Class<?> t, StringBuilder sb) {125char c = Wrapper.forBasicType(t).basicTypeChar();126if (c != 'L') {127sb.append(c);128} else {129boolean lsemi = (!t.isArray());130if (lsemi) sb.append('L');131sb.append(t.getName().replace('.', '/'));132if (lsemi) sb.append(';');133}134}135136}137138139