mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1244875 - Refactor JNI templates; r=snorp
Improve the performance of JNI calls by making JNI calls require a Context object. LocalRef inherits from Context and can make calls directly. Non-local Ref classes will generate a Context object when making a call. The patch also makes the template design cleaner in several cases.
This commit is contained in:
parent
0b0b6cd0df
commit
46edf980e0
@ -9,7 +9,7 @@
|
||||
#include "AndroidBridge.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace jni{
|
||||
namespace jni {
|
||||
|
||||
namespace {
|
||||
|
||||
@ -31,23 +31,16 @@ struct Value
|
||||
|
||||
}
|
||||
|
||||
// Base class for Method<>, Field<>, and Constructor<>.
|
||||
class Accessor {
|
||||
public:
|
||||
template<class Cls>
|
||||
static jclass EnsureClassRef(JNIEnv* env)
|
||||
{
|
||||
if (!Cls::sClassRef) {
|
||||
MOZ_ALWAYS_TRUE(Cls::sClassRef =
|
||||
AndroidBridge::GetClassGlobalRef(env, Cls::name));
|
||||
}
|
||||
return Cls::sClassRef;
|
||||
}
|
||||
|
||||
private:
|
||||
// Base class for Method<>, Field<>, and Constructor<>.
|
||||
class Accessor
|
||||
{
|
||||
static void GetNsresult(JNIEnv* env, nsresult* rv)
|
||||
{
|
||||
if (env->ExceptionCheck()) {
|
||||
#ifdef DEBUG
|
||||
env->ExceptionDescribe();
|
||||
#endif
|
||||
env->ExceptionClear();
|
||||
*rv = NS_ERROR_FAILURE;
|
||||
} else {
|
||||
@ -56,26 +49,16 @@ private:
|
||||
}
|
||||
|
||||
protected:
|
||||
// Called before making a JNIEnv call.
|
||||
template<class Traits>
|
||||
static JNIEnv* BeginAccess()
|
||||
{
|
||||
JNIEnv* const env = Traits::isMultithreaded
|
||||
? GetEnvForThread() : GetGeckoThreadEnv();
|
||||
|
||||
EnsureClassRef<typename Traits::Owner>(env);
|
||||
return env;
|
||||
}
|
||||
|
||||
// Called after making a JNIEnv call.
|
||||
template<class Traits>
|
||||
static void EndAccess(JNIEnv* env, nsresult* rv)
|
||||
static void EndAccess(const typename Traits::Owner::Context& ctx,
|
||||
nsresult* rv)
|
||||
{
|
||||
if (Traits::exceptionMode == ExceptionMode::ABORT) {
|
||||
MOZ_CATCH_JNI_EXCEPTION(env);
|
||||
MOZ_CATCH_JNI_EXCEPTION(ctx.Env());
|
||||
|
||||
} else if (Traits::exceptionMode == ExceptionMode::NSRESULT) {
|
||||
GetNsresult(env, rv);
|
||||
GetNsresult(ctx.Env(), rv);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -86,39 +69,37 @@ template<class Traits, typename ReturnType = typename Traits::ReturnType>
|
||||
class Method : public Accessor
|
||||
{
|
||||
typedef Accessor Base;
|
||||
typedef typename Traits::Owner Owner;
|
||||
typedef typename Traits::Owner::Context Context;
|
||||
|
||||
protected:
|
||||
static jmethodID sID;
|
||||
|
||||
static JNIEnv* BeginAccess()
|
||||
static void BeginAccess(const Context& ctx)
|
||||
{
|
||||
JNIEnv* const env = Base::BeginAccess<Traits>();
|
||||
|
||||
if (sID) {
|
||||
return env;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Traits::isStatic) {
|
||||
MOZ_ALWAYS_TRUE(sID = AndroidBridge::GetStaticMethodID(
|
||||
env, Traits::Owner::sClassRef, Traits::name, Traits::signature));
|
||||
ctx.Env(), ctx.ClassRef(), Traits::name, Traits::signature));
|
||||
} else {
|
||||
MOZ_ALWAYS_TRUE(sID = AndroidBridge::GetMethodID(
|
||||
env, Traits::Owner::sClassRef, Traits::name, Traits::signature));
|
||||
ctx.Env(), ctx.ClassRef(), Traits::name, Traits::signature));
|
||||
}
|
||||
return env;
|
||||
}
|
||||
|
||||
static void EndAccess(JNIEnv* env, nsresult* rv)
|
||||
static void EndAccess(const Context& ctx, nsresult* rv)
|
||||
{
|
||||
return Base::EndAccess<Traits>(env, rv);
|
||||
return Base::EndAccess<Traits>(ctx, rv);
|
||||
}
|
||||
|
||||
public:
|
||||
template<typename... Args>
|
||||
static ReturnType Call(const Owner* cls, nsresult* rv, const Args&... args)
|
||||
static ReturnType Call(const Context& ctx, nsresult* rv, const Args&... args)
|
||||
{
|
||||
JNIEnv* const env = BeginAccess();
|
||||
JNIEnv* const env = ctx.Env();
|
||||
BeginAccess(ctx);
|
||||
|
||||
jvalue jargs[] = {
|
||||
Value(TypeAdapter<Args>::FromNative(env, args)).val ...
|
||||
@ -127,11 +108,11 @@ public:
|
||||
auto result = TypeAdapter<ReturnType>::ToNative(env,
|
||||
Traits::isStatic ?
|
||||
(env->*TypeAdapter<ReturnType>::StaticCall)(
|
||||
Owner::sClassRef, sID, jargs) :
|
||||
ctx.RawClassRef(), sID, jargs) :
|
||||
(env->*TypeAdapter<ReturnType>::Call)(
|
||||
cls->mInstance, sID, jargs));
|
||||
ctx.Get(), sID, jargs));
|
||||
|
||||
EndAccess(env, rv);
|
||||
EndAccess(ctx, rv);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
@ -146,26 +127,27 @@ template<class Traits>
|
||||
class Method<Traits, void> : public Method<Traits, bool>
|
||||
{
|
||||
typedef Method<Traits, bool> Base;
|
||||
typedef typename Traits::Owner Owner;
|
||||
typedef typename Traits::Owner::Context Context;
|
||||
|
||||
public:
|
||||
template<typename... Args>
|
||||
static void Call(const Owner* cls, nsresult* rv,
|
||||
static void Call(const Context& ctx, nsresult* rv,
|
||||
const Args&... args)
|
||||
{
|
||||
JNIEnv* const env = Base::BeginAccess();
|
||||
JNIEnv* const env = ctx.Env();
|
||||
Base::BeginAccess(ctx);
|
||||
|
||||
jvalue jargs[] = {
|
||||
Value(TypeAdapter<Args>::FromNative(env, args)).val ...
|
||||
};
|
||||
|
||||
if (Traits::isStatic) {
|
||||
env->CallStaticVoidMethodA(Owner::sClassRef, Base::sID, jargs);
|
||||
env->CallStaticVoidMethodA(ctx.RawClassRef(), Base::sID, jargs);
|
||||
} else {
|
||||
env->CallVoidMethodA(cls->mInstance, Base::sID, jargs);
|
||||
env->CallVoidMethodA(ctx.Get(), Base::sID, jargs);
|
||||
}
|
||||
|
||||
Base::EndAccess(env, rv);
|
||||
Base::EndAccess(ctx, rv);
|
||||
}
|
||||
};
|
||||
|
||||
@ -173,25 +155,26 @@ public:
|
||||
// Constructor<> is used to construct a JNI instance given a traits class.
|
||||
template<class Traits>
|
||||
class Constructor : protected Method<Traits, typename Traits::ReturnType> {
|
||||
typedef typename Traits::Owner Owner;
|
||||
typedef typename Traits::Owner::Context Context;
|
||||
typedef typename Traits::ReturnType ReturnType;
|
||||
typedef Method<Traits, ReturnType> Base;
|
||||
|
||||
public:
|
||||
template<typename... Args>
|
||||
static ReturnType Call(const Owner* cls, nsresult* rv,
|
||||
static ReturnType Call(const Context& ctx, nsresult* rv,
|
||||
const Args&... args)
|
||||
{
|
||||
JNIEnv* const env = Base::BeginAccess();
|
||||
JNIEnv* const env = ctx.Env();
|
||||
Base::BeginAccess(ctx);
|
||||
|
||||
jvalue jargs[] = {
|
||||
Value(TypeAdapter<Args>::FromNative(env, args)).val ...
|
||||
};
|
||||
|
||||
auto result = TypeAdapter<ReturnType>::ToNative(
|
||||
env, env->NewObjectA(Owner::sClassRef, Base::sID, jargs));
|
||||
env, env->NewObjectA(ctx.RawClassRef(), Base::sID, jargs));
|
||||
|
||||
Base::EndAccess(env, rv);
|
||||
Base::EndAccess(ctx, rv);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
@ -202,7 +185,7 @@ template<class Traits>
|
||||
class Field : public Accessor
|
||||
{
|
||||
typedef Accessor Base;
|
||||
typedef typename Traits::Owner Owner;
|
||||
typedef typename Traits::Owner::Context Context;
|
||||
typedef typename Traits::ReturnType GetterType;
|
||||
typedef typename Traits::SetterType SetterType;
|
||||
|
||||
@ -210,62 +193,61 @@ private:
|
||||
|
||||
static jfieldID sID;
|
||||
|
||||
static JNIEnv* BeginAccess()
|
||||
static void BeginAccess(const Context& ctx)
|
||||
{
|
||||
JNIEnv* const env = Base::BeginAccess<Traits>();
|
||||
|
||||
if (sID) {
|
||||
return env;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Traits::isStatic) {
|
||||
MOZ_ALWAYS_TRUE(sID = AndroidBridge::GetStaticFieldID(
|
||||
env, Traits::Owner::sClassRef, Traits::name, Traits::signature));
|
||||
ctx.Env(), ctx.ClassRef(), Traits::name, Traits::signature));
|
||||
} else {
|
||||
MOZ_ALWAYS_TRUE(sID = AndroidBridge::GetFieldID(
|
||||
env, Traits::Owner::sClassRef, Traits::name, Traits::signature));
|
||||
ctx.Env(), ctx.ClassRef(), Traits::name, Traits::signature));
|
||||
}
|
||||
return env;
|
||||
}
|
||||
|
||||
static void EndAccess(JNIEnv* env, nsresult* rv)
|
||||
static void EndAccess(const Context& ctx, nsresult* rv)
|
||||
{
|
||||
return Base::EndAccess<Traits>(env, rv);
|
||||
return Base::EndAccess<Traits>(ctx, rv);
|
||||
}
|
||||
|
||||
public:
|
||||
static GetterType Get(const Owner* cls, nsresult* rv)
|
||||
static GetterType Get(const Context& ctx, nsresult* rv)
|
||||
{
|
||||
JNIEnv* const env = BeginAccess();
|
||||
JNIEnv* const env = ctx.Env();
|
||||
BeginAccess(ctx);
|
||||
|
||||
auto result = TypeAdapter<GetterType>::ToNative(
|
||||
env, Traits::isStatic ?
|
||||
|
||||
(env->*TypeAdapter<GetterType>::StaticGet)
|
||||
(Owner::sClassRef, sID) :
|
||||
(ctx.RawClassRef(), sID) :
|
||||
|
||||
(env->*TypeAdapter<GetterType>::Get)
|
||||
(cls->mInstance, sID));
|
||||
(ctx.Get(), sID));
|
||||
|
||||
EndAccess(env, rv);
|
||||
EndAccess(ctx, rv);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void Set(const Owner* cls, nsresult* rv, SetterType val)
|
||||
static void Set(const Context& ctx, nsresult* rv, SetterType val)
|
||||
{
|
||||
JNIEnv* const env = BeginAccess();
|
||||
JNIEnv* const env = ctx.Env();
|
||||
BeginAccess(ctx);
|
||||
|
||||
if (Traits::isStatic) {
|
||||
(env->*TypeAdapter<SetterType>::StaticSet)(
|
||||
Owner::sClassRef, sID,
|
||||
ctx.RawClassRef(), sID,
|
||||
TypeAdapter<SetterType>::FromNative(env, val));
|
||||
} else {
|
||||
(env->*TypeAdapter<SetterType>::Set)(
|
||||
cls->mInstance, sID,
|
||||
ctx.Get(), sID,
|
||||
TypeAdapter<SetterType>::FromNative(env, val));
|
||||
}
|
||||
|
||||
EndAccess(env, rv);
|
||||
EndAccess(ctx, rv);
|
||||
}
|
||||
};
|
||||
|
||||
@ -275,7 +257,7 @@ template<class T> jfieldID Field<T>::sID;
|
||||
|
||||
// Define the sClassRef member declared in Refs.h and
|
||||
// used by Method and Field above.
|
||||
template<class C> jclass Class<C>::sClassRef;
|
||||
template<class C, typename T> jclass Context<C, T>::sClassRef;
|
||||
|
||||
} // namespace jni
|
||||
} // namespace mozilla
|
||||
|
@ -239,24 +239,24 @@ struct ProxyArg
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct ProxyArg<Ref<T>>
|
||||
template<class C, typename T>
|
||||
struct ProxyArg<Ref<C, T>>
|
||||
{
|
||||
// Ref types need to be saved by global ref.
|
||||
typedef typename T::GlobalRef Type;
|
||||
typedef typename TypeAdapter<Ref<T>>::JNIType JNIType;
|
||||
typedef typename C::GlobalRef Type;
|
||||
typedef typename TypeAdapter<Ref<C, T>>::JNIType JNIType;
|
||||
|
||||
static void Clear(JNIEnv* env, Type& ref) { ref.Clear(env); }
|
||||
|
||||
static Type From(JNIEnv* env, JNIType val)
|
||||
{
|
||||
return Type(env, T::Ref::From(val));
|
||||
return Type(env, C::Ref::From(val));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> struct ProxyArg<const T&> : ProxyArg<T> {};
|
||||
template<> struct ProxyArg<Param<String>> : ProxyArg<Ref<String>> {};
|
||||
template<class T> struct ProxyArg<LocalRef<T>> : ProxyArg<Ref<T>> {};
|
||||
template<typename C> struct ProxyArg<const C&> : ProxyArg<C> {};
|
||||
template<> struct ProxyArg<StringParam> : ProxyArg<String::Ref> {};
|
||||
template<class C> struct ProxyArg<LocalRef<C>> : ProxyArg<typename C::Ref> {};
|
||||
|
||||
// ProxyNativeCall implements the functor object that is passed to
|
||||
// UsesNativeCallProxy::OnNativeCall
|
||||
@ -268,11 +268,11 @@ class ProxyNativeCall
|
||||
template<class T, class I, class A, bool S, bool V>
|
||||
friend class NativeStubImpl;
|
||||
|
||||
// "this arg" refers to the ClassObject::LocalRef (for static methods) or
|
||||
// "this arg" refers to the Class::LocalRef (for static methods) or
|
||||
// Owner::LocalRef (for instance methods) that we optionally (as indicated
|
||||
// by HasThisArg) pass into the destination C++ function.
|
||||
typedef typename mozilla::Conditional<IsStatic,
|
||||
ClassObject, Owner>::Type ThisArgClass;
|
||||
Class, Owner>::Type ThisArgClass;
|
||||
typedef typename mozilla::Conditional<IsStatic,
|
||||
jclass, jobject>::Type ThisArgJNIType;
|
||||
|
||||
@ -280,7 +280,7 @@ class ProxyNativeCall
|
||||
// Method template parameter in NativeStubImpl::Wrap.
|
||||
typedef typename mozilla::Conditional<IsStatic,
|
||||
typename mozilla::Conditional<HasThisArg,
|
||||
void (*) (const ClassObject::LocalRef&, Args...),
|
||||
void (*) (const Class::LocalRef&, Args...),
|
||||
void (*) (Args...)>::Type,
|
||||
typename mozilla::Conditional<HasThisArg,
|
||||
void (Impl::*) (const typename Owner::LocalRef&, Args...),
|
||||
@ -308,7 +308,7 @@ class ProxyNativeCall
|
||||
|
||||
template<bool Static, bool ThisArg, size_t... Indices>
|
||||
typename mozilla::EnableIf<Static && ThisArg, void>::Type
|
||||
Call(const ClassObject::LocalRef& cls,
|
||||
Call(const Class::LocalRef& cls,
|
||||
mozilla::IndexSequence<Indices...>) const
|
||||
{
|
||||
(*mNativeCall)(cls, mozilla::Get<Indices>(mArgs)...);
|
||||
@ -316,7 +316,7 @@ class ProxyNativeCall
|
||||
|
||||
template<bool Static, bool ThisArg, size_t... Indices>
|
||||
typename mozilla::EnableIf<Static && !ThisArg, void>::Type
|
||||
Call(const ClassObject::LocalRef& cls,
|
||||
Call(const Class::LocalRef& cls,
|
||||
mozilla::IndexSequence<Indices...>) const
|
||||
{
|
||||
(*mNativeCall)(mozilla::Get<Indices>(mArgs)...);
|
||||
@ -531,7 +531,7 @@ public:
|
||||
static MOZ_JNICALL void Wrap(JNIEnv* env, jobject instance)
|
||||
{
|
||||
if (mozilla::IsBaseOf<UsesNativeCallProxy, Impl>::value) {
|
||||
auto cls = ClassObject::LocalRef::Adopt(
|
||||
auto cls = Class::LocalRef::Adopt(
|
||||
env, env->GetObjectClass(instance));
|
||||
Dispatch(ProxyNativeCall<Impl, Owner, /* IsStatic */ true,
|
||||
/* HasThisArg */ false, const typename Owner::LocalRef&>(
|
||||
@ -566,14 +566,14 @@ public:
|
||||
}
|
||||
|
||||
// Static method with class reference
|
||||
template<ReturnType (*Method) (const ClassObject::LocalRef&, Args...)>
|
||||
template<ReturnType (*Method) (const Class::LocalRef&, Args...)>
|
||||
static MOZ_JNICALL ReturnJNIType Wrap(JNIEnv* env,
|
||||
jclass cls, typename TypeAdapter<Args>::JNIType... args)
|
||||
{
|
||||
static_assert(!mozilla::IsBaseOf<UsesNativeCallProxy, Impl>::value,
|
||||
"Native call proxy only supports void return type");
|
||||
|
||||
auto clazz = ClassObject::LocalRef::Adopt(env, cls);
|
||||
auto clazz = Class::LocalRef::Adopt(env, cls);
|
||||
const auto res = TypeAdapter<ReturnType>::FromNative(env,
|
||||
(*Method)(clazz, TypeAdapter<Args>::ToNative(env, args)...));
|
||||
clazz.Forget();
|
||||
@ -604,7 +604,7 @@ public:
|
||||
}
|
||||
|
||||
// Static method with class reference
|
||||
template<void (*Method) (const ClassObject::LocalRef&, Args...)>
|
||||
template<void (*Method) (const Class::LocalRef&, Args...)>
|
||||
static MOZ_JNICALL void Wrap(JNIEnv* env,
|
||||
jclass cls, typename TypeAdapter<Args>::JNIType... args)
|
||||
{
|
||||
@ -614,7 +614,7 @@ public:
|
||||
Args...>(Method, env, cls, args...));
|
||||
return;
|
||||
}
|
||||
auto clazz = ClassObject::LocalRef::Adopt(env, cls);
|
||||
auto clazz = Class::LocalRef::Adopt(env, cls);
|
||||
(*Method)(clazz, TypeAdapter<Args>::ToNative(env, args)...);
|
||||
clazz.Forget();
|
||||
}
|
||||
@ -656,11 +656,11 @@ public:
|
||||
if (sInited) {
|
||||
return;
|
||||
}
|
||||
JNIEnv* const env = GetEnvForThread();
|
||||
MOZ_ALWAYS_TRUE(!env->RegisterNatives(
|
||||
Accessor::EnsureClassRef<Cls>(env),
|
||||
Natives::methods,
|
||||
sizeof(Natives::methods) / sizeof(Natives::methods[0])));
|
||||
const auto& ctx = typename Cls::Context();
|
||||
ctx.Env()->RegisterNatives(
|
||||
ctx.ClassRef(), Natives::methods,
|
||||
sizeof(Natives::methods) / sizeof(Natives::methods[0]));
|
||||
MOZ_CATCH_JNI_EXCEPTION(ctx.Env());
|
||||
sInited = true;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -27,7 +27,7 @@ template<typename T> struct TypeAdapter;
|
||||
|
||||
// TypeAdapter<LocalRef<Cls>> applies when jobject is a return value.
|
||||
template<class Cls> struct TypeAdapter<LocalRef<Cls>> {
|
||||
typedef decltype(Ref<Cls>(nullptr).Get()) JNIType;
|
||||
using JNIType = typename Cls::Ref::JNIType;
|
||||
|
||||
static constexpr auto Call = &JNIEnv::CallObjectMethodA;
|
||||
static constexpr auto StaticCall = &JNIEnv::CallStaticObjectMethodA;
|
||||
@ -37,7 +37,7 @@ template<class Cls> struct TypeAdapter<LocalRef<Cls>> {
|
||||
// Declare instance as jobject because JNI methods return
|
||||
// jobject even if the return value is really jstring, etc.
|
||||
static LocalRef<Cls> ToNative(JNIEnv* env, jobject instance) {
|
||||
return LocalRef<Cls>::Adopt(env, instance);
|
||||
return LocalRef<Cls>::Adopt(env, JNIType(instance));
|
||||
}
|
||||
|
||||
static JNIType FromNative(JNIEnv*, LocalRef<Cls>&& instance) {
|
||||
@ -64,29 +64,29 @@ template<class Cls> constexpr jobject
|
||||
|
||||
|
||||
// TypeAdapter<Ref<Cls>> applies when jobject is a parameter value.
|
||||
template<class Cls> struct TypeAdapter<Ref<Cls>> {
|
||||
typedef decltype(Ref<Cls>(nullptr).Get()) JNIType;
|
||||
template<class Cls, typename T> struct TypeAdapter<Ref<Cls, T>> {
|
||||
using JNIType = typename Ref<Cls, T>::JNIType;
|
||||
|
||||
static constexpr auto Set = &JNIEnv::SetObjectField;
|
||||
static constexpr auto StaticSet = &JNIEnv::SetStaticObjectField;
|
||||
|
||||
static Ref<Cls> ToNative(JNIEnv* env, JNIType instance) {
|
||||
return Ref<Cls>::From(instance);
|
||||
static DependentRef<Cls> ToNative(JNIEnv* env, JNIType instance) {
|
||||
return DependentRef<Cls>(instance);
|
||||
}
|
||||
|
||||
static JNIType FromNative(JNIEnv*, const Ref<Cls>& instance) {
|
||||
static JNIType FromNative(JNIEnv*, const Ref<Cls, T>& instance) {
|
||||
return instance.Get();
|
||||
}
|
||||
};
|
||||
|
||||
template<class Cls> constexpr void
|
||||
(JNIEnv::*TypeAdapter<Ref<Cls>>::Set)(jobject, jfieldID, jobject);
|
||||
template<class Cls> constexpr void
|
||||
(JNIEnv::*TypeAdapter<Ref<Cls>>::StaticSet)(jclass, jfieldID, jobject);
|
||||
template<class Cls, typename T> constexpr void
|
||||
(JNIEnv::*TypeAdapter<Ref<Cls, T>>::Set)(jobject, jfieldID, jobject);
|
||||
template<class Cls, typename T> constexpr void
|
||||
(JNIEnv::*TypeAdapter<Ref<Cls, T>>::StaticSet)(jclass, jfieldID, jobject);
|
||||
|
||||
|
||||
// jstring has its own Param type.
|
||||
template<> struct TypeAdapter<Param<String>>
|
||||
template<> struct TypeAdapter<StringParam>
|
||||
: public TypeAdapter<String::Ref>
|
||||
{};
|
||||
|
||||
@ -98,7 +98,7 @@ template<class Cls> struct TypeAdapter<const Cls&>
|
||||
#define DEFINE_PRIMITIVE_TYPE_ADAPTER(NativeType, JNIType, JNIName) \
|
||||
\
|
||||
template<> struct TypeAdapter<NativeType> { \
|
||||
typedef JNIType JNI##Type; \
|
||||
using JNI##Type = JNIType; \
|
||||
\
|
||||
static constexpr auto Call = &JNIEnv::Call ## JNIName ## MethodA; \
|
||||
static constexpr auto StaticCall = &JNIEnv::CallStatic ## JNIName ## MethodA; \
|
||||
|
@ -47,19 +47,19 @@ DEFINE_PRIMITIVE_TYPE_ADAPTER(double, jdouble, Double, MOZ_JNICALL_ABI);
|
||||
|
||||
} // namespace detail
|
||||
|
||||
constexpr char Object::name[];
|
||||
template<> const char TypedObject<jstring>::name[] = "java/lang/String";
|
||||
template<> const char TypedObject<jclass>::name[] = "java/lang/Class";
|
||||
template<> const char TypedObject<jthrowable>::name[] = "java/lang/Throwable";
|
||||
template<> const char TypedObject<jbooleanArray>::name[] = "[Z";
|
||||
template<> const char TypedObject<jbyteArray>::name[] = "[B";
|
||||
template<> const char TypedObject<jcharArray>::name[] = "[C";
|
||||
template<> const char TypedObject<jshortArray>::name[] = "[S";
|
||||
template<> const char TypedObject<jintArray>::name[] = "[I";
|
||||
template<> const char TypedObject<jlongArray>::name[] = "[J";
|
||||
template<> const char TypedObject<jfloatArray>::name[] = "[F";
|
||||
template<> const char TypedObject<jdoubleArray>::name[] = "[D";
|
||||
template<> const char TypedObject<jobjectArray>::name[] = "[Ljava/lang/Object;";
|
||||
template<> const char Context<Object, jobject>::name[] = "java/lang/Object";
|
||||
template<> const char Context<TypedObject<jstring>, jstring>::name[] = "java/lang/String";
|
||||
template<> const char Context<TypedObject<jclass>, jclass>::name[] = "java/lang/Class";
|
||||
template<> const char Context<TypedObject<jthrowable>, jthrowable>::name[] = "java/lang/Throwable";
|
||||
template<> const char Context<TypedObject<jbooleanArray>, jbooleanArray>::name[] = "[Z";
|
||||
template<> const char Context<TypedObject<jbyteArray>, jbyteArray>::name[] = "[B";
|
||||
template<> const char Context<TypedObject<jcharArray>, jcharArray>::name[] = "[C";
|
||||
template<> const char Context<TypedObject<jshortArray>, jshortArray>::name[] = "[S";
|
||||
template<> const char Context<TypedObject<jintArray>, jintArray>::name[] = "[I";
|
||||
template<> const char Context<TypedObject<jlongArray>, jlongArray>::name[] = "[J";
|
||||
template<> const char Context<TypedObject<jfloatArray>, jfloatArray>::name[] = "[F";
|
||||
template<> const char Context<TypedObject<jdoubleArray>, jdoubleArray>::name[] = "[D";
|
||||
template<> const char Context<TypedObject<jobjectArray>, jobjectArray>::name[] = "[Ljava/lang/Object;";
|
||||
|
||||
|
||||
JNIEnv* sGeckoThreadEnv;
|
||||
@ -128,8 +128,7 @@ bool ThrowException(JNIEnv *aEnv, const char *aClass,
|
||||
{
|
||||
MOZ_ASSERT(aEnv, "Invalid thread JNI env");
|
||||
|
||||
ClassObject::LocalRef cls =
|
||||
ClassObject::LocalRef::Adopt(aEnv->FindClass(aClass));
|
||||
Class::LocalRef cls = Class::LocalRef::Adopt(aEnv->FindClass(aClass));
|
||||
MOZ_ASSERT(cls, "Cannot find exception class");
|
||||
|
||||
return !aEnv->ThrowNew(cls.Get(), aMessage);
|
||||
@ -158,7 +157,7 @@ bool HandleUncaughtException(JNIEnv* aEnv)
|
||||
if (stack) {
|
||||
// GeckoAppShell wants us to annotate and trigger the crash reporter.
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
NS_LITERAL_CSTRING("AuxiliaryJavaStack"), nsCString(stack));
|
||||
NS_LITERAL_CSTRING("AuxiliaryJavaStack"), stack->ToCString());
|
||||
}
|
||||
#endif // MOZ_CRASHREPORTER
|
||||
|
||||
@ -205,5 +204,10 @@ void SetNativeHandle(JNIEnv* env, jobject instance, uintptr_t handle)
|
||||
static_cast<jlong>(handle));
|
||||
}
|
||||
|
||||
jclass GetClassGlobalRef(JNIEnv* aEnv, const char* aClassName)
|
||||
{
|
||||
return AndroidBridge::GetClassGlobalRef(aEnv, aClassName);
|
||||
}
|
||||
|
||||
} // jni
|
||||
} // mozilla
|
||||
|
@ -66,6 +66,8 @@ uintptr_t GetNativeHandle(JNIEnv* env, jobject instance);
|
||||
|
||||
void SetNativeHandle(JNIEnv* env, jobject instance, uintptr_t handle);
|
||||
|
||||
jclass GetClassGlobalRef(JNIEnv* aEnv, const char* aClassName);
|
||||
|
||||
} // jni
|
||||
} // mozilla
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user