Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/langtools/src/share/classes/com/sun/tools/javap/ConstantWriter.java
38899 views
1
/*
2
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package com.sun.tools.javap;
27
28
import com.sun.tools.classfile.ClassFile;
29
import com.sun.tools.classfile.ConstantPool;
30
import com.sun.tools.classfile.ConstantPoolException;
31
32
import static com.sun.tools.classfile.ConstantPool.*;
33
34
/*
35
* Write a constant pool entry.
36
*
37
* <p><b>This is NOT part of any supported API.
38
* If you write code that depends on this, you do so at your own risk.
39
* This code and its internal interfaces are subject to change or
40
* deletion without notice.</b>
41
*/
42
public class ConstantWriter extends BasicWriter {
43
public static ConstantWriter instance(Context context) {
44
ConstantWriter instance = context.get(ConstantWriter.class);
45
if (instance == null)
46
instance = new ConstantWriter(context);
47
return instance;
48
}
49
50
protected ConstantWriter(Context context) {
51
super(context);
52
context.put(ConstantWriter.class, this);
53
classWriter = ClassWriter.instance(context);
54
options = Options.instance(context);
55
}
56
57
protected void writeConstantPool() {
58
ConstantPool constant_pool = classWriter.getClassFile().constant_pool;
59
writeConstantPool(constant_pool);
60
}
61
62
protected void writeConstantPool(ConstantPool constant_pool) {
63
ConstantPool.Visitor<Integer, Void> v = new ConstantPool.Visitor<Integer,Void>() {
64
public Integer visitClass(CONSTANT_Class_info info, Void p) {
65
print("#" + info.name_index);
66
tab();
67
println("// " + stringValue(info));
68
return 1;
69
}
70
71
public Integer visitDouble(CONSTANT_Double_info info, Void p) {
72
println(stringValue(info));
73
return 2;
74
}
75
76
public Integer visitFieldref(CONSTANT_Fieldref_info info, Void p) {
77
print("#" + info.class_index + ".#" + info.name_and_type_index);
78
tab();
79
println("// " + stringValue(info));
80
return 1;
81
}
82
83
public Integer visitFloat(CONSTANT_Float_info info, Void p) {
84
println(stringValue(info));
85
return 1;
86
}
87
88
public Integer visitInteger(CONSTANT_Integer_info info, Void p) {
89
println(stringValue(info));
90
return 1;
91
}
92
93
public Integer visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, Void p) {
94
print("#" + info.class_index + ".#" + info.name_and_type_index);
95
tab();
96
println("// " + stringValue(info));
97
return 1;
98
}
99
100
public Integer visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, Void p) {
101
print("#" + info.bootstrap_method_attr_index + ":#" + info.name_and_type_index);
102
tab();
103
println("// " + stringValue(info));
104
return 1;
105
}
106
107
public Integer visitLong(CONSTANT_Long_info info, Void p) {
108
println(stringValue(info));
109
return 2;
110
}
111
112
public Integer visitNameAndType(CONSTANT_NameAndType_info info, Void p) {
113
print("#" + info.name_index + ":#" + info.type_index);
114
tab();
115
println("// " + stringValue(info));
116
return 1;
117
}
118
119
public Integer visitMethodref(CONSTANT_Methodref_info info, Void p) {
120
print("#" + info.class_index + ".#" + info.name_and_type_index);
121
tab();
122
println("// " + stringValue(info));
123
return 1;
124
}
125
126
public Integer visitMethodHandle(CONSTANT_MethodHandle_info info, Void p) {
127
print("#" + info.reference_kind.tag + ":#" + info.reference_index);
128
tab();
129
println("// " + stringValue(info));
130
return 1;
131
}
132
133
public Integer visitMethodType(CONSTANT_MethodType_info info, Void p) {
134
print("#" + info.descriptor_index);
135
tab();
136
println("// " + stringValue(info));
137
return 1;
138
}
139
140
public Integer visitString(CONSTANT_String_info info, Void p) {
141
print("#" + info.string_index);
142
tab();
143
println("// " + stringValue(info));
144
return 1;
145
}
146
147
public Integer visitUtf8(CONSTANT_Utf8_info info, Void p) {
148
println(stringValue(info));
149
return 1;
150
}
151
152
};
153
println("Constant pool:");
154
indent(+1);
155
int width = String.valueOf(constant_pool.size()).length() + 1;
156
int cpx = 1;
157
while (cpx < constant_pool.size()) {
158
print(String.format("%" + width + "s", ("#" + cpx)));
159
try {
160
CPInfo cpInfo = constant_pool.get(cpx);
161
print(String.format(" = %-18s ", cpTagName(cpInfo)));
162
cpx += cpInfo.accept(v, null);
163
} catch (ConstantPool.InvalidIndex ex) {
164
// should not happen
165
}
166
}
167
indent(-1);
168
}
169
170
protected void write(int cpx) {
171
ClassFile classFile = classWriter.getClassFile();
172
if (cpx == 0) {
173
print("#0");
174
return;
175
}
176
177
CPInfo cpInfo;
178
try {
179
cpInfo = classFile.constant_pool.get(cpx);
180
} catch (ConstantPoolException e) {
181
print("#" + cpx);
182
return;
183
}
184
185
int tag = cpInfo.getTag();
186
switch (tag) {
187
case CONSTANT_Methodref:
188
case CONSTANT_InterfaceMethodref:
189
case CONSTANT_Fieldref:
190
// simplify references within this class
191
CPRefInfo ref = (CPRefInfo) cpInfo;
192
try {
193
if (ref.class_index == classFile.this_class)
194
cpInfo = classFile.constant_pool.get(ref.name_and_type_index);
195
} catch (ConstantPool.InvalidIndex e) {
196
// ignore, for now
197
}
198
}
199
print(tagName(tag) + " " + stringValue(cpInfo));
200
}
201
202
String cpTagName(CPInfo cpInfo) {
203
String n = cpInfo.getClass().getSimpleName();
204
return n.replace("CONSTANT_", "").replace("_info", "");
205
}
206
207
String tagName(int tag) {
208
switch (tag) {
209
case CONSTANT_Utf8:
210
return "Utf8";
211
case CONSTANT_Integer:
212
return "int";
213
case CONSTANT_Float:
214
return "float";
215
case CONSTANT_Long:
216
return "long";
217
case CONSTANT_Double:
218
return "double";
219
case CONSTANT_Class:
220
return "class";
221
case CONSTANT_String:
222
return "String";
223
case CONSTANT_Fieldref:
224
return "Field";
225
case CONSTANT_MethodHandle:
226
return "MethodHandle";
227
case CONSTANT_MethodType:
228
return "MethodType";
229
case CONSTANT_Methodref:
230
return "Method";
231
case CONSTANT_InterfaceMethodref:
232
return "InterfaceMethod";
233
case CONSTANT_InvokeDynamic:
234
return "InvokeDynamic";
235
case CONSTANT_NameAndType:
236
return "NameAndType";
237
default:
238
return "(unknown tag " + tag + ")";
239
}
240
}
241
242
String stringValue(int constant_pool_index) {
243
ClassFile classFile = classWriter.getClassFile();
244
try {
245
return stringValue(classFile.constant_pool.get(constant_pool_index));
246
} catch (ConstantPool.InvalidIndex e) {
247
return report(e);
248
}
249
}
250
251
String stringValue(CPInfo cpInfo) {
252
return stringValueVisitor.visit(cpInfo);
253
}
254
255
StringValueVisitor stringValueVisitor = new StringValueVisitor();
256
257
private class StringValueVisitor implements ConstantPool.Visitor<String, Void> {
258
public String visit(CPInfo info) {
259
return info.accept(this, null);
260
}
261
262
public String visitClass(CONSTANT_Class_info info, Void p) {
263
return getCheckedName(info);
264
}
265
266
String getCheckedName(CONSTANT_Class_info info) {
267
try {
268
return checkName(info.getName());
269
} catch (ConstantPoolException e) {
270
return report(e);
271
}
272
}
273
274
public String visitDouble(CONSTANT_Double_info info, Void p) {
275
return info.value + "d";
276
}
277
278
public String visitFieldref(CONSTANT_Fieldref_info info, Void p) {
279
return visitRef(info, p);
280
}
281
282
public String visitFloat(CONSTANT_Float_info info, Void p) {
283
return info.value + "f";
284
}
285
286
public String visitInteger(CONSTANT_Integer_info info, Void p) {
287
return String.valueOf(info.value);
288
}
289
290
public String visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, Void p) {
291
return visitRef(info, p);
292
}
293
294
public String visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, Void p) {
295
try {
296
String callee = stringValue(info.getNameAndTypeInfo());
297
return "#" + info.bootstrap_method_attr_index + ":" + callee;
298
} catch (ConstantPoolException e) {
299
return report(e);
300
}
301
}
302
303
public String visitLong(CONSTANT_Long_info info, Void p) {
304
return info.value + "l";
305
}
306
307
public String visitNameAndType(CONSTANT_NameAndType_info info, Void p) {
308
return getCheckedName(info) + ":" + getType(info);
309
}
310
311
String getCheckedName(CONSTANT_NameAndType_info info) {
312
try {
313
return checkName(info.getName());
314
} catch (ConstantPoolException e) {
315
return report(e);
316
}
317
}
318
319
String getType(CONSTANT_NameAndType_info info) {
320
try {
321
return info.getType();
322
} catch (ConstantPoolException e) {
323
return report(e);
324
}
325
}
326
327
public String visitMethodHandle(CONSTANT_MethodHandle_info info, Void p) {
328
try {
329
return info.reference_kind.name + " " + stringValue(info.getCPRefInfo());
330
} catch (ConstantPoolException e) {
331
return report(e);
332
}
333
}
334
335
public String visitMethodType(CONSTANT_MethodType_info info, Void p) {
336
try {
337
return info.getType();
338
} catch (ConstantPoolException e) {
339
return report(e);
340
}
341
}
342
343
public String visitMethodref(CONSTANT_Methodref_info info, Void p) {
344
return visitRef(info, p);
345
}
346
347
public String visitString(CONSTANT_String_info info, Void p) {
348
try {
349
ClassFile classFile = classWriter.getClassFile();
350
int string_index = info.string_index;
351
return stringValue(classFile.constant_pool.getUTF8Info(string_index));
352
} catch (ConstantPoolException e) {
353
return report(e);
354
}
355
}
356
357
public String visitUtf8(CONSTANT_Utf8_info info, Void p) {
358
String s = info.value;
359
StringBuilder sb = new StringBuilder();
360
for (int i = 0; i < s.length(); i++) {
361
char c = s.charAt(i);
362
switch (c) {
363
case '\t':
364
sb.append('\\').append('t');
365
break;
366
case '\n':
367
sb.append('\\').append('n');
368
break;
369
case '\r':
370
sb.append('\\').append('r');
371
break;
372
case '\"':
373
sb.append('\\').append('\"');
374
break;
375
default:
376
sb.append(c);
377
}
378
}
379
return sb.toString();
380
}
381
382
String visitRef(CPRefInfo info, Void p) {
383
String cn = getCheckedClassName(info);
384
String nat;
385
try {
386
nat = stringValue(info.getNameAndTypeInfo());
387
} catch (ConstantPoolException e) {
388
nat = report(e);
389
}
390
return cn + "." + nat;
391
}
392
393
String getCheckedClassName(CPRefInfo info) {
394
try {
395
return checkName(info.getClassName());
396
} catch (ConstantPoolException e) {
397
return report(e);
398
}
399
}
400
}
401
402
/* If name is a valid binary name, return it; otherwise quote it. */
403
private static String checkName(String name) {
404
if (name == null)
405
return "null";
406
407
int len = name.length();
408
if (len == 0)
409
return "\"\"";
410
411
int cc = '/';
412
int cp;
413
for (int k = 0; k < len; k += Character.charCount(cp)) {
414
cp = name.codePointAt(k);
415
if ((cc == '/' && !Character.isJavaIdentifierStart(cp))
416
|| (cp != '/' && !Character.isJavaIdentifierPart(cp))) {
417
return "\"" + addEscapes(name) + "\"";
418
}
419
cc = cp;
420
}
421
422
return name;
423
}
424
425
/* If name requires escapes, put them in, so it can be a string body. */
426
private static String addEscapes(String name) {
427
String esc = "\\\"\n\t";
428
String rep = "\\\"nt";
429
StringBuilder buf = null;
430
int nextk = 0;
431
int len = name.length();
432
for (int k = 0; k < len; k++) {
433
char cp = name.charAt(k);
434
int n = esc.indexOf(cp);
435
if (n >= 0) {
436
if (buf == null)
437
buf = new StringBuilder(len * 2);
438
if (nextk < k)
439
buf.append(name, nextk, k);
440
buf.append('\\');
441
buf.append(rep.charAt(n));
442
nextk = k+1;
443
}
444
}
445
if (buf == null)
446
return name;
447
if (nextk < len)
448
buf.append(name, nextk, len);
449
return buf.toString();
450
}
451
452
private ClassWriter classWriter;
453
private Options options;
454
}
455
456