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