0
|
1 /*
|
|
2 * Copyright 2002-2004 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
20 * CA 95054 USA or visit www.sun.com if you need additional information or
|
|
21 * have any 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 }
|