1 /* 2 * Copyright (c) 1996, 2020, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package org.openjdk.asmtools.jdis; 24 25 import org.openjdk.asmtools.jasm.JasmTokens; 26 import org.openjdk.asmtools.jasm.Modifiers; 27 28 import java.io.DataInputStream; 29 import java.io.IOException; 30 31 import static java.lang.String.format; 32 import static org.openjdk.asmtools.jasm.Tables.AttrTag; 33 import static org.openjdk.asmtools.jasm.Tables.CF_Context; 34 import static org.openjdk.asmtools.jdis.TraceUtils.traceln; 35 36 /** 37 * Field data for field members in a class of the Java Disassembler 38 */ 39 public class FieldData extends MemberData { 40 41 // CP index to the field name 42 protected int name_cpx; 43 // CP index to the field type 44 protected int type_cpx; 45 // CP index to the field value 46 protected int value_cpx = 0; 47 48 public FieldData(ClassData cls) { 49 super(cls); 50 memberType = "FieldData"; 51 } 52 53 @Override 54 protected boolean handleAttributes(DataInputStream in, AttrTag attrtag, int attrlen) throws IOException { 55 // Read the Attributes 56 boolean handled = true; 57 switch (attrtag) { 58 case ATT_Signature: 59 if( signature != null ) { 60 traceln("Record attribute: more than one attribute Signature are in component.attribute_info_attributes[attribute_count]"); 61 traceln("Last one will be used."); 62 } 63 signature = new SignatureData(cls).read(in, attrlen); 64 break; 65 case ATT_ConstantValue: 66 if (attrlen != 2) { 67 throw new ClassFormatError(format("%s: Invalid attribute length #%d", AttrTag.ATT_ConstantValue.printval(), attrlen)); 68 } 69 value_cpx = in.readUnsignedShort(); 70 break; 71 default: 72 handled = false; 73 break; 74 } 75 return handled; 76 } 77 78 /** 79 * Read and resolve the field data called from ClassData. 80 * Precondition: NumFields has already been read from the stream. 81 */ 82 public void read(DataInputStream in) throws IOException { 83 // read the Fields CP indexes 84 access = in.readUnsignedShort(); 85 name_cpx = in.readUnsignedShort(); 86 type_cpx = in.readUnsignedShort(); 87 // Read the attributes 88 readAttributes(in); 89 // 90 TraceUtils.traceln(2, 91 format("FieldData: name[%d]=%s type[%d]=%s%s", 92 name_cpx, cls.pool.getString(name_cpx), 93 type_cpx, cls.pool.getString(type_cpx), 94 signature != null ? signature : "")); 95 } 96 97 98 /** 99 * Prints the field data to the current output stream. called from ClassData. 100 */ 101 @Override 102 public void print() throws IOException { 103 // Print annotations first 104 super.printAnnotations(getIndentString()); 105 106 StringBuilder bodyPrefix = new StringBuilder(getIndentString()).append(Modifiers.accessString(access, CF_Context.CTX_FIELD)); 107 StringBuilder tailPrefix = new StringBuilder(); 108 109 if (isSynthetic) { 110 bodyPrefix.append(JasmTokens.Token.SYNTHETIC.parseKey()).append(' '); 111 } 112 if (isDeprecated) { 113 bodyPrefix.append(JasmTokens.Token.DEPRECATED.parseKey()).append(' '); 114 } 115 116 // field 117 bodyPrefix.append(JasmTokens.Token.FIELDREF.parseKey()).append(' '); 118 119 if (value_cpx != 0) { 120 tailPrefix.append("\t= ").append(cls.pool.ConstantStrValue(value_cpx)); 121 } 122 123 printVar(bodyPrefix, tailPrefix,name_cpx, type_cpx); 124 } 125 } // end FieldData 126