📄 classreader.java
字号:
void indexPool() { poolIdx = new int[nextChar()]; poolObj = new Object[poolIdx.length]; int i = 1; while (i < poolIdx.length) { poolIdx[i++] = bp; byte tag = buf[bp++]; switch (tag) { case CONSTANT_Utf8: case CONSTANT_Unicode: { int len = nextChar(); bp = bp + len; break; } case CONSTANT_Class: case CONSTANT_String: bp = bp + 2; break; case CONSTANT_Fieldref: case CONSTANT_Methodref: case CONSTANT_InterfaceMethodref: case CONSTANT_NameandType: case CONSTANT_Integer: case CONSTANT_Float: bp = bp + 4; break; case CONSTANT_Long: case CONSTANT_Double: bp = bp + 8; i++; break; default: throw badClassFile("bad.const.pool.tag.at", Byte.toString(tag), Integer.toString(bp -1)); } } } /** Read constant pool entry at start address i, use pool as a cache. */ Object readPool(int i) { Object result = poolObj[i]; if (result != null) return result; int index = poolIdx[i]; if (index == 0) return null; byte tag = buf[index]; switch (tag) { case CONSTANT_Utf8: poolObj[i] = names.fromUtf(buf, index + 3, getChar(index + 1)); break; case CONSTANT_Unicode: throw badClassFile("unicode.str.not.supported"); case CONSTANT_Class: poolObj[i] = readClassOrType(getChar(index + 1)); break; case CONSTANT_String: // FIXME: (footprint) do not use toString here poolObj[i] = readName(getChar(index + 1)).toString(); break; case CONSTANT_Fieldref: { ClassSymbol owner = readClassSymbol(getChar(index + 1)); NameAndType nt = (NameAndType)readPool(getChar(index + 3)); poolObj[i] = new VarSymbol(0, nt.name, nt.type, owner); break; } case CONSTANT_Methodref: case CONSTANT_InterfaceMethodref: { ClassSymbol owner = readClassSymbol(getChar(index + 1)); NameAndType nt = (NameAndType)readPool(getChar(index + 3)); poolObj[i] = new MethodSymbol(0, nt.name, nt.type, owner); break; } case CONSTANT_NameandType: poolObj[i] = new NameAndType( readName(getChar(index + 1)), readType(getChar(index + 3))); break; case CONSTANT_Integer: poolObj[i] = getInt(index + 1); break; case CONSTANT_Float: poolObj[i] = new Float(getFloat(index + 1)); break; case CONSTANT_Long: poolObj[i] = new Long(getLong(index + 1)); break; case CONSTANT_Double: poolObj[i] = new Double(getDouble(index + 1)); break; default: throw badClassFile("bad.const.pool.tag", Byte.toString(tag)); } return poolObj[i]; } /** Read signature and convert to type. */ Type readType(int i) { int index = poolIdx[i]; return sigToType(buf, index + 3, getChar(index + 1)); } /** If name is an array type or class signature, return the * corresponding type; otherwise return a ClassSymbol with given name. */ Object readClassOrType(int i) { int index = poolIdx[i]; int len = getChar(index + 1); int start = index + 3; assert buf[start] == '[' || buf[start + len - 1] != ';'; // by the above assertion, the following test can be // simplified to (buf[start] == '[') return (buf[start] == '[' || buf[start + len - 1] == ';') ? (Object)sigToType(buf, start, len) : (Object)enterClass(names.fromUtf(internalize(buf, start, len))); } /** Read signature and convert to type parameters. */ List<Type> readTypeParams(int i) { int index = poolIdx[i]; return sigToTypeParams(buf, index + 3, getChar(index + 1)); } /** Read class entry. */ ClassSymbol readClassSymbol(int i) { return (ClassSymbol) (readPool(i)); } /** Read name. */ Name readName(int i) { return (Name) (readPool(i)); }/************************************************************************ * Reading Types ***********************************************************************/ /** The unread portion of the currently read type is * signature[sigp..siglimit-1]. */ byte[] signature; int sigp; int siglimit; boolean sigEnterPhase = false; /** Convert signature to type, where signature is a name. */ Type sigToType(Name sig) { return sig == null ? null : sigToType(sig.table.names, sig.index, sig.len); } /** Convert signature to type, where signature is a byte array segment. */ Type sigToType(byte[] sig, int offset, int len) { signature = sig; sigp = offset; siglimit = offset + len; return sigToType(); } /** Convert signature to type, where signature is implicit. */ Type sigToType() { switch ((char) signature[sigp]) { case 'T': sigp++; int start = sigp; while (signature[sigp] != ';') sigp++; sigp++; return sigEnterPhase ? Type.noType : findTypeVar(names.fromUtf(signature, start, sigp - 1 - start)); case '+': { sigp++; Type t = sigToType(); return new WildcardType(t, BoundKind.EXTENDS, syms.boundClass); } case '*': sigp++; return new WildcardType(syms.objectType, BoundKind.UNBOUND, syms.boundClass); case '-': { sigp++; Type t = sigToType(); return new WildcardType(t, BoundKind.SUPER, syms.boundClass); } case 'B': sigp++; return syms.byteType; case 'C': sigp++; return syms.charType; case 'D': sigp++; return syms.doubleType; case 'F': sigp++; return syms.floatType; case 'I': sigp++; return syms.intType; case 'J': sigp++; return syms.longType; case 'L': { // int oldsigp = sigp; Type t = classSigToType(); if (sigp < siglimit && signature[sigp] == '.') throw badClassFile("deprecated inner class signature syntax " + "(please recompile from source)"); /* System.err.println(" decoded " + new String(signature, oldsigp, sigp-oldsigp) + " => " + t + " outer " + t.outer()); */ return t; } case 'S': sigp++; return syms.shortType; case 'V': sigp++; return syms.voidType; case 'Z': sigp++; return syms.booleanType; case '[': sigp++; return new ArrayType(sigToType(), syms.arrayClass); case '(': sigp++; List<Type> argtypes = sigToTypes(')'); Type restype = sigToType(); List<Type> thrown = List.nil(); while (signature[sigp] == '^') { sigp++; thrown = thrown.prepend(sigToType()); } return new MethodType(argtypes, restype, thrown.reverse(), syms.methodClass); case '<': typevars = typevars.dup(currentOwner); Type poly = new ForAll(sigToTypeParams(), sigToType()); typevars = typevars.leave(); return poly; default: throw badClassFile("bad.signature", Convert.utf2string(signature, sigp, 10)); } } byte[] signatureBuffer = new byte[0]; int sbp = 0; /** Convert class signature to type, where signature is implicit. */ Type classSigToType() { if (signature[sigp] != 'L') throw badClassFile("bad.class.signature", Convert.utf2string(signature, sigp, 10)); sigp++; Type outer = Type.noType; int startSbp = sbp; while (true) { final byte c = signature[sigp++]; switch (c) { case ';': { // end ClassSymbol t = enterClass(names.fromUtf(signatureBuffer, startSbp, sbp - startSbp)); if (outer == Type.noType) outer = t.erasure(types); else outer = new ClassType(outer, List.<Type>nil(), t); sbp = startSbp; return outer; } case '<': // generic arguments ClassSymbol t = enterClass(names.fromUtf(signatureBuffer, startSbp, sbp - startSbp)); outer = new ClassType(outer, sigToTypes('>'), t) { boolean completed = false; public Type getEnclosingType() { if (!completed) { completed = true; tsym.complete(); Type enclosingType = tsym.type.getEnclosingType(); if (enclosingType != Type.noType) { List<Type> typeArgs = super.getEnclosingType().allparams(); List<Type> typeParams = enclosingType.allparams(); if (typeParams.length() != typeArgs.length()) { // no "rare" types super.setEnclosingType(types.erasure(enclosingType)); } else { super.setEnclosingType(types.subst(enclosingType, typeParams, typeArgs)); } } else { super.setEnclosingType(Type.noType); } } return super.getEnclosingType(); } public void setEnclosingType(Type outer) { throw new UnsupportedOperationException(); } }; switch (signature[sigp++]) { case ';': if (sigp < signature.length && signature[sigp] == '.') { // support old-style GJC signatures // The signature produced was // Lfoo/Outer<Lfoo/X;>;.Lfoo/Outer$Inner<Lfoo/Y;>; // rather than say // Lfoo/Outer<Lfoo/X;>.Inner<Lfoo/Y;>; // so we skip past ".Lfoo/Outer$" sigp += (sbp - startSbp) + // "foo/Outer" 3; // ".L" and "$" signatureBuffer[sbp++] = (byte)'$'; break; } else { sbp = startSbp; return outer; } case '.': signatureBuffer[sbp++] = (byte)'$'; break; default: throw new AssertionError(signature[sigp-1]); } continue; case '.': signatureBuffer[sbp++] = (byte)'$'; continue; case '/': signatureBuffer[sbp++] = (byte)'.'; continue; default:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -