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 */ 59 package jdk.internal.org.objectweb.asm; 60 61 /** 62 * An {@link FieldVisitor} that generates Java fields in bytecode form. 63 * 64 * @author Eric Bruneton 65 */ 66 final 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 */ FieldWriter(final ClassWriter cw, final int access, final String name, final String desc, final String signature, final Object value)148 FieldWriter(final ClassWriter cw, final int access, final String name, 149 final String desc, final String signature, final Object value) { 150 super(Opcodes.ASM6); 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 (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 visitAnnotation(final String desc, final boolean visible)174 public AnnotationVisitor visitAnnotation(final String desc, 175 final boolean visible) { 176 ByteVector bv = new ByteVector(); 177 // write type, and reserve space for values count 178 bv.putShort(cw.newUTF8(desc)).putShort(0); 179 AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2); 180 if (visible) { 181 aw.next = anns; 182 anns = aw; 183 } else { 184 aw.next = ianns; 185 ianns = aw; 186 } 187 return aw; 188 } 189 190 @Override visitTypeAnnotation(final int typeRef, final TypePath typePath, final String desc, final boolean visible)191 public AnnotationVisitor visitTypeAnnotation(final int typeRef, 192 final TypePath typePath, final String desc, final boolean visible) { 193 ByteVector bv = new ByteVector(); 194 // write target_type and target_info 195 AnnotationWriter.putTarget(typeRef, typePath, bv); 196 // write type, and reserve space for values count 197 bv.putShort(cw.newUTF8(desc)).putShort(0); 198 AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 199 bv.length - 2); 200 if (visible) { 201 aw.next = tanns; 202 tanns = aw; 203 } else { 204 aw.next = itanns; 205 itanns = aw; 206 } 207 return aw; 208 } 209 210 @Override visitAttribute(final Attribute attr)211 public void visitAttribute(final Attribute attr) { 212 attr.next = attrs; 213 attrs = attr; 214 } 215 216 @Override visitEnd()217 public void visitEnd() { 218 } 219 220 // ------------------------------------------------------------------------ 221 // Utility methods 222 // ------------------------------------------------------------------------ 223 224 /** 225 * Returns the size of this field. 226 * 227 * @return the size of this field. 228 */ getSize()229 int getSize() { 230 int size = 8; 231 if (value != 0) { 232 cw.newUTF8("ConstantValue"); 233 size += 8; 234 } 235 if ((access & Opcodes.ACC_SYNTHETIC) != 0) { 236 if ((cw.version & 0xFFFF) < Opcodes.V1_5 237 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) { 238 cw.newUTF8("Synthetic"); 239 size += 6; 240 } 241 } 242 if ((access & Opcodes.ACC_DEPRECATED) != 0) { 243 cw.newUTF8("Deprecated"); 244 size += 6; 245 } 246 if (signature != 0) { 247 cw.newUTF8("Signature"); 248 size += 8; 249 } 250 if (anns != null) { 251 cw.newUTF8("RuntimeVisibleAnnotations"); 252 size += 8 + anns.getSize(); 253 } 254 if (ianns != null) { 255 cw.newUTF8("RuntimeInvisibleAnnotations"); 256 size += 8 + ianns.getSize(); 257 } 258 if (tanns != null) { 259 cw.newUTF8("RuntimeVisibleTypeAnnotations"); 260 size += 8 + tanns.getSize(); 261 } 262 if (itanns != null) { 263 cw.newUTF8("RuntimeInvisibleTypeAnnotations"); 264 size += 8 + itanns.getSize(); 265 } 266 if (attrs != null) { 267 size += attrs.getSize(cw, null, 0, -1, -1); 268 } 269 return size; 270 } 271 272 /** 273 * Puts the content of this field into the given byte vector. 274 * 275 * @param out 276 * where the content of this field must be put. 277 */ put(final ByteVector out)278 void put(final ByteVector out) { 279 final int FACTOR = ClassWriter.TO_ACC_SYNTHETIC; 280 int mask = Opcodes.ACC_DEPRECATED | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE 281 | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / FACTOR); 282 out.putShort(access & ~mask).putShort(name).putShort(desc); 283 int attributeCount = 0; 284 if (value != 0) { 285 ++attributeCount; 286 } 287 if ((access & Opcodes.ACC_SYNTHETIC) != 0) { 288 if ((cw.version & 0xFFFF) < Opcodes.V1_5 289 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) { 290 ++attributeCount; 291 } 292 } 293 if ((access & Opcodes.ACC_DEPRECATED) != 0) { 294 ++attributeCount; 295 } 296 if (signature != 0) { 297 ++attributeCount; 298 } 299 if (anns != null) { 300 ++attributeCount; 301 } 302 if (ianns != null) { 303 ++attributeCount; 304 } 305 if (tanns != null) { 306 ++attributeCount; 307 } 308 if (itanns != null) { 309 ++attributeCount; 310 } 311 if (attrs != null) { 312 attributeCount += attrs.getCount(); 313 } 314 out.putShort(attributeCount); 315 if (value != 0) { 316 out.putShort(cw.newUTF8("ConstantValue")); 317 out.putInt(2).putShort(value); 318 } 319 if ((access & Opcodes.ACC_SYNTHETIC) != 0) { 320 if ((cw.version & 0xFFFF) < Opcodes.V1_5 321 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) { 322 out.putShort(cw.newUTF8("Synthetic")).putInt(0); 323 } 324 } 325 if ((access & Opcodes.ACC_DEPRECATED) != 0) { 326 out.putShort(cw.newUTF8("Deprecated")).putInt(0); 327 } 328 if (signature != 0) { 329 out.putShort(cw.newUTF8("Signature")); 330 out.putInt(2).putShort(signature); 331 } 332 if (anns != null) { 333 out.putShort(cw.newUTF8("RuntimeVisibleAnnotations")); 334 anns.put(out); 335 } 336 if (ianns != null) { 337 out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations")); 338 ianns.put(out); 339 } 340 if (tanns != null) { 341 out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations")); 342 tanns.put(out); 343 } 344 if (itanns != null) { 345 out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations")); 346 itanns.put(out); 347 } 348 if (attrs != null) { 349 attrs.put(cw, null, 0, -1, -1, out); 350 } 351 } 352 } 353