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 + -
显示快捷键?