/*
* This file is part of the Jikes RVM project (http://jikesrvm.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License. You
* may obtain a copy of the License at
*
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership.
*/
class MethodInvocation {
static boolean verbose = true; // set to true to get messages for each test
static boolean allTestPass = true;
static int testFlagForVoid = 0; // flag to be updated by method returning void
public static native void setVerboseOff();
/************************************************************
* Declare native methods that will call the JNI method invocation
*/
static native int invokeStaticMethodA(Object objArg);
static native int invokeStaticMethodV(Object objArg);
static native int invokeStaticMethod(Object objArg);
static native int invokeVirtualMethodA(MethodInvocation targetObj, Object objArg);
static native int invokeVirtualMethodV(MethodInvocation targetObj, Object objArg);
static native int invokeVirtualMethod(MethodInvocation targetObj, Object objArg);
static native int invokeNonVirtualMethodA(MethodInvocationSub targetObj, Object objArg);
static native int invokeNonVirtualMethodV(MethodInvocationSub targetObj, Object objArg);
static native int invokeNonVirtualMethod(MethodInvocationSub targetObj, Object objArg);
/************************************************************
* Static methods serving as target to be invoked from native code
* receive arguments of every type, return one of each type
*/
/* The signature is: (BCSIJFDLjava/lang/Object;Z)Z */
public static boolean staticReturnBoolean(byte val0, char val1, short val2,
int val3, long val4, float val5,
double val6, Object val7, boolean val8) {
return !val8;
}
/* The signature is: (BCSIJFDLjava/lang/Object;Z)B */
public static byte staticReturnByte(byte val0, char val1, short val2,
int val3, long val4, float val5,
double val6, Object val7, boolean val8) {
return (byte) (val0 + 3);
}
/* The signature is: (BCSIJFDLjava/lang/Object;Z)C */
public static char staticReturnChar(byte val0, char val1, short val2,
int val3, long val4, float val5,
double val6, Object val7, boolean val8) {
if (val1 == 'a')
return 'b';
else
return 'c'; // didn't get the expected argument, force test to fail
}
/* The signature is: (BCSIJFDLjava/lang/Object;Z)S */
public static short staticReturnShort(byte val0, char val1, short val2,
int val3, long val4, float val5,
double val6, Object val7, boolean val8) {
return (short) (val2 + 15);
}
/* The signature is: (BCSIJFDLjava/lang/Object;Z)I */
public static int staticReturnInt(byte val0, char val1, short val2,
int val3, long val4, float val5,
double val6, Object val7, boolean val8) {
return val3 + val2;
}
/* The signature is: (BCSIJFDLjava/lang/Object;Z)J */
public static long staticReturnLong(byte val0, char val1, short val2,
int val3, long val4, float val5,
double val6, Object val7, boolean val8) {
return val4 + val3;
}
/* The signature is: (BCSIJFDLjava/lang/Object;Z)F */
public static float staticReturnFloat(byte val0, char val1, short val2,
int val3, long val4, float val5,
double val6, Object val7, boolean val8) {
return val5 + (float) 100.0;
}
/* The signature is: (BCSIJFDLjava/lang/Object;Z)D */
public static double staticReturnDouble(byte val0, char val1, short val2,
int val3, long val4, float val5,
double val6, Object val7, boolean val8) {
return val6 + 100.0;
}
/* The signature is: (BCSIJFDLjava/lang/Object;Z) */
public static void staticReturnVoid(byte val0, char val1, short val2,
int val3, long val4, float val5,
double val6, Object val7, boolean val8) {
testFlagForVoid = 789; // update the flag to indicate success
}
/* The signature is: (BCSIJFDLjava/lang/Object;Z)Ljava/lang/Object; */
public static Object staticReturnObject(byte val0, char val1, short val2,
int val3, long val4, float val5,
double val6, Object val7, boolean val8) {
return new String("Year 2000");
}
/************************************************************
* Virtual methods serving as target to be invoked from native code
* receive arguments of every type, return one of each type
*/
/* The signature is: (BCSIJFDLjava/lang/Object;Z)Z */
public boolean virtualReturnBoolean(byte val0, char val1, short val2,
int val3, long val4, float val5,
double val6, Object val7, boolean val8) {
return !val8;
}
/* The signature is: (BCSIJFDLjava/lang/Object;Z)B */
public byte virtualReturnByte(byte val0, char val1, short val2,
int val3, long val4, float val5,
double val6, Object val7, boolean val8) {
return (byte) (val0 + 7);
}
/* The signature is: (BCSIJFDLjava/lang/Object;Z)C */
public char virtualReturnChar(byte val0, char val1, short val2,
int val3, long val4, float val5,
double val6, Object val7, boolean val8) {
if (val1 == 'x')
return 'y';
else
return 'z'; // didn't get the expected argument, force test to fail
}
/* The signature is: (BCSIJFDLjava/lang/Object;Z)S */
public short virtualReturnShort(byte val0, char val1, short val2,
int val3, long val4, float val5,
double val6, Object val7, boolean val8) {
return (short) (val2 + 23);
}
/* The signature is: (BCSIJFDLjava/lang/Object;Z)I */
public int virtualReturnInt(byte val0, char val1, short val2,
int val3, long val4, float val5,
double val6, Object val7, boolean val8) {
return val3 + val0;
}
/* The signature is: (BCSIJFDLjava/lang/Object;Z)J */
public long virtualReturnLong(byte val0, char val1, short val2,
int val3, long val4, float val5,
double val6, Object val7, boolean val8) {
return val4 + val2;
}
/* The signature is: (BCSIJFDLjava/lang/Object;Z)F */
public float virtualReturnFloat(byte val0, char val1, short val2,
int val3, long val4, float val5,
double val6, Object val7, boolean val8) {
return val5 + (float) 32.0;
}
/* The signature is: (BCSIJFDLjava/lang/Object;Z)D */
public double virtualReturnDouble(byte val0, char val1, short val2,
int val3, long val4, float val5,
double val6, Object val7, boolean val8) {
return val6 + 1000.0;
}
/* The signature is: (BCSIJFDLjava/lang/Object;Z) */
public void virtualReturnVoid(byte val0, char val1, short val2,
int val3, long val4, float val5,
double val6, Object val7, boolean val8) {
testFlagForVoid = 456; // update the flag to indicate success
}
/* The signature is: (BCSIJFDLjava/lang/Object;Z)Ljava/lang/Object; */
public Object virtualReturnObject(byte val0, char val1, short val2,
int val3, long val4, float val5,
double val6, Object val7, boolean val8) {
return new String("RVM");
}
/************************************************************
* Dummy constructor to get to the virtual methods
*/
MethodInvocation() {
}
/************************************************************
* Main body of the test program
*/
public static void main(String[] args) {
int returnValue;
String anObj = new String("Year of the Dragon");
System.loadLibrary("MethodInvocation");
if (args.length != 0) {
if (args[0].equals("-quiet")) {
verbose = false;
setVerboseOff();
}
}
/**
* Test the static method invocations
*/
// pass arguments as an array of jvalue
returnValue = invokeStaticMethodA(anObj);
checkTest(returnValue, "callStatic<type>MethodA");
// pass arguments as va_list pointer to a variable argument list
testFlagForVoid = 0; // reset flag to be updated by method returning void
returnValue = invokeStaticMethodV(anObj);
checkTest(returnValue, "callStatic<type>MethodV");
// pass arguments as a variable argument list at the call site
testFlagForVoid = 0; // reset flag to be updated by method returning void
returnValue = invokeStaticMethod(anObj);
checkTest(returnValue, "callStatic<type>Method");
/**
* Test the virtual method invocations
*/
// pass arguments as an array of jvalue
MethodInvocation targetObj = new MethodInvocation();
returnValue = invokeVirtualMethodA(targetObj, anObj);
checkTest(returnValue, "call<type>MethodA");
// pass arguments as va_list pointer to a variable argument list
testFlagForVoid = 0; // reset flag to be updated by method returning void
returnValue = invokeVirtualMethodV(targetObj, anObj);
checkTest(returnValue, "call<type>MethodV");
// pass arguments as a variable argument list at the call site
testFlagForVoid = 0; // reset flag to be updated by method returning void
returnValue = invokeVirtualMethod(targetObj, anObj);
checkTest(returnValue, "call<type>Method");
/**
* Test the nonvirtual method invocations
*/
MethodInvocationSub subObj = new MethodInvocationSub();
// reset flag to be updated by method returning void
testFlagForVoid = 0;
MethodInvocationSub.testFlagForVoid = 0;
// pass arguments as an array of jvalue
returnValue = invokeNonVirtualMethodA(subObj, anObj);
checkTest(returnValue, "callNonVirtual<type>MethodA");
// reset flag to be updated by method returning void
testFlagForVoid = 0;
MethodInvocationSub.testFlagForVoid = 0;
// pass arguments as va_list pointer to a variable argument list
returnValue = invokeNonVirtualMethodV(subObj, anObj);
checkTest(returnValue, "callNonVirtual<type>MethodV");
// reset flag to be updated by method returning void
testFlagForVoid = 0;
MethodInvocationSub.testFlagForVoid = 0;
// pass arguments as a variable argument list at the call site
returnValue = invokeNonVirtualMethod(subObj, anObj);
checkTest(returnValue, "callNonVirtual<type>Method");
// Summarize tests
if (allTestPass)
System.out.println("PASS: MethodInvocation");
else
System.out.println("FAIL: MethodInvocation");
}
static void printVerbose(String str) {
if (verbose)
System.out.println(str);
}
static void checkTest(int returnValue, String testName) {
if (returnValue == 0) {
printVerbose("PASS: " + testName);
} else {
allTestPass = false;
printVerbose("FAIL: " + testName);
}
}
}