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