AttributeWriter.java revision 3792:d516975e8110
133965Sjdp/* 233965Sjdp * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. 3218822Sdim * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 433965Sjdp * 5218822Sdim * This code is free software; you can redistribute it and/or modify it 633965Sjdp * under the terms of the GNU General Public License version 2 only, as 733965Sjdp * published by the Free Software Foundation. Oracle designates this 8218822Sdim * particular file as subject to the "Classpath" exception as provided 9218822Sdim * by Oracle in the LICENSE file that accompanied this code. 10218822Sdim * 1133965Sjdp * This code is distributed in the hope that it will be useful, but WITHOUT 12218822Sdim * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13218822Sdim * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14218822Sdim * version 2 for more details (a copy is included in the LICENSE file that 15218822Sdim * accompanied this code). 16218822Sdim * 17218822Sdim * You should have received a copy of the GNU General Public License version 18218822Sdim * 2 along with this work; if not, write to the Free Software Foundation, 19218822Sdim * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20218822Sdim * 21218822Sdim * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22218822Sdim * or visit www.oracle.com if you need additional information or have any 23218822Sdim * questions. 24218822Sdim */ 25218822Sdim 26218822Sdimpackage com.sun.tools.javap; 27218822Sdim 28218822Sdimimport com.sun.tools.classfile.AccessFlags; 29218822Sdimimport com.sun.tools.classfile.AnnotationDefault_attribute; 30218822Sdimimport com.sun.tools.classfile.Attribute; 31218822Sdimimport com.sun.tools.classfile.Attributes; 32218822Sdimimport com.sun.tools.classfile.BootstrapMethods_attribute; 33218822Sdimimport com.sun.tools.classfile.CharacterRangeTable_attribute; 34218822Sdimimport com.sun.tools.classfile.CharacterRangeTable_attribute.Entry; 35218822Sdimimport com.sun.tools.classfile.Code_attribute; 36218822Sdimimport com.sun.tools.classfile.CompilationID_attribute; 37218822Sdimimport com.sun.tools.classfile.ConstantPool; 38218822Sdimimport com.sun.tools.classfile.ConstantPoolException; 39218822Sdimimport com.sun.tools.classfile.ConstantValue_attribute; 40218822Sdimimport com.sun.tools.classfile.DefaultAttribute; 41218822Sdimimport com.sun.tools.classfile.Deprecated_attribute; 42218822Sdimimport com.sun.tools.classfile.EnclosingMethod_attribute; 43218822Sdimimport com.sun.tools.classfile.Exceptions_attribute; 44218822Sdimimport com.sun.tools.classfile.InnerClasses_attribute; 45218822Sdimimport com.sun.tools.classfile.InnerClasses_attribute.Info; 46218822Sdimimport com.sun.tools.classfile.LineNumberTable_attribute; 47218822Sdimimport com.sun.tools.classfile.LocalVariableTable_attribute; 48218822Sdimimport com.sun.tools.classfile.LocalVariableTypeTable_attribute; 49218822Sdimimport com.sun.tools.classfile.MethodParameters_attribute; 50218822Sdimimport com.sun.tools.classfile.Module_attribute; 51218822Sdimimport com.sun.tools.classfile.ModuleHashes_attribute; 52218822Sdimimport com.sun.tools.classfile.ModuleMainClass_attribute; 53218822Sdimimport com.sun.tools.classfile.ModulePackages_attribute; 54218822Sdimimport com.sun.tools.classfile.ModuleTarget_attribute; 55218822Sdimimport com.sun.tools.classfile.ModuleVersion_attribute; 56218822Sdimimport com.sun.tools.classfile.RuntimeInvisibleAnnotations_attribute; 57218822Sdimimport com.sun.tools.classfile.RuntimeInvisibleParameterAnnotations_attribute; 58218822Sdimimport com.sun.tools.classfile.RuntimeInvisibleTypeAnnotations_attribute; 59218822Sdimimport com.sun.tools.classfile.RuntimeVisibleAnnotations_attribute; 60218822Sdimimport com.sun.tools.classfile.RuntimeVisibleParameterAnnotations_attribute; 61218822Sdimimport com.sun.tools.classfile.RuntimeVisibleTypeAnnotations_attribute; 62218822Sdimimport com.sun.tools.classfile.Signature_attribute; 63218822Sdimimport com.sun.tools.classfile.SourceDebugExtension_attribute; 64218822Sdimimport com.sun.tools.classfile.SourceFile_attribute; 65218822Sdimimport com.sun.tools.classfile.SourceID_attribute; 66218822Sdimimport com.sun.tools.classfile.StackMapTable_attribute; 67218822Sdimimport com.sun.tools.classfile.StackMap_attribute; 68218822Sdimimport com.sun.tools.classfile.Synthetic_attribute; 69218822Sdim 70218822Sdimimport static com.sun.tools.classfile.AccessFlags.*; 71218822Sdim 72218822Sdimimport com.sun.tools.javac.util.Assert; 73218822Sdimimport com.sun.tools.javac.util.StringUtils; 74218822Sdim 75218822Sdim/* 76218822Sdim * A writer for writing Attributes as text. 77218822Sdim * 78218822Sdim * <p><b>This is NOT part of any supported API. 79218822Sdim * If you write code that depends on this, you do so at your own risk. 80218822Sdim * This code and its internal interfaces are subject to change or 81218822Sdim * deletion without notice.</b> 82218822Sdim */ 83218822Sdimpublic class AttributeWriter extends BasicWriter 84218822Sdim implements Attribute.Visitor<Void,Void> 85218822Sdim{ 86218822Sdim public static AttributeWriter instance(Context context) { 87218822Sdim AttributeWriter instance = context.get(AttributeWriter.class); 88218822Sdim if (instance == null) 89218822Sdim instance = new AttributeWriter(context); 90218822Sdim return instance; 91218822Sdim } 92218822Sdim 93218822Sdim protected AttributeWriter(Context context) { 94218822Sdim super(context); 95218822Sdim context.put(AttributeWriter.class, this); 96218822Sdim annotationWriter = AnnotationWriter.instance(context); 97218822Sdim codeWriter = CodeWriter.instance(context); 98218822Sdim constantWriter = ConstantWriter.instance(context); 99218822Sdim options = Options.instance(context); 100218822Sdim } 101218822Sdim 102218822Sdim public void write(Object owner, Attribute attr, ConstantPool constant_pool) { 103218822Sdim if (attr != null) { 104218822Sdim Assert.checkNonNull(constant_pool); 105218822Sdim Assert.checkNonNull(owner); 106218822Sdim this.constant_pool = constant_pool; 107218822Sdim this.owner = owner; 108218822Sdim attr.accept(this, null); 109218822Sdim } 110218822Sdim } 111218822Sdim 112218822Sdim public void write(Object owner, Attributes attrs, ConstantPool constant_pool) { 113218822Sdim if (attrs != null) { 114218822Sdim Assert.checkNonNull(constant_pool); 115218822Sdim Assert.checkNonNull(owner); 116218822Sdim this.constant_pool = constant_pool; 117218822Sdim this.owner = owner; 118218822Sdim for (Attribute attr: attrs) 119218822Sdim attr.accept(this, null); 120218822Sdim } 121218822Sdim } 122218822Sdim 123218822Sdim @Override 124218822Sdim public Void visitDefault(DefaultAttribute attr, Void ignore) { 125218822Sdim if (attr.reason != null) { 126218822Sdim report(attr.reason); 127218822Sdim } 128218822Sdim byte[] data = attr.info; 129218822Sdim int i = 0; 130218822Sdim int j = 0; 131218822Sdim print(" "); 132218822Sdim try { 133218822Sdim print(attr.getName(constant_pool)); 134218822Sdim } catch (ConstantPoolException e) { 135218822Sdim report(e); 136218822Sdim print("attribute name = #" + attr.attribute_name_index); 137218822Sdim } 138218822Sdim print(": "); 139218822Sdim println("length = 0x" + toHex(attr.info.length)); 140218822Sdim 141218822Sdim print(" "); 142218822Sdim 143218822Sdim while (i < data.length) { 144218822Sdim print(toHex(data[i], 2)); 145218822Sdim 146218822Sdim j++; 147218822Sdim if (j == 16) { 148218822Sdim println(); 149218822Sdim print(" "); 150218822Sdim j = 0; 151218822Sdim } else { 152218822Sdim print(" "); 153218822Sdim } 154218822Sdim i++; 155218822Sdim } 156218822Sdim println(); 157218822Sdim return null; 158218822Sdim } 159218822Sdim 160218822Sdim @Override 161218822Sdim public Void visitAnnotationDefault(AnnotationDefault_attribute attr, Void ignore) { 162218822Sdim println("AnnotationDefault:"); 163218822Sdim indent(+1); 164218822Sdim print("default_value: "); 165218822Sdim annotationWriter.write(attr.default_value); 166218822Sdim indent(-1); 167218822Sdim return null; 168218822Sdim } 169218822Sdim 170218822Sdim @Override 171218822Sdim public Void visitBootstrapMethods(BootstrapMethods_attribute attr, Void p) { 172218822Sdim println(Attribute.BootstrapMethods + ":"); 173218822Sdim for (int i = 0; i < attr.bootstrap_method_specifiers.length ; i++) { 174218822Sdim BootstrapMethods_attribute.BootstrapMethodSpecifier bsm = attr.bootstrap_method_specifiers[i]; 175218822Sdim indent(+1); 176218822Sdim print(i + ": #" + bsm.bootstrap_method_ref + " "); 177218822Sdim println(constantWriter.stringValue(bsm.bootstrap_method_ref)); 178218822Sdim indent(+1); 179218822Sdim println("Method arguments:"); 180218822Sdim indent(+1); 181218822Sdim for (int j = 0; j < bsm.bootstrap_arguments.length; j++) { 182218822Sdim print("#" + bsm.bootstrap_arguments[j] + " "); 183218822Sdim println(constantWriter.stringValue(bsm.bootstrap_arguments[j])); 184218822Sdim } 185218822Sdim indent(-3); 186218822Sdim } 187218822Sdim return null; 188218822Sdim } 189218822Sdim 190218822Sdim @Override 191218822Sdim public Void visitCharacterRangeTable(CharacterRangeTable_attribute attr, Void ignore) { 192218822Sdim println("CharacterRangeTable:"); 193218822Sdim indent(+1); 194218822Sdim for (Entry e : attr.character_range_table) { 195218822Sdim print(String.format(" %2d, %2d, %6x, %6x, %4x", 196218822Sdim e.start_pc, e.end_pc, 197218822Sdim e.character_range_start, e.character_range_end, 198218822Sdim e.flags)); 199218822Sdim tab(); 200218822Sdim print(String.format("// %2d, %2d, %4d:%02d, %4d:%02d", 201218822Sdim e.start_pc, e.end_pc, 202218822Sdim (e.character_range_start >> 10), (e.character_range_start & 0x3ff), 203218822Sdim (e.character_range_end >> 10), (e.character_range_end & 0x3ff))); 204218822Sdim if ((e.flags & CharacterRangeTable_attribute.CRT_STATEMENT) != 0) 205218822Sdim print(", statement"); 206218822Sdim if ((e.flags & CharacterRangeTable_attribute.CRT_BLOCK) != 0) 207218822Sdim print(", block"); 208218822Sdim if ((e.flags & CharacterRangeTable_attribute.CRT_ASSIGNMENT) != 0) 209218822Sdim print(", assignment"); 210218822Sdim if ((e.flags & CharacterRangeTable_attribute.CRT_FLOW_CONTROLLER) != 0) 211218822Sdim print(", flow-controller"); 212218822Sdim if ((e.flags & CharacterRangeTable_attribute.CRT_FLOW_TARGET) != 0) 213218822Sdim print(", flow-target"); 214218822Sdim if ((e.flags & CharacterRangeTable_attribute.CRT_INVOKE) != 0) 215218822Sdim print(", invoke"); 216218822Sdim if ((e.flags & CharacterRangeTable_attribute.CRT_CREATE) != 0) 217218822Sdim print(", create"); 218218822Sdim if ((e.flags & CharacterRangeTable_attribute.CRT_BRANCH_TRUE) != 0) 219218822Sdim print(", branch-true"); 220218822Sdim if ((e.flags & CharacterRangeTable_attribute.CRT_BRANCH_FALSE) != 0) 221218822Sdim print(", branch-false"); 222218822Sdim println(); 223218822Sdim } 224218822Sdim indent(-1); 225218822Sdim return null; 226218822Sdim } 227218822Sdim 228218822Sdim @Override 229218822Sdim public Void visitCode(Code_attribute attr, Void ignore) { 230218822Sdim codeWriter.write(attr, constant_pool); 231218822Sdim return null; 232218822Sdim } 233218822Sdim 234218822Sdim @Override 235218822Sdim public Void visitCompilationID(CompilationID_attribute attr, Void ignore) { 236218822Sdim constantWriter.write(attr.compilationID_index); 237218822Sdim return null; 238218822Sdim } 239218822Sdim 240218822Sdim private String getJavaPackage(ModulePackages_attribute attr, int index) { 241218822Sdim try { 242218822Sdim return getJavaName(attr.getPackage(index, constant_pool)); 243218822Sdim } catch (ConstantPoolException e) { 244218822Sdim return report(e); 245218822Sdim } 246218822Sdim } 247218822Sdim 248218822Sdim @Override 249218822Sdim public Void visitModulePackages(ModulePackages_attribute attr, Void ignore) { 250218822Sdim println("ModulePackages: "); 251218822Sdim indent(+1); 252218822Sdim for (int i = 0; i < attr.packages_count; i++) { 253218822Sdim print("#" + attr.packages_index[i]); 254218822Sdim tab(); 255218822Sdim println("// " + getJavaPackage(attr, i)); 256218822Sdim } 257218822Sdim indent(-1); 258218822Sdim return null; 259218822Sdim } 260218822Sdim 261218822Sdim @Override 262218822Sdim public Void visitConstantValue(ConstantValue_attribute attr, Void ignore) { 263218822Sdim print("ConstantValue: "); 264218822Sdim constantWriter.write(attr.constantvalue_index); 265218822Sdim println(); 266218822Sdim return null; 267218822Sdim } 268218822Sdim 269218822Sdim @Override 270218822Sdim public Void visitDeprecated(Deprecated_attribute attr, Void ignore) { 271218822Sdim println("Deprecated: true"); 272218822Sdim return null; 273218822Sdim } 274218822Sdim 275218822Sdim @Override 276218822Sdim public Void visitEnclosingMethod(EnclosingMethod_attribute attr, Void ignore) { 277218822Sdim print("EnclosingMethod: #" + attr.class_index + ".#" + attr.method_index); 278218822Sdim tab(); 279218822Sdim print("// " + getJavaClassName(attr)); 280218822Sdim if (attr.method_index != 0) 281218822Sdim print("." + getMethodName(attr)); 282218822Sdim println(); 283218822Sdim return null; 284218822Sdim } 285218822Sdim 286218822Sdim private String getJavaClassName(EnclosingMethod_attribute a) { 287218822Sdim try { 288218822Sdim return getJavaName(a.getClassName(constant_pool)); 289218822Sdim } catch (ConstantPoolException e) { 290218822Sdim return report(e); 291218822Sdim } 292218822Sdim } 293218822Sdim 294218822Sdim private String getMethodName(EnclosingMethod_attribute a) { 295218822Sdim try { 296218822Sdim return a.getMethodName(constant_pool); 297218822Sdim } catch (ConstantPoolException e) { 298218822Sdim return report(e); 299218822Sdim } 300218822Sdim } 301218822Sdim 302218822Sdim @Override 303218822Sdim public Void visitExceptions(Exceptions_attribute attr, Void ignore) { 304218822Sdim println("Exceptions:"); 305218822Sdim indent(+1); 306218822Sdim print("throws "); 307218822Sdim for (int i = 0; i < attr.number_of_exceptions; i++) { 308218822Sdim if (i > 0) 309218822Sdim print(", "); 310218822Sdim print(getJavaException(attr, i)); 311218822Sdim } 312218822Sdim println(); 313218822Sdim indent(-1); 314218822Sdim return null; 315218822Sdim } 316218822Sdim 317218822Sdim private String getJavaException(Exceptions_attribute attr, int index) { 318218822Sdim try { 319218822Sdim return getJavaName(attr.getException(index, constant_pool)); 320218822Sdim } catch (ConstantPoolException e) { 321218822Sdim return report(e); 322218822Sdim } 323218822Sdim } 324218822Sdim 325218822Sdim @Override 326218822Sdim public Void visitModuleHashes(ModuleHashes_attribute attr, Void ignore) { 327218822Sdim println("ModuleHashes:"); 328218822Sdim indent(+1); 329218822Sdim print("algorithm #" + attr.algorithm_index); 330218822Sdim tab(); 331218822Sdim println("// " + getAlgorithm(attr)); 332218822Sdim for (ModuleHashes_attribute.Entry e : attr.hashes_table) { 333218822Sdim print("#" + e.module_name_index); 334218822Sdim tab(); 335218822Sdim println("// " + getModuleName(e)); 336218822Sdim println("hash_length: " + e.hash.length); 337218822Sdim println("hash: [" + toHex(e.hash) + "]"); 338218822Sdim } 339218822Sdim indent(-1); 340218822Sdim return null; 341218822Sdim } 342218822Sdim 343218822Sdim private String getAlgorithm(ModuleHashes_attribute attr) { 344218822Sdim try { 345218822Sdim return constant_pool.getUTF8Value(attr.algorithm_index); 346218822Sdim } catch (ConstantPoolException e) { 347218822Sdim return report(e); 348218822Sdim } 349218822Sdim } 350218822Sdim 351218822Sdim private String getModuleName(ModuleHashes_attribute.Entry entry) { 352218822Sdim try { 353218822Sdim return constant_pool.getUTF8Value(entry.module_name_index); 354218822Sdim } catch (ConstantPoolException e) { 355218822Sdim return report(e); 356218822Sdim } 357218822Sdim } 358218822Sdim 359218822Sdim @Override 360218822Sdim public Void visitInnerClasses(InnerClasses_attribute attr, Void ignore) { 361218822Sdim boolean first = true; 362218822Sdim for (Info info : attr.classes) { 363218822Sdim //access 364218822Sdim AccessFlags access_flags = info.inner_class_access_flags; 365218822Sdim if (options.checkAccess(access_flags)) { 366218822Sdim if (first) { 367218822Sdim writeInnerClassHeader(); 368218822Sdim first = false; 369218822Sdim } 370218822Sdim for (String name: access_flags.getInnerClassModifiers()) 371218822Sdim print(name + " "); 372218822Sdim if (info.inner_name_index != 0) { 373218822Sdim print("#" + info.inner_name_index + "= "); 374218822Sdim } 375218822Sdim print("#" + info.inner_class_info_index); 376218822Sdim if (info.outer_class_info_index != 0) { 377218822Sdim print(" of #" + info.outer_class_info_index); 378218822Sdim } 379218822Sdim print(";"); 380218822Sdim tab(); 381218822Sdim print("// "); 382218822Sdim if (info.inner_name_index != 0) { 383218822Sdim print(getInnerName(constant_pool, info) + "="); 384218822Sdim } 385218822Sdim constantWriter.write(info.inner_class_info_index); 386218822Sdim if (info.outer_class_info_index != 0) { 387218822Sdim print(" of "); 388218822Sdim constantWriter.write(info.outer_class_info_index); 389218822Sdim } 390218822Sdim println(); 391218822Sdim } 392218822Sdim } 393218822Sdim if (!first) 394218822Sdim indent(-1); 395218822Sdim return null; 396218822Sdim } 397218822Sdim 398218822Sdim String getInnerName(ConstantPool constant_pool, InnerClasses_attribute.Info info) { 399218822Sdim try { 400218822Sdim return info.getInnerName(constant_pool); 401218822Sdim } catch (ConstantPoolException e) { 402218822Sdim return report(e); 40333965Sjdp } 404218822Sdim } 405218822Sdim 406218822Sdim private void writeInnerClassHeader() { 407218822Sdim println("InnerClasses:"); 408218822Sdim indent(+1); 409218822Sdim } 41033965Sjdp 411218822Sdim @Override 412218822Sdim public Void visitLineNumberTable(LineNumberTable_attribute attr, Void ignore) { 413218822Sdim println("LineNumberTable:"); 414218822Sdim indent(+1); 415218822Sdim for (LineNumberTable_attribute.Entry entry: attr.line_number_table) { 416218822Sdim println("line " + entry.line_number + ": " + entry.start_pc); 417218822Sdim } 418218822Sdim indent(-1); 419218822Sdim return null; 420218822Sdim } 421218822Sdim 422218822Sdim @Override 423218822Sdim public Void visitLocalVariableTable(LocalVariableTable_attribute attr, Void ignore) { 424218822Sdim println("LocalVariableTable:"); 425218822Sdim indent(+1); 426218822Sdim println("Start Length Slot Name Signature"); 427218822Sdim for (LocalVariableTable_attribute.Entry entry : attr.local_variable_table) { 428218822Sdim println(String.format("%5d %7d %5d %5s %s", 429218822Sdim entry.start_pc, entry.length, entry.index, 430218822Sdim constantWriter.stringValue(entry.name_index), 431218822Sdim constantWriter.stringValue(entry.descriptor_index))); 432218822Sdim } 433218822Sdim indent(-1); 434218822Sdim return null; 435218822Sdim } 436218822Sdim 437218822Sdim @Override 438218822Sdim public Void visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr, Void ignore) { 439218822Sdim println("LocalVariableTypeTable:"); 440218822Sdim indent(+1); 441218822Sdim println("Start Length Slot Name Signature"); 442218822Sdim for (LocalVariableTypeTable_attribute.Entry entry : attr.local_variable_table) { 443218822Sdim println(String.format("%5d %7d %5d %5s %s", 444218822Sdim entry.start_pc, entry.length, entry.index, 445218822Sdim constantWriter.stringValue(entry.name_index), 446218822Sdim constantWriter.stringValue(entry.signature_index))); 447218822Sdim } 448218822Sdim indent(-1); 449218822Sdim return null; 450218822Sdim } 451218822Sdim 452218822Sdim @Override 453218822Sdim public Void visitModuleMainClass(ModuleMainClass_attribute attr, Void ignore) { 454218822Sdim print("ModuleMainClass: #" + attr.main_class_index); 455218822Sdim tab(); 456218822Sdim print("// " + getJavaClassName(attr)); 457218822Sdim println(); 458218822Sdim return null; 459218822Sdim } 460218822Sdim 461218822Sdim private String getJavaClassName(ModuleMainClass_attribute a) { 462218822Sdim try { 463218822Sdim return getJavaName(a.getMainClassName(constant_pool)); 46433965Sjdp } catch (ConstantPoolException e) { 465218822Sdim return report(e); 466218822Sdim } 46733965Sjdp } 46833965Sjdp 469218822Sdim private static final String format = "%-31s%s"; 47033965Sjdp 47133965Sjdp @Override 47233965Sjdp public Void visitMethodParameters(MethodParameters_attribute attr, 47333965Sjdp Void ignore) { 47433965Sjdp final String header = String.format(format, "Name", "Flags"); 47533965Sjdp println("MethodParameters:"); 47633965Sjdp indent(+1); 47733965Sjdp println(header); 47833965Sjdp for (MethodParameters_attribute.Entry entry : 47933965Sjdp attr.method_parameter_table) { 48033965Sjdp String namestr = 48133965Sjdp entry.name_index != 0 ? 48233965Sjdp constantWriter.stringValue(entry.name_index) : "<no name>"; 483218822Sdim String flagstr = 484218822Sdim (0 != (entry.flags & ACC_FINAL) ? "final " : "") + 485218822Sdim (0 != (entry.flags & ACC_MANDATED) ? "mandated " : "") + 486218822Sdim (0 != (entry.flags & ACC_SYNTHETIC) ? "synthetic" : ""); 487218822Sdim println(String.format(format, namestr, flagstr)); 488218822Sdim } 48933965Sjdp indent(-1); 49033965Sjdp return null; 49133965Sjdp } 49233965Sjdp 49333965Sjdp @Override 49433965Sjdp public Void visitModule(Module_attribute attr, Void ignore) { 49533965Sjdp println("Module:"); 49633965Sjdp indent(+1); 49733965Sjdp 49833965Sjdp print(attr.module_name); 49933965Sjdp tab(); 50033965Sjdp println("// " + constantWriter.stringValue(attr.module_name)); 50133965Sjdp 50233965Sjdp print(String.format("%x", attr.module_flags)); 50333965Sjdp tab(); 50433965Sjdp print("// "); 50533965Sjdp if ((attr.module_flags & Module_attribute.ACC_OPEN) != 0) 50633965Sjdp print(" ACC_OPEN"); 50733965Sjdp if ((attr.module_flags & Module_attribute.ACC_MANDATED) != 0) 50833965Sjdp print(" ACC_MANDATED"); 50933965Sjdp if ((attr.module_flags & Module_attribute.ACC_SYNTHETIC) != 0) 51033965Sjdp print(" ACC_SYNTHETIC"); 51133965Sjdp println(); 512218822Sdim 51333965Sjdp printRequiresTable(attr); 51433965Sjdp printExportsTable(attr); 51533965Sjdp printOpensTable(attr); 516218822Sdim printUsesTable(attr); 51733965Sjdp printProvidesTable(attr); 51833965Sjdp indent(-1); 51933965Sjdp return null; 52033965Sjdp } 521218822Sdim 52233965Sjdp protected void printRequiresTable(Module_attribute attr) { 52333965Sjdp Module_attribute.RequiresEntry[] entries = attr.requires; 524218822Sdim print(entries.length); 52533965Sjdp tab(); 526218822Sdim println("// " + "requires"); 52733965Sjdp indent(+1); 52833965Sjdp for (Module_attribute.RequiresEntry e: entries) { 52933965Sjdp print("#" + e.requires_index + "," + String.format("%x", e.requires_flags)); 53033965Sjdp tab(); 53133965Sjdp print("// " + constantWriter.stringValue(e.requires_index)); 53233965Sjdp if ((e.requires_flags & Module_attribute.ACC_TRANSITIVE) != 0) 533218822Sdim print(" ACC_TRANSITIVE"); 53433965Sjdp if ((e.requires_flags & Module_attribute.ACC_STATIC_PHASE) != 0) 535218822Sdim print(" ACC_STATIC_PHASE"); 536218822Sdim if ((e.requires_flags & Module_attribute.ACC_SYNTHETIC) != 0) 537218822Sdim print(" ACC_SYNTHETIC"); 53833965Sjdp if ((e.requires_flags & Module_attribute.ACC_MANDATED) != 0) 53933965Sjdp print(" ACC_MANDATED"); 54033965Sjdp println(); 54133965Sjdp } 542218822Sdim indent(-1); 54333965Sjdp } 54433965Sjdp 545218822Sdim protected void printExportsTable(Module_attribute attr) { 54633965Sjdp Module_attribute.ExportsEntry[] entries = attr.exports; 547218822Sdim print(entries.length); 548218822Sdim tab(); 549218822Sdim println("// exports"); 550218822Sdim indent(+1); 551218822Sdim for (Module_attribute.ExportsEntry e: entries) { 55233965Sjdp printExportOpenEntry(e.exports_index, e.exports_flags, e.exports_to_index); 55333965Sjdp } 554218822Sdim indent(-1); 55533965Sjdp } 556218822Sdim 557218822Sdim protected void printOpensTable(Module_attribute attr) { 558218822Sdim Module_attribute.OpensEntry[] entries = attr.opens; 559218822Sdim print(entries.length); 560218822Sdim tab(); 561218822Sdim println("// opens"); 56233965Sjdp indent(+1); 56333965Sjdp for (Module_attribute.OpensEntry e: entries) { 564218822Sdim printExportOpenEntry(e.opens_index, e.opens_flags, e.opens_to_index); 56533965Sjdp } 56633965Sjdp indent(-1); 56733965Sjdp } 56833965Sjdp 56933965Sjdp protected void printExportOpenEntry(int index, int flags, int[] to_index) { 57033965Sjdp print("#" + index + "," + String.format("%x", flags)); 57133965Sjdp tab(); 57233965Sjdp print("// "); 573218822Sdim print(constantWriter.stringValue(index)); 57433965Sjdp if ((flags & Module_attribute.ACC_MANDATED) != 0) 57533965Sjdp print(" ACC_MANDATED"); 57633965Sjdp if ((flags & Module_attribute.ACC_SYNTHETIC) != 0) 57733965Sjdp print(" ACC_SYNTHETIC"); 57833965Sjdp if (to_index.length == 0) { 579218822Sdim println(); 580218822Sdim } else { 581218822Sdim println(" to ... " + to_index.length); 582218822Sdim indent(+1); 583218822Sdim for (int to: to_index) { 584218822Sdim print("#" + to); 58533965Sjdp tab(); 58633965Sjdp println("// ... to " + constantWriter.stringValue(to)); 587218822Sdim } 58833965Sjdp indent(-1); 589218822Sdim } 59033965Sjdp } 59133965Sjdp 59233965Sjdp protected void printUsesTable(Module_attribute attr) { 59333965Sjdp int[] entries = attr.uses_index; 59433965Sjdp print(entries.length); 59533965Sjdp tab(); 596218822Sdim println("// " + "uses"); 59733965Sjdp indent(+1); 59833965Sjdp for (int e: entries) { 59933965Sjdp print("#" + e); 60033965Sjdp tab(); 601218822Sdim println("// " + constantWriter.stringValue(e)); 60233965Sjdp } 60333965Sjdp indent(-1); 60433965Sjdp } 60533965Sjdp 606218822Sdim protected void printProvidesTable(Module_attribute attr) { 60733965Sjdp Module_attribute.ProvidesEntry[] entries = attr.provides; 60833965Sjdp print(entries.length); 60933965Sjdp tab(); 61033965Sjdp println("// " + "provides"); 61133965Sjdp indent(+1); 61233965Sjdp for (Module_attribute.ProvidesEntry e: entries) { 613218822Sdim print("#" + e.provides_index); 61433965Sjdp tab(); 61533965Sjdp print("// "); 61633965Sjdp print(constantWriter.stringValue(e.provides_index)); 61733965Sjdp println(" with ... " + e.with_count); 61833965Sjdp indent(+1); 61933965Sjdp for (int with : e.with_index) { 62033965Sjdp print("#" + with); 62133965Sjdp tab(); 622218822Sdim println("// ... with " + constantWriter.stringValue(with)); 62333965Sjdp } 62433965Sjdp indent(-1); 62533965Sjdp } 62633965Sjdp indent(-1); 627218822Sdim } 62833965Sjdp 62933965Sjdp @Override 63033965Sjdp public Void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, Void ignore) { 63133965Sjdp println("RuntimeVisibleAnnotations:"); 63233965Sjdp indent(+1); 63333965Sjdp for (int i = 0; i < attr.annotations.length; i++) { 634218822Sdim print(i + ": "); 63533965Sjdp annotationWriter.write(attr.annotations[i]); 63633965Sjdp println(); 63733965Sjdp } 63833965Sjdp indent(-1); 63933965Sjdp return null; 64033965Sjdp } 64133965Sjdp 64233965Sjdp @Override 64333965Sjdp public Void visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, Void ignore) { 64433965Sjdp println("RuntimeInvisibleAnnotations:"); 64533965Sjdp indent(+1); 64633965Sjdp for (int i = 0; i < attr.annotations.length; i++) { 64733965Sjdp print(i + ": "); 648218822Sdim annotationWriter.write(attr.annotations[i]); 64933965Sjdp println(); 65033965Sjdp } 65133965Sjdp indent(-1); 65233965Sjdp return null; 653218822Sdim } 65433965Sjdp 65533965Sjdp @Override 65633965Sjdp public Void visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, Void ignore) { 65733965Sjdp println("RuntimeVisibleTypeAnnotations:"); 65833965Sjdp indent(+1); 65933965Sjdp for (int i = 0; i < attr.annotations.length; i++) { 660218822Sdim print(i + ": "); 66133965Sjdp annotationWriter.write(attr.annotations[i]); 66233965Sjdp println(); 66333965Sjdp } 66433965Sjdp indent(-1); 66533965Sjdp return null; 66633965Sjdp } 667218822Sdim 66833965Sjdp @Override 66933965Sjdp public Void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, Void ignore) { 67033965Sjdp println("RuntimeInvisibleTypeAnnotations:"); 67133965Sjdp indent(+1); 67233965Sjdp for (int i = 0; i < attr.annotations.length; i++) { 67333965Sjdp print(i + ": "); 67433965Sjdp annotationWriter.write(attr.annotations[i]); 67533965Sjdp println(); 67633965Sjdp } 67733965Sjdp indent(-1); 67833965Sjdp return null; 67933965Sjdp } 68033965Sjdp 68133965Sjdp @Override 68233965Sjdp public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, Void ignore) { 68333965Sjdp println("RuntimeVisibleParameterAnnotations:"); 684218822Sdim indent(+1); 68533965Sjdp for (int param = 0; param < attr.parameter_annotations.length; param++) { 68633965Sjdp println("parameter " + param + ": "); 68733965Sjdp indent(+1); 68833965Sjdp for (int i = 0; i < attr.parameter_annotations[param].length; i++) { 68933965Sjdp print(i + ": "); 69033965Sjdp annotationWriter.write(attr.parameter_annotations[param][i]); 69133965Sjdp println(); 69233965Sjdp } 69333965Sjdp indent(-1); 694218822Sdim } 69533965Sjdp indent(-1); 69633965Sjdp return null; 69733965Sjdp } 69833965Sjdp 69933965Sjdp @Override 70033965Sjdp public Void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr, Void ignore) { 70133965Sjdp println("RuntimeInvisibleParameterAnnotations:"); 70233965Sjdp indent(+1); 70333965Sjdp for (int param = 0; param < attr.parameter_annotations.length; param++) { 70433965Sjdp println(param + ": "); 705218822Sdim indent(+1); 70633965Sjdp for (int i = 0; i < attr.parameter_annotations[param].length; i++) { 70733965Sjdp print(i + ": "); 70833965Sjdp annotationWriter.write(attr.parameter_annotations[param][i]); 70933965Sjdp println(); 710218822Sdim } 71133965Sjdp indent(-1); 71233965Sjdp } 71333965Sjdp indent(-1); 71433965Sjdp return null; 715218822Sdim } 71633965Sjdp 71733965Sjdp @Override 71833965Sjdp public Void visitSignature(Signature_attribute attr, Void ignore) { 71933965Sjdp print("Signature: #" + attr.signature_index); 72033965Sjdp tab(); 72133965Sjdp println("// " + getSignature(attr)); 722218822Sdim return null; 72333965Sjdp } 72433965Sjdp 725218822Sdim String getSignature(Signature_attribute info) { 72633965Sjdp try { 727218822Sdim return info.getSignature(constant_pool); 72833965Sjdp } catch (ConstantPoolException e) { 72933965Sjdp return report(e); 73033965Sjdp } 73133965Sjdp } 732218822Sdim 733218822Sdim @Override 73433965Sjdp public Void visitSourceDebugExtension(SourceDebugExtension_attribute attr, Void ignore) { 73533965Sjdp println("SourceDebugExtension:"); 736218822Sdim indent(+1); 73733965Sjdp for (String s: attr.getValue().split("[\r\n]+")) { 738218822Sdim println(s); 739218822Sdim } 740218822Sdim indent(-1); 74133965Sjdp return null; 742218822Sdim } 743218822Sdim 74433965Sjdp @Override 74533965Sjdp public Void visitSourceFile(SourceFile_attribute attr, Void ignore) { 746218822Sdim println("SourceFile: \"" + getSourceFile(attr) + "\""); 74733965Sjdp return null; 74833965Sjdp } 749218822Sdim 75033965Sjdp private String getSourceFile(SourceFile_attribute attr) { 751218822Sdim try { 752218822Sdim return attr.getSourceFile(constant_pool); 753218822Sdim } catch (ConstantPoolException e) { 754218822Sdim return report(e); 755218822Sdim } 75633965Sjdp } 75733965Sjdp 75833965Sjdp @Override 75933965Sjdp public Void visitSourceID(SourceID_attribute attr, Void ignore) { 76033965Sjdp constantWriter.write(attr.sourceID_index); 76133965Sjdp return null; 76233965Sjdp } 76333965Sjdp 76433965Sjdp @Override 76533965Sjdp public Void visitStackMap(StackMap_attribute attr, Void ignore) { 766218822Sdim println("StackMap: number_of_entries = " + attr.number_of_entries); 76733965Sjdp indent(+1); 76833965Sjdp StackMapTableWriter w = new StackMapTableWriter(); 76933965Sjdp for (StackMapTable_attribute.stack_map_frame entry : attr.entries) { 77033965Sjdp w.write(entry); 77133965Sjdp } 77233965Sjdp indent(-1); 773218822Sdim return null; 77433965Sjdp } 775218822Sdim 776218822Sdim @Override 777218822Sdim public Void visitStackMapTable(StackMapTable_attribute attr, Void ignore) { 77833965Sjdp println("StackMapTable: number_of_entries = " + attr.number_of_entries); 77933965Sjdp indent(+1); 780218822Sdim StackMapTableWriter w = new StackMapTableWriter(); 781218822Sdim for (StackMapTable_attribute.stack_map_frame entry : attr.entries) { 782218822Sdim w.write(entry); 783218822Sdim } 784218822Sdim indent(-1); 785218822Sdim return null; 786218822Sdim } 787218822Sdim 788218822Sdim class StackMapTableWriter // also handles CLDC StackMap attributes 789218822Sdim implements StackMapTable_attribute.stack_map_frame.Visitor<Void,Void> { 79033965Sjdp public void write(StackMapTable_attribute.stack_map_frame frame) { 791218822Sdim frame.accept(this, null); 792218822Sdim } 793218822Sdim 794218822Sdim @Override 795218822Sdim public Void visit_same_frame(StackMapTable_attribute.same_frame frame, Void p) { 79633965Sjdp printHeader(frame, "/* same */"); 79733965Sjdp return null; 79833965Sjdp } 79933965Sjdp 80033965Sjdp @Override 80133965Sjdp public Void visit_same_locals_1_stack_item_frame(StackMapTable_attribute.same_locals_1_stack_item_frame frame, Void p) { 802218822Sdim printHeader(frame, "/* same_locals_1_stack_item */"); 803218822Sdim indent(+1); 804218822Sdim printMap("stack", frame.stack); 80533965Sjdp indent(-1); 80633965Sjdp return null; 807218822Sdim } 808218822Sdim 809218822Sdim @Override 810218822Sdim public Void visit_same_locals_1_stack_item_frame_extended(StackMapTable_attribute.same_locals_1_stack_item_frame_extended frame, Void p) { 811218822Sdim printHeader(frame, "/* same_locals_1_stack_item_frame_extended */"); 812218822Sdim indent(+1); 813218822Sdim println("offset_delta = " + frame.offset_delta); 814218822Sdim printMap("stack", frame.stack); 815218822Sdim indent(-1); 816218822Sdim return null; 81733965Sjdp } 818218822Sdim 819218822Sdim @Override 820218822Sdim public Void visit_chop_frame(StackMapTable_attribute.chop_frame frame, Void p) { 82133965Sjdp printHeader(frame, "/* chop */"); 822218822Sdim indent(+1); 823218822Sdim println("offset_delta = " + frame.offset_delta); 824218822Sdim indent(-1); 825218822Sdim return null; 826218822Sdim } 82733965Sjdp 82833965Sjdp @Override 82933965Sjdp public Void visit_same_frame_extended(StackMapTable_attribute.same_frame_extended frame, Void p) { 830218822Sdim printHeader(frame, "/* same_frame_extended */"); 831218822Sdim indent(+1); 832218822Sdim println("offset_delta = " + frame.offset_delta); 833218822Sdim indent(-1); 834218822Sdim return null; 835218822Sdim } 83633965Sjdp 837218822Sdim @Override 838218822Sdim public Void visit_append_frame(StackMapTable_attribute.append_frame frame, Void p) { 839218822Sdim printHeader(frame, "/* append */"); 840218822Sdim indent(+1); 841218822Sdim println("offset_delta = " + frame.offset_delta); 842218822Sdim printMap("locals", frame.locals); 843218822Sdim indent(-1); 844218822Sdim return null; 845218822Sdim } 846218822Sdim 84733965Sjdp @Override 848218822Sdim public Void visit_full_frame(StackMapTable_attribute.full_frame frame, Void p) { 849218822Sdim if (frame instanceof StackMap_attribute.stack_map_frame) { 85033965Sjdp printHeader(frame, "offset = " + frame.offset_delta); 851218822Sdim indent(+1); 852218822Sdim } else { 853218822Sdim printHeader(frame, "/* full_frame */"); 85433965Sjdp indent(+1); 85533965Sjdp println("offset_delta = " + frame.offset_delta); 85633965Sjdp } 85733965Sjdp printMap("locals", frame.locals); 858218822Sdim printMap("stack", frame.stack); 859218822Sdim indent(-1); 860218822Sdim return null; 861218822Sdim } 862218822Sdim 863218822Sdim void printHeader(StackMapTable_attribute.stack_map_frame frame, String extra) { 864218822Sdim print("frame_type = " + frame.frame_type + " "); 865218822Sdim println(extra); 866218822Sdim } 867218822Sdim 868218822Sdim void printMap(String name, StackMapTable_attribute.verification_type_info[] map) { 869218822Sdim print(name + " = ["); 87033965Sjdp for (int i = 0; i < map.length; i++) { 87133965Sjdp StackMapTable_attribute.verification_type_info info = map[i]; 87233965Sjdp int tag = info.tag; 87333965Sjdp switch (tag) { 87433965Sjdp case StackMapTable_attribute.verification_type_info.ITEM_Object: 87533965Sjdp print(" "); 87633965Sjdp constantWriter.write(((StackMapTable_attribute.Object_variable_info) info).cpool_index); 87733965Sjdp break; 87833965Sjdp case StackMapTable_attribute.verification_type_info.ITEM_Uninitialized: 879218822Sdim print(" " + mapTypeName(tag)); 880218822Sdim print(" " + ((StackMapTable_attribute.Uninitialized_variable_info) info).offset); 88133965Sjdp break; 882218822Sdim default: 883218822Sdim print(" " + mapTypeName(tag)); 88433965Sjdp } 88533965Sjdp print(i == (map.length - 1) ? " " : ","); 886218822Sdim } 887218822Sdim println("]"); 888218822Sdim } 889218822Sdim 890218822Sdim String mapTypeName(int tag) { 891218822Sdim switch (tag) { 892218822Sdim case StackMapTable_attribute.verification_type_info.ITEM_Top: 893218822Sdim return "top"; 894218822Sdim 895218822Sdim case StackMapTable_attribute.verification_type_info.ITEM_Integer: 896218822Sdim return "int"; 897218822Sdim 898218822Sdim case StackMapTable_attribute.verification_type_info.ITEM_Float: 899218822Sdim return "float"; 900218822Sdim 901218822Sdim case StackMapTable_attribute.verification_type_info.ITEM_Long: 902218822Sdim return "long"; 903218822Sdim 904218822Sdim case StackMapTable_attribute.verification_type_info.ITEM_Double: 905218822Sdim return "double"; 906218822Sdim 907218822Sdim case StackMapTable_attribute.verification_type_info.ITEM_Null: 908218822Sdim return "null"; 909218822Sdim 910218822Sdim case StackMapTable_attribute.verification_type_info.ITEM_UninitializedThis: 911218822Sdim return "this"; 912218822Sdim 913218822Sdim case StackMapTable_attribute.verification_type_info.ITEM_Object: 914218822Sdim return "CP"; 915218822Sdim 916218822Sdim case StackMapTable_attribute.verification_type_info.ITEM_Uninitialized: 917218822Sdim return "uninitialized"; 918218822Sdim 919218822Sdim default: 920218822Sdim report("unrecognized verification_type_info tag: " + tag); 921218822Sdim return "[tag:" + tag + "]"; 92233965Sjdp } 923218822Sdim } 924218822Sdim } 925218822Sdim 926218822Sdim @Override 927218822Sdim public Void visitSynthetic(Synthetic_attribute attr, Void ignore) { 928218822Sdim println("Synthetic: true"); 929218822Sdim return null; 930218822Sdim } 931218822Sdim 932218822Sdim @Override 933218822Sdim public Void visitModuleTarget(ModuleTarget_attribute attr, Void ignore) { 934218822Sdim println("ModuleTarget:"); 935218822Sdim indent(+1); 936218822Sdim print("os_name: #" + attr.os_name_index); 937218822Sdim if (attr.os_name_index != 0) { 938218822Sdim tab(); 939218822Sdim print("// " + getOSName(attr)); 940218822Sdim } 941218822Sdim println(); 942218822Sdim print("os_arch: #" + attr.os_arch_index); 943218822Sdim if (attr.os_arch_index != 0) { 944218822Sdim tab(); 945218822Sdim print("// " + getOSArch(attr)); 946218822Sdim } 947218822Sdim println(); 948218822Sdim print("os_version: #" + attr.os_version_index); 949218822Sdim if (attr.os_version_index != 0) { 950218822Sdim tab(); 951218822Sdim print("// " + getOSVersion(attr)); 952218822Sdim } 953218822Sdim println(); 954218822Sdim indent(-1); 955218822Sdim return null; 956218822Sdim } 957218822Sdim 958218822Sdim private String getOSName(ModuleTarget_attribute attr) { 959218822Sdim try { 960218822Sdim return constant_pool.getUTF8Value(attr.os_name_index); 961218822Sdim } catch (ConstantPoolException e) { 962218822Sdim return report(e); 963218822Sdim } 964218822Sdim } 965218822Sdim 966218822Sdim private String getOSArch(ModuleTarget_attribute attr) { 967218822Sdim try { 968218822Sdim return constant_pool.getUTF8Value(attr.os_arch_index); 969218822Sdim } catch (ConstantPoolException e) { 970218822Sdim return report(e); 971218822Sdim } 972218822Sdim } 973218822Sdim 974218822Sdim private String getOSVersion(ModuleTarget_attribute attr) { 975218822Sdim try { 976218822Sdim return constant_pool.getUTF8Value(attr.os_version_index); 977218822Sdim } catch (ConstantPoolException e) { 978218822Sdim return report(e); 979218822Sdim } 980218822Sdim } 981218822Sdim 982218822Sdim @Override 983218822Sdim public Void visitModuleVersion(ModuleVersion_attribute attr, Void ignore) { 984218822Sdim print("ModuleVersion: #" + attr.version_index); 985218822Sdim indent(+1); 986218822Sdim tab(); 987218822Sdim println("// " + getVersion(attr)); 988218822Sdim indent(-1); 989218822Sdim return null; 990218822Sdim } 991218822Sdim 992218822Sdim private String getVersion(ModuleVersion_attribute attr) { 993218822Sdim try { 994218822Sdim return constant_pool.getUTF8Value(attr.version_index); 995218822Sdim } catch (ConstantPoolException e) { 996218822Sdim return report(e); 997218822Sdim } 998218822Sdim } 999218822Sdim 1000218822Sdim static String getJavaName(String name) { 1001218822Sdim return name.replace('/', '.'); 1002218822Sdim } 1003218822Sdim 1004218822Sdim String toHex(byte b, int w) { 1005218822Sdim return toHex(b & 0xff, w); 1006218822Sdim } 1007218822Sdim 1008218822Sdim static String toHex(int i) { 1009218822Sdim return StringUtils.toUpperCase(Integer.toString(i, 16)); 1010218822Sdim } 1011218822Sdim 1012218822Sdim static String toHex(int i, int w) { 1013218822Sdim String s = StringUtils.toUpperCase(Integer.toHexString(i)); 1014218822Sdim while (s.length() < w) 1015218822Sdim s = "0" + s; 1016218822Sdim return StringUtils.toUpperCase(s); 1017218822Sdim } 1018218822Sdim 1019218822Sdim static String toHex(byte[] ba) { 1020218822Sdim StringBuilder sb = new StringBuilder(ba.length); 1021218822Sdim for (byte b: ba) { 1022218822Sdim sb.append(String.format("%02x", b & 0xff)); 1023218822Sdim } 1024218822Sdim return sb.toString(); 1025218822Sdim } 1026218822Sdim 1027218822Sdim private final AnnotationWriter annotationWriter; 1028218822Sdim private final CodeWriter codeWriter; 1029218822Sdim private final ConstantWriter constantWriter; 1030218822Sdim private final Options options; 1031218822Sdim 1032218822Sdim private ConstantPool constant_pool; 1033218822Sdim private Object owner; 1034218822Sdim} 1035218822Sdim