1/* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. Oracle designates this 7 * particular file as subject to the "Classpath" exception as provided 8 * by Oracle in the LICENSE file that accompanied this code. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25/* 26 * This file is available under and governed by the GNU General Public 27 * License version 2 only, as published by the Free Software Foundation. 28 * However, the following notice accompanied the original version of this 29 * file: 30 * 31 * ASM: a very small and fast Java bytecode manipulation framework 32 * Copyright (c) 2000-2011 INRIA, France Telecom 33 * All rights reserved. 34 * 35 * Redistribution and use in source and binary forms, with or without 36 * modification, are permitted provided that the following conditions 37 * are met: 38 * 1. Redistributions of source code must retain the above copyright 39 * notice, this list of conditions and the following disclaimer. 40 * 2. Redistributions in binary form must reproduce the above copyright 41 * notice, this list of conditions and the following disclaimer in the 42 * documentation and/or other materials provided with the distribution. 43 * 3. Neither the name of the copyright holders nor the names of its 44 * contributors may be used to endorse or promote products derived from 45 * this software without specific prior written permission. 46 * 47 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 48 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 49 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 50 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 51 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 52 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 53 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 54 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 55 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 56 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 57 * THE POSSIBILITY OF SUCH DAMAGE. 58 */ 59package jdk.internal.org.objectweb.asm; 60 61/** 62 * An {@link FieldVisitor} that generates Java fields in bytecode form. 63 * 64 * @author Eric Bruneton 65 */ 66final class FieldWriter extends FieldVisitor { 67 68 /** 69 * The class writer to which this field must be added. 70 */ 71 private final ClassWriter cw; 72 73 /** 74 * Access flags of this field. 75 */ 76 private final int access; 77 78 /** 79 * The index of the constant pool item that contains the name of this 80 * method. 81 */ 82 private final int name; 83 84 /** 85 * The index of the constant pool item that contains the descriptor of this 86 * field. 87 */ 88 private final int desc; 89 90 /** 91 * The index of the constant pool item that contains the signature of this 92 * field. 93 */ 94 private int signature; 95 96 /** 97 * The index of the constant pool item that contains the constant value of 98 * this field. 99 */ 100 private int value; 101 102 /** 103 * The runtime visible annotations of this field. May be <tt>null</tt>. 104 */ 105 private AnnotationWriter anns; 106 107 /** 108 * The runtime invisible annotations of this field. May be <tt>null</tt>. 109 */ 110 private AnnotationWriter ianns; 111 112 /** 113 * The runtime visible type annotations of this field. May be <tt>null</tt>. 114 */ 115 private AnnotationWriter tanns; 116 117 /** 118 * The runtime invisible type annotations of this field. May be 119 * <tt>null</tt>. 120 */ 121 private AnnotationWriter itanns; 122 123 /** 124 * The non standard attributes of this field. May be <tt>null</tt>. 125 */ 126 private Attribute attrs; 127 128 // ------------------------------------------------------------------------ 129 // Constructor 130 // ------------------------------------------------------------------------ 131 132 /** 133 * Constructs a new {@link FieldWriter}. 134 * 135 * @param cw 136 * the class writer to which this field must be added. 137 * @param access 138 * the field's access flags (see {@link Opcodes}). 139 * @param name 140 * the field's name. 141 * @param desc 142 * the field's descriptor (see {@link Type}). 143 * @param signature 144 * the field's signature. May be <tt>null</tt>. 145 * @param value 146 * the field's constant value. May be <tt>null</tt>. 147 */ 148 FieldWriter(final ClassWriter cw, final int access, final String name, 149 final String desc, final String signature, final Object value) { 150 super(Opcodes.ASM5); 151 if (cw.firstField == null) { 152 cw.firstField = this; 153 } else { 154 cw.lastField.fv = this; 155 } 156 cw.lastField = this; 157 this.cw = cw; 158 this.access = access; 159 this.name = cw.newUTF8(name); 160 this.desc = cw.newUTF8(desc); 161 if (ClassReader.SIGNATURES && signature != null) { 162 this.signature = cw.newUTF8(signature); 163 } 164 if (value != null) { 165 this.value = cw.newConstItem(value).index; 166 } 167 } 168 169 // ------------------------------------------------------------------------ 170 // Implementation of the FieldVisitor abstract class 171 // ------------------------------------------------------------------------ 172 173 @Override 174 public AnnotationVisitor visitAnnotation(final String desc, 175 final boolean visible) { 176 if (!ClassReader.ANNOTATIONS) { 177 return null; 178 } 179 ByteVector bv = new ByteVector(); 180 // write type, and reserve space for values count 181 bv.putShort(cw.newUTF8(desc)).putShort(0); 182 AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2); 183 if (visible) { 184 aw.next = anns; 185 anns = aw; 186 } else { 187 aw.next = ianns; 188 ianns = aw; 189 } 190 return aw; 191 } 192 193 @Override 194 public AnnotationVisitor visitTypeAnnotation(final int typeRef, 195 final TypePath typePath, final String desc, final boolean visible) { 196 if (!ClassReader.ANNOTATIONS) { 197 return null; 198 } 199 ByteVector bv = new ByteVector(); 200 // write target_type and target_info 201 AnnotationWriter.putTarget(typeRef, typePath, bv); 202 // write type, and reserve space for values count 203 bv.putShort(cw.newUTF8(desc)).putShort(0); 204 AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 205 bv.length - 2); 206 if (visible) { 207 aw.next = tanns; 208 tanns = aw; 209 } else { 210 aw.next = itanns; 211 itanns = aw; 212 } 213 return aw; 214 } 215 216 @Override 217 public void visitAttribute(final Attribute attr) { 218 attr.next = attrs; 219 attrs = attr; 220 } 221 222 @Override 223 public void visitEnd() { 224 } 225 226 // ------------------------------------------------------------------------ 227 // Utility methods 228 // ------------------------------------------------------------------------ 229 230 /** 231 * Returns the size of this field. 232 * 233 * @return the size of this field. 234 */ 235 int getSize() { 236 int size = 8; 237 if (value != 0) { 238 cw.newUTF8("ConstantValue"); 239 size += 8; 240 } 241 if ((access & Opcodes.ACC_SYNTHETIC) != 0) { 242 if ((cw.version & 0xFFFF) < Opcodes.V1_5 243 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) { 244 cw.newUTF8("Synthetic"); 245 size += 6; 246 } 247 } 248 if ((access & Opcodes.ACC_DEPRECATED) != 0) { 249 cw.newUTF8("Deprecated"); 250 size += 6; 251 } 252 if (ClassReader.SIGNATURES && signature != 0) { 253 cw.newUTF8("Signature"); 254 size += 8; 255 } 256 if (ClassReader.ANNOTATIONS && anns != null) { 257 cw.newUTF8("RuntimeVisibleAnnotations"); 258 size += 8 + anns.getSize(); 259 } 260 if (ClassReader.ANNOTATIONS && ianns != null) { 261 cw.newUTF8("RuntimeInvisibleAnnotations"); 262 size += 8 + ianns.getSize(); 263 } 264 if (ClassReader.ANNOTATIONS && tanns != null) { 265 cw.newUTF8("RuntimeVisibleTypeAnnotations"); 266 size += 8 + tanns.getSize(); 267 } 268 if (ClassReader.ANNOTATIONS && itanns != null) { 269 cw.newUTF8("RuntimeInvisibleTypeAnnotations"); 270 size += 8 + itanns.getSize(); 271 } 272 if (attrs != null) { 273 size += attrs.getSize(cw, null, 0, -1, -1); 274 } 275 return size; 276 } 277 278 /** 279 * Puts the content of this field into the given byte vector. 280 * 281 * @param out 282 * where the content of this field must be put. 283 */ 284 void put(final ByteVector out) { 285 final int FACTOR = ClassWriter.TO_ACC_SYNTHETIC; 286 int mask = Opcodes.ACC_DEPRECATED | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE 287 | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / FACTOR); 288 out.putShort(access & ~mask).putShort(name).putShort(desc); 289 int attributeCount = 0; 290 if (value != 0) { 291 ++attributeCount; 292 } 293 if ((access & Opcodes.ACC_SYNTHETIC) != 0) { 294 if ((cw.version & 0xFFFF) < Opcodes.V1_5 295 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) { 296 ++attributeCount; 297 } 298 } 299 if ((access & Opcodes.ACC_DEPRECATED) != 0) { 300 ++attributeCount; 301 } 302 if (ClassReader.SIGNATURES && signature != 0) { 303 ++attributeCount; 304 } 305 if (ClassReader.ANNOTATIONS && anns != null) { 306 ++attributeCount; 307 } 308 if (ClassReader.ANNOTATIONS && ianns != null) { 309 ++attributeCount; 310 } 311 if (ClassReader.ANNOTATIONS && tanns != null) { 312 ++attributeCount; 313 } 314 if (ClassReader.ANNOTATIONS && itanns != null) { 315 ++attributeCount; 316 } 317 if (attrs != null) { 318 attributeCount += attrs.getCount(); 319 } 320 out.putShort(attributeCount); 321 if (value != 0) { 322 out.putShort(cw.newUTF8("ConstantValue")); 323 out.putInt(2).putShort(value); 324 } 325 if ((access & Opcodes.ACC_SYNTHETIC) != 0) { 326 if ((cw.version & 0xFFFF) < Opcodes.V1_5 327 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) { 328 out.putShort(cw.newUTF8("Synthetic")).putInt(0); 329 } 330 } 331 if ((access & Opcodes.ACC_DEPRECATED) != 0) { 332 out.putShort(cw.newUTF8("Deprecated")).putInt(0); 333 } 334 if (ClassReader.SIGNATURES && signature != 0) { 335 out.putShort(cw.newUTF8("Signature")); 336 out.putInt(2).putShort(signature); 337 } 338 if (ClassReader.ANNOTATIONS && anns != null) { 339 out.putShort(cw.newUTF8("RuntimeVisibleAnnotations")); 340 anns.put(out); 341 } 342 if (ClassReader.ANNOTATIONS && ianns != null) { 343 out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations")); 344 ianns.put(out); 345 } 346 if (ClassReader.ANNOTATIONS && tanns != null) { 347 out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations")); 348 tanns.put(out); 349 } 350 if (ClassReader.ANNOTATIONS && itanns != null) { 351 out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations")); 352 itanns.put(out); 353 } 354 if (attrs != null) { 355 attrs.put(cw, null, 0, -1, -1, out); 356 } 357 } 358} 359