0N/A/*
2362N/A * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
0N/A * published by the Free Software Foundation.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/A/*
0N/A * @test
0N/A * @bug 6175634
0N/A * @summary Allow early return from methods
0N/A *
0N/A * @bug 6431720
0N/A * @summary Unexpected InvalidTypeException when call ThreadReference.forceEarlyReturn with VoidValue
0N/A *
0N/A * @bug 6432855
0N/A * @summary Need a way to create JDI VoidValue for use in ThreadReference.forceEarlyReturn
0N/A *
0N/A * @author Tim Bell (based on MethodExitReturnValuesTest by Jim Holmlund)
0N/A *
0N/A * @run build TestScaffold VMConnection TargetListener TargetAdapter
0N/A * @run compile -g EarlyReturnTest.java
0N/A * @run main EarlyReturnTest
0N/A */
0N/Aimport com.sun.jdi.*;
0N/Aimport com.sun.jdi.event.*;
0N/Aimport com.sun.jdi.request.*;
0N/Aimport java.util.*;
0N/Aimport java.net.URLClassLoader;
0N/Aimport java.net.URL;
0N/Aimport java.lang.reflect.Array;
0N/A
0N/A/*
0N/A * This test has a debuggee which calls a static method
0N/A * for each kind of JDI Value, and then an instance method
0N/A * for each.
0N/A *
0N/A * The debugger sets breakpoints in all methods. When a breakpoint
0N/A * is hit the debugger requests an early return and supplies a new
0N/A * return value. It then checks that the correct return values are
0N/A * included in the MethodExitEvents.
0N/A *
0N/A * Each value is stored in a static var in the debuggee. The debugger
0N/A * gets the values from these static vars to check for correct
0N/A * return values in the MethodExitEvents.
0N/A */
0N/A
0N/Aclass EarlyReturnTarg {
0N/A static boolean debuggerWatching = false;
0N/A static int failureCount = 0;
0N/A /*
0N/A * These are the values that will be used by methods
0N/A * returning normally.
0N/A */
0N/A static URL[] urls = new URL[1];
0N/A public static byte byteValue = 89;
0N/A public static char charValue = 'x';
0N/A public static double doubleValue = 2.2;
0N/A public static float floatValue = 3.3f;
0N/A public static int intValue = 1;
0N/A public static long longValue = Long.MAX_VALUE;
0N/A public static short shortValue = 8;
0N/A public static boolean booleanValue = false;
0N/A
0N/A public static Class classValue = Object.class;
0N/A public static ClassLoader classLoaderValue;
0N/A {
0N/A try {
0N/A urls[0] = new URL("hi there");
0N/A } catch (java.net.MalformedURLException ee) {
0N/A }
0N/A classLoaderValue = new URLClassLoader(urls);
0N/A }
0N/A
0N/A public static Thread threadValue = Thread.currentThread();
0N/A public static ThreadGroup threadGroupValue = threadValue.getThreadGroup();
0N/A public static String stringValue = "abc";
0N/A public static int[] intArrayValue = new int[] {1, 2, 3};
0N/A
0N/A public static EarlyReturnTarg objectValue =
0N/A new EarlyReturnTarg();
0N/A public String ivar = stringValue;
0N/A
0N/A /*
0N/A * These are the values that will be used by methods
0N/A * returning early. These are != the normal values
0N/A * defined above.
0N/A */
0N/A static URL[] eurls = new URL[1];
0N/A public static byte ebyteValue = 42;
0N/A public static char echarValue = 'a';
0N/A public static double edoubleValue = 6.6;
0N/A public static float efloatValue = 9.9f;
0N/A public static int eintValue = 7;
0N/A public static long elongValue = Long.MIN_VALUE;
0N/A public static short eshortValue = 3;
0N/A public static boolean ebooleanValue = true;
0N/A
0N/A public static Class eclassValue = String.class;
0N/A public static ClassLoader eclassLoaderValue;
0N/A {
0N/A try {
0N/A urls[0] = new URL("been there, done that");
0N/A } catch (java.net.MalformedURLException ee) {
0N/A }
0N/A classLoaderValue = new URLClassLoader(urls);
0N/A }
0N/A public static Thread ethreadValue;
0N/A public static ThreadGroup ethreadGroupValue;
0N/A public static String estringValue = "wxyz";
0N/A public static int[] eintArrayValue = new int[] {10, 11, 12};
0N/A
0N/A public static java.util.Date eobjectValue = new java.util.Date();
0N/A
0N/A // Used to check the return values seen on the debugee side
0N/A public static boolean chk(byte v) {
0N/A return v == (debuggerWatching ? ebyteValue: byteValue);
0N/A }
0N/A public static boolean chk(char v) {
0N/A return v == (debuggerWatching ? echarValue: charValue);
0N/A }
0N/A public static boolean chk(double v) {
0N/A return v == (debuggerWatching ? edoubleValue: doubleValue);
0N/A }
0N/A public static boolean chk(float v) {
0N/A return v == (debuggerWatching ? efloatValue: floatValue);
0N/A }
0N/A public static boolean chk(int v) {
0N/A return v == (debuggerWatching ? eintValue: intValue);
0N/A }
0N/A public static boolean chk(long v) {
0N/A return v == (debuggerWatching ? elongValue: longValue);
0N/A }
0N/A public static boolean chk(short v) {
0N/A return v == (debuggerWatching ? eshortValue: shortValue);
0N/A }
0N/A public static boolean chk(boolean v) {
0N/A return v == (debuggerWatching ? ebooleanValue: booleanValue);
0N/A }
0N/A public static boolean chk(String v) {
0N/A return v.equals(debuggerWatching ? estringValue: stringValue);
0N/A }
0N/A public static boolean chk(Object v) {
0N/A return v.equals(debuggerWatching ? eobjectValue: objectValue);
0N/A }
0N/A
0N/A // Used to show which set of tests follows
0N/A public static String s_show(String p1) { return p1;}
0N/A
0N/A // These are the static methods
0N/A public static byte s_bytef(int p1){ return byteValue; }
0N/A public static char s_charf() { return charValue; }
0N/A public static double s_doublef() { return doubleValue; }
0N/A public static float s_floatf() { return floatValue; }
0N/A public static int s_intf() { return intValue; }
0N/A public static long s_longf() { return longValue; }
0N/A public static short s_shortf() { return shortValue; }
0N/A public static boolean s_booleanf(){ return booleanValue; }
0N/A public static String s_stringf() { return stringValue; }
0N/A public static Class s_classf() { return classValue; }
0N/A public static ClassLoader s_classLoaderf()
0N/A { return classLoaderValue; }
0N/A public static Thread s_threadf() { return threadValue; }
0N/A public static ThreadGroup s_threadGroupf()
0N/A { return threadGroupValue; }
0N/A public static int[] s_intArrayf() { return intArrayValue; }
0N/A public static Object s_nullObjectf() { return null; }
0N/A public static Object s_objectf() { return objectValue; }
0N/A public static void s_voidf() { System.err.println("debugee in s_voidf");}
0N/A
0N/A // These are the instance methods
0N/A public byte i_bytef(int p1) { return byteValue; }
0N/A public char i_charf() { return charValue; }
0N/A public double i_doublef() { return doubleValue; }
0N/A public float i_floatf() { return floatValue; }
0N/A public int i_intf() { return intValue; }
0N/A public long i_longf() { return longValue; }
0N/A public short i_shortf() { return shortValue; }
0N/A public boolean i_booleanf() { return booleanValue; }
0N/A public String i_stringf() { return stringValue; }
0N/A public Class i_classf() { return classValue; }
0N/A public ClassLoader i_classLoaderf()
0N/A { return classLoaderValue; }
0N/A public Thread i_threadf() { return threadValue; }
0N/A public ThreadGroup i_threadGroupf()
0N/A { return threadGroupValue; }
0N/A public int[] i_intArrayf() { return intArrayValue; }
0N/A public Object i_nullObjectf() { return null; }
0N/A public Object i_objectf() { return objectValue; }
0N/A public void i_voidf() {}
0N/A
0N/A static void doit(EarlyReturnTarg xx) throws Exception {
0N/A System.err.print("debugee in doit ");
0N/A if (debuggerWatching) {
0N/A System.err.println("with a debugger watching. Early returns expected.");
0N/A } else {
0N/A System.err.println("with no debugger watching. Normal returns.");
0N/A }
0N/A
0N/A s_show("========== Testing static methods ================");
0N/A if (!chk( s_bytef(88))) failureCount++;
0N/A if (!chk( s_charf())) failureCount++;
0N/A if (!chk( s_doublef())) failureCount++;
0N/A if (!chk( s_floatf())) failureCount++;
0N/A if (!chk( s_intf())) failureCount++;
0N/A if (!chk( s_longf())) failureCount++;
0N/A if (!chk( s_shortf())) failureCount++;
0N/A if (!chk( s_booleanf())) failureCount++;
0N/A
0N/A if (!chk( s_stringf())) failureCount++;
0N/A s_classf();
0N/A s_classLoaderf();
0N/A s_threadf();
0N/A s_threadGroupf();
0N/A s_intArrayf();
0N/A s_nullObjectf();
0N/A if (!chk( s_objectf())) failureCount++;
0N/A s_voidf();
0N/A
0N/A s_show("========== Testing instance methods ================");
0N/A if (!chk( xx.i_bytef(89))) failureCount++;
0N/A if (!chk( xx.i_charf())) failureCount++;
0N/A if (!chk( xx.i_doublef())) failureCount++;
0N/A if (!chk( xx.i_floatf())) failureCount++;
0N/A if (!chk( xx.i_intf())) failureCount++;
0N/A if (!chk( xx.i_longf())) failureCount++;
0N/A if (!chk( xx.i_shortf())) failureCount++;
0N/A if (!chk( xx.i_booleanf())) failureCount++;
0N/A if (!chk( xx.i_stringf())) failureCount++;
0N/A xx.i_intArrayf();
0N/A xx.i_classf();
0N/A xx.i_classLoaderf();
0N/A xx.i_threadf();
0N/A xx.i_threadGroupf();
0N/A xx.i_nullObjectf();
0N/A if (!chk( xx.i_objectf())) failureCount++;
0N/A xx.i_voidf();
0N/A
0N/A }
0N/A
0N/A /** Hang so that test fails */
0N/A static void hang() {
0N/A try {
0N/A // ten minute nap
0N/A Thread.currentThread().sleep(10 * 60 * 1000);
0N/A } catch (InterruptedException exc) {
0N/A // shouldn't happen
0N/A }
0N/A }
0N/A
0N/A public static void main(String[] args) throws Exception {
0N/A // The debugger will stop at the start of main,
0N/A // set breakpoints and then do a resume.
0N/A System.err.println("debugee in main");
0N/A EarlyReturnTarg xx =
0N/A new EarlyReturnTarg();
0N/A
0N/A doit(xx);
0N/A if (debuggerWatching && failureCount > 0) {
0N/A hang();
0N/A throw new Exception("EarlyReturnTarg: failed");
0N/A }
0N/A }
0N/A}
0N/A
0N/A
0N/A
0N/Apublic class EarlyReturnTest extends TestScaffold {
0N/A
0N/A
0N/A /*
0N/A * Class patterns for which we don't want events (copied
0N/A * from the "Trace.java" example):
0N/A * http://java.sun.com/javase/technologies/core/toolsapis/jpda/
0N/A */
0N/A private String[] excludes = {
0N/A "javax.*",
0N/A "sun.*",
0N/A "com.sun.*"};
0N/A
0N/A static VirtualMachineManager vmm ;
0N/A ClassType targetClass;
0N/A Field theValueField;
0N/A static int earlyReturns = 0;
0N/A static final int expectedEarlyReturns = 34; // determined by inspection :-)
0N/A
0N/A EarlyReturnTest(String args[]) {
0N/A super(args);
0N/A }
0N/A
0N/A public static void main(String[] args) throws Exception {
0N/A EarlyReturnTest meee = new EarlyReturnTest(args);
0N/A vmm = Bootstrap.virtualMachineManager();
0N/A meee.startTests();
0N/A }
0N/A
0N/A // chkXXX methods lifted directly from MethodExitReturnValuesTest
0N/A // These methods check for correct return values. Thanks, Jim!
0N/A void ckByteValue(Value retValue) {
0N/A Field theValueField = targetClass.fieldByName("ebyteValue");
0N/A ByteValue theValue = (ByteValue)targetClass.getValue(theValueField);
0N/A
0N/A byte vv = theValue.value();
0N/A byte rv = ((ByteValue)retValue).value();
0N/A if (vv != rv) {
0N/A failure("failure: byte: expected " + vv + ", got " + rv);
0N/A } else {
0N/A System.out.println("Passed: byte " + rv);
0N/A earlyReturns++;
0N/A }
0N/A }
0N/A
0N/A void ckCharValue(Value retValue) {
0N/A Field theValueField = targetClass.fieldByName("echarValue");
0N/A CharValue theValue = (CharValue)targetClass.getValue(theValueField);
0N/A
0N/A char vv = theValue.value();
0N/A char rv = ((CharValue)retValue).value();
0N/A if (vv != rv) {
0N/A failure("failure: char: expected " + vv + ", got " + rv);
0N/A } else {
0N/A System.out.println("Passed: char " + rv);
0N/A earlyReturns++;
0N/A }
0N/A }
0N/A
0N/A void ckDoubleValue(Value retValue) {
0N/A Field theValueField = targetClass.fieldByName("edoubleValue");
0N/A DoubleValue theValue = (DoubleValue)targetClass.getValue(theValueField);
0N/A
0N/A double vv = theValue.value();
0N/A double rv = ((DoubleValue)retValue).value();
0N/A if (vv != rv) {
0N/A failure("failure: double: expected " + vv + ", got " + rv);
0N/A } else {
0N/A System.out.println("Passed: double " + rv);
0N/A earlyReturns++;
0N/A }
0N/A }
0N/A
0N/A void ckFloatValue(Value retValue) {
0N/A Field theValueField = targetClass.fieldByName("efloatValue");
0N/A FloatValue theValue = (FloatValue)targetClass.getValue(theValueField);
0N/A
0N/A float vv = theValue.value();
0N/A float rv = ((FloatValue)retValue).value();
0N/A if (vv != rv) {
0N/A failure("failure: float: expected " + vv + ", got " + rv);
0N/A } else {
0N/A System.out.println("Passed: float " + rv);
0N/A earlyReturns++;
0N/A }
0N/A }
0N/A
0N/A void ckIntValue(Value retValue) {
0N/A Field theValueField = targetClass.fieldByName("eintValue");
0N/A IntegerValue theValue = (IntegerValue)targetClass.getValue(theValueField);
0N/A
0N/A int vv = theValue.value();
0N/A int rv = ((IntegerValue)retValue).value();
0N/A if (vv != rv) {
0N/A failure("failure: int: expected " + vv + ", got " + rv);
0N/A } else {
0N/A System.out.println("Passed: int " + rv);
0N/A earlyReturns++;
0N/A }
0N/A }
0N/A
0N/A void ckLongValue(Value retValue) {
0N/A Field theValueField = targetClass.fieldByName("elongValue");
0N/A LongValue theValue = (LongValue)targetClass.getValue(theValueField);
0N/A
0N/A long vv = theValue.value();
0N/A long rv = ((LongValue)retValue).value();
0N/A if (vv != rv) {
0N/A failure("failure: long: expected " + vv + ", got " + rv);
0N/A } else {
0N/A System.out.println("Passed: long " + rv);
0N/A earlyReturns++;
0N/A }
0N/A }
0N/A
0N/A void ckShortValue(Value retValue) {
0N/A Field theValueField = targetClass.fieldByName("eshortValue");
0N/A ShortValue theValue = (ShortValue)targetClass.getValue(theValueField);
0N/A
0N/A short vv = theValue.value();
0N/A short rv = ((ShortValue)retValue).value();
0N/A if (vv != rv) {
0N/A failure("failure: short: expected " + vv + ", got " + rv);
0N/A } else {
0N/A System.out.println("Passed: short " + rv);
0N/A earlyReturns++;
0N/A }
0N/A }
0N/A
0N/A void ckBooleanValue(Value retValue) {
0N/A Field theValueField = targetClass.fieldByName("ebooleanValue");
0N/A BooleanValue theValue = (BooleanValue)targetClass.getValue(theValueField);
0N/A
0N/A boolean vv = theValue.value();
0N/A boolean rv = ((BooleanValue)retValue).value();
0N/A if (vv != rv) {
0N/A failure("failure: boolean: expected " + vv + ", got " + rv);
0N/A } else {
0N/A System.out.println("Passed: boolean " + rv);
0N/A earlyReturns++;
0N/A }
0N/A }
0N/A
0N/A void ckStringValue(Value retValue) {
0N/A Field theValueField = targetClass.fieldByName("estringValue");
0N/A StringReference theValue = (StringReference)targetClass.getValue(theValueField);
0N/A
0N/A String vv = theValue.value();
0N/A String rv = ((StringReference)retValue).value();
0N/A if (vv != rv) {
0N/A failure("failure: String: expected " + vv + ", got " + rv);
0N/A } else {
0N/A System.out.println("Passed: String: " + rv);
0N/A earlyReturns++;
0N/A }
0N/A }
0N/A
0N/A void ckClassValue(Value retValue) {
0N/A Field theValueField = targetClass.fieldByName("eclassValue");
0N/A ClassObjectReference vv = (ClassObjectReference)targetClass.
0N/A getValue(theValueField);
0N/A
0N/A ClassObjectReference rv = (ClassObjectReference)retValue;
0N/A if (vv != rv) {
0N/A failure("failure: Class: expected " + vv + ", got " + rv);
0N/A } else {
0N/A System.out.println("Passed: Class: " + rv);
0N/A earlyReturns++;
0N/A }
0N/A }
0N/A
0N/A void ckClassLoaderValue(Value retValue) {
0N/A Field theValueField = targetClass.fieldByName("eclassLoaderValue");
0N/A ClassLoaderReference vv = (ClassLoaderReference)targetClass.
0N/A getValue(theValueField);
0N/A
0N/A ClassLoaderReference rv = (ClassLoaderReference)retValue;
0N/A if (vv != rv) {
0N/A failure("failure: ClassLoader: expected " + vv + ", got " + rv);
0N/A } else {
0N/A System.out.println("Passed: ClassLoader: " + rv);
0N/A earlyReturns++;
0N/A }
0N/A }
0N/A
0N/A void ckThreadValue(Value retValue) {
0N/A Field theValueField = targetClass.fieldByName("ethreadValue");
0N/A ThreadReference vv = (ThreadReference)targetClass.
0N/A getValue(theValueField);
0N/A
0N/A ThreadReference rv = (ThreadReference)retValue;
0N/A if (vv != rv) {
0N/A failure("failure: Thread: expected " + vv + ", got " + rv);
0N/A } else {
0N/A System.out.println("Passed: Thread: " + rv);
0N/A earlyReturns++;
0N/A }
0N/A }
0N/A
0N/A void ckThreadGroupValue(Value retValue) {
0N/A Field theValueField = targetClass.fieldByName("ethreadGroupValue");
0N/A ThreadGroupReference vv = (ThreadGroupReference)targetClass.
0N/A getValue(theValueField);
0N/A
0N/A ThreadGroupReference rv = (ThreadGroupReference)retValue;
0N/A if (vv != rv) {
0N/A failure("failure: ThreadgGroup: expected " + vv + ", got " + rv);
0N/A } else {
0N/A System.out.println("Passed: ThreadGroup: " + rv);
0N/A earlyReturns++;
0N/A }
0N/A }
0N/A
0N/A void ckArrayValue(Value retValue) {
0N/A Field theValueField = targetClass.fieldByName("eintArrayValue");
0N/A ArrayReference theValue = (ArrayReference)targetClass.getValue(theValueField);
0N/A IntegerValue theElem2 = (IntegerValue)theValue.getValue(2);
0N/A
0N/A ArrayReference theRetValue = (ArrayReference)retValue;
0N/A IntegerValue retElem2 = (IntegerValue)theRetValue.getValue(2);
0N/A int vv = theElem2.value();
0N/A int rv = retElem2.value();
0N/A if (vv != rv) {
0N/A failure("failure: in[2]: expected " + vv + ", got " + rv);
0N/A } else {
0N/A System.out.println("Passed: int[2]: " + rv);
0N/A earlyReturns++;
0N/A }
0N/A }
0N/A
0N/A void ckNullObjectValue(Value retValue) {
0N/A if (retValue != null) {
0N/A failure("failure: NullObject: expected " + null + ", got " + retValue);
0N/A } else {
0N/A System.out.println("Passed: NullObject: " + retValue);
0N/A earlyReturns++;
0N/A }
0N/A }
0N/A
0N/A void ckObjectValue(Value retValue) {
0N/A ObjectReference theRetValue = (ObjectReference)retValue;
0N/A
0N/A Field theIVarField = targetClass.fieldByName("eobjectValue");
0N/A ObjectReference theRetValField = (ObjectReference)targetClass.getValue(theIVarField);
0N/A
0N/A if (! theRetValue.equals(theRetValField)) {
0N/A failure("failure: Object: expected " + theIVarField + ", got " + theRetValField);
0N/A } else {
0N/A System.out.println("Passed: Object: " + theRetValField);
0N/A earlyReturns++;
0N/A }
0N/A }
0N/A
0N/A void ckVoidValue(Value retValue) {
0N/A System.out.println("Passed: Void");
0N/A earlyReturns++;
0N/A }
0N/A
0N/A public BreakpointRequest setBreakpoint(String clsName,
0N/A String methodName,
0N/A String methodSignature) {
0N/A ReferenceType rt = findReferenceType(clsName);
0N/A if (rt == null) {
0N/A rt = resumeToPrepareOf(clsName).referenceType();
0N/A }
0N/A
0N/A Method method = findMethod(rt, methodName, methodSignature);
0N/A if (method == null) {
0N/A throw new IllegalArgumentException("Bad method name/signature");
0N/A }
0N/A BreakpointRequest bpr = eventRequestManager().createBreakpointRequest(method.location());
0N/A bpr.setSuspendPolicy(EventRequest.SUSPEND_ALL);
0N/A bpr.enable();
0N/A return bpr;
0N/A }
0N/A
0N/A public void breakpointReached(BreakpointEvent event) {
0N/A String origMethodName = event.location().method().name();
0N/A String methodName = origMethodName.substring(2);
0N/A ThreadReference tr = event.thread();
0N/A
0N/A if (vmm.majorInterfaceVersion() >= 1 &&
0N/A vmm.minorInterfaceVersion() >= 6 &&
0N/A vm().canForceEarlyReturn()) {
0N/A
0N/A try {
0N/A
0N/A if ("bytef".equals(methodName)){
0N/A Field theValueField = targetClass.fieldByName("ebyteValue");
0N/A ByteValue theValue = (ByteValue)targetClass.getValue(theValueField);
0N/A tr.forceEarlyReturn(theValue);
0N/A /*
0N/A * See what happens if we access the stack after the force
0N/A * and before the resume. Disabling this since spec says
0N/A * the stack is undefined. This type of code can be used to
0N/A * pursue just what that means.
0N/A *
0N/A * StackFrame sf = tr.frame(0);
0N/A * List<Value> ll = sf.getArgumentValues();
0N/A * for (Value vv: ll) {
0N/A * System.out.println("vv = " + vv);
0N/A * }
0N/A */
0N/A } else if ("charf".equals(methodName)) {
0N/A Field theValueField = targetClass.fieldByName("echarValue");
0N/A CharValue theValue = (CharValue)targetClass.getValue(theValueField);
0N/A tr.forceEarlyReturn(theValue);
0N/A } else if ("doublef".equals(methodName)) {
0N/A Field theValueField = targetClass.fieldByName("edoubleValue");
0N/A DoubleValue theValue = (DoubleValue)targetClass.getValue(theValueField);
0N/A tr.forceEarlyReturn(theValue);
0N/A } else if ("floatf".equals(methodName)) {
0N/A Field theValueField = targetClass.fieldByName("efloatValue");
0N/A FloatValue theValue = (FloatValue)targetClass.getValue(theValueField);
0N/A tr.forceEarlyReturn(theValue);
0N/A } else if ("intf".equals(methodName)) {
0N/A Field theValueField = targetClass.fieldByName("eintValue");
0N/A IntegerValue theValue = (IntegerValue)targetClass.getValue(theValueField);
0N/A tr.forceEarlyReturn(theValue);
0N/A } else if ("longf".equals(methodName)) {
0N/A Field theValueField = targetClass.fieldByName("elongValue");
0N/A LongValue theValue = (LongValue)targetClass.getValue(theValueField);
0N/A tr.forceEarlyReturn(theValue);
0N/A } else if ("shortf".equals(methodName)) {
0N/A Field theValueField = targetClass.fieldByName("eshortValue");
0N/A ShortValue theValue = (ShortValue)targetClass.getValue(theValueField);
0N/A tr.forceEarlyReturn(theValue);
0N/A } else if ("booleanf".equals(methodName)) {
0N/A Field theValueField = targetClass.fieldByName("ebooleanValue");
0N/A BooleanValue theValue = (BooleanValue)targetClass.getValue(theValueField);
0N/A tr.forceEarlyReturn(theValue);
0N/A } else if ("stringf".equals(methodName)) {
0N/A Field theValueField = targetClass.fieldByName("estringValue");
0N/A StringReference theValue = (StringReference)targetClass.getValue(theValueField);
0N/A tr.forceEarlyReturn(theValue);
0N/A } else if ("classf".equals(methodName)) {
0N/A Field theValueField = targetClass.fieldByName("eclassValue");
0N/A ClassObjectReference theValue = (ClassObjectReference)targetClass.getValue(theValueField);
0N/A tr.forceEarlyReturn(theValue);
0N/A } else if ("classLoaderf".equals(methodName)) {
0N/A Field theValueField = targetClass.fieldByName("eclassLoaderValue");
0N/A ClassLoaderReference theValue = (ClassLoaderReference)targetClass.getValue(theValueField);
0N/A tr.forceEarlyReturn(theValue);
0N/A } else if ("threadf".equals(methodName)) {
0N/A Field theValueField = targetClass.fieldByName("ethreadValue");
0N/A ThreadReference theValue = (ThreadReference)targetClass.getValue(theValueField);
0N/A tr.forceEarlyReturn(theValue);
0N/A } else if ("threadGroupf".equals(methodName)) {
0N/A Field theValueField = targetClass.fieldByName("ethreadGroupValue");
0N/A ThreadGroupReference theValue = (ThreadGroupReference)targetClass.getValue(theValueField);
0N/A tr.forceEarlyReturn(theValue);
0N/A } else if ("intArrayf".equals(methodName)) {
0N/A Field theValueField = targetClass.fieldByName("eintArrayValue");
0N/A ArrayReference theValue = (ArrayReference)targetClass.getValue(theValueField);
0N/A tr.forceEarlyReturn(theValue);
0N/A } else if ("nullObjectf".equals(methodName)) {
0N/A tr.forceEarlyReturn(null);
0N/A } else if ("objectf".equals(methodName)) {
0N/A Field theValueField = targetClass.fieldByName("eobjectValue");
0N/A ObjectReference theValue = (ObjectReference)targetClass.getValue(theValueField);
0N/A tr.forceEarlyReturn(theValue);
0N/A } else if ("voidf".equals(methodName)) {
0N/A VoidValue theValue = vm().mirrorOfVoid();
0N/A tr.forceEarlyReturn(theValue);
0N/A } else {
0N/A failure("failure: Unknown methodName: " + origMethodName);
0N/A }
0N/A
0N/A } catch (Exception ex) {
0N/A failure("failure: " + ex.toString());
0N/A ex.printStackTrace();
0N/A }
0N/A } else {
0N/A System.out.println("Cannot force early return for method: " + origMethodName);
0N/A }
0N/A }
0N/A
0N/A // This is the MethodExitEvent handler.
0N/A public void methodExited(MethodExitEvent event) {
0N/A String origMethodName = event.method().name();
0N/A if (vmm.majorInterfaceVersion() >= 1 &&
0N/A vmm.minorInterfaceVersion() >= 6 &&
0N/A vm().canGetMethodReturnValues()) {
0N/A Value retValue = event.returnValue();
0N/A
0N/A if (!origMethodName.startsWith("s_") &&
0N/A !origMethodName.startsWith("i_")) {
0N/A // Skip all uninteresting methods
0N/A return;
0N/A }
0N/A
0N/A String methodName = origMethodName.substring(2);
0N/A if ("show".equals(methodName)) {
0N/A System.out.println(retValue);
0N/A return;
0N/A }
0N/A
0N/A if ("bytef".equals(methodName)) ckByteValue(retValue);
0N/A else if ("charf".equals(methodName)) ckCharValue(retValue);
0N/A else if ("doublef".equals(methodName)) ckDoubleValue(retValue);
0N/A else if ("floatf".equals(methodName)) ckFloatValue(retValue);
0N/A else if ("intf".equals(methodName)) ckIntValue(retValue);
0N/A else if ("longf".equals(methodName)) ckLongValue(retValue);
0N/A else if ("shortf".equals(methodName)) ckShortValue(retValue);
0N/A else if ("booleanf".equals(methodName)) ckBooleanValue(retValue);
0N/A else if ("stringf".equals(methodName)) ckStringValue(retValue);
0N/A else if ("classf".equals(methodName)) ckClassValue(retValue);
0N/A else if ("classLoaderf".equals(methodName)) ckClassLoaderValue(retValue);
0N/A else if ("threadf".equals(methodName)) ckThreadValue(retValue);
0N/A else if ("threadGroupf".equals(methodName)) ckThreadGroupValue(retValue);
0N/A else if ("intArrayf".equals(methodName)) ckArrayValue(retValue);
0N/A else if ("nullObjectf".equals(methodName)) ckNullObjectValue(retValue);
0N/A else if ("objectf".equals(methodName)) ckObjectValue(retValue);
0N/A else if ("voidf".equals(methodName)) ckVoidValue(retValue);
0N/A else {
0N/A failure("failure: Unknown methodName: " + origMethodName);
0N/A }
0N/A } else {
0N/A System.out.println("Return Value not available for method: " + origMethodName);
0N/A }
0N/A }
0N/A
0N/A protected void runTests() throws Exception {
0N/A /*
0N/A * Get to the top of main()
0N/A * to determine targetClass and mainThread
0N/A */
0N/A
0N/A BreakpointEvent bpe = startToMain("EarlyReturnTarg");
0N/A targetClass = (ClassType)bpe.location().declaringType();
0N/A mainThread = bpe.thread();
0N/A
0N/A /*
0N/A * Ask for method exit events
0N/A */
0N/A MethodExitRequest exitRequest =
0N/A eventRequestManager().createMethodExitRequest();
0N/A
0N/A for (int i=0; i<excludes.length; ++i) {
0N/A exitRequest.addClassExclusionFilter(excludes[i]);
0N/A }
0N/A int sessionSuspendPolicy = EventRequest.SUSPEND_ALL;
0N/A //sessionSuspendPolicy = EventRequest.SUSPEND_EVENT_THREAD;
0N/A //sessionSuspendPolicy = EventRequest.SUSPEND_NONE;
0N/A exitRequest.setSuspendPolicy(sessionSuspendPolicy);
0N/A exitRequest.enable();
0N/A
0N/A /*
0N/A * Turn on the flag so debugee knows to check for early
0N/A * return values instead of regular return values.
0N/A */
0N/A Field flagField = targetClass.fieldByName("debuggerWatching");
0N/A targetClass.setValue(flagField, vm().mirrorOf(true));
0N/A
0N/A
0N/A /*
0N/A * We set and enable breakpoints on all of the interesting
0N/A * methods called by doit(). In the breakpointReached()
0N/A * handler we force an early return with a different return
0N/A * value.
0N/A *
0N/A * The MethodExitEvent handler will keep score.
0N/A */
0N/A
0N/A setBreakpoint("EarlyReturnTarg", "s_bytef", "(I)B");
0N/A setBreakpoint("EarlyReturnTarg", "s_charf", "()C");
0N/A setBreakpoint("EarlyReturnTarg", "s_doublef", "()D");
0N/A setBreakpoint("EarlyReturnTarg", "s_floatf", "()F");
0N/A setBreakpoint("EarlyReturnTarg", "s_intf", "()I");
0N/A setBreakpoint("EarlyReturnTarg", "s_longf", "()J");
0N/A setBreakpoint("EarlyReturnTarg", "s_shortf", "()S");
0N/A setBreakpoint("EarlyReturnTarg", "s_booleanf", "()Z");
0N/A
0N/A setBreakpoint("EarlyReturnTarg", "s_stringf", "()Ljava/lang/String;");
0N/A setBreakpoint("EarlyReturnTarg", "s_classf", "()Ljava/lang/Class;");
0N/A setBreakpoint("EarlyReturnTarg", "s_classLoaderf", "()Ljava/lang/ClassLoader;");
0N/A setBreakpoint("EarlyReturnTarg", "s_threadf", "()Ljava/lang/Thread;");
0N/A setBreakpoint("EarlyReturnTarg", "s_threadGroupf", "()Ljava/lang/ThreadGroup;");
0N/A setBreakpoint("EarlyReturnTarg", "s_intArrayf", "()[I");
0N/A setBreakpoint("EarlyReturnTarg", "s_nullObjectf", "()Ljava/lang/Object;");
0N/A setBreakpoint("EarlyReturnTarg", "s_objectf", "()Ljava/lang/Object;");
0N/A setBreakpoint("EarlyReturnTarg", "s_voidf", "()V");
0N/A
0N/A setBreakpoint("EarlyReturnTarg", "i_bytef", "(I)B");
0N/A setBreakpoint("EarlyReturnTarg", "i_charf", "()C");
0N/A setBreakpoint("EarlyReturnTarg", "i_doublef", "()D");
0N/A setBreakpoint("EarlyReturnTarg", "i_floatf", "()F");
0N/A setBreakpoint("EarlyReturnTarg", "i_intf", "()I");
0N/A setBreakpoint("EarlyReturnTarg", "i_longf", "()J");
0N/A setBreakpoint("EarlyReturnTarg", "i_shortf", "()S");
0N/A setBreakpoint("EarlyReturnTarg", "i_booleanf", "()Z");
0N/A setBreakpoint("EarlyReturnTarg", "i_stringf", "()Ljava/lang/String;");
0N/A setBreakpoint("EarlyReturnTarg", "i_intArrayf", "()[I");
0N/A setBreakpoint("EarlyReturnTarg", "i_classf", "()Ljava/lang/Class;");
0N/A setBreakpoint("EarlyReturnTarg", "i_classLoaderf", "()Ljava/lang/ClassLoader;");
0N/A setBreakpoint("EarlyReturnTarg", "i_threadf", "()Ljava/lang/Thread;");
0N/A setBreakpoint("EarlyReturnTarg", "i_threadGroupf", "()Ljava/lang/ThreadGroup;");
0N/A setBreakpoint("EarlyReturnTarg", "i_nullObjectf", "()Ljava/lang/Object;");
0N/A setBreakpoint("EarlyReturnTarg", "i_objectf", "()Ljava/lang/Object;");
0N/A setBreakpoint("EarlyReturnTarg", "i_voidf", "()V");
0N/A
0N/A /* Here we go. This adds 'this' as a listener so
0N/A * that our handlers above will be called.
0N/A */
0N/A listenUntilVMDisconnect();
0N/A
0N/A if (earlyReturns != expectedEarlyReturns) {
0N/A failure("failure: Expected " + expectedEarlyReturns +
0N/A ", but got " + earlyReturns);
0N/A }
0N/A System.out.println("All done, " + earlyReturns + " passed");
0N/A
0N/A
0N/A if (!testFailed) {
0N/A System.out.println();
0N/A System.out.println("EarlyReturnTest: passed");
0N/A } else {
0N/A System.out.println();
0N/A System.out.println("EarlyReturnTest: failed");
0N/A throw new Exception("EarlyReturnTest: failed");
0N/A }
0N/A }
0N/A}