Commit 52832d5e authored by Andrew Twyman's avatar Andrew Twyman

Merge pull request #161 from dropbox/atwyman/JniExceptionCheck

Add extra exception checks based on warnings
parents 53fd6bc7 fb6c37f8
......@@ -80,7 +80,11 @@ namespace djinni
Bool() : Primitive("java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", "booleanValue", "()Z") {}
friend JniClass<Bool>;
friend Primitive<Bool, bool, jboolean>;
static JniType unbox(JNIEnv* jniEnv, jmethodID method, jobject j) noexcept { return jniEnv->CallBooleanMethod(j, method); }
static JniType unbox(JNIEnv* jniEnv, jmethodID method, jobject j) {
auto result = jniEnv->CallBooleanMethod(j, method);
jniExceptionCheck(jniEnv);
return result;
}
};
class I8 : public Primitive<I8, int8_t, jbyte>
......@@ -88,7 +92,11 @@ namespace djinni
I8() : Primitive("java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", "byteValue", "()B") {}
friend JniClass<I8>;
friend Primitive<I8, int8_t, jbyte>;
static JniType unbox(JNIEnv* jniEnv, jmethodID method, jobject j) noexcept { return jniEnv->CallByteMethod(j, method); }
static JniType unbox(JNIEnv* jniEnv, jmethodID method, jobject j) {
auto result = jniEnv->CallByteMethod(j, method);
jniExceptionCheck(jniEnv);
return result;
}
};
class I16 : public Primitive<I16, int16_t, jshort>
......@@ -96,7 +104,11 @@ namespace djinni
I16() : Primitive("java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", "shortValue", "()S") {}
friend JniClass<I16>;
friend Primitive<I16, int16_t, jshort>;
static JniType unbox(JNIEnv* jniEnv, jmethodID method, jobject j) noexcept { return jniEnv->CallShortMethod(j, method); }
static JniType unbox(JNIEnv* jniEnv, jmethodID method, jobject j) {
auto result = jniEnv->CallShortMethod(j, method);
jniExceptionCheck(jniEnv);
return result;
}
};
class I32 : public Primitive<I32, int32_t, jint>
......@@ -104,7 +116,11 @@ namespace djinni
I32() : Primitive("java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", "intValue", "()I") {}
friend JniClass<I32>;
friend Primitive<I32, int32_t, jint>;
static JniType unbox(JNIEnv* jniEnv, jmethodID method, jobject j) noexcept { return jniEnv->CallIntMethod(j, method); }
static JniType unbox(JNIEnv* jniEnv, jmethodID method, jobject j) {
auto result = jniEnv->CallIntMethod(j, method);
jniExceptionCheck(jniEnv);
return result;
}
};
class I64 : public Primitive<I64, int64_t, jlong>
......@@ -112,7 +128,11 @@ namespace djinni
I64() : Primitive("java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", "longValue", "()J") {}
friend JniClass<I64>;
friend Primitive<I64, int64_t, jlong>;
static JniType unbox(JNIEnv* jniEnv, jmethodID method, jobject j) noexcept { return jniEnv->CallLongMethod(j, method); }
static JniType unbox(JNIEnv* jniEnv, jmethodID method, jobject j) {
auto result = jniEnv->CallLongMethod(j, method);
jniExceptionCheck(jniEnv);
return result;
}
};
class F32 : public Primitive<F32, float, jfloat>
......@@ -120,7 +140,11 @@ namespace djinni
F32() : Primitive("java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", "floatValue", "()F") {}
friend JniClass<F32>;
friend Primitive<F32, float, jfloat>;
static JniType unbox(JNIEnv* jniEnv, jmethodID method, jobject j) noexcept { return jniEnv->CallFloatMethod(j, method); }
static JniType unbox(JNIEnv* jniEnv, jmethodID method, jobject j) {
auto result = jniEnv->CallFloatMethod(j, method);
jniExceptionCheck(jniEnv);
return result;
}
};
class F64 : public Primitive<F64, double, jdouble>
......@@ -128,7 +152,11 @@ namespace djinni
F64() : Primitive("java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", "doubleValue", "()D") {}
friend JniClass<F64>;
friend Primitive<F64, double, jdouble>;
static JniType unbox(JNIEnv* jniEnv, jmethodID method, jobject j) noexcept { return jniEnv->CallDoubleMethod(j, method); }
static JniType unbox(JNIEnv* jniEnv, jmethodID method, jobject j) {
auto result = jniEnv->CallDoubleMethod(j, method);
jniExceptionCheck(jniEnv);
return result;
}
};
struct String
......@@ -222,6 +250,7 @@ namespace djinni
const auto & data = JniClass<Date>::get();
assert(jniEnv->IsInstanceOf(j, data.clazz.get()));
auto time_millis = jniEnv->CallLongMethod(j, data.method_get_time);
jniExceptionCheck(jniEnv);
return POSIX_EPOCH + std::chrono::milliseconds{time_millis};
}
......@@ -304,6 +333,7 @@ namespace djinni
const auto& data = JniClass<ListJniInfo>::get();
assert(jniEnv->IsInstanceOf(j, data.clazz.get()));
auto size = jniEnv->CallIntMethod(j, data.method_size);
jniExceptionCheck(jniEnv);
auto c = CppType();
c.reserve(size);
for(jint i = 0; i < size; ++i)
......@@ -366,8 +396,10 @@ namespace djinni
const auto& iteData = JniClass<IteratorJniInfo>::get();
assert(jniEnv->IsInstanceOf(j, data.clazz.get()));
auto size = jniEnv->CallIntMethod(j, data.method_size);
jniExceptionCheck(jniEnv);
auto c = CppType();
auto it = LocalRef<jobject>(jniEnv, jniEnv->CallObjectMethod(j, data.method_iterator));
jniExceptionCheck(jniEnv);
for(jint i = 0; i < size; ++i)
{
auto je = LocalRef<jobject>(jniEnv, jniEnv->CallObjectMethod(it, iteData.method_next));
......@@ -438,14 +470,19 @@ namespace djinni
const auto& iteData = JniClass<IteratorJniInfo>::get();
assert(jniEnv->IsInstanceOf(j, data.clazz.get()));
auto size = jniEnv->CallIntMethod(j, data.method_size);
jniExceptionCheck(jniEnv);
auto entrySet = LocalRef<jobject>(jniEnv, jniEnv->CallObjectMethod(j, data.method_entrySet));
jniExceptionCheck(jniEnv);
auto c = CppType();
c.reserve(size);
auto it = LocalRef<jobject>(jniEnv, jniEnv->CallObjectMethod(entrySet, entrySetData.method_iterator));
jniExceptionCheck(jniEnv);
for(jint i = 0; i < size; ++i)
{
auto je = LocalRef<jobject>(jniEnv, jniEnv->CallObjectMethod(it, iteData.method_next));
jniExceptionCheck(jniEnv);
auto jKey = LocalRef<jobject>(jniEnv, jniEnv->CallObjectMethod(je, entryData.method_getKey));
jniExceptionCheck(jniEnv);
auto jValue = LocalRef<jobject>(jniEnv, jniEnv->CallObjectMethod(je, entryData.method_getValue));
jniExceptionCheck(jniEnv);
c.emplace(Key::Boxed::toCpp(jniEnv, static_cast<JniKeyType>(jKey.get())),
......
......@@ -239,8 +239,13 @@ jint JniEnum::ordinal(JNIEnv * env, jobject obj) const {
LocalRef<jobject> JniEnum::create(JNIEnv * env, jint value) const {
LocalRef<jobject> values(env, env->CallStaticObjectMethod(m_clazz.get(), m_staticmethValues));
jniExceptionCheck(env);
DJINNI_ASSERT(values, env);
return LocalRef<jobject>(env, env->GetObjectArrayElement(static_cast<jobjectArray>(values.get()), value));
LocalRef<jobject> result(env,
env->GetObjectArrayElement(static_cast<jobjectArray>(values.get()),
value));
jniExceptionCheck(env);
return result;
}
JniLocalScope::JniLocalScope(JNIEnv* p_env, jint capacity, bool throwOnError)
......@@ -507,9 +512,9 @@ public:
jobject lock() const {
const auto & jniEnv = jniGetThreadEnv();
const JniInfo & weakRefClass = JniClass<JniInfo>::get();
jobject javaObj = jniEnv->CallObjectMethod(m_weakRef.get(), weakRefClass.method_get);
LocalRef<jobject> javaObj(jniEnv->CallObjectMethod(m_weakRef.get(), weakRefClass.method_get));
jniExceptionCheck(jniEnv);
return javaObj;
return javaObj.release();
}
// Java WeakReference objects don't have a way to check whether they're expired except
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment