summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAssam Boudjelthia <assam.boudjelthia@qt.io>2021-02-04 13:28:24 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-02-11 19:16:29 +0000
commit121ad4c22f55be831105943ba11a4ff51b732698 (patch)
tree7189400c66116833da73aa57639aedd2e4e5c475
parentafd74eb7fb2b2cd3d534cc2fdea31085fb9bb3f5 (diff)
Refactor duplicate code for clearing JNI exceptions before returning
Add a private function to handle checking/clearing and deleting the local reference to jobject before returning a QJniObject. Task-number: QTBUG-89633 Change-Id: I0ea28c8ba4da0bfc1e341c6b4c1f61fecfec87a6 Reviewed-by: Ville Voutilainen <ville.voutilainen@qt.io> (cherry picked from commit c7bcc51e2c196e5cc3def89137ca31b4a9d29157) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/corelib/kernel/qjniobject.cpp123
1 files changed, 43 insertions, 80 deletions
diff --git a/src/corelib/kernel/qjniobject.cpp b/src/corelib/kernel/qjniobject.cpp
index 6059ad4bf7..6ca56bc996 100644
--- a/src/corelib/kernel/qjniobject.cpp
+++ b/src/corelib/kernel/qjniobject.cpp
@@ -717,6 +717,27 @@ QJniObject::QJniObject(jobject obj)
}
/*!
+ \brief Get a JNI object from a jobject variant and do the necessary
+ exception clearing and delete the local reference before returning.
+ The JNI object can be null if there was an exception.
+*/
+inline static QJniObject getCleanJniObject(jobject obj)
+{
+ if (!obj)
+ return QJniObject();
+
+ QJniEnvironment env;
+ if (env.exceptionCheckAndClear()) {
+ env->DeleteLocalRef(obj);
+ return QJniObject();
+ }
+
+ QJniObject res(obj);
+ env->DeleteLocalRef(obj);
+ return res;
+}
+
+/*!
\fn QJniObject::~QJniObject()
Destroys the JNI object and releases any references held by the JNI object.
@@ -797,19 +818,11 @@ QJniObject QJniObject::callStaticObjectMethodV(jclass clazz,
va_list args)
{
QJniEnvironment env;
- jobject res = nullptr;
jmethodID id = getMethodID(env, clazz, methodName, signature, true);
- if (id) {
- res = env->CallStaticObjectMethodV(clazz, id, args);
- if (env.exceptionCheckAndClear()) {
- env->DeleteLocalRef(res);
- res = nullptr;
- }
- }
+ if (!id)
+ return QJniObject();
- QJniObject obj(res);
- env->DeleteLocalRef(res);
- return obj;
+ return getCleanJniObject(env->CallStaticObjectMethodV(clazz, id, args));
}
/*!
@@ -1150,22 +1163,16 @@ DECLARE_JNI_METHODS(Double, jdouble, "()D")
QJniObject QJniObject::callObjectMethod(const char *methodName, const char *signature, ...) const
{
QJniEnvironment env;
- jobject res = nullptr;
jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, signature);
if (id) {
va_list args;
va_start(args, signature);
- res = env->CallObjectMethodV(d->m_jobject, id, args);
+ QJniObject res = getCleanJniObject(env->CallObjectMethodV(d->m_jobject, id, args));
va_end(args);
- if (env.exceptionCheckAndClear()) {
- env->DeleteLocalRef(res);
- res = nullptr;
- }
+ return res;
}
- QJniObject obj(res);
- env->DeleteLocalRef(res);
- return obj;
+ return QJniObject();
}
/*!
@@ -1187,7 +1194,6 @@ QJniObject QJniObject::callStaticObjectMethod(const char *className,
...)
{
QJniEnvironment env;
- jobject res = nullptr;
jclass clazz = loadClass(className, env);
if (clazz) {
jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className),
@@ -1195,18 +1201,13 @@ QJniObject QJniObject::callStaticObjectMethod(const char *className,
if (id) {
va_list args;
va_start(args, signature);
- res = env->CallStaticObjectMethodV(clazz, id, args);
+ QJniObject res = getCleanJniObject(env->CallStaticObjectMethodV(clazz, id, args));
va_end(args);
- if (env.exceptionCheckAndClear()) {
- env->DeleteLocalRef(res);
- res = nullptr;
- }
+ return res;
}
}
- QJniObject obj(res);
- env->DeleteLocalRef(res);
- return obj;
+ return QJniObject();
}
/*!
@@ -1221,23 +1222,18 @@ QJniObject QJniObject::callStaticObjectMethod(jclass clazz,
...)
{
QJniEnvironment env;
- jobject res = nullptr;
if (clazz) {
jmethodID id = getMethodID(env, clazz, methodName, signature, true);
if (id) {
va_list args;
va_start(args, signature);
- res = env->CallStaticObjectMethodV(clazz, id, args);
+ QJniObject res = getCleanJniObject(env->CallStaticObjectMethodV(clazz, id, args));
va_end(args);
- if (env.exceptionCheckAndClear()) {
- env->DeleteLocalRef(res);
- res = nullptr;
- }
+ return res;
}
}
- QJniObject obj(res);
- env->DeleteLocalRef(res);
- return obj;
+
+ return QJniObject();
}
/*!
@@ -1534,15 +1530,7 @@ QJniObject QJniObject::getStaticObjectField(const char *className,
if (!id)
return QJniObject();
- jobject res = env->GetStaticObjectField(clazz, id);
- if (env.exceptionCheckAndClear()) {
- env->DeleteLocalRef(res);
- res = nullptr;
- }
-
- QJniObject obj(res);
- env->DeleteLocalRef(res);
- return obj;
+ return getCleanJniObject(env->GetStaticObjectField(clazz, id));
}
/*!
@@ -1562,19 +1550,11 @@ QJniObject QJniObject::getStaticObjectField(jclass clazz,
const char *signature)
{
QJniEnvironment env;
- jobject res = nullptr;
jfieldID id = getFieldID(env, clazz, fieldName, signature, true);
- if (id) {
- res = env->GetStaticObjectField(clazz, id);
- if (env.exceptionCheckAndClear()) {
- env->DeleteLocalRef(res);
- res = nullptr;
- }
- }
+ if (!id)
+ return QJniObject();
- QJniObject obj(res);
- env->DeleteLocalRef(res);
- return obj;
+ return getCleanJniObject(env->GetStaticObjectField(clazz, id));
}
/*!
@@ -1693,19 +1673,11 @@ void QJniObject::setField<jobjectArray>(const char *fieldName,
QJniObject QJniObject::getObjectField(const char *fieldName, const char *signature) const
{
QJniEnvironment env;
- jobject res = nullptr;
jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, signature);
- if (id) {
- res = env->GetObjectField(d->m_jobject, id);
- if (env.exceptionCheckAndClear()) {
- env->DeleteLocalRef(res);
- res = nullptr;
- }
- }
+ if (!id)
+ return QJniObject();
- QJniObject obj(res);
- env->DeleteLocalRef(res);
- return obj;
+ return getCleanJniObject(env->GetObjectField(d->m_jobject, id));
}
/*!
@@ -1802,17 +1774,8 @@ DECLARE_JNI_OBJECT_FILEDS(jdoubleArray, "[D")
QJniObject QJniObject::fromString(const QString &string)
{
QJniEnvironment env;
- jstring res = env->NewString(reinterpret_cast<const jchar*>(string.constData()),
- string.length());
-
- if (env.exceptionCheckAndClear()) {
- env->DeleteLocalRef(res);
- res = nullptr;
- }
-
- QJniObject obj(res);
- env->DeleteLocalRef(res);
- return obj;
+ return getCleanJniObject(env->NewString(reinterpret_cast<const jchar*>(string.constData()),
+ string.length()));
}
/*!