示例#1
0
        public virtual byte[] toByteArray()
        {
            if (index > 0xFFFF)
            {
                throw new RuntimeException("Class file too large!");
            }
            int         size     = 24 + 2 * interfaceCount;
            int         nbFields = 0;
            FieldWriter fb       = firstField;

            while (fb != null)
            {
                ++nbFields;
                size += fb.getSize();
                fb    = (FieldWriter)fb.fv;
            }
            int          nbMethods = 0;
            MethodWriter mb        = firstMethod;

            while (mb != null)
            {
                ++nbMethods;
                size += mb.getSize();
                mb    = (MethodWriter)mb.mv;
            }
            int attributeCount = 0;

            if (bootstrapMethods != null)
            {
                ++attributeCount;
                size += 8 + bootstrapMethods.length;
                newUTF8("BootstrapMethods");
            }
            if (ClassReader.SIGNATURES && signature != 0)
            {
                ++attributeCount;
                size += 8;
                newUTF8("Signature");
            }
            if (sourceFile != 0)
            {
                ++attributeCount;
                size += 8;
                newUTF8("SourceFile");
            }
            if (sourceDebug != null)
            {
                ++attributeCount;
                size += sourceDebug.length + 6;
                newUTF8("SourceDebugExtension");
            }
            if (enclosingMethodOwner != 0)
            {
                ++attributeCount;
                size += 10;
                newUTF8("EnclosingMethod");
            }
            if ((access & Opcodes.ACC_DEPRECATED) != 0)
            {
                ++attributeCount;
                size += 6;
                newUTF8("Deprecated");
            }
            if ((access & Opcodes.ACC_SYNTHETIC) != 0)
            {
                if ((version & 0xFFFF) < Opcodes.V1_5 || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0)
                {
                    ++attributeCount;
                    size += 6;
                    newUTF8("Synthetic");
                }
            }
            if (innerClasses != null)
            {
                ++attributeCount;
                size += 8 + innerClasses.length;
                newUTF8("InnerClasses");
            }
            if (ClassReader.ANNOTATIONS && anns != null)
            {
                ++attributeCount;
                size += 8 + anns.getSize();
                newUTF8("RuntimeVisibleAnnotations");
            }
            if (ClassReader.ANNOTATIONS && ianns != null)
            {
                ++attributeCount;
                size += 8 + ianns.getSize();
                newUTF8("RuntimeInvisibleAnnotations");
            }
            if (ClassReader.ANNOTATIONS && tanns != null)
            {
                ++attributeCount;
                size += 8 + tanns.getSize();
                newUTF8("RuntimeVisibleTypeAnnotations");
            }
            if (ClassReader.ANNOTATIONS && itanns != null)
            {
                ++attributeCount;
                size += 8 + itanns.getSize();
                newUTF8("RuntimeInvisibleTypeAnnotations");
            }
            if (attrs != null)
            {
                attributeCount += attrs.getCount();
                size           += attrs.getSize(this, null, 0, -1, -1);
            }
            size += pool.length;
            ByteVector @out = new ByteVector(size);

            @out.putInt(unchecked ((int)0xCAFEBABE)).putInt(version);
            @out.putShort(index).putByteArray(pool.data, 0, pool.length);
            int mask = Opcodes.ACC_DEPRECATED | ACC_SYNTHETIC_ATTRIBUTE | ((access & ACC_SYNTHETIC_ATTRIBUTE) / TO_ACC_SYNTHETIC);

            @out.putShort(access & ~mask).putShort(name).putShort(superName);
            @out.putShort(interfaceCount);
            for (int i = 0; i < interfaceCount; ++i)
            {
                @out.putShort(interfaces[i]);
            }
            @out.putShort(nbFields);
            fb = firstField;
            while (fb != null)
            {
                fb.put(@out);
                fb = (FieldWriter)fb.fv;
            }
            @out.putShort(nbMethods);
            mb = firstMethod;
            while (mb != null)
            {
                mb.put(@out);
                mb = (MethodWriter)mb.mv;
            }
            @out.putShort(attributeCount);
            if (bootstrapMethods != null)
            {
                @out.putShort(newUTF8("BootstrapMethods"));
                @out.putInt(bootstrapMethods.length + 2).putShort(bootstrapMethodsCount);
                @out.putByteArray(bootstrapMethods.data, 0, bootstrapMethods.length);
            }
            if (ClassReader.SIGNATURES && signature != 0)
            {
                @out.putShort(newUTF8("Signature")).putInt(2).putShort(signature);
            }
            if (sourceFile != 0)
            {
                @out.putShort(newUTF8("SourceFile")).putInt(2).putShort(sourceFile);
            }
            if (sourceDebug != null)
            {
                int len = sourceDebug.length;
                @out.putShort(newUTF8("SourceDebugExtension")).putInt(len);
                @out.putByteArray(sourceDebug.data, 0, len);
            }
            if (enclosingMethodOwner != 0)
            {
                @out.putShort(newUTF8("EnclosingMethod")).putInt(4);
                @out.putShort(enclosingMethodOwner).putShort(enclosingMethod);
            }
            if ((access & Opcodes.ACC_DEPRECATED) != 0)
            {
                @out.putShort(newUTF8("Deprecated")).putInt(0);
            }
            if ((access & Opcodes.ACC_SYNTHETIC) != 0)
            {
                if ((version & 0xFFFF) < Opcodes.V1_5 || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0)
                {
                    @out.putShort(newUTF8("Synthetic")).putInt(0);
                }
            }
            if (innerClasses != null)
            {
                @out.putShort(newUTF8("InnerClasses"));
                @out.putInt(innerClasses.length + 2).putShort(innerClassesCount);
                @out.putByteArray(innerClasses.data, 0, innerClasses.length);
            }
            if (ClassReader.ANNOTATIONS && anns != null)
            {
                @out.putShort(newUTF8("RuntimeVisibleAnnotations"));
                anns.put(@out);
            }
            if (ClassReader.ANNOTATIONS && ianns != null)
            {
                @out.putShort(newUTF8("RuntimeInvisibleAnnotations"));
                ianns.put(@out);
            }
            if (ClassReader.ANNOTATIONS && tanns != null)
            {
                @out.putShort(newUTF8("RuntimeVisibleTypeAnnotations"));
                tanns.put(@out);
            }
            if (ClassReader.ANNOTATIONS && itanns != null)
            {
                @out.putShort(newUTF8("RuntimeInvisibleTypeAnnotations"));
                itanns.put(@out);
            }
            if (attrs != null)
            {
                attrs.put(this, null, 0, -1, -1, @out);
            }
            if (hasAsmInsns)
            {
                anns              = null;
                ianns             = null;
                attrs             = null;
                innerClassesCount = 0;
                innerClasses      = null;
                firstField        = null;
                lastField         = null;
                firstMethod       = null;
                lastMethod        = null;
                compute           = MethodWriter.INSERTED_FRAMES;
                hasAsmInsns       = false;
                new ClassReader(@out.data).accept(this, ClassReader.EXPAND_FRAMES | ClassReader.EXPAND_ASM_INSNS);
                return(toByteArray());
            }
            return(@out.data);
        }