classdecoder.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 531 行 · 第 1/2 页
JAVA
531 行
wide = true;
break;
default:
wide = false;
}
final boolean isstatic = (modifiers & Modifier.ACC_STATIC) != 0;
final int staticsIdx;
final VmField fs;
if (isstatic) {
// If static allocate space for it.
switch (signature.charAt(0)) {
case 'B':
staticsIdx = statics.allocIntField();
break;
case 'C':
staticsIdx = statics.allocIntField();
break;
case 'D':
staticsIdx = statics.allocLongField();
break;
case 'F':
staticsIdx = statics.allocIntField();
break;
case 'I':
staticsIdx = statics.allocIntField();
break;
case 'J':
staticsIdx = statics.allocLongField();
break;
case 'S':
staticsIdx = statics.allocIntField();
break;
case 'Z':
staticsIdx = statics.allocIntField();
break;
default:
{
if (Modifier.isAddressType(signature)) {
staticsIdx = statics.allocAddressField();
} else {
staticsIdx = statics.allocObjectField();
//System.out.println(NumberUtils.hex(staticsIdx)
// + "\t" + cls.getName() + "." + name);
}
}
break;
}
fs = new VmStaticField(name, signature, modifiers,
staticsIdx, cls, slotSize);
} else {
staticsIdx = -1;
final int fieldOffset;
// Set the offset (keep in mind that this will be fixed
// by ClassResolver with respect to the objectsize of the
// super-class.
fieldOffset = objectSize;
// Increment the objectSize
if (wide)
objectSize += 8;
else
objectSize += 4;
fs = new VmInstanceField(name, signature, modifiers,
fieldOffset, cls, slotSize);
}
ftable[ i] = fs;
// Read field attributes
final int acount = reader.readu2();
for (int a = 0; a < acount; a++) {
final String attrName = cp.getUTF8(reader.readu2());
final int length = reader.readu4();
if (isstatic
&& VmArray.equals(ConstantValueAttrName, attrName)) {
final int idx = reader.readu2();
switch (signature.charAt(0)) {
case 'B':
statics.setInt(staticsIdx, cp.getInt(idx));
break;
case 'C':
statics.setInt(staticsIdx, cp.getInt(idx));
break;
case 'D':
statics.setLong(staticsIdx, cp.getLong(idx));
break;
case 'F':
statics.setInt(staticsIdx, cp.getInt(idx));
break;
case 'I':
statics.setInt(staticsIdx, cp.getInt(idx));
break;
case 'J':
statics.setLong(staticsIdx, cp.getLong(idx));
break;
case 'S':
statics.setInt(staticsIdx, cp.getInt(idx));
break;
case 'Z':
statics.setInt(staticsIdx, cp.getInt(idx));
break;
default:
//throw new IllegalArgumentException("signature "
// + signature);
statics.setObject(staticsIdx, cp.getString(idx));
break;
}
} else {
reader.skip(length);
}
}
}
cls.setFieldTable(ftable);
if (objectSize > 0) {
((VmNormalClass) cls).setObjectSize(objectSize);
}
}
}
/**
* Read the method table
*
* @param reader
* @param rejectNatives
* @param cls
* @param cp
*/
private static void readMethods(ClassReader reader, boolean rejectNatives,
VmType cls, VmCP cp, VmStatics statics) {
final int mcount = reader.readu2();
if (mcount > 0) {
final VmMethod[] mtable = new VmMethod[ mcount];
for (int i = 0; i < mcount; i++) {
final int modifiers = reader.readu2();
final String name = cp.getUTF8(reader.readu2());
final String signature = cp.getUTF8(reader.readu2());
final boolean isStatic = ((modifiers & Modifier.ACC_STATIC) != 0);
final VmMethod mts;
final boolean isSpecial = name.equals("<init>");
//final int staticsIdx = statics.allocMethod();
if (isStatic || isSpecial) {
if (isSpecial) {
mts = new VmSpecialMethod(name, signature, modifiers,
cls);
} else {
mts = new VmStaticMethod(name, signature, modifiers,
cls);
}
} else {
mts = new VmInstanceMethod(name, signature, modifiers, cls);
}
//statics.setMethod(staticsIdx, mts);
mtable[ i] = mts;
// Read methods attributes
final int acount = reader.readu2();
for (int a = 0; a < acount; a++) {
String attrName = cp.getUTF8(reader.readu2());
int length = reader.readu4();
if (VmArray.equals(CodeAttrName, attrName)) {
mts.setBytecode(readCode(reader, cls, cp, mts));
} else if (VmArray.equals(ExceptionsAttrName, attrName)) {
mts.setExceptions(readExceptions(reader, cls, cp));
} else {
reader.skip(length);
}
}
if ((modifiers & Modifier.ACC_NATIVE) != 0) {
if (rejectNatives) { throw new ClassFormatError(
"Native method " + mts); }
}
}
cls.setMethodTable(mtable);
}
}
/**
* Decode the data of a code-attribute
*
* @param reader
* @param cls
* @param cp
* @param method
* @return The read code
*/
private static final VmByteCode readCode(ClassReader reader, VmType cls,
VmCP cp, VmMethod method) {
final int maxStack = reader.readu2();
final int noLocals = reader.readu2();
final int codelength = reader.readu4();
final byte[] code = reader.readBytes(codelength);
// Read the exception Table
final int ecount = reader.readu2();
final VmInterpretedExceptionHandler[] etable = new VmInterpretedExceptionHandler[ ecount];
for (int i = 0; i < ecount; i++) {
final int startPC = reader.readu2();
final int endPC = reader.readu2();
final int handlerPC = reader.readu2();
final int catchType = reader.readu2();
etable[ i] = new VmInterpretedExceptionHandler(cp, startPC, endPC,
handlerPC, catchType);
}
// Read the attributes
VmLineNumberMap lnTable = null;
final int acount = reader.readu2();
for (int i = 0; i < acount; i++) {
final String attrName = cp.getUTF8(reader.readu2());
final int len = reader.readu4();
if (VmArray.equals(LineNrTableAttrName, attrName)) {
lnTable = readLineNrTable(reader);
} else {
reader.skip(len);
}
}
return new VmByteCode(method, code, noLocals, maxStack, etable, lnTable);
}
/**
* Decode the data of a Exceptions attribute
*
* @param reader
* @param cls
* @param cp
* @return The read exceptions
*/
private static final VmExceptions readExceptions(ClassReader reader,
VmType cls, VmCP cp) {
// Read the exceptions
final int ecount = reader.readu2();
final VmConstClass[] list = new VmConstClass[ ecount];
for (int i = 0; i < ecount; i++) {
final int idx = reader.readu2();
list[ i] = cp.getConstClass(idx);
}
return new VmExceptions(list);
}
/**
* Decode the data of a LineNumberTable-attribute
*
* @param reader
* @return The line number map
*/
private static final VmLineNumberMap readLineNrTable(ClassReader reader) {
final int len = reader.readu2();
final char[] lnTable = new char[ len * VmLineNumberMap.LNT_ELEMSIZE];
for (int i = 0; i < len; i++) {
final int ofs = i * VmLineNumberMap.LNT_ELEMSIZE;
lnTable[ ofs + VmLineNumberMap.LNT_STARTPC_OFS] = (char) reader
.readu2();
lnTable[ ofs + VmLineNumberMap.LNT_LINENR_OFS] = (char) reader
.readu2();
}
return new VmLineNumberMap(lnTable);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?