< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java

Print this page

 205      *    'c' -- classes
 206      *    'f' -- fields
 207      *    'i' -- innerclass attributes
 208      *    'm' -- methods
 209      *  For example, to dump everything:
 210      *    javac -XDdumpmodifiers=cifm MyProg.java
 211      */
 212     private boolean dumpClassModifiers; // -XDdumpmodifiers=c
 213     private boolean dumpFieldModifiers; // -XDdumpmodifiers=f
 214     private boolean dumpInnerClassModifiers; // -XDdumpmodifiers=i
 215     private boolean dumpMethodModifiers; // -XDdumpmodifiers=m
 216 
 217 
 218     /** Return flags as a string, separated by " ".
 219      */
 220     public static String flagNames(long flags) {
 221         StringBuilder sbuf = new StringBuilder();
 222         int i = 0;
 223         long f = flags & StandardFlags;
 224         while (f != 0) {
 225             if ((f & 1) != 0) {
 226                 sbuf.append(" ");
 227                 sbuf.append(flagName[i]);
 228             }
 229             f = f >> 1;
 230             i++;
 231         }
 232         return sbuf.toString();
 233     }
 234     //where
 235         private static final String[] flagName = {
 236             "PUBLIC", "PRIVATE", "PROTECTED", "STATIC", "FINAL",
 237             "SUPER", "VOLATILE", "TRANSIENT", "NATIVE", "INTERFACE",

 238             "ABSTRACT", "STRICTFP"};
 239 
 240 /* ****************************************************************
 241  * Output routines
 242  ******************************************************************/
 243 
 244     /** Write a character into given byte buffer;
 245      *  byte buffer will not be grown.
 246      */
 247     void putChar(ByteBuffer buf, int op, int x) {
 248         buf.elems[op  ] = (byte)((x >>  8) & 0xFF);
 249         buf.elems[op+1] = (byte)((x      ) & 0xFF);
 250     }
 251 
 252     /** Write an integer into given byte buffer;
 253      *  byte buffer will not be grown.
 254      */
 255     void putInt(ByteBuffer buf, int adr, int x) {
 256         buf.elems[adr  ] = (byte)((x >> 24) & 0xFF);
 257         buf.elems[adr+1] = (byte)((x >> 16) & 0xFF);

 817             databuf.appendChar(poolWriter.putClass(srvc));
 818             databuf.appendChar(impls.size());
 819             impls.forEach(impl -> databuf.appendChar(poolWriter.putClass(impl)));
 820         });
 821 
 822         endAttr(alenIdx);
 823         return 1;
 824     }
 825 
 826 /* ********************************************************************
 827  * Writing Objects
 828  **********************************************************************/
 829 
 830     /** Write "inner classes" attribute.
 831      */
 832     void writeInnerClasses() {
 833         int alenIdx = writeAttr(names.InnerClasses);
 834         databuf.appendChar(poolWriter.innerClasses.size());
 835         for (ClassSymbol inner : poolWriter.innerClasses) {
 836             inner.markAbstractIfNeeded(types);
 837             int flags = adjustFlags(inner.flags_field);
 838             if ((flags & INTERFACE) != 0) flags |= ABSTRACT; // Interfaces are always ABSTRACT
 839             flags &= ~STRICTFP; //inner classes should not have the strictfp flag set.
 840             if (dumpInnerClassModifiers) {
 841                 PrintWriter pw = log.getWriter(Log.WriterKind.ERROR);
 842                 pw.println("INNERCLASS  " + inner.name);
 843                 pw.println("---" + flagNames(flags));
 844             }
 845             databuf.appendChar(poolWriter.putClass(inner));
 846             databuf.appendChar(
 847                 inner.owner.kind == TYP && !inner.name.isEmpty() ? poolWriter.putClass((ClassSymbol)inner.owner) : 0);
 848             databuf.appendChar(
 849                 !inner.name.isEmpty() ? poolWriter.putName(inner.name) : 0);
 850             databuf.appendChar(flags);
 851         }
 852         endAttr(alenIdx);
 853     }
 854 











 855     int writeRecordAttribute(ClassSymbol csym) {
 856         int alenIdx = writeAttr(names.Record);
 857         Scope s = csym.members();
 858         databuf.appendChar(csym.getRecordComponents().size());
 859         for (VarSymbol v: csym.getRecordComponents()) {
 860             //databuf.appendChar(poolWriter.putMember(v.accessor.head.snd));
 861             databuf.appendChar(poolWriter.putName(v.name));
 862             databuf.appendChar(poolWriter.putDescriptor(v));
 863             int acountIdx = beginAttrs();
 864             int acount = 0;
 865             acount += writeMemberAttrs(v, true);
 866             endAttrs(acountIdx, acount);
 867         }
 868         endAttr(alenIdx);
 869         return 1;
 870     }
 871 
 872     /**
 873      * Write NestMembers attribute (if needed)
 874      */

 948             }
 949         } while (lastBootstrapMethods < poolWriter.bootstrapMethods.size());
 950         databuf.appendChar(poolWriter.bootstrapMethods.size());
 951         for (BsmKey bsmKey : poolWriter.bootstrapMethods.keySet()) {
 952             //write BSM handle
 953             databuf.appendChar(poolWriter.putConstant(bsmKey.bsm));
 954             LoadableConstant[] uniqueArgs = bsmKey.staticArgs;
 955             //write static args length
 956             databuf.appendChar(uniqueArgs.length);
 957             //write static args array
 958             for (LoadableConstant arg : uniqueArgs) {
 959                 databuf.appendChar(poolWriter.putConstant(arg));
 960             }
 961         }
 962         endAttr(alenIdx);
 963     }
 964 
 965     /** Write field symbol, entering all references into constant pool.
 966      */
 967     void writeField(VarSymbol v) {
 968         int flags = adjustFlags(v.flags());
 969         databuf.appendChar(flags);
 970         if (dumpFieldModifiers) {
 971             PrintWriter pw = log.getWriter(Log.WriterKind.ERROR);
 972             pw.println("FIELD  " + v.name);
 973             pw.println("---" + flagNames(v.flags()));
 974         }
 975         databuf.appendChar(poolWriter.putName(v.name));
 976         databuf.appendChar(poolWriter.putDescriptor(v));







 977         int acountIdx = beginAttrs();
 978         int acount = 0;
 979         if (v.getConstValue() != null) {
 980             int alenIdx = writeAttr(names.ConstantValue);
 981             databuf.appendChar(poolWriter.putConstant(v.getConstValue()));
 982             endAttr(alenIdx);
 983             acount++;
 984         }
 985         acount += writeMemberAttrs(v, false);
 986         acount += writeExtraAttributes(v);
 987         endAttrs(acountIdx, acount);
 988     }
 989 
 990     /** Write method symbol, entering all references into constant pool.
 991      */
 992     void writeMethod(MethodSymbol m) {
 993         int flags = adjustFlags(m.flags());
 994         databuf.appendChar(flags);
 995         if (dumpMethodModifiers) {
 996             PrintWriter pw = log.getWriter(Log.WriterKind.ERROR);
 997             pw.println("METHOD  " + m.name);
 998             pw.println("---" + flagNames(m.flags()));
 999         }
1000         databuf.appendChar(poolWriter.putName(m.name));
1001         databuf.appendChar(poolWriter.putDescriptor(m));
















1002         int acountIdx = beginAttrs();
1003         int acount = 0;
1004         if (m.code != null) {
1005             int alenIdx = writeAttr(names.Code);
1006             writeCode(m.code);
1007             m.code = null; // to conserve space
1008             endAttr(alenIdx);
1009             acount++;
1010         }
1011         List<Type> thrown = m.erasure(types).getThrownTypes();
1012         if (thrown.nonEmpty()) {
1013             int alenIdx = writeAttr(names.Exceptions);
1014             databuf.appendChar(thrown.length());
1015             for (List<Type> l = thrown; l.nonEmpty(); l = l.tail)
1016                 databuf.appendChar(poolWriter.putClass(l.head));
1017             endAttr(alenIdx);
1018             acount++;
1019         }
1020         if (m.defaultValue != null) {
1021             int alenIdx = writeAttr(names.AnnotationDefault);

1559         }
1560         return outFile; // may be null if write failed
1561     }
1562 
1563     /** Write class `c' to outstream `out'.
1564      */
1565     public void writeClassFile(OutputStream out, ClassSymbol c)
1566         throws IOException, PoolOverflow, StringOverflow {
1567         Assert.check((c.flags() & COMPOUND) == 0);
1568         databuf.reset();
1569         poolbuf.reset();
1570 
1571         Type supertype = types.supertype(c.type);
1572         List<Type> interfaces = types.interfaces(c.type);
1573         List<Type> typarams = c.type.getTypeArguments();
1574 
1575         int flags;
1576         if (c.owner.kind == MDL) {
1577             flags = ACC_MODULE;
1578         } else {
1579             flags = adjustFlags(c.flags() & ~DEFAULT);

1580             if ((flags & PROTECTED) != 0) flags |= PUBLIC;
1581             flags = flags & ClassFlags & ~STRICTFP;
1582             if ((flags & INTERFACE) == 0) flags |= ACC_SUPER;
1583         }
1584 
1585         if (dumpClassModifiers) {
1586             PrintWriter pw = log.getWriter(Log.WriterKind.ERROR);
1587             pw.println();
1588             pw.println("CLASSFILE  " + c.getQualifiedName());
1589             pw.println("---" + flagNames(flags));
1590         }
1591         databuf.appendChar(flags);
1592 
1593         if (c.owner.kind == MDL) {
1594             PackageSymbol unnamed = ((ModuleSymbol) c.owner).unnamedPackage;
1595             databuf.appendChar(poolWriter.putClass(new ClassSymbol(0, names.module_info, unnamed)));
1596         } else {
1597             databuf.appendChar(poolWriter.putClass(c));
1598         }
1599         databuf.appendChar(supertype.hasTag(CLASS) ? poolWriter.putClass((ClassSymbol)supertype.tsym) : 0);
1600         databuf.appendChar(interfaces.length());
1601         for (List<Type> l = interfaces; l.nonEmpty(); l = l.tail)
1602             databuf.appendChar(poolWriter.putClass((ClassSymbol)l.head.tsym));

1688         }
1689 
1690         if (c.isRecord()) {
1691             acount += writeRecordAttribute(c);
1692         }
1693 
1694         if (target.hasSealedClasses()) {
1695             acount += writePermittedSubclassesIfNeeded(c);
1696         }
1697 
1698         if (!poolWriter.bootstrapMethods.isEmpty()) {
1699             writeBootstrapMethods();
1700             acount++;
1701         }
1702 
1703         if (!poolWriter.innerClasses.isEmpty()) {
1704             writeInnerClasses();
1705             acount++;
1706         }
1707 





