/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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 6175634
* @summary Allow early return from methods
*
* @bug 6431720
* @summary Unexpected InvalidTypeException when call ThreadReference.forceEarlyReturn with VoidValue
*
* @bug 6432855
* @summary Need a way to create JDI VoidValue for use in ThreadReference.forceEarlyReturn
*
* @author Tim Bell (based on MethodExitReturnValuesTest by Jim Holmlund)
*
* @run build TestScaffold VMConnection TargetListener TargetAdapter
* @run compile -g EarlyReturnTest.java
* @run main EarlyReturnTest
*/
/*
* This test has a debuggee which calls a static method
* for each kind of JDI Value, and then an instance method
* for each.
*
* The debugger sets breakpoints in all methods. When a breakpoint
* is hit the debugger requests an early return and supplies a new
* return value. It then checks that the correct return values are
* included in the MethodExitEvents.
*
* Each value is stored in a static var in the debuggee. The debugger
* gets the values from these static vars to check for correct
* return values in the MethodExitEvents.
*/
class EarlyReturnTarg {
static boolean debuggerWatching = false;
/*
* These are the values that will be used by methods
* returning normally.
*/
public static boolean booleanValue = false;
{
try {
}
}
new EarlyReturnTarg();
/*
* These are the values that will be used by methods
* returning early. These are != the normal values
* defined above.
*/
public static boolean ebooleanValue = true;
{
try {
}
}
// Used to check the return values seen on the debugee side
public static boolean chk(byte v) {
}
public static boolean chk(char v) {
}
public static boolean chk(double v) {
}
public static boolean chk(float v) {
}
public static boolean chk(int v) {
}
public static boolean chk(long v) {
}
public static boolean chk(short v) {
}
public static boolean chk(boolean v) {
}
}
}
// Used to show which set of tests follows
// These are the static methods
{ return classLoaderValue; }
{ return threadGroupValue; }
// These are the instance methods
{ return classLoaderValue; }
{ return threadGroupValue; }
public void i_voidf() {}
if (debuggerWatching) {
} else {
}
s_show("========== Testing static methods ================");
s_classf();
s_threadf();
s_intArrayf();
s_voidf();
s_show("========== Testing instance methods ================");
xx.i_intArrayf();
xx.i_classLoaderf();
xx.i_threadGroupf();
xx.i_nullObjectf();
}
/** Hang so that test fails */
static void hang() {
try {
// ten minute nap
} catch (InterruptedException exc) {
// shouldn't happen
}
}
// The debugger will stop at the start of main,
// set breakpoints and then do a resume.
new EarlyReturnTarg();
hang();
throw new Exception("EarlyReturnTarg: failed");
}
}
}
/*
* Class patterns for which we don't want events (copied
* from the "Trace.java" example):
*/
"javax.*",
"sun.*",
"com.sun.*"};
super(args);
}
meee.startTests();
}
// chkXXX methods lifted directly from MethodExitReturnValuesTest
// These methods check for correct return values. Thanks, Jim!
} else {
earlyReturns++;
}
}
} else {
earlyReturns++;
}
}
} else {
earlyReturns++;
}
}
} else {
earlyReturns++;
}
}
} else {
earlyReturns++;
}
}
} else {
earlyReturns++;
}
}
} else {
earlyReturns++;
}
}
} else {
earlyReturns++;
}
}
} else {
earlyReturns++;
}
}
} else {
earlyReturns++;
}
}
} else {
earlyReturns++;
}
}
} else {
earlyReturns++;
}
}
} else {
earlyReturns++;
}
}
} else {
earlyReturns++;
}
}
} else {
earlyReturns++;
}
}
} else {
earlyReturns++;
}
}
earlyReturns++;
}
}
throw new IllegalArgumentException("Bad method name/signature");
}
return bpr;
}
vm().canForceEarlyReturn()) {
try {
/*
* See what happens if we access the stack after the force
* and before the resume. Disabling this since spec says
* the stack is undefined. This type of code can be used to
* pursue just what that means.
*
* StackFrame sf = tr.frame(0);
* List<Value> ll = sf.getArgumentValues();
* for (Value vv: ll) {
* System.out.println("vv = " + vv);
* }
*/
} else {
}
}
} else {
}
}
// This is the MethodExitEvent handler.
vm().canGetMethodReturnValues()) {
// Skip all uninteresting methods
return;
}
return;
}
else {
}
} else {
}
}
/*
* Get to the top of main()
* to determine targetClass and mainThread
*/
/*
* Ask for method exit events
*/
}
//sessionSuspendPolicy = EventRequest.SUSPEND_EVENT_THREAD;
//sessionSuspendPolicy = EventRequest.SUSPEND_NONE;
/*
* Turn on the flag so debugee knows to check for early
* return values instead of regular return values.
*/
/*
* We set and enable breakpoints on all of the interesting
* methods called by doit(). In the breakpointReached()
* handler we force an early return with a different return
* value.
*
* The MethodExitEvent handler will keep score.
*/
/* Here we go. This adds 'this' as a listener so
* that our handlers above will be called.
*/
if (earlyReturns != expectedEarlyReturns) {
", but got " + earlyReturns);
}
if (!testFailed) {
} else {
throw new Exception("EarlyReturnTest: failed");
}
}
}