1 /* 2 * Copyright (c) 2022, 2024, 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 package jdk.internal.classfile.impl; 26 27 import java.lang.classfile.Annotation; 28 import java.lang.classfile.Attribute; 29 import java.lang.classfile.AttributeMapper; 30 import java.lang.classfile.AttributedElement; 31 import java.lang.classfile.BufWriter; 32 import java.lang.classfile.ClassReader; 33 import java.lang.classfile.attribute.*; 34 import java.util.List; 35 36 import static java.lang.classfile.Attributes.*; 37 38 public sealed abstract class AbstractAttributeMapper<T extends Attribute<T>> 39 implements AttributeMapper<T> { 40 41 private final String name; 42 private final AttributeMapper.AttributeStability stability; 43 private final boolean allowMultiple; 44 45 protected abstract void writeBody(BufWriter buf, T attr); 46 47 public AbstractAttributeMapper(String name, AttributeMapper.AttributeStability stability) { 48 this(name, stability, false); 49 } 50 51 public AbstractAttributeMapper(String name, 52 AttributeMapper.AttributeStability stability, 53 boolean allowMultiple) { 54 this.name = name; 55 this.stability = stability; 56 this.allowMultiple = allowMultiple; 57 } 58 59 @Override 60 public final String name() { 61 return name; 62 } 63 64 @Override 65 public final void writeAttribute(BufWriter writer, T attr) { 66 BufWriterImpl buf = (BufWriterImpl) writer; 67 buf.writeIndex(buf.constantPool().utf8Entry(name)); 68 int lengthIndex = buf.skip(4); 69 writeBody(buf, attr); 70 int written = buf.size() - lengthIndex - 4; 71 buf.patchInt(lengthIndex, written); 72 } 73 74 @Override 75 public AttributeMapper.AttributeStability stability() { 76 return stability; 77 } 78 79 @Override 80 public boolean allowMultiple() { 81 return allowMultiple; 82 } 83 84 @Override 85 public String toString() { 86 return String.format("AttributeMapper[name=%s, allowMultiple=%b, stability=%s]", 87 name, allowMultiple, stability()); 88 } 89 90 public static final class AnnotationDefaultMapper extends AbstractAttributeMapper<AnnotationDefaultAttribute> { 91 public static final AnnotationDefaultMapper INSTANCE = new AnnotationDefaultMapper(); 92 93 private AnnotationDefaultMapper() { 94 super(NAME_ANNOTATION_DEFAULT, AttributeStability.CP_REFS); 95 } 96 97 @Override 98 public AnnotationDefaultAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 99 return new BoundAttribute.BoundAnnotationDefaultAttr(cf, this, p); 100 } 101 102 @Override 103 protected void writeBody(BufWriter buf, AnnotationDefaultAttribute attr) { 104 AnnotationReader.writeAnnotationValue((BufWriterImpl) buf, attr.defaultValue()); 105 } 106 } 107 108 public static final class BootstrapMethodsMapper extends AbstractAttributeMapper<BootstrapMethodsAttribute> { 109 public static final BootstrapMethodsMapper INSTANCE = new BootstrapMethodsMapper(); 110 111 private BootstrapMethodsMapper() { 112 super(NAME_BOOTSTRAP_METHODS, AttributeStability.CP_REFS); 113 } 114 115 @Override 116 public BootstrapMethodsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 117 return new BoundAttribute.BoundBootstrapMethodsAttribute(cf, this, p); 118 } 119 120 @Override 121 protected void writeBody(BufWriter buf, BootstrapMethodsAttribute attr) { 122 var b = (BufWriterImpl) buf; 123 b.writeU2(attr.bootstrapMethodsSize()); 124 for (var bsm : attr.bootstrapMethods()) { 125 ((BootstrapMethodEntryImpl) bsm).writeTo(b); 126 } 127 } 128 } 129 130 public static final class CharacterRangeTableMapper extends AbstractAttributeMapper<CharacterRangeTableAttribute> { 131 public static final CharacterRangeTableMapper INSTANCE = new CharacterRangeTableMapper(); 132 133 private CharacterRangeTableMapper() { 134 super(NAME_CHARACTER_RANGE_TABLE, AttributeStability.LABELS, true); 135 } 136 137 @Override 138 public CharacterRangeTableAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 139 return new BoundAttribute.BoundCharacterRangeTableAttribute(cf, this, p); 140 } 141 142 @Override 143 protected void writeBody(BufWriter bufWriter, CharacterRangeTableAttribute attr) { 144 List<CharacterRangeInfo> ranges = attr.characterRangeTable(); 145 BufWriterImpl buf = (BufWriterImpl) bufWriter; 146 buf.writeU2(ranges.size()); 147 for (CharacterRangeInfo info : ranges) { 148 buf.writeU2U2(info.startPc(), info.endPc()); 149 buf.writeIntInt(info.characterRangeStart(), info.characterRangeEnd()); 150 buf.writeU2(info.flags()); 151 } 152 } 153 } 154 155 public static final class CodeMapper extends AbstractAttributeMapper<CodeAttribute> { 156 public static final CodeMapper INSTANCE = new CodeMapper(); 157 158 private CodeMapper() { 159 super(NAME_CODE, AttributeStability.CP_REFS); 160 } 161 162 @Override 163 public CodeAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 164 return new CodeImpl(e, cf, this, p); 165 } 166 167 @Override 168 protected void writeBody(BufWriter buf, CodeAttribute attr) { 169 throw new UnsupportedOperationException("Code attribute does not support direct write"); 170 } 171 } 172 173 public static final class CompilationIDMapper extends AbstractAttributeMapper<CompilationIDAttribute> { 174 public static final CompilationIDMapper INSTANCE = new CompilationIDMapper(); 175 176 private CompilationIDMapper() { 177 super(NAME_COMPILATION_ID, AttributeStability.CP_REFS); 178 } 179 180 @Override 181 public CompilationIDAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 182 return new BoundAttribute.BoundCompilationIDAttribute(cf, this, p); 183 } 184 185 @Override 186 protected void writeBody(BufWriter buf, CompilationIDAttribute attr) { 187 buf.writeIndex(attr.compilationId()); 188 } 189 } 190 191 public static final class ConstantValueMapper extends AbstractAttributeMapper<ConstantValueAttribute> { 192 public static final ConstantValueMapper INSTANCE = new ConstantValueMapper(); 193 194 private ConstantValueMapper() { 195 super(NAME_CONSTANT_VALUE, AttributeStability.CP_REFS); 196 } 197 198 @Override 199 public ConstantValueAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 200 return new BoundAttribute.BoundConstantValueAttribute(cf, this, p); 201 } 202 203 @Override 204 protected void writeBody(BufWriter buf, ConstantValueAttribute attr) { 205 buf.writeIndex(attr.constant()); 206 } 207 } 208 209 public static final class DeprecatedMapper extends AbstractAttributeMapper<DeprecatedAttribute> { 210 public static final DeprecatedMapper INSTANCE = new DeprecatedMapper(); 211 212 private DeprecatedMapper() { 213 super(NAME_DEPRECATED, AttributeStability.STATELESS, true); 214 } 215 216 @Override 217 public DeprecatedAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 218 return new BoundAttribute.BoundDeprecatedAttribute(cf, this, p); 219 } 220 221 @Override 222 protected void writeBody(BufWriter buf, DeprecatedAttribute attr) { 223 // empty 224 } 225 } 226 227 public static final class EnclosingMethodMapper extends AbstractAttributeMapper<EnclosingMethodAttribute> { 228 public static final EnclosingMethodMapper INSTANCE = new EnclosingMethodMapper(); 229 230 private EnclosingMethodMapper() { 231 super(NAME_ENCLOSING_METHOD, AttributeStability.CP_REFS); 232 } 233 234 @Override 235 public EnclosingMethodAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 236 return new BoundAttribute.BoundEnclosingMethodAttribute(cf, this, p); 237 } 238 239 @Override 240 protected void writeBody(BufWriter bufWriter, EnclosingMethodAttribute attr) { 241 BufWriterImpl buf = (BufWriterImpl) bufWriter; 242 buf.writeU2U2(buf.cpIndex(attr.enclosingClass()), 243 buf.cpIndexOrZero(attr.enclosingMethod().orElse(null))); 244 } 245 } 246 247 public static final class ExceptionsMapper extends AbstractAttributeMapper<ExceptionsAttribute> { 248 public static final ExceptionsMapper INSTANCE = new ExceptionsMapper(); 249 250 private ExceptionsMapper() { 251 super(NAME_EXCEPTIONS, AttributeStability.CP_REFS); 252 } 253 254 @Override 255 public ExceptionsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 256 return new BoundAttribute.BoundExceptionsAttribute(cf, this, p); 257 } 258 259 @Override 260 protected void writeBody(BufWriter buf, ExceptionsAttribute attr) { 261 Util.writeListIndices(buf, attr.exceptions()); 262 } 263 } 264 265 public static final class InnerClassesMapper extends AbstractAttributeMapper<InnerClassesAttribute> { 266 public static final InnerClassesMapper INSTANCE = new InnerClassesMapper(); 267 268 private InnerClassesMapper() { 269 super(NAME_INNER_CLASSES, AttributeStability.CP_REFS); 270 } 271 272 @Override 273 public InnerClassesAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 274 return new BoundAttribute.BoundInnerClassesAttribute(cf, this, p); 275 } 276 277 @Override 278 protected void writeBody(BufWriter bufWriter, InnerClassesAttribute attr) { 279 List<InnerClassInfo> classes = attr.classes(); 280 BufWriterImpl buf = (BufWriterImpl) bufWriter; 281 buf.writeU2(classes.size()); 282 for (InnerClassInfo ic : classes) { 283 buf.writeU2U2U2(buf.cpIndex(ic.innerClass()), 284 buf.cpIndexOrZero(ic.outerClass().orElse(null)), 285 buf.cpIndexOrZero(ic.innerName().orElse(null))); 286 buf.writeU2(ic.flagsMask()); 287 } 288 } 289 } 290 291 public static final class LineNumberTableMapper extends AbstractAttributeMapper<LineNumberTableAttribute> { 292 public static final LineNumberTableMapper INSTANCE = new LineNumberTableMapper(); 293 294 private LineNumberTableMapper() { 295 super(NAME_LINE_NUMBER_TABLE, AttributeStability.LABELS, true); 296 } 297 298 @Override 299 public LineNumberTableAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 300 return new BoundAttribute.BoundLineNumberTableAttribute(cf, this, p); 301 } 302 303 @Override 304 protected void writeBody(BufWriter bufWriter, LineNumberTableAttribute attr) { 305 List<LineNumberInfo> lines = attr.lineNumbers(); 306 BufWriterImpl buf = (BufWriterImpl) bufWriter; 307 buf.writeU2(lines.size()); 308 for (LineNumberInfo line : lines) { 309 buf.writeU2U2(line.startPc(), line.lineNumber()); 310 } 311 } 312 } 313 314 public static final class LoadableDescriptorsMapper extends AbstractAttributeMapper<LoadableDescriptorsAttribute> { 315 public static final LoadableDescriptorsMapper INSTANCE = new LoadableDescriptorsMapper(); 316 317 private LoadableDescriptorsMapper() { 318 super(NAME_LOADABLE_DESCRIPTORS, AttributeStability.CP_REFS); 319 } 320 321 @Override 322 public LoadableDescriptorsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 323 return new BoundAttribute.BoundLoadableDescriptorsAttribute(cf, this, p); 324 } 325 326 @Override 327 protected void writeBody(BufWriter buf, LoadableDescriptorsAttribute attr) { 328 Util.writeListIndices(buf, attr.loadableDescriptors()); 329 } 330 } 331 332 public static final class LocalVariableTableMapper extends AbstractAttributeMapper<LocalVariableTableAttribute> { 333 public static final LocalVariableTableMapper INSTANCE = new LocalVariableTableMapper(); 334 335 private LocalVariableTableMapper() { 336 super(NAME_LOCAL_VARIABLE_TABLE, AttributeStability.LABELS, true); 337 } 338 339 @Override 340 public LocalVariableTableAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 341 return new BoundAttribute.BoundLocalVariableTableAttribute(e, cf, this, p); 342 } 343 344 @Override 345 protected void writeBody(BufWriter bufWriter, LocalVariableTableAttribute attr) { 346 List<LocalVariableInfo> infos = attr.localVariables(); 347 BufWriterImpl buf = (BufWriterImpl) bufWriter; 348 buf.writeU2(infos.size()); 349 for (LocalVariableInfo info : infos) { 350 buf.writeU2U2(info.startPc(), info.length()); 351 buf.writeU2U2U2(buf.cpIndex(info.name()), buf.cpIndex(info.type()), info.slot()); 352 } 353 } 354 } 355 356 public static final class LocalVariableTypeTableMapper extends AbstractAttributeMapper<LocalVariableTypeTableAttribute> { 357 public static final LocalVariableTypeTableMapper INSTANCE = new LocalVariableTypeTableMapper(); 358 359 private LocalVariableTypeTableMapper() { 360 super(NAME_LOCAL_VARIABLE_TYPE_TABLE, AttributeStability.LABELS, true); 361 } 362 363 @Override 364 public LocalVariableTypeTableAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 365 return new BoundAttribute.BoundLocalVariableTypeTableAttribute(e, cf, this, p); 366 } 367 368 @Override 369 protected void writeBody(BufWriter bufWriter, LocalVariableTypeTableAttribute attr) { 370 List<LocalVariableTypeInfo> infos = attr.localVariableTypes(); 371 BufWriterImpl buf = (BufWriterImpl) bufWriter; 372 buf.writeU2(infos.size()); 373 for (LocalVariableTypeInfo info : infos) { 374 buf.writeU2U2(info.startPc(), info.length()); 375 buf.writeU2U2U2(buf.cpIndex(info.name()), buf.cpIndex(info.signature()), info.slot()); 376 } 377 } 378 } 379 380 public static final class MethodParametersMapper extends AbstractAttributeMapper<MethodParametersAttribute> { 381 public static final MethodParametersMapper INSTANCE = new MethodParametersMapper(); 382 383 private MethodParametersMapper() { 384 super(NAME_METHOD_PARAMETERS, AttributeStability.CP_REFS); 385 } 386 387 @Override 388 public MethodParametersAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 389 return new BoundAttribute.BoundMethodParametersAttribute(cf, this, p); 390 } 391 392 @Override 393 protected void writeBody(BufWriter bufWriter, MethodParametersAttribute attr) { 394 List<MethodParameterInfo> parameters = attr.parameters(); 395 BufWriterImpl buf = (BufWriterImpl) bufWriter; 396 buf.writeU1(parameters.size()); 397 for (MethodParameterInfo info : parameters) { 398 buf.writeU2U2(buf.cpIndexOrZero(info.name().orElse(null)), 399 info.flagsMask()); 400 } 401 } 402 } 403 404 public static final class ModuleMapper extends AbstractAttributeMapper<ModuleAttribute> { 405 public static final ModuleMapper INSTANCE = new ModuleMapper(); 406 407 private ModuleMapper() { 408 super(NAME_MODULE, AttributeStability.CP_REFS); 409 } 410 411 @Override 412 public ModuleAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 413 return new BoundAttribute.BoundModuleAttribute(cf, this, p); 414 } 415 416 @Override 417 protected void writeBody(BufWriter bufWriter, ModuleAttribute attr) { 418 BufWriterImpl buf = (BufWriterImpl) bufWriter; 419 buf.writeU2U2U2(buf.cpIndex(attr.moduleName()), 420 attr.moduleFlagsMask(), 421 buf.cpIndexOrZero(attr.moduleVersion().orElse(null))); 422 buf.writeU2(attr.requires().size()); 423 for (ModuleRequireInfo require : attr.requires()) { 424 buf.writeU2U2U2(buf.cpIndex(require.requires()), 425 require.requiresFlagsMask(), 426 buf.cpIndexOrZero(require.requiresVersion().orElse(null))); 427 } 428 buf.writeU2(attr.exports().size()); 429 for (ModuleExportInfo export : attr.exports()) { 430 buf.writeU2U2(buf.cpIndex(export.exportedPackage()), 431 export.exportsFlagsMask()); 432 Util.writeListIndices(buf, export.exportsTo()); 433 } 434 buf.writeU2(attr.opens().size()); 435 for (ModuleOpenInfo open : attr.opens()) { 436 buf.writeU2U2(buf.cpIndex(open.openedPackage()), 437 open.opensFlagsMask()); 438 Util.writeListIndices(buf, open.opensTo()); 439 } 440 Util.writeListIndices(buf, attr.uses()); 441 buf.writeU2(attr.provides().size()); 442 for (ModuleProvideInfo provide : attr.provides()) { 443 buf.writeIndex(provide.provides()); 444 Util.writeListIndices(buf, provide.providesWith()); 445 } 446 } 447 } 448 449 public static final class ModuleHashesMapper extends AbstractAttributeMapper<ModuleHashesAttribute> { 450 public static final ModuleHashesMapper INSTANCE = new ModuleHashesMapper(); 451 452 private ModuleHashesMapper() { 453 super(NAME_MODULE_HASHES, AttributeStability.CP_REFS); 454 } 455 456 @Override 457 public ModuleHashesAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 458 return new BoundAttribute.BoundModuleHashesAttribute(cf, this, p); 459 } 460 461 @Override 462 protected void writeBody(BufWriter bufWriter, ModuleHashesAttribute attr) { 463 List<ModuleHashInfo> hashes = attr.hashes(); 464 BufWriterImpl buf = (BufWriterImpl) bufWriter; 465 buf.writeU2U2(buf.cpIndex(attr.algorithm()), hashes.size()); 466 for (ModuleHashInfo hash : hashes) { 467 buf.writeU2U2(buf.cpIndex(hash.moduleName()), 468 hash.hash().length); 469 buf.writeBytes(hash.hash()); 470 } 471 } 472 } 473 474 public static final class ModuleMainClassMapper extends AbstractAttributeMapper<ModuleMainClassAttribute> { 475 public static final ModuleMainClassMapper INSTANCE = new ModuleMainClassMapper(); 476 477 private ModuleMainClassMapper() { 478 super(NAME_MODULE_MAIN_CLASS, AttributeStability.CP_REFS); 479 } 480 481 @Override 482 public ModuleMainClassAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 483 return new BoundAttribute.BoundModuleMainClassAttribute(cf, this, p); 484 } 485 486 @Override 487 protected void writeBody(BufWriter buf, ModuleMainClassAttribute attr) { 488 buf.writeIndex(attr.mainClass()); 489 } 490 } 491 492 public static final class ModulePackagesMapper extends AbstractAttributeMapper<ModulePackagesAttribute> { 493 public static final ModulePackagesMapper INSTANCE = new ModulePackagesMapper(); 494 495 private ModulePackagesMapper() { 496 super(NAME_MODULE_PACKAGES, AttributeStability.CP_REFS); 497 } 498 499 @Override 500 public ModulePackagesAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 501 return new BoundAttribute.BoundModulePackagesAttribute(cf, this, p); 502 } 503 504 @Override 505 protected void writeBody(BufWriter buf, ModulePackagesAttribute attr) { 506 Util.writeListIndices(buf, attr.packages()); 507 } 508 } 509 510 public static final class ModuleResolutionMapper extends AbstractAttributeMapper<ModuleResolutionAttribute> { 511 public static final ModuleResolutionMapper INSTANCE = new ModuleResolutionMapper(); 512 513 private ModuleResolutionMapper() { 514 super(NAME_MODULE_RESOLUTION, AttributeStability.STATELESS); 515 } 516 517 @Override 518 public ModuleResolutionAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 519 return new BoundAttribute.BoundModuleResolutionAttribute(cf, this, p); 520 } 521 522 @Override 523 protected void writeBody(BufWriter buf, ModuleResolutionAttribute attr) { 524 buf.writeU2(attr.resolutionFlags()); 525 } 526 } 527 528 public static final class ModuleTargetMapper extends AbstractAttributeMapper<ModuleTargetAttribute> { 529 public static final ModuleTargetMapper INSTANCE = new ModuleTargetMapper(); 530 531 private ModuleTargetMapper() { 532 super(NAME_MODULE_TARGET, AttributeStability.CP_REFS); 533 } 534 535 @Override 536 public ModuleTargetAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 537 return new BoundAttribute.BoundModuleTargetAttribute(cf, this, p); 538 } 539 540 @Override 541 protected void writeBody(BufWriter buf, ModuleTargetAttribute attr) { 542 buf.writeIndex(attr.targetPlatform()); 543 } 544 } 545 546 public static final class NestHostMapper extends AbstractAttributeMapper<NestHostAttribute> { 547 public static final NestHostMapper INSTANCE = new NestHostMapper(); 548 549 private NestHostMapper() { 550 super(NAME_NEST_HOST, AttributeStability.CP_REFS); 551 } 552 553 @Override 554 public NestHostAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 555 return new BoundAttribute.BoundNestHostAttribute(cf, this, p); 556 } 557 558 @Override 559 protected void writeBody(BufWriter buf, NestHostAttribute attr) { 560 buf.writeIndex(attr.nestHost()); 561 } 562 } 563 564 public static final class NestMembersMapper extends AbstractAttributeMapper<NestMembersAttribute> { 565 public static final NestMembersMapper INSTANCE = new NestMembersMapper(); 566 567 private NestMembersMapper() { 568 super(NAME_NEST_MEMBERS, AttributeStability.CP_REFS); 569 } 570 571 @Override 572 public NestMembersAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 573 return new BoundAttribute.BoundNestMembersAttribute(cf, this, p); 574 } 575 576 @Override 577 protected void writeBody(BufWriter buf, NestMembersAttribute attr) { 578 Util.writeListIndices(buf, attr.nestMembers()); 579 } 580 } 581 582 public static final class PermittedSubclassesMapper extends AbstractAttributeMapper<PermittedSubclassesAttribute> { 583 public static final PermittedSubclassesMapper INSTANCE = new PermittedSubclassesMapper(); 584 585 private PermittedSubclassesMapper() { 586 super(NAME_PERMITTED_SUBCLASSES, AttributeStability.CP_REFS); 587 } 588 589 @Override 590 public PermittedSubclassesAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 591 return new BoundAttribute.BoundPermittedSubclassesAttribute(cf, this, p); 592 } 593 594 @Override 595 protected void writeBody(BufWriter buf, PermittedSubclassesAttribute attr) { 596 Util.writeListIndices(buf, attr.permittedSubclasses()); 597 } 598 } 599 600 public static final class RecordMapper extends AbstractAttributeMapper<RecordAttribute> { 601 public static final RecordMapper INSTANCE = new RecordMapper(); 602 603 private RecordMapper() { 604 super(NAME_RECORD, AttributeStability.CP_REFS); 605 } 606 607 @Override 608 public RecordAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 609 return new BoundAttribute.BoundRecordAttribute(cf, this, p); 610 } 611 612 @Override 613 protected void writeBody(BufWriter bufWriter, RecordAttribute attr) { 614 List<RecordComponentInfo> components = attr.components(); 615 BufWriterImpl buf = (BufWriterImpl) bufWriter; 616 buf.writeU2(components.size()); 617 for (RecordComponentInfo info : components) { 618 buf.writeU2U2(buf.cpIndex(info.name()), 619 buf.cpIndex(info.descriptor())); 620 Util.writeAttributes(buf, info.attributes()); 621 } 622 } 623 } 624 625 public static final class RuntimeInvisibleAnnotationsMapper extends AbstractAttributeMapper<RuntimeInvisibleAnnotationsAttribute> { 626 public static final RuntimeInvisibleAnnotationsMapper INSTANCE = new RuntimeInvisibleAnnotationsMapper(); 627 628 private RuntimeInvisibleAnnotationsMapper() { 629 super(NAME_RUNTIME_INVISIBLE_ANNOTATIONS, AttributeStability.CP_REFS); 630 } 631 632 @Override 633 public RuntimeInvisibleAnnotationsAttribute readAttribute(AttributedElement enclosing, ClassReader cf, int pos) { 634 return new BoundAttribute.BoundRuntimeInvisibleAnnotationsAttribute(cf, pos); 635 } 636 637 @Override 638 protected void writeBody(BufWriter buf, RuntimeInvisibleAnnotationsAttribute attr) { 639 AnnotationReader.writeAnnotations(buf, attr.annotations()); 640 } 641 } 642 643 public static final class RuntimeInvisibleParameterAnnotationsMapper extends AbstractAttributeMapper<RuntimeInvisibleParameterAnnotationsAttribute> { 644 public static final RuntimeInvisibleParameterAnnotationsMapper INSTANCE = new RuntimeInvisibleParameterAnnotationsMapper(); 645 646 private RuntimeInvisibleParameterAnnotationsMapper() { 647 super(NAME_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS, AttributeStability.CP_REFS); 648 } 649 650 @Override 651 public RuntimeInvisibleParameterAnnotationsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 652 return new BoundAttribute.BoundRuntimeInvisibleParameterAnnotationsAttribute(cf, this, p); 653 } 654 655 @Override 656 protected void writeBody(BufWriter buf, RuntimeInvisibleParameterAnnotationsAttribute attr) { 657 List<List<Annotation>> lists = attr.parameterAnnotations(); 658 buf.writeU1(lists.size()); 659 for (List<Annotation> list : lists) 660 AnnotationReader.writeAnnotations(buf, list); 661 } 662 } 663 664 public static final class RuntimeInvisibleTypeAnnotationsMapper extends AbstractAttributeMapper<RuntimeInvisibleTypeAnnotationsAttribute> { 665 public static final RuntimeInvisibleTypeAnnotationsMapper INSTANCE = new RuntimeInvisibleTypeAnnotationsMapper(); 666 667 private RuntimeInvisibleTypeAnnotationsMapper() { 668 super(NAME_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS, AttributeStability.UNSTABLE); 669 } 670 671 @Override 672 public RuntimeInvisibleTypeAnnotationsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 673 return new BoundAttribute.BoundRuntimeInvisibleTypeAnnotationsAttribute(e, cf, this, p); 674 } 675 676 @Override 677 protected void writeBody(BufWriter buf, RuntimeInvisibleTypeAnnotationsAttribute attr) { 678 AnnotationReader.writeTypeAnnotations(buf, attr.annotations()); 679 } 680 } 681 682 public static final class RuntimeVisibleAnnotationsMapper extends AbstractAttributeMapper<RuntimeVisibleAnnotationsAttribute> { 683 public static final RuntimeVisibleAnnotationsMapper INSTANCE = new RuntimeVisibleAnnotationsMapper(); 684 685 private RuntimeVisibleAnnotationsMapper() { 686 super(NAME_RUNTIME_VISIBLE_ANNOTATIONS, AttributeStability.CP_REFS); 687 } 688 689 @Override 690 public RuntimeVisibleAnnotationsAttribute readAttribute(AttributedElement enclosing, ClassReader cf, int pos) { 691 return new BoundAttribute.BoundRuntimeVisibleAnnotationsAttribute(cf, pos); 692 } 693 694 @Override 695 protected void writeBody(BufWriter buf, RuntimeVisibleAnnotationsAttribute attr) { 696 AnnotationReader.writeAnnotations(buf, attr.annotations()); 697 } 698 } 699 700 public static final class RuntimeVisibleParameterAnnotationsMapper extends AbstractAttributeMapper<RuntimeVisibleParameterAnnotationsAttribute> { 701 public static final RuntimeVisibleParameterAnnotationsMapper INSTANCE = new RuntimeVisibleParameterAnnotationsMapper(); 702 703 private RuntimeVisibleParameterAnnotationsMapper() { 704 super(NAME_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS, AttributeStability.CP_REFS); 705 } 706 707 @Override 708 public RuntimeVisibleParameterAnnotationsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 709 return new BoundAttribute.BoundRuntimeVisibleParameterAnnotationsAttribute(cf, this, p); 710 } 711 712 @Override 713 protected void writeBody(BufWriter buf, RuntimeVisibleParameterAnnotationsAttribute attr) { 714 List<List<Annotation>> lists = attr.parameterAnnotations(); 715 buf.writeU1(lists.size()); 716 for (List<Annotation> list : lists) 717 AnnotationReader.writeAnnotations(buf, list); 718 } 719 } 720 721 public static final class RuntimeVisibleTypeAnnotationsMapper extends AbstractAttributeMapper<RuntimeVisibleTypeAnnotationsAttribute> { 722 public static final RuntimeVisibleTypeAnnotationsMapper INSTANCE = new RuntimeVisibleTypeAnnotationsMapper(); 723 724 private RuntimeVisibleTypeAnnotationsMapper() { 725 super(NAME_RUNTIME_VISIBLE_TYPE_ANNOTATIONS, AttributeStability.UNSTABLE); 726 } 727 728 @Override 729 public RuntimeVisibleTypeAnnotationsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 730 return new BoundAttribute.BoundRuntimeVisibleTypeAnnotationsAttribute(e, cf, this, p); 731 } 732 733 @Override 734 protected void writeBody(BufWriter buf, RuntimeVisibleTypeAnnotationsAttribute attr) { 735 AnnotationReader.writeTypeAnnotations(buf, attr.annotations()); 736 } 737 } 738 739 public static final class SignatureMapper extends AbstractAttributeMapper<SignatureAttribute> { 740 public static final SignatureMapper INSTANCE = new SignatureMapper(); 741 742 private SignatureMapper() { 743 super(NAME_SIGNATURE, AttributeStability.CP_REFS); 744 } 745 746 @Override 747 public SignatureAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 748 return new BoundAttribute.BoundSignatureAttribute(cf, this, p); 749 } 750 751 @Override 752 protected void writeBody(BufWriter buf, SignatureAttribute attr) { 753 buf.writeIndex(attr.signature()); 754 } 755 } 756 757 public static final class SourceDebugExtensionMapper extends AbstractAttributeMapper<SourceDebugExtensionAttribute> { 758 public static final SourceDebugExtensionMapper INSTANCE = new SourceDebugExtensionMapper(); 759 760 private SourceDebugExtensionMapper() { 761 super(NAME_SOURCE_DEBUG_EXTENSION, AttributeStability.STATELESS); 762 } 763 764 @Override 765 public SourceDebugExtensionAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 766 return new BoundAttribute.BoundSourceDebugExtensionAttribute(cf, this, p); 767 } 768 769 @Override 770 protected void writeBody(BufWriter buf, SourceDebugExtensionAttribute attr) { 771 buf.writeBytes(attr.contents()); 772 } 773 } 774 775 public static final class SourceFileMapper extends AbstractAttributeMapper<SourceFileAttribute> { 776 public static final SourceFileMapper INSTANCE = new SourceFileMapper(); 777 778 private SourceFileMapper() { 779 super(NAME_SOURCE_FILE, AttributeStability.CP_REFS); 780 } 781 782 @Override 783 public SourceFileAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 784 return new BoundAttribute.BoundSourceFileAttribute(cf, this, p); 785 } 786 787 @Override 788 protected void writeBody(BufWriter buf, SourceFileAttribute attr) { 789 buf.writeIndex(attr.sourceFile()); 790 } 791 } 792 793 public static final class SourceIDMapper extends AbstractAttributeMapper<SourceIDAttribute> { 794 public static final SourceIDMapper INSTANCE = new SourceIDMapper(); 795 796 private SourceIDMapper() { 797 super(NAME_SOURCE_ID, AttributeStability.CP_REFS); 798 } 799 800 @Override 801 public SourceIDAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 802 return new BoundAttribute.BoundSourceIDAttribute(cf, this, p); 803 } 804 805 @Override 806 protected void writeBody(BufWriter buf, SourceIDAttribute attr) { 807 buf.writeIndex(attr.sourceId()); 808 } 809 } 810 811 public static final class StackMapTableMapper extends AbstractAttributeMapper<StackMapTableAttribute> { 812 public static final StackMapTableMapper INSTANCE = new StackMapTableMapper(); 813 814 private StackMapTableMapper() { 815 super(NAME_STACK_MAP_TABLE, AttributeStability.LABELS); 816 } 817 818 @Override 819 public StackMapTableAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 820 return new BoundAttribute.BoundStackMapTableAttribute((CodeImpl)e, cf, this, p); 821 } 822 823 @Override 824 protected void writeBody(BufWriter b, StackMapTableAttribute attr) { 825 StackMapDecoder.writeFrames(b, attr.entries()); 826 } 827 } 828 829 public static final class SyntheticMapper extends AbstractAttributeMapper<SyntheticAttribute> { 830 public static final SyntheticMapper INSTANCE = new SyntheticMapper(); 831 832 private SyntheticMapper() { 833 super(NAME_SYNTHETIC, AttributeStability.STATELESS, true); 834 } 835 836 @Override 837 public SyntheticAttribute readAttribute(AttributedElement e, ClassReader cf, int p) { 838 return new BoundAttribute.BoundSyntheticAttribute(cf, this, p); 839 } 840 841 @Override 842 protected void writeBody(BufWriter buf, SyntheticAttribute attr) { 843 // empty 844 } 845 } 846 }