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/classfile/ClassWriter.java
38899 views
1
2
/*
3
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
4
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5
*
6
* This code is free software; you can redistribute it and/or modify it
7
* under the terms of the GNU General Public License version 2 only, as
8
* published by the Free Software Foundation. Oracle designates this
9
* particular file as subject to the "Classpath" exception as provided
10
* by Oracle in the LICENSE file that accompanied this code.
11
*
12
* This code is distributed in the hope that it will be useful, but WITHOUT
13
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15
* version 2 for more details (a copy is included in the LICENSE file that
16
* accompanied this code).
17
*
18
* You should have received a copy of the GNU General Public License version
19
* 2 along with this work; if not, write to the Free Software Foundation,
20
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21
*
22
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23
* or visit www.oracle.com if you need additional information or have any
24
* questions.
25
*/
26
27
package com.sun.tools.classfile;
28
29
import java.io.ByteArrayOutputStream;
30
import java.io.DataOutputStream;
31
import java.io.File;
32
import java.io.FileOutputStream;
33
import java.io.IOException;
34
import java.io.OutputStream;
35
36
import static com.sun.tools.classfile.Annotation.*;
37
import static com.sun.tools.classfile.ConstantPool.*;
38
import static com.sun.tools.classfile.StackMapTable_attribute.*;
39
import static com.sun.tools.classfile.StackMapTable_attribute.verification_type_info.*;
40
41
/**
42
* Write a ClassFile data structure to a file or stream.
43
*
44
* <p><b>This is NOT part of any supported API.
45
* If you write code that depends on this, you do so at your own risk.
46
* This code and its internal interfaces are subject to change or
47
* deletion without notice.</b>
48
*/
49
public class ClassWriter {
50
public ClassWriter() {
51
attributeWriter = new AttributeWriter();
52
constantPoolWriter = new ConstantPoolWriter();
53
out = new ClassOutputStream();
54
}
55
56
/**
57
* Write a ClassFile data structure to a file.
58
*/
59
public void write(ClassFile classFile, File f) throws IOException {
60
FileOutputStream f_out = new FileOutputStream(f);
61
try {
62
write(classFile, f_out);
63
} finally {
64
f_out.close();
65
}
66
}
67
68
/**
69
* Write a ClassFile data structure to a stream.
70
*/
71
public void write(ClassFile classFile, OutputStream s) throws IOException {
72
this.classFile = classFile;
73
out.reset();
74
write();
75
out.writeTo(s);
76
}
77
78
protected void write() throws IOException {
79
writeHeader();
80
writeConstantPool();
81
writeAccessFlags(classFile.access_flags);
82
writeClassInfo();
83
writeFields();
84
writeMethods();
85
writeAttributes(classFile.attributes);
86
}
87
88
protected void writeHeader() {
89
out.writeInt(classFile.magic);
90
out.writeShort(classFile.minor_version);
91
out.writeShort(classFile.major_version);
92
}
93
94
protected void writeAccessFlags(AccessFlags flags) {
95
out.writeShort(flags.flags);
96
}
97
98
protected void writeAttributes(Attributes attributes) {
99
int size = attributes.size();
100
out.writeShort(size);
101
for (Attribute attr: attributes)
102
attributeWriter.write(attr, out);
103
}
104
105
protected void writeClassInfo() {
106
out.writeShort(classFile.this_class);
107
out.writeShort(classFile.super_class);
108
int[] interfaces = classFile.interfaces;
109
out.writeShort(interfaces.length);
110
for (int i: interfaces)
111
out.writeShort(i);
112
}
113
114
protected void writeDescriptor(Descriptor d) {
115
out.writeShort(d.index);
116
}
117
118
protected void writeConstantPool() {
119
ConstantPool pool = classFile.constant_pool;
120
int size = pool.size();
121
out.writeShort(size);
122
for (CPInfo cpInfo: pool.entries())
123
constantPoolWriter.write(cpInfo, out);
124
}
125
126
protected void writeFields() throws IOException {
127
Field[] fields = classFile.fields;
128
out.writeShort(fields.length);
129
for (Field f: fields)
130
writeField(f);
131
}
132
133
protected void writeField(Field f) throws IOException {
134
writeAccessFlags(f.access_flags);
135
out.writeShort(f.name_index);
136
writeDescriptor(f.descriptor);
137
writeAttributes(f.attributes);
138
}
139
140
protected void writeMethods() throws IOException {
141
Method[] methods = classFile.methods;
142
out.writeShort(methods.length);
143
for (Method m: methods) {
144
writeMethod(m);
145
}
146
}
147
148
protected void writeMethod(Method m) throws IOException {
149
writeAccessFlags(m.access_flags);
150
out.writeShort(m.name_index);
151
writeDescriptor(m.descriptor);
152
writeAttributes(m.attributes);
153
}
154
155
protected ClassFile classFile;
156
protected ClassOutputStream out;
157
protected AttributeWriter attributeWriter;
158
protected ConstantPoolWriter constantPoolWriter;
159
160
/**
161
* Subtype of ByteArrayOutputStream with the convenience methods of
162
* a DataOutputStream. Since ByteArrayOutputStream does not throw
163
* IOException, there are no exceptions from the additional
164
* convenience methods either,
165
*/
166
protected static class ClassOutputStream extends ByteArrayOutputStream {
167
public ClassOutputStream() {
168
d = new DataOutputStream(this);
169
}
170
171
public void writeByte(int value) {
172
try {
173
d.writeByte(value);
174
} catch (IOException ignore) {
175
}
176
}
177
178
public void writeShort(int value) {
179
try {
180
d.writeShort(value);
181
} catch (IOException ignore) {
182
}
183
}
184
185
public void writeInt(int value) {
186
try {
187
d.writeInt(value);
188
} catch (IOException ignore) {
189
}
190
}
191
192
public void writeLong(long value) {
193
try {
194
d.writeLong(value);
195
} catch (IOException ignore) {
196
}
197
}
198
199
public void writeFloat(float value) {
200
try {
201
d.writeFloat(value);
202
} catch (IOException ignore) {
203
}
204
}
205
206
public void writeDouble(double value) {
207
try {
208
d.writeDouble(value);
209
} catch (IOException ignore) {
210
}
211
}
212
213
public void writeUTF(String value) {
214
try {
215
d.writeUTF(value);
216
} catch (IOException ignore) {
217
}
218
}
219
220
public void writeTo(ClassOutputStream s) {
221
try {
222
super.writeTo(s);
223
} catch (IOException ignore) {
224
}
225
}
226
227
private DataOutputStream d;
228
}
229
230
/**
231
* Writer for the entries in the constant pool.
232
*/
233
protected static class ConstantPoolWriter
234
implements ConstantPool.Visitor<Integer,ClassOutputStream> {
235
protected int write(CPInfo info, ClassOutputStream out) {
236
out.writeByte(info.getTag());
237
return info.accept(this, out);
238
}
239
240
public Integer visitClass(CONSTANT_Class_info info, ClassOutputStream out) {
241
out.writeShort(info.name_index);
242
return 1;
243
}
244
245
public Integer visitDouble(CONSTANT_Double_info info, ClassOutputStream out) {
246
out.writeDouble(info.value);
247
return 2;
248
}
249
250
public Integer visitFieldref(CONSTANT_Fieldref_info info, ClassOutputStream out) {
251
writeRef(info, out);
252
return 1;
253
}
254
255
public Integer visitFloat(CONSTANT_Float_info info, ClassOutputStream out) {
256
out.writeFloat(info.value);
257
return 1;
258
}
259
260
public Integer visitInteger(CONSTANT_Integer_info info, ClassOutputStream out) {
261
out.writeInt(info.value);
262
return 1;
263
}
264
265
public Integer visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, ClassOutputStream out) {
266
writeRef(info, out);
267
return 1;
268
}
269
270
public Integer visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, ClassOutputStream out) {
271
out.writeShort(info.bootstrap_method_attr_index);
272
out.writeShort(info.name_and_type_index);
273
return 1;
274
}
275
276
public Integer visitLong(CONSTANT_Long_info info, ClassOutputStream out) {
277
out.writeLong(info.value);
278
return 2;
279
}
280
281
public Integer visitNameAndType(CONSTANT_NameAndType_info info, ClassOutputStream out) {
282
out.writeShort(info.name_index);
283
out.writeShort(info.type_index);
284
return 1;
285
}
286
287
public Integer visitMethodHandle(CONSTANT_MethodHandle_info info, ClassOutputStream out) {
288
out.writeByte(info.reference_kind.tag);
289
out.writeShort(info.reference_index);
290
return 1;
291
}
292
293
public Integer visitMethodType(CONSTANT_MethodType_info info, ClassOutputStream out) {
294
out.writeShort(info.descriptor_index);
295
return 1;
296
}
297
298
public Integer visitMethodref(CONSTANT_Methodref_info info, ClassOutputStream out) {
299
return writeRef(info, out);
300
}
301
302
public Integer visitString(CONSTANT_String_info info, ClassOutputStream out) {
303
out.writeShort(info.string_index);
304
return 1;
305
}
306
307
public Integer visitUtf8(CONSTANT_Utf8_info info, ClassOutputStream out) {
308
out.writeUTF(info.value);
309
return 1;
310
}
311
312
protected Integer writeRef(CPRefInfo info, ClassOutputStream out) {
313
out.writeShort(info.class_index);
314
out.writeShort(info.name_and_type_index);
315
return 1;
316
}
317
}
318
319
/**
320
* Writer for the different types of attribute.
321
*/
322
protected static class AttributeWriter implements Attribute.Visitor<Void,ClassOutputStream> {
323
public void write(Attributes attributes, ClassOutputStream out) {
324
int size = attributes.size();
325
out.writeShort(size);
326
for (Attribute a: attributes)
327
write(a, out);
328
}
329
330
// Note: due to the use of shared resources, this method is not reentrant.
331
public void write(Attribute attr, ClassOutputStream out) {
332
out.writeShort(attr.attribute_name_index);
333
sharedOut.reset();
334
attr.accept(this, sharedOut);
335
out.writeInt(sharedOut.size());
336
sharedOut.writeTo(out);
337
}
338
339
protected ClassOutputStream sharedOut = new ClassOutputStream();
340
protected AnnotationWriter annotationWriter = new AnnotationWriter();
341
342
public Void visitDefault(DefaultAttribute attr, ClassOutputStream out) {
343
out.write(attr.info, 0, attr.info.length);
344
return null;
345
}
346
347
public Void visitAnnotationDefault(AnnotationDefault_attribute attr, ClassOutputStream out) {
348
annotationWriter.write(attr.default_value, out);
349
return null;
350
}
351
352
public Void visitBootstrapMethods(BootstrapMethods_attribute attr, ClassOutputStream out) {
353
out.writeShort(attr.bootstrap_method_specifiers.length);
354
for (BootstrapMethods_attribute.BootstrapMethodSpecifier bsm : attr.bootstrap_method_specifiers) {
355
out.writeShort(bsm.bootstrap_method_ref);
356
int bsm_args_count = bsm.bootstrap_arguments.length;
357
out.writeShort(bsm_args_count);
358
for (int i : bsm.bootstrap_arguments) {
359
out.writeShort(i);
360
}
361
}
362
return null;
363
}
364
365
public Void visitCharacterRangeTable(CharacterRangeTable_attribute attr, ClassOutputStream out) {
366
out.writeShort(attr.character_range_table.length);
367
for (CharacterRangeTable_attribute.Entry e: attr.character_range_table)
368
writeCharacterRangeTableEntry(e, out);
369
return null;
370
}
371
372
protected void writeCharacterRangeTableEntry(CharacterRangeTable_attribute.Entry entry, ClassOutputStream out) {
373
out.writeShort(entry.start_pc);
374
out.writeShort(entry.end_pc);
375
out.writeInt(entry.character_range_start);
376
out.writeInt(entry.character_range_end);
377
out.writeShort(entry.flags);
378
}
379
380
public Void visitCode(Code_attribute attr, ClassOutputStream out) {
381
out.writeShort(attr.max_stack);
382
out.writeShort(attr.max_locals);
383
out.writeInt(attr.code.length);
384
out.write(attr.code, 0, attr.code.length);
385
out.writeShort(attr.exception_table.length);
386
for (Code_attribute.Exception_data e: attr.exception_table)
387
writeExceptionTableEntry(e, out);
388
new AttributeWriter().write(attr.attributes, out);
389
return null;
390
}
391
392
protected void writeExceptionTableEntry(Code_attribute.Exception_data exception_data, ClassOutputStream out) {
393
out.writeShort(exception_data.start_pc);
394
out.writeShort(exception_data.end_pc);
395
out.writeShort(exception_data.handler_pc);
396
out.writeShort(exception_data.catch_type);
397
}
398
399
public Void visitCompilationID(CompilationID_attribute attr, ClassOutputStream out) {
400
out.writeShort(attr.compilationID_index);
401
return null;
402
}
403
404
public Void visitConstantValue(ConstantValue_attribute attr, ClassOutputStream out) {
405
out.writeShort(attr.constantvalue_index);
406
return null;
407
}
408
409
public Void visitDeprecated(Deprecated_attribute attr, ClassOutputStream out) {
410
return null;
411
}
412
413
public Void visitEnclosingMethod(EnclosingMethod_attribute attr, ClassOutputStream out) {
414
out.writeShort(attr.class_index);
415
out.writeShort(attr.method_index);
416
return null;
417
}
418
419
public Void visitExceptions(Exceptions_attribute attr, ClassOutputStream out) {
420
out.writeShort(attr.exception_index_table.length);
421
for (int i: attr.exception_index_table)
422
out.writeShort(i);
423
return null;
424
}
425
426
public Void visitInnerClasses(InnerClasses_attribute attr, ClassOutputStream out) {
427
out.writeShort(attr.classes.length);
428
for (InnerClasses_attribute.Info info: attr.classes)
429
writeInnerClassesInfo(info, out);
430
return null;
431
}
432
433
protected void writeInnerClassesInfo(InnerClasses_attribute.Info info, ClassOutputStream out) {
434
out.writeShort(info.inner_class_info_index);
435
out.writeShort(info.outer_class_info_index);
436
out.writeShort(info.inner_name_index);
437
writeAccessFlags(info.inner_class_access_flags, out);
438
}
439
440
public Void visitLineNumberTable(LineNumberTable_attribute attr, ClassOutputStream out) {
441
out.writeShort(attr.line_number_table.length);
442
for (LineNumberTable_attribute.Entry e: attr.line_number_table)
443
writeLineNumberTableEntry(e, out);
444
return null;
445
}
446
447
protected void writeLineNumberTableEntry(LineNumberTable_attribute.Entry entry, ClassOutputStream out) {
448
out.writeShort(entry.start_pc);
449
out.writeShort(entry.line_number);
450
}
451
452
public Void visitLocalVariableTable(LocalVariableTable_attribute attr, ClassOutputStream out) {
453
out.writeShort(attr.local_variable_table.length);
454
for (LocalVariableTable_attribute.Entry e: attr.local_variable_table)
455
writeLocalVariableTableEntry(e, out);
456
return null;
457
}
458
459
protected void writeLocalVariableTableEntry(LocalVariableTable_attribute.Entry entry, ClassOutputStream out) {
460
out.writeShort(entry.start_pc);
461
out.writeShort(entry.length);
462
out.writeShort(entry.name_index);
463
out.writeShort(entry.descriptor_index);
464
out.writeShort(entry.index);
465
}
466
467
public Void visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr, ClassOutputStream out) {
468
out.writeShort(attr.local_variable_table.length);
469
for (LocalVariableTypeTable_attribute.Entry e: attr.local_variable_table)
470
writeLocalVariableTypeTableEntry(e, out);
471
return null;
472
}
473
474
protected void writeLocalVariableTypeTableEntry(LocalVariableTypeTable_attribute.Entry entry, ClassOutputStream out) {
475
out.writeShort(entry.start_pc);
476
out.writeShort(entry.length);
477
out.writeShort(entry.name_index);
478
out.writeShort(entry.signature_index);
479
out.writeShort(entry.index);
480
}
481
482
public Void visitMethodParameters(MethodParameters_attribute attr, ClassOutputStream out) {
483
out.writeByte(attr.method_parameter_table.length);
484
for (MethodParameters_attribute.Entry e : attr.method_parameter_table) {
485
out.writeShort(e.name_index);
486
out.writeShort(e.flags);
487
}
488
return null;
489
}
490
491
public Void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, ClassOutputStream out) {
492
annotationWriter.write(attr.annotations, out);
493
return null;
494
}
495
496
public Void visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, ClassOutputStream out) {
497
annotationWriter.write(attr.annotations, out);
498
return null;
499
}
500
501
public Void visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, ClassOutputStream out) {
502
annotationWriter.write(attr.annotations, out);
503
return null;
504
}
505
506
public Void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, ClassOutputStream out) {
507
annotationWriter.write(attr.annotations, out);
508
return null;
509
}
510
511
public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, ClassOutputStream out) {
512
out.writeByte(attr.parameter_annotations.length);
513
for (Annotation[] annos: attr.parameter_annotations)
514
annotationWriter.write(annos, out);
515
return null;
516
}
517
518
public Void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr, ClassOutputStream out) {
519
out.writeByte(attr.parameter_annotations.length);
520
for (Annotation[] annos: attr.parameter_annotations)
521
annotationWriter.write(annos, out);
522
return null;
523
}
524
525
public Void visitSignature(Signature_attribute attr, ClassOutputStream out) {
526
out.writeShort(attr.signature_index);
527
return null;
528
}
529
530
public Void visitSourceDebugExtension(SourceDebugExtension_attribute attr, ClassOutputStream out) {
531
out.write(attr.debug_extension, 0, attr.debug_extension.length);
532
return null;
533
}
534
535
public Void visitSourceFile(SourceFile_attribute attr, ClassOutputStream out) {
536
out.writeShort(attr.sourcefile_index);
537
return null;
538
}
539
540
public Void visitSourceID(SourceID_attribute attr, ClassOutputStream out) {
541
out.writeShort(attr.sourceID_index);
542
return null;
543
}
544
545
public Void visitStackMap(StackMap_attribute attr, ClassOutputStream out) {
546
if (stackMapWriter == null)
547
stackMapWriter = new StackMapTableWriter();
548
549
out.writeShort(attr.entries.length);
550
for (stack_map_frame f: attr.entries)
551
stackMapWriter.write(f, out);
552
return null;
553
}
554
555
public Void visitStackMapTable(StackMapTable_attribute attr, ClassOutputStream out) {
556
if (stackMapWriter == null)
557
stackMapWriter = new StackMapTableWriter();
558
559
out.writeShort(attr.entries.length);
560
for (stack_map_frame f: attr.entries)
561
stackMapWriter.write(f, out);
562
return null;
563
}
564
565
public Void visitSynthetic(Synthetic_attribute attr, ClassOutputStream out) {
566
return null;
567
}
568
569
protected void writeAccessFlags(AccessFlags flags, ClassOutputStream p) {
570
sharedOut.writeShort(flags.flags);
571
}
572
573
protected StackMapTableWriter stackMapWriter;
574
}
575
576
/**
577
* Writer for the frames of StackMap and StackMapTable attributes.
578
*/
579
protected static class StackMapTableWriter
580
implements stack_map_frame.Visitor<Void,ClassOutputStream> {
581
582
public void write(stack_map_frame frame, ClassOutputStream out) {
583
out.write(frame.frame_type);
584
frame.accept(this, out);
585
}
586
587
public Void visit_same_frame(same_frame frame, ClassOutputStream p) {
588
return null;
589
}
590
591
public Void visit_same_locals_1_stack_item_frame(same_locals_1_stack_item_frame frame, ClassOutputStream out) {
592
writeVerificationTypeInfo(frame.stack[0], out);
593
return null;
594
}
595
596
public Void visit_same_locals_1_stack_item_frame_extended(same_locals_1_stack_item_frame_extended frame, ClassOutputStream out) {
597
out.writeShort(frame.offset_delta);
598
writeVerificationTypeInfo(frame.stack[0], out);
599
return null;
600
}
601
602
public Void visit_chop_frame(chop_frame frame, ClassOutputStream out) {
603
out.writeShort(frame.offset_delta);
604
return null;
605
}
606
607
public Void visit_same_frame_extended(same_frame_extended frame, ClassOutputStream out) {
608
out.writeShort(frame.offset_delta);
609
return null;
610
}
611
612
public Void visit_append_frame(append_frame frame, ClassOutputStream out) {
613
out.writeShort(frame.offset_delta);
614
for (verification_type_info l: frame.locals)
615
writeVerificationTypeInfo(l, out);
616
return null;
617
}
618
619
public Void visit_full_frame(full_frame frame, ClassOutputStream out) {
620
out.writeShort(frame.offset_delta);
621
out.writeShort(frame.locals.length);
622
for (verification_type_info l: frame.locals)
623
writeVerificationTypeInfo(l, out);
624
out.writeShort(frame.stack.length);
625
for (verification_type_info s: frame.stack)
626
writeVerificationTypeInfo(s, out);
627
return null;
628
}
629
630
protected void writeVerificationTypeInfo(verification_type_info info,
631
ClassOutputStream out) {
632
out.write(info.tag);
633
switch (info.tag) {
634
case ITEM_Top:
635
case ITEM_Integer:
636
case ITEM_Float:
637
case ITEM_Long:
638
case ITEM_Double:
639
case ITEM_Null:
640
case ITEM_UninitializedThis:
641
break;
642
643
case ITEM_Object:
644
Object_variable_info o = (Object_variable_info) info;
645
out.writeShort(o.cpool_index);
646
break;
647
648
case ITEM_Uninitialized:
649
Uninitialized_variable_info u = (Uninitialized_variable_info) info;
650
out.writeShort(u.offset);
651
break;
652
653
default:
654
throw new Error();
655
}
656
}
657
}
658
659
/**
660
* Writer for annotations and the values they contain.
661
*/
662
protected static class AnnotationWriter
663
implements Annotation.element_value.Visitor<Void,ClassOutputStream> {
664
public void write(Annotation[] annos, ClassOutputStream out) {
665
out.writeShort(annos.length);
666
for (Annotation anno: annos)
667
write(anno, out);
668
}
669
670
public void write(TypeAnnotation[] annos, ClassOutputStream out) {
671
out.writeShort(annos.length);
672
for (TypeAnnotation anno: annos)
673
write(anno, out);
674
}
675
676
public void write(Annotation anno, ClassOutputStream out) {
677
out.writeShort(anno.type_index);
678
out.writeShort(anno.element_value_pairs.length);
679
for (element_value_pair p: anno.element_value_pairs)
680
write(p, out);
681
}
682
683
public void write(TypeAnnotation anno, ClassOutputStream out) {
684
write(anno.position, out);
685
write(anno.annotation, out);
686
}
687
688
public void write(element_value_pair pair, ClassOutputStream out) {
689
out.writeShort(pair.element_name_index);
690
write(pair.value, out);
691
}
692
693
public void write(element_value ev, ClassOutputStream out) {
694
out.writeByte(ev.tag);
695
ev.accept(this, out);
696
}
697
698
public Void visitPrimitive(Primitive_element_value ev, ClassOutputStream out) {
699
out.writeShort(ev.const_value_index);
700
return null;
701
}
702
703
public Void visitEnum(Enum_element_value ev, ClassOutputStream out) {
704
out.writeShort(ev.type_name_index);
705
out.writeShort(ev.const_name_index);
706
return null;
707
}
708
709
public Void visitClass(Class_element_value ev, ClassOutputStream out) {
710
out.writeShort(ev.class_info_index);
711
return null;
712
}
713
714
public Void visitAnnotation(Annotation_element_value ev, ClassOutputStream out) {
715
write(ev.annotation_value, out);
716
return null;
717
}
718
719
public Void visitArray(Array_element_value ev, ClassOutputStream out) {
720
out.writeShort(ev.num_values);
721
for (element_value v: ev.values)
722
write(v, out);
723
return null;
724
}
725
726
// TODO: Move this to TypeAnnotation to be closer with similar logic?
727
private void write(TypeAnnotation.Position p, ClassOutputStream out) {
728
out.writeByte(p.type.targetTypeValue());
729
switch (p.type) {
730
// instanceof
731
case INSTANCEOF:
732
// new expression
733
case NEW:
734
// constructor/method reference receiver
735
case CONSTRUCTOR_REFERENCE:
736
case METHOD_REFERENCE:
737
out.writeShort(p.offset);
738
break;
739
// local variable
740
case LOCAL_VARIABLE:
741
// resource variable
742
case RESOURCE_VARIABLE:
743
int table_length = p.lvarOffset.length;
744
out.writeShort(table_length);
745
for (int i = 0; i < table_length; ++i) {
746
out.writeShort(1); // for table length
747
out.writeShort(p.lvarOffset[i]);
748
out.writeShort(p.lvarLength[i]);
749
out.writeShort(p.lvarIndex[i]);
750
}
751
break;
752
// exception parameter
753
case EXCEPTION_PARAMETER:
754
out.writeShort(p.exception_index);
755
break;
756
// method receiver
757
case METHOD_RECEIVER:
758
// Do nothing
759
break;
760
// type parameters
761
case CLASS_TYPE_PARAMETER:
762
case METHOD_TYPE_PARAMETER:
763
out.writeByte(p.parameter_index);
764
break;
765
// type parameters bounds
766
case CLASS_TYPE_PARAMETER_BOUND:
767
case METHOD_TYPE_PARAMETER_BOUND:
768
out.writeByte(p.parameter_index);
769
out.writeByte(p.bound_index);
770
break;
771
// class extends or implements clause
772
case CLASS_EXTENDS:
773
out.writeShort(p.type_index);
774
break;
775
// throws
776
case THROWS:
777
out.writeShort(p.type_index);
778
break;
779
// method parameter
780
case METHOD_FORMAL_PARAMETER:
781
out.writeByte(p.parameter_index);
782
break;
783
// type cast
784
case CAST:
785
// method/constructor/reference type argument
786
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
787
case METHOD_INVOCATION_TYPE_ARGUMENT:
788
case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
789
case METHOD_REFERENCE_TYPE_ARGUMENT:
790
out.writeShort(p.offset);
791
out.writeByte(p.type_index);
792
break;
793
// We don't need to worry about these
794
case METHOD_RETURN:
795
case FIELD:
796
break;
797
case UNKNOWN:
798
throw new AssertionError("ClassWriter: UNKNOWN target type should never occur!");
799
default:
800
throw new AssertionError("ClassWriter: Unknown target type for position: " + p);
801
}
802
803
{ // Append location data for generics/arrays.
804
// TODO: check for overrun?
805
out.writeByte((byte)p.location.size());
806
for (int i : TypeAnnotation.Position.getBinaryFromTypePath(p.location))
807
out.writeByte((byte)i);
808
}
809
}
810
}
811
}
812
813