/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_jni_Types_h__ #define mozilla_jni_Types_h__ #include #include "mozilla/jni/Refs.h" #include "mozilla/jni/TypeAdapter.h" namespace mozilla { namespace jni { namespace detail { // TypeAdapter specializations are the interfaces between native/C++ types such // as int32_t and JNI types such as jint. The template parameter T is the native // type, and each TypeAdapter specialization can have the following members: // // * Call: JNIEnv member pointer for making a method call that returns T. // * StaticCall: JNIEnv member pointer for making a static call that returns T. // * Get: JNIEnv member pointer for getting a field of type T. // * StaticGet: JNIEnv member pointer for getting a static field of type T. // * Set: JNIEnv member pointer for setting a field of type T. // * StaticGet: JNIEnv member pointer for setting a static field of type T. // * ToNative: static function that converts the JNI type to the native type. // * FromNative: static function that converts the native type to the JNI type. // TypeAdapter> applies when jobject is a return value. template struct TypeAdapter> { using JNIType = typename Cls::Ref::JNIType; static constexpr auto Call = &JNIEnv::CallObjectMethodA; static constexpr auto StaticCall = &JNIEnv::CallStaticObjectMethodA; static constexpr auto Get = &JNIEnv::GetObjectField; static constexpr auto StaticGet = &JNIEnv::GetStaticObjectField; // Declare instance as jobject because JNI methods return // jobject even if the return value is really jstring, etc. static LocalRef ToNative(JNIEnv* env, jobject instance) { return LocalRef::Adopt(env, JNIType(instance)); } static JNIType FromNative(JNIEnv*, LocalRef&& instance) { return instance.Forget(); } }; // clang is picky about function types, including attributes that modify the // calling convention, lining up. GCC appears to be somewhat less so. #ifdef __clang__ # define MOZ_JNICALL_ABI JNICALL #else # define MOZ_JNICALL_ABI #endif // NDK r18 made jvalue* method parameters const. We detect the change directly // instead of using ndk-version.h in order to remain compatible with r15 for // now, which doesn't include those headers. class CallArgs { static const jvalue* test(void (JNIEnv::*)(jobject, jmethodID, const jvalue*)); static jvalue* test(void (JNIEnv::*)(jobject, jmethodID, jvalue*)); public: using JValueType = decltype(test(&JNIEnv::CallVoidMethodA)); }; template constexpr jobject (JNIEnv::*TypeAdapter>::Call)( jobject, jmethodID, CallArgs::JValueType) MOZ_JNICALL_ABI; template constexpr jobject (JNIEnv::*TypeAdapter>::StaticCall)( jclass, jmethodID, CallArgs::JValueType) MOZ_JNICALL_ABI; template constexpr jobject (JNIEnv::*TypeAdapter>::Get)(jobject, jfieldID); template constexpr jobject (JNIEnv::*TypeAdapter>::StaticGet)(jclass, jfieldID); // TypeAdapter> applies when jobject is a parameter value. template struct TypeAdapter> { using JNIType = typename Ref::JNIType; static constexpr auto Set = &JNIEnv::SetObjectField; static constexpr auto StaticSet = &JNIEnv::SetStaticObjectField; static DependentRef ToNative(JNIEnv* env, JNIType instance) { return DependentRef(instance); } static JNIType FromNative(JNIEnv*, const Ref& instance) { return instance.Get(); } }; template constexpr void (JNIEnv::*TypeAdapter>::Set)(jobject, jfieldID, jobject); template constexpr void (JNIEnv::*TypeAdapter>::StaticSet)(jclass, jfieldID, jobject); // jstring has its own Param type. template <> struct TypeAdapter : public TypeAdapter {}; template struct TypeAdapter : public TypeAdapter {}; } // namespace detail using namespace detail; } // namespace jni } // namespace mozilla #endif // mozilla_jni_Types_h__