2
|
1 |
/*
|
|
2 |
* Copyright 2001-2002 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 |
* @test
|
|
26 |
* @bug 4451941 4527072
|
|
27 |
* @summary Test argument types for invoke
|
|
28 |
*
|
|
29 |
* @author Robert Field
|
|
30 |
*
|
|
31 |
* @library ..
|
|
32 |
* @run build TestScaffold VMConnection TargetListener TargetAdapter
|
|
33 |
* @run compile -g InvokeTest.java
|
|
34 |
* @run main InvokeTest
|
|
35 |
*/
|
|
36 |
import com.sun.jdi.*;
|
|
37 |
import com.sun.jdi.event.*;
|
|
38 |
import com.sun.jdi.request.*;
|
|
39 |
|
|
40 |
import java.util.*;
|
|
41 |
|
|
42 |
/********** target program **********/
|
|
43 |
|
|
44 |
class InvokeTarg {
|
|
45 |
static InvokeTarg myself = null;
|
|
46 |
|
|
47 |
boolean[] aBooleanArray = new boolean[] {true, true};
|
|
48 |
byte[] aByteArray = new byte[] {4, 2};
|
|
49 |
char[] aCharArray = new char[] {'k', 'p'};
|
|
50 |
short[] aShortArray = new short[] {55,12, 12};
|
|
51 |
int[] aIntArray = new int[] {6, 3, 1};
|
|
52 |
long[] aLongArray = new long[] {3423423};
|
|
53 |
float[] aFloatArray = new float[] {(float)2.1};
|
|
54 |
double[] aDoubleArray = new double[] {3.141595358979};
|
|
55 |
|
|
56 |
boolean[][] aBoolean2DArray = new boolean[][]
|
|
57 |
{{true, false}, {false, true}};
|
|
58 |
byte[][] aByte2DArray = new byte[][] {{22,66}, {8,9}};
|
|
59 |
char[][] aChar2DArray = new char[][] {{22,66}, {8,9}};
|
|
60 |
short[][] aShort2DArray = new short[][] {{22,66}, {8,9}};
|
|
61 |
int[][] aInt2DArray = new int[][] {{22,66}, {8,9}};
|
|
62 |
long[][] aLong2DArray = new long[][] {{22,66}, {8,9}};
|
|
63 |
float[][] aFloat2DArray = new float[][] {{22,66}, {8,9}};
|
|
64 |
double[][] aDouble2DArray = new double[][] {{22,66}, {8,9}};
|
|
65 |
|
|
66 |
String[] aStringArray = new String[] {"testing"};
|
|
67 |
String[][] aString2DArray = new String[][]
|
|
68 |
{{"hi", "there"}, {"oh"}};
|
|
69 |
Date aDate = new Date();
|
|
70 |
Date[] aDateArray = new Date[] {};
|
|
71 |
Date[][] aDate2DArray = new Date[][] {{}};
|
|
72 |
|
|
73 |
String aString = "jjxx";
|
|
74 |
long longCheck = 0;
|
|
75 |
boolean booleanCheck = false;
|
|
76 |
boolean voidCheck = false;
|
|
77 |
Object objectCheck = null;
|
|
78 |
|
|
79 |
public static void main(String[] args){
|
|
80 |
System.out.println("Howdy!");
|
|
81 |
(new InvokeTarg()).sayHi();
|
|
82 |
}
|
|
83 |
|
|
84 |
void sayHi() {
|
|
85 |
}
|
|
86 |
|
|
87 |
void checkIn() {
|
|
88 |
}
|
|
89 |
|
|
90 |
boolean invokeVoid() {
|
|
91 |
voidCheck = true;
|
|
92 |
checkIn();
|
|
93 |
return true;
|
|
94 |
}
|
|
95 |
|
|
96 |
boolean invokeBoolean(boolean val) {
|
|
97 |
booleanCheck = val;
|
|
98 |
checkIn();
|
|
99 |
return val;
|
|
100 |
}
|
|
101 |
|
|
102 |
byte invokeByte(byte val) {
|
|
103 |
longCheck = val;
|
|
104 |
checkIn();
|
|
105 |
return val;
|
|
106 |
}
|
|
107 |
|
|
108 |
char invokeChar(char val) {
|
|
109 |
longCheck = val;
|
|
110 |
checkIn();
|
|
111 |
return val;
|
|
112 |
}
|
|
113 |
|
|
114 |
short invokeShort(short val) {
|
|
115 |
longCheck = val;
|
|
116 |
checkIn();
|
|
117 |
return val;
|
|
118 |
}
|
|
119 |
|
|
120 |
int invokeInt(int val) {
|
|
121 |
longCheck = val;
|
|
122 |
checkIn();
|
|
123 |
return val;
|
|
124 |
}
|
|
125 |
|
|
126 |
long invokeLong(long val) {
|
|
127 |
longCheck = val;
|
|
128 |
checkIn();
|
|
129 |
return val;
|
|
130 |
}
|
|
131 |
|
|
132 |
float invokeFloat(float val) {
|
|
133 |
longCheck = (long)val;
|
|
134 |
checkIn();
|
|
135 |
return val;
|
|
136 |
}
|
|
137 |
|
|
138 |
double invokeDouble(double val) {
|
|
139 |
longCheck = (long)val;
|
|
140 |
checkIn();
|
|
141 |
return val;
|
|
142 |
}
|
|
143 |
|
|
144 |
boolean[] invokeBooleanArray(boolean[] val) {
|
|
145 |
objectCheck = val;
|
|
146 |
checkIn();
|
|
147 |
return val;
|
|
148 |
}
|
|
149 |
|
|
150 |
byte[] invokeByteArray(byte[] val) {
|
|
151 |
objectCheck = val;
|
|
152 |
checkIn();
|
|
153 |
return val;
|
|
154 |
}
|
|
155 |
|
|
156 |
char[] invokeCharArray(char[] val) {
|
|
157 |
objectCheck = val;
|
|
158 |
checkIn();
|
|
159 |
return val;
|
|
160 |
}
|
|
161 |
|
|
162 |
short[] invokeShortArray(short[] val) {
|
|
163 |
objectCheck = val;
|
|
164 |
checkIn();
|
|
165 |
return val;
|
|
166 |
}
|
|
167 |
|
|
168 |
int[] invokeIntArray(int[] val) {
|
|
169 |
objectCheck = val;
|
|
170 |
checkIn();
|
|
171 |
return val;
|
|
172 |
}
|
|
173 |
|
|
174 |
long[] invokeLongArray(long[] val) {
|
|
175 |
objectCheck = val;
|
|
176 |
checkIn();
|
|
177 |
return val;
|
|
178 |
}
|
|
179 |
|
|
180 |
float[] invokeFloatArray(float[] val) {
|
|
181 |
objectCheck = val;
|
|
182 |
checkIn();
|
|
183 |
return val;
|
|
184 |
}
|
|
185 |
|
|
186 |
double[] invokeDoubleArray(double[] val) {
|
|
187 |
objectCheck = val;
|
|
188 |
checkIn();
|
|
189 |
return val;
|
|
190 |
}
|
|
191 |
|
|
192 |
boolean[][] invokeBoolean2DArray(boolean[][] val) {
|
|
193 |
objectCheck = val;
|
|
194 |
checkIn();
|
|
195 |
return val;
|
|
196 |
}
|
|
197 |
|
|
198 |
byte[][] invokeByte2DArray(byte[][] val) {
|
|
199 |
objectCheck = val;
|
|
200 |
checkIn();
|
|
201 |
return val;
|
|
202 |
}
|
|
203 |
|
|
204 |
char[][] invokeChar2DArray(char[][] val) {
|
|
205 |
objectCheck = val;
|
|
206 |
checkIn();
|
|
207 |
return val;
|
|
208 |
}
|
|
209 |
|
|
210 |
short[][] invokeShort2DArray(short[][] val) {
|
|
211 |
objectCheck = val;
|
|
212 |
checkIn();
|
|
213 |
return val;
|
|
214 |
}
|
|
215 |
|
|
216 |
int[][] invokeInt2DArray(int[][] val) {
|
|
217 |
objectCheck = val;
|
|
218 |
checkIn();
|
|
219 |
return val;
|
|
220 |
}
|
|
221 |
|
|
222 |
long[][] invokeLong2DArray(long[][] val) {
|
|
223 |
objectCheck = val;
|
|
224 |
checkIn();
|
|
225 |
return val;
|
|
226 |
}
|
|
227 |
|
|
228 |
float[][] invokeFloat2DArray(float[][] val) {
|
|
229 |
objectCheck = val;
|
|
230 |
checkIn();
|
|
231 |
return val;
|
|
232 |
}
|
|
233 |
|
|
234 |
double[][] invokeDouble2DArray(double[][] val) {
|
|
235 |
objectCheck = val;
|
|
236 |
checkIn();
|
|
237 |
return val;
|
|
238 |
}
|
|
239 |
|
|
240 |
String invokeString(String val) {
|
|
241 |
objectCheck = val;
|
|
242 |
checkIn();
|
|
243 |
return val;
|
|
244 |
}
|
|
245 |
|
|
246 |
String[] invokeStringArray(String[] val) {
|
|
247 |
objectCheck = val;
|
|
248 |
checkIn();
|
|
249 |
return val;
|
|
250 |
}
|
|
251 |
|
|
252 |
String[][] invokeString2DArray(String[][] val) {
|
|
253 |
objectCheck = val;
|
|
254 |
checkIn();
|
|
255 |
return val;
|
|
256 |
}
|
|
257 |
|
|
258 |
Date invokeDate(Date val) {
|
|
259 |
objectCheck = val;
|
|
260 |
checkIn();
|
|
261 |
return val;
|
|
262 |
}
|
|
263 |
|
|
264 |
Date[] invokeDateArray(Date[] val) {
|
|
265 |
objectCheck = val;
|
|
266 |
checkIn();
|
|
267 |
return val;
|
|
268 |
}
|
|
269 |
|
|
270 |
Date[][] invokeDate2DArray(Date[][] val) {
|
|
271 |
objectCheck = val;
|
|
272 |
checkIn();
|
|
273 |
return val;
|
|
274 |
}
|
|
275 |
|
|
276 |
String invokeCombo(int[][] arr, String val) {
|
|
277 |
objectCheck = val;
|
|
278 |
checkIn();
|
|
279 |
return val;
|
|
280 |
}
|
|
281 |
|
|
282 |
int[][] invokeCombo2(int[][] val, String str) {
|
|
283 |
objectCheck = val;
|
|
284 |
checkIn();
|
|
285 |
return val;
|
|
286 |
}
|
|
287 |
}
|
|
288 |
|
|
289 |
/********** test program **********/
|
|
290 |
|
|
291 |
public class InvokeTest extends TestScaffold {
|
|
292 |
ReferenceType targetClass;
|
|
293 |
ThreadReference mainThread;
|
|
294 |
ObjectReference thisObject;
|
|
295 |
Field longCheckField;
|
|
296 |
Field booleanCheckField;
|
|
297 |
Field voidCheckField;
|
|
298 |
Field objectCheckField;
|
|
299 |
Value longValue;
|
|
300 |
Value booleanValue;
|
|
301 |
Value objectValue;
|
|
302 |
Value voidValue;
|
|
303 |
|
|
304 |
InvokeTest (String args[]) {
|
|
305 |
super(args);
|
|
306 |
}
|
|
307 |
|
|
308 |
public static void main(String[] args) throws Exception {
|
|
309 |
new InvokeTest(args).startTests();
|
|
310 |
}
|
|
311 |
|
|
312 |
/********** event handlers **********/
|
|
313 |
|
|
314 |
// not use now
|
|
315 |
public void breakpointReached(BreakpointEvent event) {
|
|
316 |
println("Got BreakpointEvent");
|
|
317 |
longValue = thisObject.getValue(longCheckField);
|
|
318 |
booleanValue = thisObject.getValue(booleanCheckField);
|
|
319 |
objectValue = thisObject.getValue(objectCheckField);
|
|
320 |
voidValue = thisObject.getValue(voidCheckField);
|
|
321 |
}
|
|
322 |
|
|
323 |
/********** test assist **********/
|
|
324 |
|
|
325 |
void invoke(Method method, List args, Value value) {
|
|
326 |
Value returnValue = null;
|
|
327 |
|
|
328 |
try {
|
|
329 |
returnValue = thisObject.invokeMethod(mainThread,
|
|
330 |
method, args, 0);
|
|
331 |
} catch ( Exception ee) {
|
|
332 |
println("Got Exception: " + ee);
|
|
333 |
ee.printStackTrace();
|
|
334 |
}
|
|
335 |
println(" return val = " + returnValue);
|
|
336 |
// It has to be the same value as what we passed in!
|
|
337 |
if (returnValue.equals(value)) {
|
|
338 |
println(" " + method.name() + " return value matches: "
|
|
339 |
+ value);
|
|
340 |
} else {
|
|
341 |
if (value != null) {
|
|
342 |
failure("FAIL: " + method.name() + " returned: " + returnValue +
|
|
343 |
" expected: " + value );
|
|
344 |
} else {
|
|
345 |
println(" " + method.name() + " return value : " + returnValue);
|
|
346 |
}
|
|
347 |
|
|
348 |
}
|
|
349 |
Value checkValue = (value instanceof PrimitiveValue)?
|
|
350 |
((value instanceof BooleanValue)?
|
|
351 |
booleanValue : longValue) :
|
|
352 |
objectValue;
|
|
353 |
}
|
|
354 |
|
|
355 |
|
|
356 |
void invoke(String methodName, String methodSig,
|
|
357 |
List args, Value value)
|
|
358 |
throws Exception {
|
|
359 |
Method method = findMethod(targetClass, methodName, methodSig);
|
|
360 |
if ( method == null) {
|
|
361 |
failure("FAILED: Can't find method: " + methodName + " for class = " + targetClass);
|
|
362 |
return;
|
|
363 |
}
|
|
364 |
invoke(method, args, value);
|
|
365 |
}
|
|
366 |
|
|
367 |
void invoke(String methodName, String methodSig, Value value)
|
|
368 |
throws Exception {
|
|
369 |
List args = new ArrayList(1);
|
|
370 |
args.add(value);
|
|
371 |
invoke(methodName, methodSig, args, value);
|
|
372 |
}
|
|
373 |
|
|
374 |
|
|
375 |
void invoke(String methodName, String methodSig, String fieldName)
|
|
376 |
throws Exception {
|
|
377 |
invoke(methodName, methodSig, fieldValue(fieldName));
|
|
378 |
}
|
|
379 |
|
|
380 |
private Method toStringMethod;
|
|
381 |
Method gettoStringMethod() {
|
|
382 |
if ( toStringMethod != null) {
|
|
383 |
return toStringMethod;
|
|
384 |
}
|
|
385 |
|
|
386 |
// We have to find it. First find java.lang.Object
|
|
387 |
List myClasses = vm().allClasses();
|
|
388 |
Iterator iter = myClasses.iterator();
|
|
389 |
ReferenceType objectMirror = null;
|
|
390 |
while (iter.hasNext()) {
|
|
391 |
ReferenceType xx = (ReferenceType)iter.next();
|
|
392 |
if (xx.name().equals("java.lang.Object")) {
|
|
393 |
objectMirror = xx;
|
|
394 |
break;
|
|
395 |
}
|
|
396 |
}
|
|
397 |
|
|
398 |
if (objectMirror == null) {
|
|
399 |
return null;
|
|
400 |
}
|
|
401 |
|
|
402 |
// Then find toSting
|
|
403 |
List meths = objectMirror.methods();
|
|
404 |
iter = meths.iterator();
|
|
405 |
while (iter.hasNext()) {
|
|
406 |
toStringMethod = (Method)iter.next();
|
|
407 |
if (toStringMethod.name().equals("toString")) {
|
|
408 |
return toStringMethod;
|
|
409 |
}
|
|
410 |
}
|
|
411 |
toStringMethod = null;
|
|
412 |
return null;
|
|
413 |
}
|
|
414 |
|
|
415 |
// This calls toString on a field
|
|
416 |
protected void callToString(String fieldName) throws Exception {
|
|
417 |
// Sorry for this kludgy use of global vars.
|
|
418 |
ObjectReference saveObject = thisObject;
|
|
419 |
Method toStringMethod = gettoStringMethod();
|
|
420 |
|
|
421 |
Field theField = targetClass.fieldByName(fieldName);
|
|
422 |
thisObject = (ObjectReference)thisObject.getValue( theField);
|
|
423 |
invoke(toStringMethod, new ArrayList(0), null);
|
|
424 |
thisObject = saveObject;
|
|
425 |
}
|
|
426 |
|
|
427 |
Value fieldValue(String fieldName) {
|
|
428 |
Field field = targetClass.fieldByName(fieldName);
|
|
429 |
return thisObject.getValue(field);
|
|
430 |
}
|
|
431 |
|
|
432 |
|
|
433 |
/********** test core **********/
|
|
434 |
|
|
435 |
protected void runTests() throws Exception {
|
|
436 |
/*
|
|
437 |
* Get to the top of sayHi()
|
|
438 |
* to determine targetClass and mainThread
|
|
439 |
*/
|
|
440 |
BreakpointEvent bpe = startTo("InvokeTarg", "sayHi", "()V");
|
|
441 |
targetClass = bpe.location().declaringType();
|
|
442 |
|
|
443 |
mainThread = bpe.thread();
|
|
444 |
|
|
445 |
StackFrame frame = mainThread.frame(0);
|
|
446 |
thisObject = frame.thisObject();
|
|
447 |
longCheckField = targetClass.fieldByName("longCheck");
|
|
448 |
booleanCheckField = targetClass.fieldByName("booleanCheck");
|
|
449 |
objectCheckField = targetClass.fieldByName("objectCheck");
|
|
450 |
voidCheckField = targetClass.fieldByName("voidCheck");
|
|
451 |
callToString("aBooleanArray");
|
|
452 |
|
|
453 |
invoke("invokeVoid", "()Z", new ArrayList(0), vm().mirrorOf(true));
|
|
454 |
|
|
455 |
invoke("invokeBoolean", "(Z)Z", vm().mirrorOf(true));
|
|
456 |
invoke("invokeByte", "(B)B", vm().mirrorOf((byte)14));
|
|
457 |
invoke("invokeChar", "(C)C", vm().mirrorOf('h'));
|
|
458 |
invoke("invokeShort", "(S)S", vm().mirrorOf((short)54));
|
|
459 |
invoke("invokeInt", "(I)I", vm().mirrorOf((int)414));
|
|
460 |
invoke("invokeLong", "(J)J", vm().mirrorOf((long)140000));
|
|
461 |
invoke("invokeFloat", "(F)F", vm().mirrorOf((float)315));
|
|
462 |
invoke("invokeDouble", "(D)D", vm().mirrorOf((double)181818));
|
|
463 |
|
|
464 |
invoke("invokeBooleanArray", "([Z)[Z", "aBooleanArray");
|
|
465 |
invoke("invokeByteArray", "([B)[B", "aByteArray");
|
|
466 |
invoke("invokeCharArray", "([C)[C", "aCharArray");
|
|
467 |
invoke("invokeShortArray", "([S)[S", "aShortArray");
|
|
468 |
invoke("invokeIntArray", "([I)[I", "aIntArray");
|
|
469 |
invoke("invokeLongArray", "([J)[J", "aLongArray");
|
|
470 |
invoke("invokeFloatArray", "([F)[F", "aFloatArray");
|
|
471 |
invoke("invokeDoubleArray", "([D)[D", "aDoubleArray");
|
|
472 |
|
|
473 |
invoke("invokeBoolean2DArray", "([[Z)[[Z", "aBoolean2DArray");
|
|
474 |
invoke("invokeByte2DArray", "([[B)[[B", "aByte2DArray");
|
|
475 |
invoke("invokeChar2DArray", "([[C)[[C", "aChar2DArray");
|
|
476 |
invoke("invokeShort2DArray", "([[S)[[S", "aShort2DArray");
|
|
477 |
invoke("invokeInt2DArray", "([[I)[[I", "aInt2DArray");
|
|
478 |
invoke("invokeLong2DArray", "([[J)[[J", "aLong2DArray");
|
|
479 |
invoke("invokeFloat2DArray", "([[F)[[F", "aFloat2DArray");
|
|
480 |
invoke("invokeDouble2DArray", "([[D)[[D", "aDouble2DArray");
|
|
481 |
|
|
482 |
invoke("invokeString", "(Ljava/lang/String;)Ljava/lang/String;",
|
|
483 |
vm().mirrorOf("Howdy"));
|
|
484 |
invoke("invokeStringArray", "([Ljava/lang/String;)[Ljava/lang/String;",
|
|
485 |
"aStringArray");
|
|
486 |
invoke("invokeString2DArray", "([[Ljava/lang/String;)[[Ljava/lang/String;",
|
|
487 |
"aString2DArray");
|
|
488 |
|
|
489 |
invoke("invokeDate", "(Ljava/util/Date;)Ljava/util/Date;",
|
|
490 |
"aDate");
|
|
491 |
invoke("invokeDateArray", "([Ljava/util/Date;)[Ljava/util/Date;",
|
|
492 |
"aDateArray");
|
|
493 |
invoke("invokeDate2DArray", "([[Ljava/util/Date;)[[Ljava/util/Date;",
|
|
494 |
"aDate2DArray");
|
|
495 |
|
|
496 |
Value i2 = fieldValue("aInt2DArray");
|
|
497 |
Value str = vm().mirrorOf("Later");
|
|
498 |
List args = new ArrayList(2);
|
|
499 |
args.add(i2);
|
|
500 |
args.add(str);
|
|
501 |
invoke("invokeCombo",
|
|
502 |
"([[ILjava/lang/String;)Ljava/lang/String;",
|
|
503 |
args, str);
|
|
504 |
invoke("invokeCombo2",
|
|
505 |
"([[ILjava/lang/String;)[[I",
|
|
506 |
args, i2);
|
|
507 |
/*
|
|
508 |
* resume the target listening for events
|
|
509 |
*/
|
|
510 |
listenUntilVMDisconnect();
|
|
511 |
|
|
512 |
/*
|
|
513 |
* deal with results of test
|
|
514 |
* if anything has called failure("foo") testFailed will be true
|
|
515 |
*/
|
|
516 |
if (!testFailed) {
|
|
517 |
println("InvokeTest: passed");
|
|
518 |
} else {
|
|
519 |
throw new Exception("InvokeTest: failed");
|
|
520 |
}
|
|
521 |
}
|
|
522 |
}
|