/*
* Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 4451941 4527072
* @summary Test argument types for invoke
* @author Robert Field
*
* @library ..
*
* @run build TestScaffold VMConnection TargetListener TargetAdapter
* @run compile -g InvokeTest.java
* @run driver InvokeTest
*/
import com.sun.jdi.*;
import com.sun.jdi.event.*;
import com.sun.jdi.request.*;
import java.util.*;
/********** target program **********/
class InvokeTarg {
static InvokeTarg myself = null;
boolean[] aBooleanArray = new boolean[] {true, true};
byte[] aByteArray = new byte[] {4, 2};
char[] aCharArray = new char[] {'k', 'p'};
short[] aShortArray = new short[] {55,12, 12};
int[] aIntArray = new int[] {6, 3, 1};
long[] aLongArray = new long[] {3423423};
float[] aFloatArray = new float[] {(float)2.1};
double[] aDoubleArray = new double[] {3.141595358979};
boolean[][] aBoolean2DArray = new boolean[][]
{{true, false}, {false, true}};
byte[][] aByte2DArray = new byte[][] {{22,66}, {8,9}};
char[][] aChar2DArray = new char[][] {{22,66}, {8,9}};
short[][] aShort2DArray = new short[][] {{22,66}, {8,9}};
int[][] aInt2DArray = new int[][] {{22,66}, {8,9}};
long[][] aLong2DArray = new long[][] {{22,66}, {8,9}};
float[][] aFloat2DArray = new float[][] {{22,66}, {8,9}};
double[][] aDouble2DArray = new double[][] {{22,66}, {8,9}};
String[] aStringArray = new String[] {"testing"};
String[][] aString2DArray = new String[][]
{{"hi", "there"}, {"oh"}};
Date aDate = new Date();
Date[] aDateArray = new Date[] {};
Date[][] aDate2DArray = new Date[][] {{}};
String aString = "jjxx";
long longCheck = 0;
boolean booleanCheck = false;
boolean voidCheck = false;
Object objectCheck = null;
public static void main(String[] args){
System.out.println("Howdy!");
(new InvokeTarg()).sayHi();
}
void sayHi() {
}
void checkIn() {
}
boolean invokeVoid() {
voidCheck = true;
checkIn();
return true;
}
boolean invokeBoolean(boolean val) {
booleanCheck = val;
checkIn();
return val;
}
byte invokeByte(byte val) {
longCheck = val;
checkIn();
return val;
}
char invokeChar(char val) {
longCheck = val;
checkIn();
return val;
}
short invokeShort(short val) {
longCheck = val;
checkIn();
return val;
}
int invokeInt(int val) {
longCheck = val;
checkIn();
return val;
}
long invokeLong(long val) {
longCheck = val;
checkIn();
return val;
}
float invokeFloat(float val) {
longCheck = (long)val;
checkIn();
return val;
}
double invokeDouble(double val) {
longCheck = (long)val;
checkIn();
return val;
}
boolean[] invokeBooleanArray(boolean[] val) {
objectCheck = val;
checkIn();
return val;
}
byte[] invokeByteArray(byte[] val) {
objectCheck = val;
checkIn();
return val;
}
char[] invokeCharArray(char[] val) {
objectCheck = val;
checkIn();
return val;
}
short[] invokeShortArray(short[] val) {
objectCheck = val;
checkIn();
return val;
}
int[] invokeIntArray(int[] val) {
objectCheck = val;
checkIn();
return val;
}
long[] invokeLongArray(long[] val) {
objectCheck = val;
checkIn();
return val;
}
float[] invokeFloatArray(float[] val) {
objectCheck = val;
checkIn();
return val;
}
double[] invokeDoubleArray(double[] val) {
objectCheck = val;
checkIn();
return val;
}
boolean[][] invokeBoolean2DArray(boolean[][] val) {
objectCheck = val;
checkIn();
return val;
}
byte[][] invokeByte2DArray(byte[][] val) {
objectCheck = val;
checkIn();
return val;
}
char[][] invokeChar2DArray(char[][] val) {
objectCheck = val;
checkIn();
return val;
}
short[][] invokeShort2DArray(short[][] val) {
objectCheck = val;
checkIn();
return val;
}
int[][] invokeInt2DArray(int[][] val) {
objectCheck = val;
checkIn();
return val;
}
long[][] invokeLong2DArray(long[][] val) {
objectCheck = val;
checkIn();
return val;
}
float[][] invokeFloat2DArray(float[][] val) {
objectCheck = val;
checkIn();
return val;
}
double[][] invokeDouble2DArray(double[][] val) {
objectCheck = val;
checkIn();
return val;
}
String invokeString(String val) {
objectCheck = val;
checkIn();
return val;
}
String[] invokeStringArray(String[] val) {
objectCheck = val;
checkIn();
return val;
}
String[][] invokeString2DArray(String[][] val) {
objectCheck = val;
checkIn();
return val;
}
Date invokeDate(Date val) {
objectCheck = val;
checkIn();
return val;
}
Date[] invokeDateArray(Date[] val) {
objectCheck = val;
checkIn();
return val;
}
Date[][] invokeDate2DArray(Date[][] val) {
objectCheck = val;
checkIn();
return val;
}
String invokeCombo(int[][] arr, String val) {
objectCheck = val;
checkIn();
return val;
}
int[][] invokeCombo2(int[][] val, String str) {
objectCheck = val;
checkIn();
return val;
}
}
/********** test program **********/
public class InvokeTest extends TestScaffold {
ReferenceType targetClass;
ThreadReference mainThread;
ObjectReference thisObject;
Field longCheckField;
Field booleanCheckField;
Field voidCheckField;
Field objectCheckField;
Value longValue;
Value booleanValue;
Value objectValue;
Value voidValue;
InvokeTest (String args[]) {
super(args);
}
public static void main(String[] args) throws Exception {
new InvokeTest(args).startTests();
}
/********** event handlers **********/
// not use now
public void breakpointReached(BreakpointEvent event) {
println("Got BreakpointEvent");
longValue = thisObject.getValue(longCheckField);
booleanValue = thisObject.getValue(booleanCheckField);
objectValue = thisObject.getValue(objectCheckField);
voidValue = thisObject.getValue(voidCheckField);
}
/********** test assist **********/
void invoke(Method method, List args, Value value) {
Value returnValue = null;
try {
returnValue = thisObject.invokeMethod(mainThread,
method, args, 0);
} catch ( Exception ee) {
println("Got Exception: " + ee);
ee.printStackTrace();
}
println(" return val = " + returnValue);
// It has to be the same value as what we passed in!
if (returnValue.equals(value)) {
println(" " + method.name() + " return value matches: "
+ value);
} else {
if (value != null) {
failure("FAIL: " + method.name() + " returned: " + returnValue +
" expected: " + value );
} else {
println(" " + method.name() + " return value : " + returnValue);
}
}
Value checkValue = (value instanceof PrimitiveValue)?
((value instanceof BooleanValue)?
booleanValue : longValue) :
objectValue;
}
void invoke(String methodName, String methodSig,
List args, Value value)
throws Exception {
Method method = findMethod(targetClass, methodName, methodSig);
if ( method == null) {
failure("FAILED: Can't find method: " + methodName + " for class = " + targetClass);
return;
}
invoke(method, args, value);
}
void invoke(String methodName, String methodSig, Value value)
throws Exception {
List args = new ArrayList(1);
args.add(value);
invoke(methodName, methodSig, args, value);
}
void invoke(String methodName, String methodSig, String fieldName)
throws Exception {
invoke(methodName, methodSig, fieldValue(fieldName));
}
private Method toStringMethod;
Method gettoStringMethod() {
if ( toStringMethod != null) {
return toStringMethod;
}
// We have to find it. First find java.lang.Object
List myClasses = vm().allClasses();
Iterator iter = myClasses.iterator();
ReferenceType objectMirror = null;
while (iter.hasNext()) {
ReferenceType xx = (ReferenceType)iter.next();
if (xx.name().equals("java.lang.Object")) {
objectMirror = xx;
break;
}
}
if (objectMirror == null) {
return null;
}
// Then find toSting
List meths = objectMirror.methods();
iter = meths.iterator();
while (iter.hasNext()) {
toStringMethod = (Method)iter.next();
if (toStringMethod.name().equals("toString")) {
return toStringMethod;
}
}
toStringMethod = null;
return null;
}
// This calls toString on a field
protected void callToString(String fieldName) throws Exception {
// Sorry for this kludgy use of global vars.
ObjectReference saveObject = thisObject;
Method toStringMethod = gettoStringMethod();
Field theField = targetClass.fieldByName(fieldName);
thisObject = (ObjectReference)thisObject.getValue( theField);
invoke(toStringMethod, new ArrayList(0), null);
thisObject = saveObject;
}
Value fieldValue(String fieldName) {
Field field = targetClass.fieldByName(fieldName);
return thisObject.getValue(field);
}
/********** test core **********/
protected void runTests() throws Exception {
/*
* Get to the top of sayHi()
* to determine targetClass and mainThread
*/
BreakpointEvent bpe = startTo("InvokeTarg", "sayHi", "()V");
targetClass = bpe.location().declaringType();
mainThread = bpe.thread();
StackFrame frame = mainThread.frame(0);
thisObject = frame.thisObject();
longCheckField = targetClass.fieldByName("longCheck");
booleanCheckField = targetClass.fieldByName("booleanCheck");
objectCheckField = targetClass.fieldByName("objectCheck");
voidCheckField = targetClass.fieldByName("voidCheck");
callToString("aBooleanArray");
invoke("invokeVoid", "()Z", new ArrayList(0), vm().mirrorOf(true));
invoke("invokeBoolean", "(Z)Z", vm().mirrorOf(true));
invoke("invokeByte", "(B)B", vm().mirrorOf((byte)14));
invoke("invokeChar", "(C)C", vm().mirrorOf('h'));
invoke("invokeShort", "(S)S", vm().mirrorOf((short)54));
invoke("invokeInt", "(I)I", vm().mirrorOf((int)414));
invoke("invokeLong", "(J)J", vm().mirrorOf((long)140000));
invoke("invokeFloat", "(F)F", vm().mirrorOf((float)315));
invoke("invokeDouble", "(D)D", vm().mirrorOf((double)181818));
invoke("invokeBooleanArray", "([Z)[Z", "aBooleanArray");
invoke("invokeByteArray", "([B)[B", "aByteArray");
invoke("invokeCharArray", "([C)[C", "aCharArray");
invoke("invokeShortArray", "([S)[S", "aShortArray");
invoke("invokeIntArray", "([I)[I", "aIntArray");
invoke("invokeLongArray", "([J)[J", "aLongArray");
invoke("invokeFloatArray", "([F)[F", "aFloatArray");
invoke("invokeDoubleArray", "([D)[D", "aDoubleArray");
invoke("invokeBoolean2DArray", "([[Z)[[Z", "aBoolean2DArray");
invoke("invokeByte2DArray", "([[B)[[B", "aByte2DArray");
invoke("invokeChar2DArray", "([[C)[[C", "aChar2DArray");
invoke("invokeShort2DArray", "([[S)[[S", "aShort2DArray");
invoke("invokeInt2DArray", "([[I)[[I", "aInt2DArray");
invoke("invokeLong2DArray", "([[J)[[J", "aLong2DArray");
invoke("invokeFloat2DArray", "([[F)[[F", "aFloat2DArray");
invoke("invokeDouble2DArray", "([[D)[[D", "aDouble2DArray");
invoke("invokeString", "(Ljava/lang/String;)Ljava/lang/String;",
vm().mirrorOf("Howdy"));
invoke("invokeStringArray", "([Ljava/lang/String;)[Ljava/lang/String;",
"aStringArray");
invoke("invokeString2DArray", "([[Ljava/lang/String;)[[Ljava/lang/String;",
"aString2DArray");
invoke("invokeDate", "(Ljava/util/Date;)Ljava/util/Date;",
"aDate");
invoke("invokeDateArray", "([Ljava/util/Date;)[Ljava/util/Date;",
"aDateArray");
invoke("invokeDate2DArray", "([[Ljava/util/Date;)[[Ljava/util/Date;",
"aDate2DArray");
Value i2 = fieldValue("aInt2DArray");
Value str = vm().mirrorOf("Later");
List args = new ArrayList(2);
args.add(i2);
args.add(str);
invoke("invokeCombo",
"([[ILjava/lang/String;)Ljava/lang/String;",
args, str);
invoke("invokeCombo2",
"([[ILjava/lang/String;)[[I",
args, i2);
/*
* resume the target listening for events
*/
listenUntilVMDisconnect();
/*
* deal with results of test
* if anything has called failure("foo") testFailed will be true
*/
if (!testFailed) {
println("InvokeTest: passed");
} else {
throw new Exception("InvokeTest: failed");
}
}
}