| /* |
| * Copyright (C) 2003, 2004, 2005, 2008, 2009, 2010 Apple Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #ifndef JNIUtility_h |
| #define JNIUtility_h |
| |
| #if ENABLE(MAC_JAVA_BRIDGE) |
| |
| #include <JavaVM/jni.h> |
| |
| // The order of these items can not be modified as they are tightly |
| // bound with the JVM on Mac OSX. If new types need to be added, they |
| // should be added to the end. It is used in jni_obc.mm when calling |
| // through to the JVM. Newly added items need to be made compatible |
| // in that file. |
| typedef enum { |
| invalid_type = 0, |
| void_type, |
| object_type, |
| boolean_type, |
| byte_type, |
| char_type, |
| short_type, |
| int_type, |
| long_type, |
| float_type, |
| double_type, |
| array_type |
| } JNIType; |
| |
| namespace JSC { |
| |
| namespace Bindings { |
| |
| class JavaParameter; |
| |
| const char* getCharactersFromJString(jstring); |
| void releaseCharactersForJString(jstring, const char*); |
| |
| const char* getCharactersFromJStringInEnv(JNIEnv*, jstring); |
| void releaseCharactersForJStringInEnv(JNIEnv*, jstring, const char*); |
| const jchar* getUCharactersFromJStringInEnv(JNIEnv*, jstring); |
| void releaseUCharactersForJStringInEnv(JNIEnv*, jstring, const jchar*); |
| |
| JNIType JNITypeFromClassName(const char* name); |
| JNIType JNITypeFromPrimitiveType(char type); |
| const char* signatureFromPrimitiveType(JNIType); |
| |
| jvalue getJNIField(jobject, JNIType, const char* name, const char* signature); |
| |
| jmethodID getMethodID(jobject, const char* name, const char* sig); |
| JNIEnv* getJNIEnv(); |
| JavaVM* getJavaVM(); |
| void setJavaVM(JavaVM*); |
| |
| |
| template <typename T> struct JNICaller; |
| |
| template<> struct JNICaller<void> { |
| static void callA(jobject obj, jmethodID mid, jvalue* args) |
| { |
| getJNIEnv()->CallVoidMethodA(obj, mid, args); |
| } |
| static void callV(jobject obj, jmethodID mid, va_list args) |
| { |
| getJNIEnv()->CallVoidMethodV(obj, mid, args); |
| } |
| }; |
| |
| template<> struct JNICaller<jobject> { |
| static jobject callA(jobject obj, jmethodID mid, jvalue* args) |
| { |
| return getJNIEnv()->CallObjectMethodA(obj, mid, args); |
| } |
| static jobject callV(jobject obj, jmethodID mid, va_list args) |
| { |
| return getJNIEnv()->CallObjectMethodV(obj, mid, args); |
| } |
| }; |
| |
| template<> struct JNICaller<jboolean> { |
| static jboolean callA(jobject obj, jmethodID mid, jvalue* args) |
| { |
| return getJNIEnv()->CallBooleanMethodA(obj, mid, args); |
| } |
| static jboolean callV(jobject obj, jmethodID mid, va_list args) |
| { |
| return getJNIEnv()->CallBooleanMethodV(obj, mid, args); |
| } |
| static jboolean callStaticV(jclass cls, jmethodID mid, va_list args) |
| { |
| return getJNIEnv()->CallStaticBooleanMethod(cls, mid, args); |
| } |
| }; |
| |
| template<> struct JNICaller<jbyte> { |
| static jbyte callA(jobject obj, jmethodID mid, jvalue* args) |
| { |
| return getJNIEnv()->CallByteMethodA(obj, mid, args); |
| } |
| static jbyte callV(jobject obj, jmethodID mid, va_list args) |
| { |
| return getJNIEnv()->CallByteMethodV(obj, mid, args); |
| } |
| }; |
| |
| template<> struct JNICaller<jchar> { |
| static jchar callA(jobject obj, jmethodID mid, jvalue* args) |
| { |
| return getJNIEnv()->CallCharMethodA(obj, mid, args); |
| } |
| static jchar callV(jobject obj, jmethodID mid, va_list args) |
| { |
| return getJNIEnv()->CallCharMethodV(obj, mid, args); |
| } |
| }; |
| |
| template<> struct JNICaller<jshort> { |
| static jshort callA(jobject obj, jmethodID mid, jvalue* args) |
| { |
| return getJNIEnv()->CallShortMethodA(obj, mid, args); |
| } |
| static jshort callV(jobject obj, jmethodID mid, va_list args) |
| { |
| return getJNIEnv()->CallShortMethodV(obj, mid, args); |
| } |
| }; |
| |
| template<> struct JNICaller<jint> { |
| static jint callA(jobject obj, jmethodID mid, jvalue* args) |
| { |
| return getJNIEnv()->CallIntMethodA(obj, mid, args); |
| } |
| static jint callV(jobject obj, jmethodID mid, va_list args) |
| { |
| return getJNIEnv()->CallIntMethodV(obj, mid, args); |
| } |
| }; |
| |
| template<> struct JNICaller<jlong> { |
| static jlong callA(jobject obj, jmethodID mid, jvalue* args) |
| { |
| return getJNIEnv()->CallLongMethodA(obj, mid, args); |
| } |
| static jlong callV(jobject obj, jmethodID mid, va_list args) |
| { |
| return getJNIEnv()->CallLongMethodV(obj, mid, args); |
| } |
| }; |
| |
| template<> struct JNICaller<jfloat> { |
| static jfloat callA(jobject obj, jmethodID mid, jvalue* args) |
| { |
| return getJNIEnv()->CallFloatMethodA(obj, mid, args); |
| } |
| static jfloat callV(jobject obj, jmethodID mid, va_list args) |
| { |
| return getJNIEnv()->CallFloatMethodV(obj, mid, args); |
| } |
| }; |
| |
| template<> struct JNICaller<jdouble> { |
| static jdouble callA(jobject obj, jmethodID mid, jvalue* args) |
| { |
| return getJNIEnv()->CallDoubleMethodA(obj, mid, args); |
| } |
| static jdouble callV(jobject obj, jmethodID mid, va_list args) |
| { |
| return getJNIEnv()->CallDoubleMethodV(obj, mid, args); |
| } |
| }; |
| |
| template<typename T> T callJNIMethodIDA(jobject obj, jmethodID mid, jvalue *args) |
| { |
| return JNICaller<T>::callA(obj, mid, args); |
| } |
| |
| template<typename T> |
| static T callJNIMethodV(jobject obj, const char* name, const char* sig, va_list args) |
| { |
| JavaVM* jvm = getJavaVM(); |
| JNIEnv* env = getJNIEnv(); |
| |
| if (obj && jvm && env) { |
| jclass cls = env->GetObjectClass(obj); |
| if (cls) { |
| jmethodID mid = env->GetMethodID(cls, name, sig); |
| if (mid) { |
| // Avoids references to cls without popping the local frame. |
| env->DeleteLocalRef(cls); |
| return JNICaller<T>::callV(obj, mid, args); |
| } |
| LOG_ERROR("Could not find method: %s for %p", name, obj); |
| env->ExceptionDescribe(); |
| env->ExceptionClear(); |
| fprintf(stderr, "\n"); |
| |
| env->DeleteLocalRef(cls); |
| } else |
| LOG_ERROR("Could not find class for %p", obj); |
| } |
| |
| return 0; |
| } |
| |
| template<typename T> |
| T callJNIMethod(jobject obj, const char* methodName, const char* methodSignature, ...) |
| { |
| va_list args; |
| va_start(args, methodSignature); |
| |
| T result = callJNIMethodV<T>(obj, methodName, methodSignature, args); |
| |
| va_end(args); |
| |
| return result; |
| } |
| |
| template<typename T> |
| T callJNIStaticMethod(jclass cls, const char* methodName, const char* methodSignature, ...) |
| { |
| JavaVM* jvm = getJavaVM(); |
| JNIEnv* env = getJNIEnv(); |
| va_list args; |
| |
| va_start(args, methodSignature); |
| |
| T result = 0; |
| |
| if (cls && jvm && env) { |
| jmethodID mid = env->GetStaticMethodID(cls, methodName, methodSignature); |
| if (mid) |
| result = JNICaller<T>::callStaticV(cls, mid, args); |
| else { |
| LOG_ERROR("Could not find method: %s for %p", methodName, cls); |
| env->ExceptionDescribe(); |
| env->ExceptionClear(); |
| fprintf(stderr, "\n"); |
| } |
| } |
| |
| va_end(args); |
| |
| return result; |
| } |
| |
| } // namespace Bindings |
| |
| } // namespace JSC |
| |
| #endif // ENABLE(MAC_JAVA_BRIDGE) |
| |
| #endif // JNIUtility_h |