blob: 5d489d9d2fb404d5c0da56b3ae3554fbbbf6487d [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1998-2005 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26#include "util.h"
27#include "ArrayReferenceImpl.h"
28#include "inStream.h"
29#include "outStream.h"
30
31static jboolean
32length(PacketInputStream *in, PacketOutputStream *out)
33{
34 JNIEnv *env = getEnv();
35 jsize arrayLength;
36
37 jarray array = inStream_readArrayRef(env, in);
38 if (inStream_error(in)) {
39 return JNI_TRUE;
40 }
41
42 arrayLength = JNI_FUNC_PTR(env,GetArrayLength)(env, array);
43 (void)outStream_writeInt(out, arrayLength);
44 return JNI_TRUE;
45}
46
47static void *
48newComponents(PacketOutputStream *out, jint length, size_t nbytes)
49{
50 void *ptr = NULL;
51
52 if ( length > 0 ) {
53 ptr = jvmtiAllocate(length*((jint)nbytes));
54 if ( ptr == NULL ) {
55 outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY));
56 } else {
57 (void)memset(ptr, 0, length*nbytes);
58 }
59 }
60 return ptr;
61}
62
63static void
64deleteComponents(void *ptr)
65{
66 jvmtiDeallocate(ptr);
67}
68
69static void
70writeBooleanComponents(JNIEnv *env, PacketOutputStream *out,
71 jarray array, jint index, jint length)
72{
73 jboolean *components;
74
75 components = newComponents(out, length, sizeof(jboolean));
76 if (components != NULL) {
77 jint i;
78 JNI_FUNC_PTR(env,GetBooleanArrayRegion)(env, array, index, length, components);
79 for (i = 0; i < length; i++) {
80 (void)outStream_writeBoolean(out, components[i]);
81 }
82 deleteComponents(components);
83 }
84}
85
86static void
87writeByteComponents(JNIEnv *env, PacketOutputStream *out,
88 jarray array, jint index, jint length)
89{
90 jbyte *components;
91
92 components = newComponents(out, length, sizeof(jbyte));
93 if (components != NULL) {
94 jint i;
95 JNI_FUNC_PTR(env,GetByteArrayRegion)(env, array, index, length, components);
96 for (i = 0; i < length; i++) {
97 (void)outStream_writeByte(out, components[i]);
98 }
99 deleteComponents(components);
100 }
101}
102
103static void
104writeCharComponents(JNIEnv *env, PacketOutputStream *out,
105 jarray array, jint index, jint length)
106{
107 jchar *components;
108
109 components = newComponents(out, length, sizeof(jchar));
110 if (components != NULL) {
111 jint i;
112 JNI_FUNC_PTR(env,GetCharArrayRegion)(env, array, index, length, components);
113 for (i = 0; i < length; i++) {
114 (void)outStream_writeChar(out, components[i]);
115 }
116 deleteComponents(components);
117 }
118}
119
120static void
121writeShortComponents(JNIEnv *env, PacketOutputStream *out,
122 jarray array, jint index, jint length)
123{
124 jshort *components;
125
126 components = newComponents(out, length, sizeof(jshort));
127 if (components != NULL) {
128 jint i;
129 JNI_FUNC_PTR(env,GetShortArrayRegion)(env, array, index, length, components);
130 for (i = 0; i < length; i++) {
131 (void)outStream_writeShort(out, components[i]);
132 }
133 deleteComponents(components);
134 }
135}
136
137static void
138writeIntComponents(JNIEnv *env, PacketOutputStream *out,
139 jarray array, jint index, jint length)
140{
141 jint *components;
142
143 components = newComponents(out, length, sizeof(jint));
144 if (components != NULL) {
145 jint i;
146 JNI_FUNC_PTR(env,GetIntArrayRegion)(env, array, index, length, components);
147 for (i = 0; i < length; i++) {
148 (void)outStream_writeInt(out, components[i]);
149 }
150 deleteComponents(components);
151 }
152}
153
154static void
155writeLongComponents(JNIEnv *env, PacketOutputStream *out,
156 jarray array, jint index, jint length)
157{
158 jlong *components;
159
160 components = newComponents(out, length, sizeof(jlong));
161 if (components != NULL) {
162 jint i;
163 JNI_FUNC_PTR(env,GetLongArrayRegion)(env, array, index, length, components);
164 for (i = 0; i < length; i++) {
165 (void)outStream_writeLong(out, components[i]);
166 }
167 deleteComponents(components);
168 }
169}
170
171static void
172writeFloatComponents(JNIEnv *env, PacketOutputStream *out,
173 jarray array, jint index, jint length)
174{
175 jfloat *components;
176
177 components = newComponents(out, length, sizeof(jfloat));
178 if (components != NULL) {
179 jint i;
180 JNI_FUNC_PTR(env,GetFloatArrayRegion)(env, array, index, length, components);
181 for (i = 0; i < length; i++) {
182 (void)outStream_writeFloat(out, components[i]);
183 }
184 deleteComponents(components);
185 }
186}
187
188static void
189writeDoubleComponents(JNIEnv *env, PacketOutputStream *out,
190 jarray array, jint index, jint length)
191{
192 jdouble *components;
193
194 components = newComponents(out, length, sizeof(jdouble));
195 if (components != NULL) {
196 jint i;
197 JNI_FUNC_PTR(env,GetDoubleArrayRegion)(env, array, index, length, components);
198 for (i = 0; i < length; i++) {
199 (void)outStream_writeDouble(out, components[i]);
200 }
201 deleteComponents(components);
202 }
203}
204
205static void
206writeObjectComponents(JNIEnv *env, PacketOutputStream *out,
207 jarray array, jint index, jint length)
208{
209
210 WITH_LOCAL_REFS(env, length) {
211
212 int i;
213 jobject component;
214
215 for (i = 0; i < length; i++) {
216 component = JNI_FUNC_PTR(env,GetObjectArrayElement)(env, array, index + i);
217 if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
218 /* cleared by caller */
219 break;
220 }
221 (void)outStream_writeByte(out, specificTypeKey(env, component));
222 (void)outStream_writeObjectRef(env, out, component);
223 }
224
225 } END_WITH_LOCAL_REFS(env);
226}
227
228static jboolean
229getValues(PacketInputStream *in, PacketOutputStream *out)
230{
231 JNIEnv *env = getEnv();
232 jint arrayLength;
233 jarray array;
234 jint index;
235 jint length;
236
237 array = inStream_readArrayRef(env, in);
238 if (inStream_error(in)) {
239 return JNI_TRUE;
240 }
241 index = inStream_readInt(in);
242 if (inStream_error(in)) {
243 return JNI_TRUE;
244 }
245 length = inStream_readInt(in);
246 if (inStream_error(in)) {
247 return JNI_TRUE;
248 }
249
250 arrayLength = JNI_FUNC_PTR(env,GetArrayLength)(env, array);
251
252 if (length == -1) {
253 length = arrayLength - index;
254 }
255
256 if ((index < 0) || (index > arrayLength - 1)) {
257 outStream_setError(out, JDWP_ERROR(INVALID_INDEX));
258 return JNI_TRUE;
259 }
260
261 if ((length < 0) || (length + index > arrayLength)) {
262 outStream_setError(out, JDWP_ERROR(INVALID_LENGTH));
263 return JNI_TRUE;
264 }
265
266 WITH_LOCAL_REFS(env, 1) {
267
268 jclass arrayClass;
269 char *signature = NULL;
270 char *componentSignature;
271 jbyte typeKey;
272 jvmtiError error;
273
274 arrayClass = JNI_FUNC_PTR(env,GetObjectClass)(env, array);
275 error = classSignature(arrayClass, &signature, NULL);
276 if (error != JVMTI_ERROR_NONE) {
277 goto err;
278 }
279 componentSignature = &signature[1];
280 typeKey = componentSignature[0];
281
282 (void)outStream_writeByte(out, typeKey);
283 (void)outStream_writeInt(out, length);
284
285 if (isObjectTag(typeKey)) {
286 writeObjectComponents(env, out, array, index, length);
287 } else {
288 switch (typeKey) {
289 case JDWP_TAG(BYTE):
290 writeByteComponents(env, out, array, index, length);
291 break;
292
293 case JDWP_TAG(CHAR):
294 writeCharComponents(env, out, array, index, length);
295 break;
296
297 case JDWP_TAG(FLOAT):
298 writeFloatComponents(env, out, array, index, length);
299 break;
300
301 case JDWP_TAG(DOUBLE):
302 writeDoubleComponents(env, out, array, index, length);
303 break;
304
305 case JDWP_TAG(INT):
306 writeIntComponents(env, out, array, index, length);
307 break;
308
309 case JDWP_TAG(LONG):
310 writeLongComponents(env, out, array, index, length);
311 break;
312
313 case JDWP_TAG(SHORT):
314 writeShortComponents(env, out, array, index, length);
315 break;
316
317 case JDWP_TAG(BOOLEAN):
318 writeBooleanComponents(env, out, array, index, length);
319 break;
320
321 default:
322 outStream_setError(out, JDWP_ERROR(INVALID_TAG));
323 break;
324 }
325 }
326
327 jvmtiDeallocate(signature);
328
329 err:;
330
331 } END_WITH_LOCAL_REFS(env);
332
333 if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
334 outStream_setError(out, JDWP_ERROR(INTERNAL));
335 JNI_FUNC_PTR(env,ExceptionClear)(env);
336 }
337
338 return JNI_TRUE;
339}
340
341static jdwpError
342readBooleanComponents(JNIEnv *env, PacketInputStream *in,
343 jarray array, int index, int length)
344{
345 int i;
346 jboolean component;
347
348 for (i = 0; (i < length) && !inStream_error(in); i++) {
349 component = inStream_readBoolean(in);
350 JNI_FUNC_PTR(env,SetBooleanArrayRegion)(env, array, index + i, 1, &component);
351 }
352 return inStream_error(in);
353}
354
355static jdwpError
356readByteComponents(JNIEnv *env, PacketInputStream *in,
357 jarray array, int index, int length)
358{
359 int i;
360 jbyte component;
361
362 for (i = 0; (i < length) && !inStream_error(in); i++) {
363 component = inStream_readByte(in);
364 JNI_FUNC_PTR(env,SetByteArrayRegion)(env, array, index + i, 1, &component);
365 }
366 return inStream_error(in);
367}
368
369static jdwpError
370readCharComponents(JNIEnv *env, PacketInputStream *in,
371 jarray array, int index, int length)
372{
373 int i;
374 jchar component;
375
376 for (i = 0; (i < length) && !inStream_error(in); i++) {
377 component = inStream_readChar(in);
378 JNI_FUNC_PTR(env,SetCharArrayRegion)(env, array, index + i, 1, &component);
379 }
380 return inStream_error(in);
381}
382
383static jdwpError
384readShortComponents(JNIEnv *env, PacketInputStream *in,
385 jarray array, int index, int length)
386{
387 int i;
388 jshort component;
389
390 for (i = 0; (i < length) && !inStream_error(in); i++) {
391 component = inStream_readShort(in);
392 JNI_FUNC_PTR(env,SetShortArrayRegion)(env, array, index + i, 1, &component);
393 }
394 return inStream_error(in);
395}
396
397static jdwpError
398readIntComponents(JNIEnv *env, PacketInputStream *in,
399 jarray array, int index, int length)
400{
401 int i;
402 jint component;
403
404 for (i = 0; (i < length) && !inStream_error(in); i++) {
405 component = inStream_readInt(in);
406 JNI_FUNC_PTR(env,SetIntArrayRegion)(env, array, index + i, 1, &component);
407 }
408 return inStream_error(in);
409}
410
411static jdwpError
412readLongComponents(JNIEnv *env, PacketInputStream *in,
413 jarray array, int index, int length)
414{
415 int i;
416 jlong component;
417
418 for (i = 0; (i < length) && !inStream_error(in); i++) {
419 component = inStream_readLong(in);
420 JNI_FUNC_PTR(env,SetLongArrayRegion)(env, array, index + i, 1, &component);
421 }
422 return inStream_error(in);
423}
424
425static jdwpError
426readFloatComponents(JNIEnv *env, PacketInputStream *in,
427 jarray array, int index, int length)
428{
429 int i;
430 jfloat component;
431
432 for (i = 0; (i < length) && !inStream_error(in); i++) {
433 component = inStream_readFloat(in);
434 JNI_FUNC_PTR(env,SetFloatArrayRegion)(env, array, index + i, 1, &component);
435 }
436 return inStream_error(in);
437}
438
439static jdwpError
440readDoubleComponents(JNIEnv *env, PacketInputStream *in,
441 jarray array, int index, int length)
442{
443 int i;
444 jdouble component;
445
446 for (i = 0; (i < length) && !inStream_error(in); i++) {
447 component = inStream_readDouble(in);
448 JNI_FUNC_PTR(env,SetDoubleArrayRegion)(env, array, index + i, 1, &component);
449 }
450 return inStream_error(in);
451}
452
453
454static jdwpError
455readObjectComponents(JNIEnv *env, PacketInputStream *in,
456 jarray array, int index, int length)
457 /* char *componentSignature) */
458{
459 int i;
460
461 for (i = 0; i < length; i++) {
462 jobject object = inStream_readObjectRef(env, in);
463
464 JNI_FUNC_PTR(env,SetObjectArrayElement)(env, array, index + i, object);
465 if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
466 /* caller will clear */
467 break;
468 }
469 }
470
471 return JDWP_ERROR(NONE);
472}
473
474
475static jboolean
476setValues(PacketInputStream *in, PacketOutputStream *out)
477{
478 JNIEnv *env = getEnv();
479 jdwpError serror = JDWP_ERROR(NONE);
480 int arrayLength;
481 jarray array;
482 jint index;
483 jint length;
484
485 array = inStream_readArrayRef(env, in);
486 if (inStream_error(in)) {
487 return JNI_TRUE;
488 }
489 index = inStream_readInt(in);
490 if (inStream_error(in)) {
491 return JNI_TRUE;
492 }
493 length = inStream_readInt(in);
494 if (inStream_error(in)) {
495 return JNI_TRUE;
496 }
497
498 arrayLength = JNI_FUNC_PTR(env,GetArrayLength)(env, array);
499
500 if ((index < 0) || (index > arrayLength - 1)) {
501 outStream_setError(out, JDWP_ERROR(INVALID_INDEX));
502 return JNI_TRUE;
503 }
504
505 if ((length < 0) || (length + index > arrayLength)) {
506 outStream_setError(out, JDWP_ERROR(INVALID_LENGTH));
507 return JNI_TRUE;
508 }
509
510 WITH_LOCAL_REFS(env, 1) {
511
512 jclass arrayClass;
513 char *signature = NULL;
514 char *componentSignature;
515 jvmtiError error;
516
517 arrayClass = JNI_FUNC_PTR(env,GetObjectClass)(env, array);
518 error = classSignature(arrayClass, &signature, NULL);
519 if (error != JVMTI_ERROR_NONE) {
520 goto err;
521 }
522 componentSignature = &signature[1];
523
524 switch (componentSignature[0]) {
525 case JDWP_TAG(OBJECT):
526 case JDWP_TAG(ARRAY):
527 serror = readObjectComponents(env, in, array, index, length);
528 break;
529
530 case JDWP_TAG(BYTE):
531 serror = readByteComponents(env, in, array, index, length);
532 break;
533
534 case JDWP_TAG(CHAR):
535 serror = readCharComponents(env, in, array, index, length);
536 break;
537
538 case JDWP_TAG(FLOAT):
539 serror = readFloatComponents(env, in, array, index, length);
540 break;
541
542 case JDWP_TAG(DOUBLE):
543 serror = readDoubleComponents(env, in, array, index, length);
544 break;
545
546 case JDWP_TAG(INT):
547 serror = readIntComponents(env, in, array, index, length);
548 break;
549
550 case JDWP_TAG(LONG):
551 serror = readLongComponents(env, in, array, index, length);
552 break;
553
554 case JDWP_TAG(SHORT):
555 serror = readShortComponents(env, in, array, index, length);
556 break;
557
558 case JDWP_TAG(BOOLEAN):
559 serror = readBooleanComponents(env, in, array, index, length);
560 break;
561
562 default:
563 {
564 ERROR_MESSAGE(("Invalid array component signature: %s",
565 componentSignature));
566 EXIT_ERROR(AGENT_ERROR_INVALID_OBJECT,NULL);
567 }
568 break;
569 }
570
571 jvmtiDeallocate(signature);
572
573 err:;
574
575 } END_WITH_LOCAL_REFS(env);
576
577 if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
578 /*
579 * TO DO: Check exception type
580 */
581 serror = JDWP_ERROR(TYPE_MISMATCH);
582 JNI_FUNC_PTR(env,ExceptionClear)(env);
583 }
584
585 outStream_setError(out, serror);
586 return JNI_TRUE;
587}
588
589
590void *ArrayReference_Cmds[] = { (void *)0x3
591 ,(void *)length
592 ,(void *)getValues
593 ,(void *)setValues};