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 }
|