34 import com.sun.tools.javac.code.Symbol.PackageSymbol;
35 import com.sun.tools.javac.code.Type;
36 import com.sun.tools.javac.code.Types;
37 import com.sun.tools.javac.jvm.ClassWriter.PoolOverflow;
38 import com.sun.tools.javac.jvm.ClassWriter.StringOverflow;
39 import com.sun.tools.javac.jvm.PoolConstant.LoadableConstant;
40 import com.sun.tools.javac.jvm.PoolConstant.LoadableConstant.BasicConstant;
41 import com.sun.tools.javac.jvm.PoolConstant.Dynamic;
42 import com.sun.tools.javac.jvm.PoolConstant.Dynamic.BsmKey;
43 import com.sun.tools.javac.jvm.PoolConstant.NameAndType;
44 import com.sun.tools.javac.util.ByteBuffer;
45 import com.sun.tools.javac.util.InvalidUtfException;
46 import com.sun.tools.javac.util.List;
47 import com.sun.tools.javac.util.Name;
48 import com.sun.tools.javac.util.Names;
49
50 import java.io.IOException;
51 import java.io.OutputStream;
52 import java.util.ArrayDeque;
53 import java.util.HashMap;
54 import java.util.LinkedHashMap;
55 import java.util.LinkedHashSet;
56 import java.util.Map;
57
58 import static com.sun.tools.javac.code.Kinds.Kind.TYP;
59 import static com.sun.tools.javac.code.TypeTag.ARRAY;
60 import static com.sun.tools.javac.code.TypeTag.CLASS;
61 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Class;
62 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_MethodType;
63 import static com.sun.tools.javac.jvm.ClassFile.externalize;
64
65 /**
66 * Pool interface towards {@code ClassWriter}. Exposes methods to encode and write javac entities
67 * into the constant pool.
68 *
69 * <p><b>This is NOT part of any supported API.
70 * If you write code that depends on this, you do so at your own risk.
71 * This code and its internal interfaces are subject to change or
72 * deletion without notice.</b>
73 */
74 public class PoolWriter {
75
76 /** Max number of constant pool entries. */
77 public static final int MAX_ENTRIES = 0xFFFF;
78
79 /** Max number of char in a string constant. */
80 public static final int MAX_STRING_LENGTH = 0xFFFF;
81
82 private static final int POOL_BUF_SIZE = 0x7fff;
83
84 private final Types types;
85
86 private final Names names;
87
88 /** Pool helper **/
89 final WriteablePoolHelper pool;
90
91 /** Sole signature generator */
92 final SharedSignatureGenerator signatureGen;
93
94 /** The inner classes to be written, as an ordered set (enclosing first). */
95 LinkedHashSet<ClassSymbol> innerClasses = new LinkedHashSet<>();
96
97 /** The list of entries in the BootstrapMethods attribute. */
98 Map<BsmKey, Integer> bootstrapMethods = new LinkedHashMap<>();
99
100 public PoolWriter(Types types, Names names) {
101 this.types = types;
102 this.names = names;
103 this.signatureGen = new SharedSignatureGenerator();
104 this.pool = new WriteablePoolHelper();
105 }
106
107 /**
108 * Puts a class symbol into the pool and return its index.
109 */
110 int putClass(ClassSymbol csym) {
111 return putClass(csym.type);
112 }
113
114 /**
115 * Puts a type into the pool and return its index. The type could be either a class, a type variable
116 * or an array type.
215 * Puts a module entry into the pool and returns its index.
216 */
217 int putModule(ModuleSymbol mod) {
218 return pool.writeIfNeeded(mod);
219 }
220
221 /**
222 * Enter an inner class into the `innerClasses' set.
223 */
224 void enterInner(ClassSymbol c) {
225 if (c.type.isCompound()) {
226 throw new AssertionError("Unexpected intersection type: " + c.type);
227 }
228 c.complete();
229 if (c.owner.enclClass() != null && !innerClasses.contains(c)) {
230 enterInner(c.owner.enclClass());
231 innerClasses.add(c);
232 }
233 }
234
235 /**
236 * Create a new Utf8 entry representing a descriptor for given (member) symbol.
237 */
238 private Type descriptorType(Symbol s) {
239 return s.kind == Kind.MTH ? s.externalType(types) : s.erasure(types);
240 }
241
242 private int makeBootstrapEntry(Dynamic dynamic) {
243 BsmKey bsmKey = dynamic.bsmKey(types);
244
245 // Figure out the index for existing BSM; create a new BSM if no key
246 Integer index = bootstrapMethods.get(bsmKey);
247 if (index == null) {
248 index = bootstrapMethods.size();
249 bootstrapMethods.put(bsmKey, index);
250 }
251
252 return index;
253 }
254
495 private Name typeSig(Type type) {
496 signatureGen.reset();
497 signatureGen.assembleSig(type);
498 return signatureGen.toName();
499 }
500
501 private Name classSig(Type t) {
502 signatureGen.reset();
503 List<Type> typarams = t.getTypeArguments();
504 if (typarams.nonEmpty()) {
505 signatureGen.assembleParamsSig(typarams);
506 }
507 signatureGen.assembleSig(types.supertype(t));
508 for (Type i : types.interfaces(t))
509 signatureGen.assembleSig(i);
510 return signatureGen.toName();
511 }
512
513 void reset() {
514 innerClasses.clear();
515 bootstrapMethods.clear();
516 pool.reset();
517 }
518 }
|
34 import com.sun.tools.javac.code.Symbol.PackageSymbol;
35 import com.sun.tools.javac.code.Type;
36 import com.sun.tools.javac.code.Types;
37 import com.sun.tools.javac.jvm.ClassWriter.PoolOverflow;
38 import com.sun.tools.javac.jvm.ClassWriter.StringOverflow;
39 import com.sun.tools.javac.jvm.PoolConstant.LoadableConstant;
40 import com.sun.tools.javac.jvm.PoolConstant.LoadableConstant.BasicConstant;
41 import com.sun.tools.javac.jvm.PoolConstant.Dynamic;
42 import com.sun.tools.javac.jvm.PoolConstant.Dynamic.BsmKey;
43 import com.sun.tools.javac.jvm.PoolConstant.NameAndType;
44 import com.sun.tools.javac.util.ByteBuffer;
45 import com.sun.tools.javac.util.InvalidUtfException;
46 import com.sun.tools.javac.util.List;
47 import com.sun.tools.javac.util.Name;
48 import com.sun.tools.javac.util.Names;
49
50 import java.io.IOException;
51 import java.io.OutputStream;
52 import java.util.ArrayDeque;
53 import java.util.HashMap;
54 import java.util.HashSet;
55 import java.util.LinkedHashMap;
56 import java.util.LinkedHashSet;
57 import java.util.Map;
58 import java.util.Set;
59
60 import static com.sun.tools.javac.code.Kinds.Kind.TYP;
61 import static com.sun.tools.javac.code.TypeTag.ARRAY;
62 import static com.sun.tools.javac.code.TypeTag.CLASS;
63 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_Class;
64 import static com.sun.tools.javac.jvm.ClassFile.CONSTANT_MethodType;
65 import static com.sun.tools.javac.jvm.ClassFile.externalize;
66
67 /**
68 * Pool interface towards {@code ClassWriter}. Exposes methods to encode and write javac entities
69 * into the constant pool.
70 *
71 * <p><b>This is NOT part of any supported API.
72 * If you write code that depends on this, you do so at your own risk.
73 * This code and its internal interfaces are subject to change or
74 * deletion without notice.</b>
75 */
76 public class PoolWriter {
77
78 /** Max number of constant pool entries. */
79 public static final int MAX_ENTRIES = 0xFFFF;
80
81 /** Max number of char in a string constant. */
82 public static final int MAX_STRING_LENGTH = 0xFFFF;
83
84 private static final int POOL_BUF_SIZE = 0x7fff;
85
86 private final Types types;
87
88 private final Names names;
89
90 /** Pool helper **/
91 final WriteablePoolHelper pool;
92
93 /** Sole signature generator */
94 final SharedSignatureGenerator signatureGen;
95
96 /** The inner classes to be written, as an ordered set (enclosing first). */
97 LinkedHashSet<ClassSymbol> innerClasses = new LinkedHashSet<>();
98
99 Set<Symbol> loadableDescriptors = new HashSet<>();
100
101 /** The list of entries in the BootstrapMethods attribute. */
102 Map<BsmKey, Integer> bootstrapMethods = new LinkedHashMap<>();
103
104 public PoolWriter(Types types, Names names) {
105 this.types = types;
106 this.names = names;
107 this.signatureGen = new SharedSignatureGenerator();
108 this.pool = new WriteablePoolHelper();
109 }
110
111 /**
112 * Puts a class symbol into the pool and return its index.
113 */
114 int putClass(ClassSymbol csym) {
115 return putClass(csym.type);
116 }
117
118 /**
119 * Puts a type into the pool and return its index. The type could be either a class, a type variable
120 * or an array type.
219 * Puts a module entry into the pool and returns its index.
220 */
221 int putModule(ModuleSymbol mod) {
222 return pool.writeIfNeeded(mod);
223 }
224
225 /**
226 * Enter an inner class into the `innerClasses' set.
227 */
228 void enterInner(ClassSymbol c) {
229 if (c.type.isCompound()) {
230 throw new AssertionError("Unexpected intersection type: " + c.type);
231 }
232 c.complete();
233 if (c.owner.enclClass() != null && !innerClasses.contains(c)) {
234 enterInner(c.owner.enclClass());
235 innerClasses.add(c);
236 }
237 }
238
239 /** Enter a value class into the `loadableDescriptorsClasses' set.
240 */
241 void enterLoadableDescriptorsClass(Symbol c) {
242 if (c.type.isCompound()) {
243 throw new AssertionError("Unexpected intersection type: " + c.type);
244 }
245 c.complete();
246 loadableDescriptors.add(c);
247 }
248
249 /**
250 * Create a new Utf8 entry representing a descriptor for given (member) symbol.
251 */
252 private Type descriptorType(Symbol s) {
253 return s.kind == Kind.MTH ? s.externalType(types) : s.erasure(types);
254 }
255
256 private int makeBootstrapEntry(Dynamic dynamic) {
257 BsmKey bsmKey = dynamic.bsmKey(types);
258
259 // Figure out the index for existing BSM; create a new BSM if no key
260 Integer index = bootstrapMethods.get(bsmKey);
261 if (index == null) {
262 index = bootstrapMethods.size();
263 bootstrapMethods.put(bsmKey, index);
264 }
265
266 return index;
267 }
268
509 private Name typeSig(Type type) {
510 signatureGen.reset();
511 signatureGen.assembleSig(type);
512 return signatureGen.toName();
513 }
514
515 private Name classSig(Type t) {
516 signatureGen.reset();
517 List<Type> typarams = t.getTypeArguments();
518 if (typarams.nonEmpty()) {
519 signatureGen.assembleParamsSig(typarams);
520 }
521 signatureGen.assembleSig(types.supertype(t));
522 for (Type i : types.interfaces(t))
523 signatureGen.assembleSig(i);
524 return signatureGen.toName();
525 }
526
527 void reset() {
528 innerClasses.clear();
529 loadableDescriptors.clear();
530 bootstrapMethods.clear();
531 pool.reset();
532 }
533 }
|