1708         endAttrs(acountIdx, acount);
1709 
1710         out.write(poolbuf.elems, 0, poolbuf.length);
1711 
1712         poolWriter.writePool(out);
1713         poolWriter.reset(); // to save space
1714 
1715         out.write(databuf.elems, 0, databuf.length);
1716     }
1717 
1718      /**Allows subclasses to write additional class attributes
1719       *
1720       * @return the number of attributes written
1721       */
1722     protected int writeExtraClassAttributes(ClassSymbol c) {
1723         return 0;
1724     }
1725 
1726     /**Allows friends to write additional attributes
1727      *
1728      * @return the number of attributes written
1729      */
1730     protected int writeExtraAttributes(Symbol sym) {
1731         int i = 0;
1732         for (ToIntFunction<Symbol> hook : extraAttributeHooks) {
1733             i += hook.applyAsInt(sym);
1734         }
1735         return i;
1736     }
1737 
1738     int adjustFlags(final long flags) {
1739         int result = (int)flags;
1740 
1741         // Elide strictfp bit in class files
1742         if (target.obsoleteAccStrict())
1743             result &= ~STRICTFP;
1744 
1745         if ((flags & BRIDGE) != 0)
1746             result |= ACC_BRIDGE;
1747         if ((flags & VARARGS) != 0)
1748             result |= ACC_VARARGS;
1749         if ((flags & DEFAULT) != 0)
1750             result &= ~ABSTRACT;








1751         return result;
1752     }
1753 
1754     long getLastModified(FileObject filename) {
1755         long mod = 0;
1756         try {
1757             mod = filename.getLastModified();
1758         } catch (SecurityException e) {
1759             throw new AssertionError("CRT: couldn't get source file modification date: " + e.getMessage());
1760         }
1761         return mod;
1762     }
1763 }

 205      *    'c' -- classes
 206      *    'f' -- fields
 207      *    'i' -- innerclass attributes
 208      *    'm' -- methods
 209      *  For example, to dump everything:
 210      *    javac -XDdumpmodifiers=cifm MyProg.java
 211      */
 212     private boolean dumpClassModifiers; // -XDdumpmodifiers=c
 213     private boolean dumpFieldModifiers; // -XDdumpmodifiers=f
 214     private boolean dumpInnerClassModifiers; // -XDdumpmodifiers=i
 215     private boolean dumpMethodModifiers; // -XDdumpmodifiers=m
 216 
 217 
 218     /** Return flags as a string, separated by " ".
 219      */
 220     public static String flagNames(long flags) {
 221         StringBuilder sbuf = new StringBuilder();
 222         int i = 0;
 223         long f = flags & StandardFlags;
 224         while (f != 0) {
 225             if ((f & 1) != 0 && flagName[i] != "") {
 226                 sbuf.append(" ");
 227                 sbuf.append(flagName[i]);
 228             }
 229             f = f >> 1;
 230             i++;
 231         }
 232         return sbuf.toString();
 233     }
 234     //where
 235         private static final String[] flagName = {
 236             "PUBLIC", "PRIVATE", "PROTECTED", "STATIC", "FINAL",
 237             // the empty position should be for synchronized but right now we don't have any test checking it
 238             "", "VOLATILE", "TRANSIENT", "NATIVE", "INTERFACE",
 239             "ABSTRACT", "STRICTFP"};
 240 
 241 /* ****************************************************************
 242  * Output routines
 243  ******************************************************************/
 244 
 245     /** Write a character into given byte buffer;
 246      *  byte buffer will not be grown.
 247      */
 248     void putChar(ByteBuffer buf, int op, int x) {
 249         buf.elems[op  ] = (byte)((x >>  8) & 0xFF);
 250         buf.elems[op+1] = (byte)((x      ) & 0xFF);
 251     }
 252 
 253     /** Write an integer into given byte buffer;
 254      *  byte buffer will not be grown.
 255      */
 256     void putInt(ByteBuffer buf, int adr, int x) {
 257         buf.elems[adr  ] = (byte)((x >> 24) & 0xFF);
 258         buf.elems[adr+1] = (byte)((x >> 16) & 0xFF);

 818             databuf.appendChar(poolWriter.putClass(srvc));
 819             databuf.appendChar(impls.size());
 820             impls.forEach(impl -> databuf.appendChar(poolWriter.putClass(impl)));
 821         });
 822 
 823         endAttr(alenIdx);
 824         return 1;
 825     }
 826 
 827 /* ********************************************************************
 828  * Writing Objects
 829  **********************************************************************/
 830 
 831     /** Write "inner classes" attribute.
 832      */
 833     void writeInnerClasses() {
 834         int alenIdx = writeAttr(names.InnerClasses);
 835         databuf.appendChar(poolWriter.innerClasses.size());
 836         for (ClassSymbol inner : poolWriter.innerClasses) {
 837             inner.markAbstractIfNeeded(types);
 838             int flags = adjustFlags(inner, inner.flags_field);
 839             if ((flags & INTERFACE) != 0) flags |= ABSTRACT; // Interfaces are always ABSTRACT

 840             if (dumpInnerClassModifiers) {
 841                 PrintWriter pw = log.getWriter(Log.WriterKind.ERROR);
 842                 pw.println("INNERCLASS  " + inner.name);
 843                 pw.println("---" + flagNames(flags));
 844             }
 845             databuf.appendChar(poolWriter.putClass(inner));
 846             databuf.appendChar(
 847                 inner.owner.kind == TYP && !inner.name.isEmpty() ? poolWriter.putClass((ClassSymbol)inner.owner) : 0);
 848             databuf.appendChar(
 849                 !inner.name.isEmpty() ? poolWriter.putName(inner.name) : 0);
 850             databuf.appendChar(flags);
 851         }
 852         endAttr(alenIdx);
 853     }
 854 
 855      /** Write out "LoadableDescriptors" attribute by enumerating the value classes encountered in field/method descriptors during this compilation.
 856       */
 857      void writeLoadableDescriptorsAttribute() {
 858         int alenIdx = writeAttr(names.LoadableDescriptors);
 859         databuf.appendChar(poolWriter.loadableDescriptors.size());
 860         for (Symbol c : poolWriter.loadableDescriptors) {
 861             databuf.appendChar(poolWriter.putDescriptor(c));
 862         }
 863         endAttr(alenIdx);
 864      }
 865 
 866     int writeRecordAttribute(ClassSymbol csym) {
 867         int alenIdx = writeAttr(names.Record);
 868         Scope s = csym.members();
 869         databuf.appendChar(csym.getRecordComponents().size());
 870         for (VarSymbol v: csym.getRecordComponents()) {
 871             //databuf.appendChar(poolWriter.putMember(v.accessor.head.snd));
 872             databuf.appendChar(poolWriter.putName(v.name));
 873             databuf.appendChar(poolWriter.putDescriptor(v));
 874             int acountIdx = beginAttrs();
 875             int acount = 0;
 876             acount += writeMemberAttrs(v, true);
 877             endAttrs(acountIdx, acount);
 878         }
 879         endAttr(alenIdx);
 880         return 1;
 881     }
 882 
 883     /**
 884      * Write NestMembers attribute (if needed)
 885      */

 959             }
 960         } while (lastBootstrapMethods < poolWriter.bootstrapMethods.size());
 961         databuf.appendChar(poolWriter.bootstrapMethods.size());
 962         for (BsmKey bsmKey : poolWriter.bootstrapMethods.keySet()) {
 963             //write BSM handle
 964             databuf.appendChar(poolWriter.putConstant(bsmKey.bsm));
 965             LoadableConstant[] uniqueArgs = bsmKey.staticArgs;
 966             //write static args length
 967             databuf.appendChar(uniqueArgs.length);
 968             //write static args array
 969             for (LoadableConstant arg : uniqueArgs) {
 970                 databuf.appendChar(poolWriter.putConstant(arg));
 971             }
 972         }
 973         endAttr(alenIdx);
 974     }
 975 
 976     /** Write field symbol, entering all references into constant pool.
 977      */
 978     void writeField(VarSymbol v) {
 979         int flags = adjustFlags(v, v.flags());
 980         databuf.appendChar(flags);
 981         if (dumpFieldModifiers) {
 982             PrintWriter pw = log.getWriter(Log.WriterKind.ERROR);
 983             pw.println("FIELD  " + v.name);
 984             pw.println("---" + flagNames(v.flags()));
 985         }
 986         databuf.appendChar(poolWriter.putName(v.name));
 987         databuf.appendChar(poolWriter.putDescriptor(v));
 988         Type fldType = v.erasure(types);
 989         if (fldType.requiresLoadableDescriptors(v.owner)) {
 990             poolWriter.enterLoadableDescriptorsClass(fldType.tsym);
 991             if (preview.isPreview(Source.Feature.VALUE_CLASSES)) {
 992                 preview.markUsesPreview(null);
 993             }
 994         }
 995         int acountIdx = beginAttrs();
 996         int acount = 0;
 997         if (v.getConstValue() != null) {
 998             int alenIdx = writeAttr(names.ConstantValue);
 999             databuf.appendChar(poolWriter.putConstant(v.getConstValue()));
1000             endAttr(alenIdx);
1001             acount++;
1002         }
1003         acount += writeMemberAttrs(v, false);
1004         acount += writeExtraAttributes(v);
1005         endAttrs(acountIdx, acount);
1006     }
1007 
1008     /** Write method symbol, entering all references into constant pool.
1009      */
1010     void writeMethod(MethodSymbol m) {
1011         int flags = adjustFlags(m, m.flags());
1012         databuf.appendChar(flags);
1013         if (dumpMethodModifiers) {
1014             PrintWriter pw = log.getWriter(Log.WriterKind.ERROR);
1015             pw.println("METHOD  " + m.name);
1016             pw.println("---" + flagNames(m.flags()));
1017         }
1018         databuf.appendChar(poolWriter.putName(m.name));
1019         databuf.appendChar(poolWriter.putDescriptor(m));
1020         MethodType mtype = (MethodType) m.externalType(types);
1021         for (Type t : mtype.getParameterTypes()) {
1022             if (t.requiresLoadableDescriptors(m.owner)) {
1023                 poolWriter.enterLoadableDescriptorsClass(t.tsym);
1024                 if (preview.isPreview(Source.Feature.VALUE_CLASSES)) {
1025                     preview.markUsesPreview(null);
1026                 }
1027             }
1028         }
1029         Type returnType = mtype.getReturnType();
1030         if (returnType.requiresLoadableDescriptors(m.owner)) {
1031             poolWriter.enterLoadableDescriptorsClass(returnType.tsym);
1032             if (preview.isPreview(Source.Feature.VALUE_CLASSES)) {
1033                 preview.markUsesPreview(null);
1034             }
1035         }
1036         int acountIdx = beginAttrs();
1037         int acount = 0;
1038         if (m.code != null) {
1039             int alenIdx = writeAttr(names.Code);
1040             writeCode(m.code);
1041             m.code = null; // to conserve space
1042             endAttr(alenIdx);
1043             acount++;
1044         }
1045         List<Type> thrown = m.erasure(types).getThrownTypes();
1046         if (thrown.nonEmpty()) {
1047             int alenIdx = writeAttr(names.Exceptions);
1048             databuf.appendChar(thrown.length());
1049             for (List<Type> l = thrown; l.nonEmpty(); l = l.tail)
1050                 databuf.appendChar(poolWriter.putClass(l.head));
1051             endAttr(alenIdx);
1052             acount++;
1053         }
1054         if (m.defaultValue != null) {
1055             int alenIdx = writeAttr(names.AnnotationDefault);

1593         }
1594         return outFile; // may be null if write failed
1595     }
1596 
1597     /** Write class `c' to outstream `out'.
1598      */
1599     public void writeClassFile(OutputStream out, ClassSymbol c)
1600         throws IOException, PoolOverflow, StringOverflow {
1601         Assert.check((c.flags() & COMPOUND) == 0);
1602         databuf.reset();
1603         poolbuf.reset();
1604 
1605         Type supertype = types.supertype(c.type);
1606         List<Type> interfaces = types.interfaces(c.type);
1607         List<Type> typarams = c.type.getTypeArguments();
1608 
1609         int flags;
1610         if (c.owner.kind == MDL) {
1611             flags = ACC_MODULE;
1612         } else {
1613             long originalFlags = c.flags();
1614             flags = adjustFlags(c, c.flags() & ~(DEFAULT | STRICTFP));
1615             if ((flags & PROTECTED) != 0) flags |= PUBLIC;
1616             flags = flags & ClassFlags;
1617             flags |= (originalFlags & IDENTITY_TYPE) != 0 ? ACC_IDENTITY : flags;
1618         }
1619 
1620         if (dumpClassModifiers) {
1621             PrintWriter pw = log.getWriter(Log.WriterKind.ERROR);
1622             pw.println();
1623             pw.println("CLASSFILE  " + c.getQualifiedName());
1624             pw.println("---" + flagNames(flags));
1625         }
1626         databuf.appendChar(flags);
1627 
1628         if (c.owner.kind == MDL) {
1629             PackageSymbol unnamed = ((ModuleSymbol) c.owner).unnamedPackage;
1630             databuf.appendChar(poolWriter.putClass(new ClassSymbol(0, names.module_info, unnamed)));
1631         } else {
1632             databuf.appendChar(poolWriter.putClass(c));
1633         }
1634         databuf.appendChar(supertype.hasTag(CLASS) ? poolWriter.putClass((ClassSymbol)supertype.tsym) : 0);
1635         databuf.appendChar(interfaces.length());
1636         for (List<Type> l = interfaces; l.nonEmpty(); l = l.tail)
1637             databuf.appendChar(poolWriter.putClass((ClassSymbol)l.head.tsym));

1723         }
1724 
1725         if (c.isRecord()) {
1726             acount += writeRecordAttribute(c);
1727         }
1728 
1729         if (target.hasSealedClasses()) {
1730             acount += writePermittedSubclassesIfNeeded(c);
1731         }
1732 
1733         if (!poolWriter.bootstrapMethods.isEmpty()) {
1734             writeBootstrapMethods();
1735             acount++;
1736         }
1737 
1738         if (!poolWriter.innerClasses.isEmpty()) {
1739             writeInnerClasses();
1740             acount++;
1741         }
1742 
1743         if (!poolWriter.loadableDescriptors.isEmpty()) {
1744             writeLoadableDescriptorsAttribute();
1745             acount++;
1746         }
1747 
1748         endAttrs(acountIdx, acount);
1749 
1750         out.write(poolbuf.elems, 0, poolbuf.length);
1751 
1752         poolWriter.writePool(out);
1753         poolWriter.reset(); // to save space
1754 
1755         out.write(databuf.elems, 0, databuf.length);
1756     }
1757 
1758      /**Allows subclasses to write additional class attributes
1759       *
1760       * @return the number of attributes written
1761       */
1762     protected int writeExtraClassAttributes(ClassSymbol c) {
1763         return 0;
1764     }
1765 
1766     /**Allows friends to write additional attributes
1767      *
1768      * @return the number of attributes written
1769      */
1770     protected int writeExtraAttributes(Symbol sym) {
1771         int i = 0;
1772         for (ToIntFunction<Symbol> hook : extraAttributeHooks) {
1773             i += hook.applyAsInt(sym);
1774         }
1775         return i;
1776     }
1777 
1778     int adjustFlags(Symbol sym, final long flags) {
1779         int result = (int)flags;
1780 
1781         // Elide strictfp bit in class files
1782         if (target.obsoleteAccStrict())
1783             result &= ~STRICTFP;
1784 
1785         if ((flags & BRIDGE) != 0)
1786             result |= ACC_BRIDGE;
1787         if ((flags & VARARGS) != 0)
1788             result |= ACC_VARARGS;
1789         if ((flags & DEFAULT) != 0)
1790             result &= ~ABSTRACT;
1791         if ((flags & IDENTITY_TYPE) != 0) {
1792             result |= ACC_IDENTITY;
1793         }
1794         if (sym.kind == VAR) {
1795             if ((flags & STRICT) != 0) {
1796                 result |= ACC_STRICT;
1797             }
1798         }
1799         return result;
1800     }
1801 
1802     long getLastModified(FileObject filename) {
1803         long mod = 0;
1804         try {
1805             mod = filename.getLastModified();
1806         } catch (SecurityException e) {
1807             throw new AssertionError("CRT: couldn't get source file modification date: " + e.getMessage());
1808         }
1809         return mod;
1810     }
1811 }
< prev index next >