< 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);

 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      */

 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      *

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);

 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.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 "Preload" attribute by enumerating the value classes encountered in field/method descriptors during this compilation.
 856       */
 857      void writePreloadAttribute() {
 858         int alenIdx = writeAttr(names.Preload);
 859         databuf.appendChar(poolWriter.preloadClasses.size());
 860         for (ClassSymbol c : poolWriter.preloadClasses) {
 861             databuf.appendChar(poolWriter.putClass(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      */

 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.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.requiresPreload(v.owner)) {
 990             poolWriter.enterPreloadClass((ClassSymbol) fldType.tsym);
 991         }
 992         int acountIdx = beginAttrs();
 993         int acount = 0;
 994         if (v.getConstValue() != null) {
 995             int alenIdx = writeAttr(names.ConstantValue);
 996             databuf.appendChar(poolWriter.putConstant(v.getConstValue()));
 997             endAttr(alenIdx);
 998             acount++;
 999         }
1000         acount += writeMemberAttrs(v, false);
1001         acount += writeExtraAttributes(v);
1002         endAttrs(acountIdx, acount);
1003     }
1004 
1005     /** Write method symbol, entering all references into constant pool.
1006      */
1007     void writeMethod(MethodSymbol m) {
1008         int flags = adjustFlags(m.flags());
1009         databuf.appendChar(flags);
1010         if (dumpMethodModifiers) {
1011             PrintWriter pw = log.getWriter(Log.WriterKind.ERROR);
1012             pw.println("METHOD  " + m.name);
1013             pw.println("---" + flagNames(m.flags()));
1014         }
1015         databuf.appendChar(poolWriter.putName(m.name));
1016         databuf.appendChar(poolWriter.putDescriptor(m));
1017         MethodType mtype = (MethodType) m.externalType(types);
1018         for (Type t : mtype.getParameterTypes()) {
1019             if (t.requiresPreload(m.owner)) {
1020                 poolWriter.enterPreloadClass((ClassSymbol) t.tsym);
1021             }
1022         }
1023         Type returnType = mtype.getReturnType();
1024         if (returnType.requiresPreload(m.owner)) {
1025             poolWriter.enterPreloadClass((ClassSymbol) returnType.tsym);
1026         }
1027         int acountIdx = beginAttrs();
1028         int acount = 0;
1029         if (m.code != null) {
1030             int alenIdx = writeAttr(names.Code);
1031             writeCode(m.code);
1032             m.code = null; // to conserve space
1033             endAttr(alenIdx);
1034             acount++;
1035         }
1036         List<Type> thrown = m.erasure(types).getThrownTypes();
1037         if (thrown.nonEmpty()) {
1038             int alenIdx = writeAttr(names.Exceptions);
1039             databuf.appendChar(thrown.length());
1040             for (List<Type> l = thrown; l.nonEmpty(); l = l.tail)
1041                 databuf.appendChar(poolWriter.putClass(l.head));
1042             endAttr(alenIdx);
1043             acount++;
1044         }
1045         if (m.defaultValue != null) {
1046             int alenIdx = writeAttr(names.AnnotationDefault);

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

1714         }
1715 
1716         if (c.isRecord()) {
1717             acount += writeRecordAttribute(c);
1718         }
1719 
1720         if (target.hasSealedClasses()) {
1721             acount += writePermittedSubclassesIfNeeded(c);
1722         }
1723 
1724         if (!poolWriter.bootstrapMethods.isEmpty()) {
1725             writeBootstrapMethods();
1726             acount++;
1727         }
1728 
1729         if (!poolWriter.innerClasses.isEmpty()) {
1730             writeInnerClasses();
1731             acount++;
1732         }
1733 
1734         if (!poolWriter.preloadClasses.isEmpty()) {
1735             writePreloadAttribute();
1736             acount++;
1737         }
1738 
1739         endAttrs(acountIdx, acount);
1740 
1741         out.write(poolbuf.elems, 0, poolbuf.length);
1742 
1743         poolWriter.writePool(out);
1744         poolWriter.reset(); // to save space
1745 
1746         out.write(databuf.elems, 0, databuf.length);
1747     }
1748 
1749      /**Allows subclasses to write additional class attributes
1750       *
1751       * @return the number of attributes written
1752       */
1753     protected int writeExtraClassAttributes(ClassSymbol c) {
1754         return 0;
1755     }
1756 
1757     /**Allows friends to write additional attributes
1758      *

1762         int i = 0;
1763         for (ToIntFunction<Symbol> hook : extraAttributeHooks) {
1764             i += hook.applyAsInt(sym);
1765         }
1766         return i;
1767     }
1768 
1769     int adjustFlags(final long flags) {
1770         int result = (int)flags;
1771 
1772         // Elide strictfp bit in class files
1773         if (target.obsoleteAccStrict())
1774             result &= ~STRICTFP;
1775 
1776         if ((flags & BRIDGE) != 0)
1777             result |= ACC_BRIDGE;
1778         if ((flags & VARARGS) != 0)
1779             result |= ACC_VARARGS;
1780         if ((flags & DEFAULT) != 0)
1781             result &= ~ABSTRACT;
1782         if ((flags & IDENTITY_TYPE) != 0) {
1783             result |= ACC_IDENTITY;
1784         }
1785         if ((flags & STRICT) != 0) {
1786             result |= ACC_STRICT;
1787         }
1788         return result;
1789     }
1790 
1791     long getLastModified(FileObject filename) {
1792         long mod = 0;
1793         try {
1794             mod = filename.getLastModified();
1795         } catch (SecurityException e) {
1796             throw new AssertionError("CRT: couldn't get source file modification date: " + e.getMessage());
1797         }
1798         return mod;
1799     }
1800 }
< prev index next >