/* * $Id$ * * Copyright (C) 2003-2015 JNode.org * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; If not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package org.jnode.vm.classmgr; import java.lang.reflect.Field; import org.jnode.annotation.PrivilegedActionPragma; import org.jnode.vm.isolate.VmIsolateLocal; import sun.reflect.ReflectionFactory; public abstract class VmField extends VmMember { /** * java.lang.reflect.Field corresponding to this field */ private VmIsolateLocal<Field> javaFieldHolder; /** * Type of this field */ private VmType type; /** * Is the type of this field primitive? */ private final boolean primitive; /** * The size of this field in bytes */ private final byte typeSize; /** * Create a new instance * * @param name * @param signature * @param modifiers * @param declaringClass * @param slotSize */ protected VmField( String name, String signature, int modifiers, VmType declaringClass, int slotSize) { super(name, signature, modifiers | (((Modifier.isPrimitive(signature) || Modifier.isAddressType(signature)) ? 0 : Modifier.ACC_OBJECTREF)), declaringClass); this.primitive = Modifier.isPrimitive(signature); this.typeSize = Modifier.getTypeSize(signature, slotSize); } /** * Is this a field with a primitive type? * * @return boolean */ public final boolean isPrimitive() { return primitive; } /** * Is this a field transient? * * @return boolean */ public final boolean isTransient() { return ((this.getModifiers() & Modifier.ACC_TRANSIENT) != 0); } /** * Is the field of the type Address? * * @return boolean */ public boolean isAddressType() { return Modifier.isAddressType(signature); } /** * Is the field a non-primitive field and not an address type? * * @return boolean */ public boolean isObjectRef() { return Modifier.isObjectRef(getModifiers()); } /** * Is this a field of double width (double, long) * * @return boolean */ public final boolean isWide() { return ((this.getModifiers() & Modifier.ACC_WIDE) != 0); } /** * Return me as java.lang.reflect.Field * * @return Field */ @PrivilegedActionPragma public final Field asField() { if (javaFieldHolder == null) { javaFieldHolder = new VmIsolateLocal<Field>(); } Field javaField = javaFieldHolder.get(); if (javaField == null) { //slot VmType<?> d_class = getDeclaringClass(); int slot = -1; for (int i = 0; i < d_class.getNoDeclaredFields(); i++) { if (this == d_class.getDeclaredField(i)) { slot = i; break; } } if (slot == -1) { throw new ClassFormatError("Invalid field: " + this.getName()); } javaField = ReflectionFactory.getReflectionFactory().newField(d_class.asClass(), getName(), getType().asClass(), getModifiers(), slot, getSignature(), getRawAnnotations()); javaFieldHolder.set(javaField); } return javaField; } /** * Resolve the type of this field */ protected final synchronized void resolve() { try { type = new Signature(getSignature(), declaringClass.getLoader()).getType(); } catch (ClassNotFoundException ex) { throw (Error) new NoClassDefFoundError().initCause(ex); } } public String toString() { return getMangledName(); } public String getMangledName() { return Mangler.mangleClassName(declaringClass.getName()) + Mangler.mangle('.' + getName() + '.' + getSignature()); } /** * Returns the type. * * @return VmClass */ public VmType<?> getType() { if (type == null) { resolve(); } return type; } /** * Gets the size of this field in bytes [1..8]. * * @return size of this field */ public byte getTypeSize() { return typeSize; } }