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 ...@@ -80,7 +80,11 @@ namespace djinni
Bool() : Primitive("java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", "booleanValue", "()Z") {} Bool() : Primitive("java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", "booleanValue", "()Z") {}
friend JniClass<Bool>; friend JniClass<Bool>;
friend Primitive<Bool, bool, jboolean>; 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> class I8 : public Primitive<I8, int8_t, jbyte>
...@@ -88,7 +92,11 @@ namespace djinni ...@@ -88,7 +92,11 @@ namespace djinni
I8() : Primitive("java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", "byteValue", "()B") {} I8() : Primitive("java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", "byteValue", "()B") {}
friend JniClass<I8>; friend JniClass<I8>;
friend Primitive<I8, int8_t, jbyte>; 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> class I16 : public Primitive<I16, int16_t, jshort>
...@@ -96,7 +104,11 @@ namespace djinni ...@@ -96,7 +104,11 @@ namespace djinni
I16() : Primitive("java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", "shortValue", "()S") {} I16() : Primitive("java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", "shortValue", "()S") {}
friend JniClass<I16>; friend JniClass<I16>;
friend Primitive<I16, int16_t, jshort>; 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> class I32 : public Primitive<I32, int32_t, jint>
...@@ -104,7 +116,11 @@ namespace djinni ...@@ -104,7 +116,11 @@ namespace djinni
I32() : Primitive("java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", "intValue", "()I") {} I32() : Primitive("java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", "intValue", "()I") {}
friend JniClass<I32>; friend JniClass<I32>;
friend Primitive<I32, int32_t, jint>; 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> class I64 : public Primitive<I64, int64_t, jlong>
...@@ -112,7 +128,11 @@ namespace djinni ...@@ -112,7 +128,11 @@ namespace djinni
I64() : Primitive("java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", "longValue", "()J") {} I64() : Primitive("java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", "longValue", "()J") {}
friend JniClass<I64>; friend JniClass<I64>;
friend Primitive<I64, int64_t, jlong>; 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> class F32 : public Primitive<F32, float, jfloat>
...@@ -120,7 +140,11 @@ namespace djinni ...@@ -120,7 +140,11 @@ namespace djinni
F32() : Primitive("java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", "floatValue", "()F") {} F32() : Primitive("java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", "floatValue", "()F") {}
friend JniClass<F32>; friend JniClass<F32>;
friend Primitive<F32, float, jfloat>; 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> class F64 : public Primitive<F64, double, jdouble>
...@@ -128,7 +152,11 @@ namespace djinni ...@@ -128,7 +152,11 @@ namespace djinni
F64() : Primitive("java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", "doubleValue", "()D") {} F64() : Primitive("java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", "doubleValue", "()D") {}
friend JniClass<F64>; friend JniClass<F64>;
friend Primitive<F64, double, jdouble>; 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 struct String
...@@ -222,6 +250,7 @@ namespace djinni ...@@ -222,6 +250,7 @@ namespace djinni
const auto & data = JniClass<Date>::get(); const auto & data = JniClass<Date>::get();
assert(jniEnv->IsInstanceOf(j, data.clazz.get())); assert(jniEnv->IsInstanceOf(j, data.clazz.get()));
auto time_millis = jniEnv->CallLongMethod(j, data.method_get_time); auto time_millis = jniEnv->CallLongMethod(j, data.method_get_time);
jniExceptionCheck(jniEnv);
return POSIX_EPOCH + std::chrono::milliseconds{time_millis}; return POSIX_EPOCH + std::chrono::milliseconds{time_millis};
} }
...@@ -304,6 +333,7 @@ namespace djinni ...@@ -304,6 +333,7 @@ namespace djinni
const auto& data = JniClass<ListJniInfo>::get(); const auto& data = JniClass<ListJniInfo>::get();
assert(jniEnv->IsInstanceOf(j, data.clazz.get())); assert(jniEnv->IsInstanceOf(j, data.clazz.get()));
auto size = jniEnv->CallIntMethod(j, data.method_size); auto size = jniEnv->CallIntMethod(j, data.method_size);
jniExceptionCheck(jniEnv);
auto c = CppType(); auto c = CppType();
c.reserve(size); c.reserve(size);
for(jint i = 0; i < size; ++i) for(jint i = 0; i < size; ++i)
...@@ -366,8 +396,10 @@ namespace djinni ...@@ -366,8 +396,10 @@ namespace djinni
const auto& iteData = JniClass<IteratorJniInfo>::get(); const auto& iteData = JniClass<IteratorJniInfo>::get();
assert(jniEnv->IsInstanceOf(j, data.clazz.get())); assert(jniEnv->IsInstanceOf(j, data.clazz.get()));
auto size = jniEnv->CallIntMethod(j, data.method_size); auto size = jniEnv->CallIntMethod(j, data.method_size);
jniExceptionCheck(jniEnv);
auto c = CppType(); auto c = CppType();
auto it = LocalRef<jobject>(jniEnv, jniEnv->CallObjectMethod(j, data.method_iterator)); auto it = LocalRef<jobject>(jniEnv, jniEnv->CallObjectMethod(j, data.method_iterator));
jniExceptionCheck(jniEnv);
for(jint i = 0; i < size; ++i) for(jint i = 0; i < size; ++i)
{ {
auto je = LocalRef<jobject>(jniEnv, jniEnv->CallObjectMethod(it, iteData.method_next)); auto je = LocalRef<jobject>(jniEnv, jniEnv->CallObjectMethod(it, iteData.method_next));
...@@ -438,14 +470,19 @@ namespace djinni ...@@ -438,14 +470,19 @@ namespace djinni
const auto& iteData = JniClass<IteratorJniInfo>::get(); const auto& iteData = JniClass<IteratorJniInfo>::get();
assert(jniEnv->IsInstanceOf(j, data.clazz.get())); assert(jniEnv->IsInstanceOf(j, data.clazz.get()));
auto size = jniEnv->CallIntMethod(j, data.method_size); auto size = jniEnv->CallIntMethod(j, data.method_size);
jniExceptionCheck(jniEnv);
auto entrySet = LocalRef<jobject>(jniEnv, jniEnv->CallObjectMethod(j, data.method_entrySet)); auto entrySet = LocalRef<jobject>(jniEnv, jniEnv->CallObjectMethod(j, data.method_entrySet));
jniExceptionCheck(jniEnv);
auto c = CppType(); auto c = CppType();
c.reserve(size); c.reserve(size);
auto it = LocalRef<jobject>(jniEnv, jniEnv->CallObjectMethod(entrySet, entrySetData.method_iterator)); auto it = LocalRef<jobject>(jniEnv, jniEnv->CallObjectMethod(entrySet, entrySetData.method_iterator));
jniExceptionCheck(jniEnv);
for(jint i = 0; i < size; ++i) for(jint i = 0; i < size; ++i)
{ {
auto je = LocalRef<jobject>(jniEnv, jniEnv->CallObjectMethod(it, iteData.method_next)); auto je = LocalRef<jobject>(jniEnv, jniEnv->CallObjectMethod(it, iteData.method_next));
jniExceptionCheck(jniEnv);
auto jKey = LocalRef<jobject>(jniEnv, jniEnv->CallObjectMethod(je, entryData.method_getKey)); auto jKey = LocalRef<jobject>(jniEnv, jniEnv->CallObjectMethod(je, entryData.method_getKey));
jniExceptionCheck(jniEnv);
auto jValue = LocalRef<jobject>(jniEnv, jniEnv->CallObjectMethod(je, entryData.method_getValue)); auto jValue = LocalRef<jobject>(jniEnv, jniEnv->CallObjectMethod(je, entryData.method_getValue));
jniExceptionCheck(jniEnv); jniExceptionCheck(jniEnv);
c.emplace(Key::Boxed::toCpp(jniEnv, static_cast<JniKeyType>(jKey.get())), c.emplace(Key::Boxed::toCpp(jniEnv, static_cast<JniKeyType>(jKey.get())),
......
...@@ -239,8 +239,13 @@ jint JniEnum::ordinal(JNIEnv * env, jobject obj) const { ...@@ -239,8 +239,13 @@ jint JniEnum::ordinal(JNIEnv * env, jobject obj) const {
LocalRef<jobject> JniEnum::create(JNIEnv * env, jint value) const { LocalRef<jobject> JniEnum::create(JNIEnv * env, jint value) const {
LocalRef<jobject> values(env, env->CallStaticObjectMethod(m_clazz.get(), m_staticmethValues)); LocalRef<jobject> values(env, env->CallStaticObjectMethod(m_clazz.get(), m_staticmethValues));
jniExceptionCheck(env);
DJINNI_ASSERT(values, 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) JniLocalScope::JniLocalScope(JNIEnv* p_env, jint capacity, bool throwOnError)
...@@ -507,9 +512,9 @@ public: ...@@ -507,9 +512,9 @@ public:
jobject lock() const { jobject lock() const {
const auto & jniEnv = jniGetThreadEnv(); const auto & jniEnv = jniGetThreadEnv();
const JniInfo & weakRefClass = JniClass<JniInfo>::get(); 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); jniExceptionCheck(jniEnv);
return javaObj; return javaObj.release();
} }
// Java WeakReference objects don't have a way to check whether they're expired except // 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