jdk-24/test/jdk/jni/nullCaller/CallHelper.hpp
Coleen Phillimore a6bdee48f3 8324681: Replace NULL with nullptr in HotSpot jtreg test native code files
Reviewed-by: kevinw, kbarrett, dholmes
2024-01-29 17:07:32 +00:00

211 lines
6.5 KiB
C++

/*
* Copyright (c) 2022, 2024, 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.
*/
#ifndef __CallHelper_hpp__
#define __CallHelper_hpp__
#include <stdlib.h>
#include <stdio.h>
#include <jni.h>
#undef NDEBUG
#include <assert.h>
#include <string>
#include <algorithm>
/*
* basis of classes to provide a bunch of checking in native calls to java
*/
class CallHelper {
public:
CallHelper(JNIEnv* e, const std::string& cname, const std::string& mname, const std::string& sig) :
classname(cname), method(mname), signature(sig), m(nullptr), env(e) {
c = env->FindClass(classname.c_str());
assert (c != nullptr);
}
protected:
// emit a message with the call made appended to the message
void emitErrorMessage(const std::string& msg) {
std::string nm = classname;
std::replace(nm.begin(), nm.end(), '/', '.');
::fprintf(stderr, "ERROR: %s::%s, %s\n", nm.c_str(), method.c_str(), msg.c_str());
}
// check the given object which is expected to be null
void checkReturnNull(jobject obj) {
if (obj != nullptr) {
emitErrorMessage("Null return expected");
::exit(-1);
}
}
// check the given object which is expected to NOT be null
void checkReturnNotNull(jobject obj) {
if (obj == nullptr) {
emitErrorMessage("Non-Null return expected");
::exit(-1);
}
}
// check if any unexpected exceptions were thrown
void checkException() {
if (env->ExceptionOccurred() != nullptr) {
emitErrorMessage("Exception was thrown");
env->ExceptionDescribe();
::exit(-1);
}
}
// check if an expected exception was thrown
void checkExpectedExceptionThrown(const std::string& exception) {
jclass expected = env->FindClass(exception.c_str());
assert(expected != nullptr);
jthrowable t = env->ExceptionOccurred();
if (env->IsInstanceOf(t, expected) == JNI_FALSE) {
emitErrorMessage("Didn't get the expected " + exception);
::exit(-1);
}
env->ExceptionClear();
}
protected:
std::string classname;
std::string method;
std::string signature;
jclass c;
jmethodID m;
JNIEnv* env;
};
/*
* support for making checked calls on instances of an object
*/
class InstanceCall : public CallHelper {
public:
InstanceCall(JNIEnv* e, const std::string& cname, const std::string& mname, const std::string& sig)
: CallHelper(e, cname, mname, sig) {
m = env->GetMethodID(c, method.c_str(), signature.c_str());
assert(m != nullptr);
}
// call on the given object, checking for exceptions and that the return is not null
jobject callReturnNotNull(jobject obj) {
jobject robj = call(obj);
checkReturnNotNull(robj);
return robj;
}
// call on the given object with an argument,
// checking for exceptions and that the return is not null
jobject callReturnNotNull(jobject obj, jobject arg) {
jobject robj = call(obj, arg);
checkReturnNotNull(robj);
return robj;
}
// call on the given object, checking for exceptions and that the return is null
jobject callReturnIsNull(jobject obj) {
jobject robj = call(obj);
checkReturnNull(robj);
return robj;
}
// call on the given object with an argument,
// checking for exceptions and that the return is null
jobject callReturnIsNull(jobject obj, jobject arg) {
jobject robj = call(obj, arg);
checkReturnNull(robj);
return robj;
}
// call a void method checking if exceptions were thrown
void callVoidMethod(jobject obj) {
env->CallVoidMethod(obj, m);
checkException();
}
jobject call(jobject obj) {
jobject robj = env->CallObjectMethod(obj, m);
checkException();
return robj;
}
jobject call(jobject obj, jobject arg) {
jobject robj = env->CallObjectMethod(obj, m, arg);
checkException();
return robj;
}
};
/*
* support for making checked static calls
*/
class StaticCall : public CallHelper {
public:
StaticCall(JNIEnv* e, const std::string& cname, const std::string& mname, const std::string& sig)
: CallHelper(e, cname, mname, sig) {
m = env->GetStaticMethodID(c, method.c_str(), signature.c_str());
assert(m != nullptr);
}
// call a method returning an object checking for exceptions and
// the return value is not null.
jobject callReturnNotNull(jobject arg) {
jobject robj = env->CallStaticObjectMethod(c, m, arg);
checkException();
checkReturnNotNull(robj);
return robj;
}
// call a void method checking if any exceptions thrown
void callVoidMethod() {
env->CallStaticVoidMethod(c, m);
checkException();
}
// call method returning boolean that is expected to throw the
// given exception
void callBooleanMethodWithException(const std::string& exception) {
env->CallStaticBooleanMethod(c, m);
checkExpectedExceptionThrown(exception);
}
// call method returning an object that is expected to throw the
// given exception
void callObjectMethodWithException(const std::string& exception) {
env->CallStaticObjectMethod(c, m);
checkExpectedExceptionThrown(exception);
}
};
void emitErrorMessageAndExit(const std::string& msg) {
::fprintf(stderr, "ERROR: %s\n", msg.c_str());
::exit(-1);
}
#endif // __CallHelper_hpp__