History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/com/sun/tools/jdi/ArrayReferenceImpl.java (1 of 18352 files). Show all

Unified · Split

java/pkg/com/sun/tools/jdi/ArrayReferenceImpl.java+283−0
@@ -0,0 +1,283 @@
1+/*
2+ * Copyright (c) 1998, 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. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package com.sun.tools.jdi;
27+
28+import com.sun.jdi.*;
29+
30+import java.util.List;
31+import java.util.ArrayList;
32+import java.util.Arrays;
33+import java.util.Iterator;
34+
35+public class ArrayReferenceImpl extends ObjectReferenceImpl
36+ implements ArrayReference
37+{
38+ int length = -1;
39+
40+ ArrayReferenceImpl(VirtualMachine aVm,long aRef) {
41+ super(aVm,aRef);
42+ }
43+
44+ protected ClassTypeImpl invokableReferenceType(Method method) {
45+ // The method has to be a method on Object since
46+ // arrays don't have methods nor any other 'superclasses'
47+ // So, use the ClassTypeImpl for Object instead of
48+ // the ArrayTypeImpl for the array itself.
49+ return (ClassTypeImpl)method.declaringType();
50+ }
51+
52+ ArrayTypeImpl arrayType() {
53+ return (ArrayTypeImpl)type();
54+ }
55+
56+ /**
57+ * Return array length.
58+ * Need not be synchronized since it cannot be provably stale.
59+ */
60+ public int length() {
61+ if(length == -1) {
62+ try {
63+ length = JDWP.ArrayReference.Length.
64+ process(vm, this).arrayLength;
65+ } catch (JDWPException exc) {
66+ throw exc.toJDIException();
67+ }
68+ }
69+ return length;
70+ }
71+
72+ public Value getValue(int index) {
73+ List list = getValues(index, 1);
74+ return (Value)list.get(0);
75+ }
76+
77+ public List<Value> getValues() {
78+ return getValues(0, -1);
79+ }
80+
81+ /**
82+ * Validate that the range to set/get is valid.
83+ * length of -1 (meaning rest of array) has been converted
84+ * before entry.
85+ */
86+ private void validateArrayAccess(int index, int length) {
87+ // because length can be computed from index,
88+ // index must be tested first for correct error message
89+ if ((index < 0) || (index > length())) {
90+ throw new IndexOutOfBoundsException(
91+ "Invalid array index: " + index);
92+ }
93+ if (length < 0) {
94+ throw new IndexOutOfBoundsException(
95+ "Invalid array range length: " + length);
96+ }
97+ if (index + length > length()) {
98+ throw new IndexOutOfBoundsException(
99+ "Invalid array range: " +
100+ index + " to " + (index + length - 1));
101+ }
102+ }
103+
104+ @SuppressWarnings("unchecked")
105+ private static <T> T cast(Object x) {
106+ return (T)x;
107+ }
108+
109+ public List<Value> getValues(int index, int length) {
110+ if (length == -1) { // -1 means the rest of the array
111+ length = length() - index;
112+ }
113+ validateArrayAccess(index, length);
114+ if (length == 0) {
115+ return new ArrayList<Value>();
116+ }
117+
118+ List<Value> vals;
119+ try {
120+ vals = cast(JDWP.ArrayReference.GetValues.process(vm, this, index, length).values);
121+ } catch (JDWPException exc) {
122+ throw exc.toJDIException();
123+ }
124+
125+ return vals;
126+ }
127+
128+ public void setValue(int index, Value value)
129+ throws InvalidTypeException,
130+ ClassNotLoadedException {
131+ List<Value> list = new ArrayList<Value>(1);
132+ list.add(value);
133+ setValues(index, list, 0, 1);
134+ }
135+
136+ public void setValues(List<? extends Value> values)
137+ throws InvalidTypeException,
138+ ClassNotLoadedException {
139+ setValues(0, values, 0, -1);
140+ }
141+
142+ public void setValues(int index, List<? extends Value> values,
143+ int srcIndex, int length)
144+ throws InvalidTypeException,
145+ ClassNotLoadedException {
146+
147+ if (length == -1) { // -1 means the rest of the array
148+ // shorter of, the rest of the array and rest of
149+ // the source values
150+ length = Math.min(length() - index,
151+ values.size() - srcIndex);
152+ }
153+ validateMirrorsOrNulls(values);
154+ validateArrayAccess(index, length);
155+
156+ if ((srcIndex < 0) || (srcIndex > values.size())) {
157+ throw new IndexOutOfBoundsException(
158+ "Invalid source index: " + srcIndex);
159+ }
160+ if (srcIndex + length > values.size()) {
161+ throw new IndexOutOfBoundsException(
162+ "Invalid source range: " +
163+ srcIndex + " to " +
164+ (srcIndex + length - 1));
165+ }
166+
167+ boolean somethingToSet = false;;
168+ ValueImpl[] setValues = new ValueImpl[length];
169+
170+ for (int i = 0; i < length; i++) {
171+ ValueImpl value = (ValueImpl)values.get(srcIndex + i);
172+
173+ try {
174+ // Validate and convert if necessary
175+ setValues[i] =
176+ ValueImpl.prepareForAssignment(value,
177+ new Component());
178+ somethingToSet = true;
179+ } catch (ClassNotLoadedException e) {
180+ /*
181+ * Since we got this exception,
182+ * the component must be a reference type.
183+ * This means the class has not yet been loaded
184+ * through the defining class's class loader.
185+ * If the value we're trying to set is null,
186+ * then setting to null is essentially a
187+ * no-op, and we should allow it without an
188+ * exception.
189+ */
190+ if (value != null) {
191+ throw e;
192+ }
193+ }
194+ }
195+ if (somethingToSet) {
196+ try {
197+ JDWP.ArrayReference.SetValues.
198+ process(vm, this, index, setValues);
199+ } catch (JDWPException exc) {
200+ throw exc.toJDIException();
201+ }
202+ }
203+ }
204+
205+ public String toString() {
206+ return "instance of " + arrayType().componentTypeName() +
207+ "[" + length() + "] (id=" + uniqueID() + ")";
208+ }
209+
210+ byte typeValueKey() {
211+ return JDWP.Tag.ARRAY;
212+ }
213+
214+ void validateAssignment(ValueContainer destination)
215+ throws InvalidTypeException, ClassNotLoadedException {
216+ try {
217+ super.validateAssignment(destination);
218+ } catch (ClassNotLoadedException e) {
219+ /*
220+ * An array can be used extensively without the
221+ * enclosing loader being recorded by the VM as an
222+ * initiating loader of the array type. In addition, the
223+ * load of an array class is fairly harmless as long as
224+ * the component class is already loaded. So we relax the
225+ * rules a bit and allow the assignment as long as the
226+ * ultimate component types are assignable.
227+ */
228+ boolean valid = false;
229+ JNITypeParser destParser = new JNITypeParser(
230+ destination.signature());
231+ JNITypeParser srcParser = new JNITypeParser(
232+ arrayType().signature());
233+ int destDims = destParser.dimensionCount();
234+ if (destDims <= srcParser.dimensionCount()) {
235+ /*
236+ * Remove all dimensions from the destination. Remove
237+ * the same number of dimensions from the source.
238+ * Get types for both and check to see if they are
239+ * compatible.
240+ */
241+ String destComponentSignature =
242+ destParser.componentSignature(destDims);
243+ Type destComponentType =
244+ destination.findType(destComponentSignature);
245+ String srcComponentSignature =
246+ srcParser.componentSignature(destDims);
247+ Type srcComponentType =
248+ arrayType().findComponentType(srcComponentSignature);
249+ valid = ArrayTypeImpl.isComponentAssignable(destComponentType,
250+ srcComponentType);
251+ }
252+
253+ if (!valid) {
254+ throw new InvalidTypeException("Cannot assign " +
255+ arrayType().name() +
256+ " to " +
257+ destination.typeName());
258+ }
259+ }
260+ }
261+
262+ /*
263+ * Represents an array component to other internal parts of this
264+ * implementation. This is not exposed at the JDI level. Currently,
265+ * this class is needed only for type checking so it does not even
266+ * reference a particular component - just a generic component
267+ * of this array. In the future we may need to expand its use.
268+ */
269+ class Component implements ValueContainer {
270+ public Type type() throws ClassNotLoadedException {
271+ return arrayType().componentType();
272+ }
273+ public String typeName() {
274+ return arrayType().componentTypeName();
275+ }
276+ public String signature() {
277+ return arrayType().componentSignature();
278+ }
279+ public Type findType(String signature) throws ClassNotLoadedException {
280+ return arrayType().findComponentType(signature);
281+ }
282+ }
283+}