1 /* 2 * Copyright (c) 2002, 2004, 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 */ 24 25 package sun.jvm.hotspot.jdi; 26 27 import java.util.ArrayList; 28 import java.util.List; 29 import java.util.Map; 30 import java.util.Set; 31 32 import sun.jvm.hotspot.oops.ArrayKlass; 33 import sun.jvm.hotspot.oops.Instance; 34 import sun.jvm.hotspot.oops.InstanceKlass; 35 import sun.jvm.hotspot.oops.Klass; 36 import sun.jvm.hotspot.oops.ObjArrayKlass; 37 import sun.jvm.hotspot.oops.Symbol; 38 import sun.jvm.hotspot.oops.TypeArrayKlass; 39 40 import com.sun.jdi.ArrayReference; 41 import com.sun.jdi.ArrayType; 42 import com.sun.jdi.ClassLoaderReference; 43 import com.sun.jdi.ClassNotLoadedException; 44 import com.sun.jdi.InterfaceType; 45 import com.sun.jdi.Method; 46 import com.sun.jdi.PrimitiveType; 47 import com.sun.jdi.ReferenceType; 48 import com.sun.jdi.Type; 49 import com.sun.jdi.VirtualMachine; 50 51 public class ArrayTypeImpl extends ReferenceTypeImpl implements ArrayType { 52 protected ArrayTypeImpl(VirtualMachine aVm, ArrayKlass aRef) { 53 super(aVm, aRef); 54 } 55 56 public ArrayReference newInstance(int length) { 57 vm.throwNotReadOnlyException("ArrayType.newInstance(int)"); 58 return null; 59 } 60 61 public String componentSignature() { 62 return signature().substring(1); // Just skip the leading '[' 63 } 64 65 public String componentTypeName() { 66 JNITypeParser parser = new JNITypeParser(componentSignature()); 67 return parser.typeName(); 68 } 69 70 public ClassLoaderReference classLoader() { 71 if (ref() instanceof TypeArrayKlass) { 72 // primitive array klasses are loaded by bootstrap loader 73 return null; 74 } else { 75 Klass bottomKlass = ((ObjArrayKlass)ref()).getBottomKlass(); 76 if (bottomKlass instanceof TypeArrayKlass) { 77 // multidimensional primitive array klasses are loaded by bootstrap loader 78 return null; 79 } else { 80 // class loader of any other obj array klass is same as the loader 81 // that loaded the bottom InstanceKlass 82 Instance xx = (Instance)(((InstanceKlass) bottomKlass).getClassLoader()); 83 return vm.classLoaderMirror(xx); 84 } 85 } 86 } 87 88 @Override 89 void addVisibleMethods(Map<String, Method> methodMap, Set<InterfaceType> handledInterfaces) { 90 // arrays don't have methods 91 } 92 93 List getAllMethods() { 94 // arrays don't have methods 95 // JLS says arrays have methods of java.lang.Object. But 96 // JVMDI-JDI returns zero size list. We do the same here 97 // for consistency. 98 return new ArrayList(0); 99 } 100 101 /* 102 * Find the type object, if any, of a component type of this array. 103 * The component type does not have to be immediate; e.g. this method 104 * can be used to find the component Foo of Foo[][]. 105 */ 106 public Type componentType() throws ClassNotLoadedException { 107 ArrayKlass k = (ArrayKlass) ref(); 108 if (k instanceof ObjArrayKlass) { 109 Klass elementKlass = ((ObjArrayKlass)k).getElementKlass(); 110 if (elementKlass == null) { 111 throw new ClassNotLoadedException(componentSignature()); 112 } else { 113 return vm.referenceType(elementKlass); 114 } 115 } else { 116 // It's a primitive type 117 return vm.primitiveTypeMirror(signature().charAt(1)); 118 } 119 } 120 121 static boolean isComponentAssignable(Type destination, Type source) { 122 if (source instanceof PrimitiveType) { 123 // Assignment of primitive arrays requires identical 124 // component types. 125 return source.equals(destination); 126 } else { 127 if (destination instanceof PrimitiveType) { 128 return false; 129 } 130 131 ReferenceTypeImpl refSource = (ReferenceTypeImpl)source; 132 ReferenceTypeImpl refDestination = (ReferenceTypeImpl)destination; 133 // Assignment of object arrays requires availability 134 // of widening conversion of component types 135 return refSource.isAssignableTo(refDestination); 136 } 137 } 138 139 140 /* 141 * Return true if an instance of the given reference type 142 * can be assigned to a variable of this type 143 */ 144 boolean isAssignableTo(ReferenceType destType) { 145 if (destType instanceof ArrayType) { 146 try { 147 Type destComponentType = ((ArrayType)destType).componentType(); 148 return isComponentAssignable(destComponentType, componentType()); 149 } catch (ClassNotLoadedException e) { 150 // One or both component types has not yet been 151 // loaded => can't assign 152 return false; 153 } 154 } else { 155 Symbol typeName = ((ReferenceTypeImpl)destType).typeNameAsSymbol(); 156 if (destType instanceof InterfaceType) { 157 // Every array type implements java.io.Serializable and 158 // java.lang.Cloneable. fixme in JVMDI-JDI, includes only 159 // Cloneable but not Serializable. 160 return typeName.equals(vm.javaLangCloneable()) || 161 typeName.equals(vm.javaIoSerializable()); 162 } else { 163 // Only valid ClassType assignee is Object 164 return typeName.equals(vm.javaLangObject()); 165 } 166 } 167 } 168 169 List inheritedTypes() { 170 // arrays are derived from java.lang.Object and 171 // B[] is derived from A[] if B is derived from A. 172 // But JVMDI-JDI returns zero sized list and we do the 173 // same for consistency. 174 return new ArrayList(0); 175 } 176 177 int getModifiers() { 178 /* 179 * For object arrays, the return values for Interface 180 * Accessible.isPrivate(), Accessible.isProtected(), 181 * etc... are the same as would be returned for the 182 * component type. Fetch the modifier bits from the 183 * component type and use those. 184 * 185 * For primitive arrays, the modifiers are always 186 * VMModifiers.FINAL | VMModifiers.PUBLIC 187 * 188 * Reference com.sun.jdi.Accessible.java. 189 */ 190 try { 191 Type t = componentType(); 192 if (t instanceof PrimitiveType) { 193 return VMModifiers.FINAL | VMModifiers.PUBLIC; 194 } else { 195 ReferenceType rt = (ReferenceType)t; 196 return rt.modifiers(); 197 } 198 } catch (ClassNotLoadedException cnle) { 199 cnle.printStackTrace(); 200 } 201 return -1; 202 } 203 204 public String toString() { 205 return "array class " + name() + " (" + loaderString() + ")"; 206 } 207 208 /* 209 * Save a pointless trip over the wire for these methods 210 * which have undefined results for arrays. 211 */ 212 public boolean isPrepared() { return true; } 213 public boolean isVerified() { return true; } 214 public boolean isInitialized() { return true; } 215 public boolean failedToInitialize() { return false; } 216 public boolean isAbstract() { return false; } 217 218 /* 219 * Defined always to be true for arrays 220 */ 221 public boolean isFinal() { return true; } 222 }