169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/* 269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Javassist, a Java-bytecode translator toolkit. 369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved. 469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The contents of this file are subject to the Mozilla Public License Version 669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1.1 (the "License"); you may not use this file except in compliance with 769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the License. Alternatively, the contents of this file may be used under 869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the terms of the GNU Lesser General Public License Version 2.1 or later. 969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Software distributed under the License is distributed on an "AS IS" basis, 1169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 1269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * for the specific language governing rights and limitations under the 1369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * License. 1469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 1569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 1669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpackage javassist.bytecode.stackmap; 1769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 1869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.*; 1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic class TypedBlock extends BasicBlock { 2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int stackTop, numLocals; 2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public TypeData[] stackTypes, localsTypes; 2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // set by a Liveness object. 2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // inputs[i] is true if the i-th variable is used within this block. 2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public boolean[] inputs; 2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // working area for Liveness class. 2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public boolean updating; 3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int status; 3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public byte[] localsUsage; 3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Divides the method body into basic blocks. 3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The type information of the first block is initialized. 3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param optmize if it is true and the method does not include 3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * branches, this method returns null. 3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static TypedBlock[] makeBlocks(MethodInfo minfo, CodeAttribute ca, 4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal boolean optimize) 4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws BadBytecode 4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypedBlock[] blocks = (TypedBlock[])new Maker().make(minfo); 4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (optimize && blocks.length < 2) 4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (blocks.length == 0 || blocks[0].incoming == 0) 4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return null; 4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ConstPool pool = minfo.getConstPool(); 5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal boolean isStatic = (minfo.getAccessFlags() & AccessFlag.STATIC) != 0; 5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal blocks[0].initFirstBlock(ca.getMaxStack(), ca.getMaxLocals(), 5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal pool.getClassName(), minfo.getDescriptor(), 5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal isStatic, minfo.isConstructor()); 5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal new Liveness().compute(ca.iterator(), blocks, ca.getMaxLocals(), 5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal blocks[0].localsTypes); 5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return blocks; 5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected TypedBlock(int pos) { 6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal super(pos); 6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal localsTypes = null; 6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal inputs = null; 6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal updating = false; 6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected void toString2(StringBuffer sbuf) { 6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal super.toString2(sbuf); 6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append(",\n stack={"); 6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal printTypes(sbuf, stackTop, stackTypes); 7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append("}, locals={"); 7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal printTypes(sbuf, numLocals, localsTypes); 7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append("}, inputs={"); 7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (inputs != null) 7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < inputs.length; i++) 7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append(inputs[i] ? "1, " : "0, "); 7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append('}'); 7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private void printTypes(StringBuffer sbuf, int size, 8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypeData[] types) { 8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (types == null) 8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return; 8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < size; i++) { 8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (i > 0) 8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append(", "); 8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypeData td = types[i]; 9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append(td == null ? "<>" : td.toString()); 9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public boolean alreadySet() { 9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return localsTypes != null; 9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void setStackMap(int st, TypeData[] stack, int nl, TypeData[] locals) 9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws BadBytecode 10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stackTop = st; 10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stackTypes = stack; 10369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal numLocals = nl; 10469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal localsTypes = locals; 10569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 10669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 10769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /* 10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Computes the correct value of numLocals. 10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void resetNumLocals() { 11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (localsTypes != null) { 11269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int nl = localsTypes.length; 11369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while (nl > 0 && localsTypes[nl - 1] == TypeTag.TOP) { 11469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (nl > 1) { 11569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypeData td = localsTypes[nl - 2]; 11669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (td == TypeTag.LONG || td == TypeTag.DOUBLE) 11769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 11869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 11969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal --nl; 12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal numLocals = nl; 12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static class Maker extends BasicBlock.Maker { 12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected BasicBlock makeBlock(int pos) { 12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return new TypedBlock(pos); 13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected BasicBlock[] makeArray(int size) { 13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return new TypedBlock[size]; 13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Initializes the first block by the given method descriptor. 13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param block the first basic block that this method initializes. 14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param className a dot-separated fully qualified class name. 14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * For example, <code>javassist.bytecode.stackmap.BasicBlock</code>. 14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param methodDesc method descriptor. 14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param isStatic true if the method is a static method. 14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param isConstructor true if the method is a constructor. 14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal void initFirstBlock(int maxStack, int maxLocals, String className, 14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String methodDesc, boolean isStatic, boolean isConstructor) 14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws BadBytecode 15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (methodDesc.charAt(0) != '(') 15269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new BadBytecode("no method descriptor: " + methodDesc); 15369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 15469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stackTop = 0; 15569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stackTypes = new TypeData[maxStack]; 15669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypeData[] locals = new TypeData[maxLocals]; 15769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (isConstructor) 15869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal locals[0] = new TypeData.UninitThis(className); 15969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (!isStatic) 16069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal locals[0] = new TypeData.ClassName(className); 16169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 16269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int n = isStatic ? -1 : 0; 16369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int i = 1; 16469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal try { 16569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while ((i = descToTag(methodDesc, i, ++n, locals)) > 0) 16669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (locals[n].is2WordType()) 16769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal locals[++n] = TypeTag.TOP; 16869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 16969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catch (StringIndexOutOfBoundsException e) { 17069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new BadBytecode("bad method descriptor: " 17169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal + methodDesc); 17269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 17369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 17469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal numLocals = n; 17569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal localsTypes = locals; 17669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 17769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 17869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private static int descToTag(String desc, int i, 17969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int n, TypeData[] types) 18069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws BadBytecode 18169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 18269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int i0 = i; 18369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int arrayDim = 0; 18469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal char c = desc.charAt(i); 18569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (c == ')') 18669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return 0; 18769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 18869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while (c == '[') { 18969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ++arrayDim; 19069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal c = desc.charAt(++i); 19169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 19269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 19369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (c == 'L') { 19469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int i2 = desc.indexOf(';', ++i); 19569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (arrayDim > 0) 19669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal types[n] = new TypeData.ClassName(desc.substring(i0, ++i2)); 19769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 19869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal types[n] = new TypeData.ClassName(desc.substring(i0 + 1, ++i2 - 1) 19969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal .replace('/', '.')); 20069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return i2; 20169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 20269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (arrayDim > 0) { 20369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal types[n] = new TypeData.ClassName(desc.substring(i0, ++i)); 20469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return i; 20569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 20669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 20769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypeData t = toPrimitiveTag(c); 20869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (t == null) 20969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new BadBytecode("bad method descriptor: " + desc); 21069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 21169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal types[n] = t; 21269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return i + 1; 21369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 21469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 21569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 21669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private static TypeData toPrimitiveTag(char c) { 21769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal switch (c) { 21869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case 'Z' : 21969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case 'C' : 22069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case 'B' : 22169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case 'S' : 22269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case 'I' : 22369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return TypeTag.INTEGER; 22469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case 'J' : 22569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return TypeTag.LONG; 22669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case 'F' : 22769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return TypeTag.FLOAT; 22869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case 'D' : 22969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return TypeTag.DOUBLE; 23069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case 'V' : 23169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal default : 23269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return null; 23369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 23469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 23569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 23669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static String getRetType(String desc) { 23769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int i = desc.indexOf(')'); 23869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (i < 0) 23969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return "java.lang.Object"; 24069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 24169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal char c = desc.charAt(i + 1); 24269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (c == '[') 24369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return desc.substring(i + 1); 24469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (c == 'L') 24569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return desc.substring(i + 2, desc.length() - 1).replace('/', '.'); 24669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 24769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return "java.lang.Object"; 24869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 24969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal} 250