1 /* 2 * Copyright (C) 2003 Apple Computer, Inc. All rights reserved. 3 * Copyright 2009, The Android Open Source Project 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #ifndef _JNI_UTILITY_H_ 28 #define _JNI_UTILITY_H_ 29 30 #include <JavaVM/jni.h> 31 #include "npruntime.h" 32 33 // The order of these items can not be modified as they are tightly 34 // bound with the JVM on Mac OSX. If new types need to be added, they 35 // should be added to the end. It is used in jni_obc.mm when calling 36 // through to the JVM. Newly added items need to be made compatible 37 // in that file. 38 typedef enum { 39 invalid_type = 0, 40 void_type, 41 object_type, 42 boolean_type, 43 byte_type, 44 char_type, 45 short_type, 46 int_type, 47 long_type, 48 float_type, 49 double_type, 50 array_type 51 } JNIType; 52 53 namespace JSC { 54 55 namespace Bindings { 56 57 const char *getCharactersFromJString(jstring aJString); 58 void releaseCharactersForJString(jstring aJString, const char *s); 59 60 const char *getCharactersFromJStringInEnv(JNIEnv *env, jstring aJString); 61 void releaseCharactersForJStringInEnv(JNIEnv *env, jstring aJString, const char *s); 62 const jchar *getUCharactersFromJStringInEnv(JNIEnv *env, jstring aJString); 63 void releaseUCharactersForJStringInEnv(JNIEnv *env, jstring aJString, const jchar *s); 64 65 JNIType JNITypeFromClassName(const char *name); 66 JNIType JNITypeFromPrimitiveType(char type); 67 const char *signatureFromPrimitiveType(JNIType type); 68 69 jvalue convertNPVariantToJValue(NPVariant, JNIType, const char* javaClassName); 70 void convertJValueToNPVariant(jvalue, JNIType, const char* javaClassName, NPVariant*); 71 72 jvalue getJNIField(jobject obj, JNIType type, const char *name, const char *signature); 73 74 jmethodID getMethodID(jobject obj, const char *name, const char *sig); 75 JNIEnv* getJNIEnv(); 76 JavaVM* getJavaVM(); 77 void setJavaVM(JavaVM*); 78 79 80 template <typename T> struct JNICaller; 81 82 template<> struct JNICaller<void> { 83 static void callA(jobject obj, jmethodID mid, jvalue* args) 84 { 85 return getJNIEnv()->CallVoidMethodA(obj, mid, args); 86 } 87 static void callV(jobject obj, jmethodID mid, va_list args) 88 { 89 return getJNIEnv()->CallVoidMethodV(obj, mid, args); 90 } 91 }; 92 93 template<> struct JNICaller<jobject> { 94 static jobject callA(jobject obj, jmethodID mid, jvalue* args) 95 { 96 return getJNIEnv()->CallObjectMethodA(obj, mid, args); 97 } 98 static jobject callV(jobject obj, jmethodID mid, va_list args) 99 { 100 return getJNIEnv()->CallObjectMethodV(obj, mid, args); 101 } 102 }; 103 104 template<> struct JNICaller<jboolean> { 105 static jboolean callA(jobject obj, jmethodID mid, jvalue* args) 106 { 107 return getJNIEnv()->CallBooleanMethodA(obj, mid, args); 108 } 109 static jboolean callV(jobject obj, jmethodID mid, va_list args) 110 { 111 return getJNIEnv()->CallBooleanMethodV(obj, mid, args); 112 } 113 static jboolean callStaticV(jclass cls, jmethodID mid, va_list args) 114 { 115 return getJNIEnv()->CallStaticBooleanMethod(cls, mid, args); 116 } 117 118 }; 119 120 template<> struct JNICaller<jbyte> { 121 static jbyte callA(jobject obj, jmethodID mid, jvalue* args) 122 { 123 return getJNIEnv()->CallByteMethodA(obj, mid, args); 124 } 125 static jbyte callV(jobject obj, jmethodID mid, va_list args) 126 { 127 return getJNIEnv()->CallByteMethodV(obj, mid, args); 128 } 129 }; 130 131 template<> struct JNICaller<jchar> { 132 static jchar callA(jobject obj, jmethodID mid, jvalue* args) 133 { 134 return getJNIEnv()->CallCharMethodA(obj, mid, args); 135 } 136 static jchar callV(jobject obj, jmethodID mid, va_list args) 137 { 138 return getJNIEnv()->CallCharMethodV(obj, mid, args); 139 } 140 }; 141 142 template<> struct JNICaller<jshort> { 143 static jshort callA(jobject obj, jmethodID mid, jvalue* args) 144 { 145 return getJNIEnv()->CallShortMethodA(obj, mid, args); 146 } 147 static jshort callV(jobject obj, jmethodID mid, va_list args) 148 { 149 return getJNIEnv()->CallShortMethodV(obj, mid, args); 150 } 151 }; 152 153 template<> struct JNICaller<jint> { 154 static jint callA(jobject obj, jmethodID mid, jvalue* args) 155 { 156 return getJNIEnv()->CallIntMethodA(obj, mid, args); 157 } 158 static jint callV(jobject obj, jmethodID mid, va_list args) 159 { 160 return getJNIEnv()->CallIntMethodV(obj, mid, args); 161 } 162 }; 163 164 template<> struct JNICaller<jlong> { 165 static jlong callA(jobject obj, jmethodID mid, jvalue* args) 166 { 167 return getJNIEnv()->CallLongMethodA(obj, mid, args); 168 } 169 static jlong callV(jobject obj, jmethodID mid, va_list args) 170 { 171 return getJNIEnv()->CallLongMethodV(obj, mid, args); 172 } 173 }; 174 175 template<> struct JNICaller<jfloat> { 176 static jfloat callA(jobject obj, jmethodID mid, jvalue* args) 177 { 178 return getJNIEnv()->CallFloatMethodA(obj, mid, args); 179 } 180 static jfloat callV(jobject obj, jmethodID mid, va_list args) 181 { 182 return getJNIEnv()->CallFloatMethodV(obj, mid, args); 183 } 184 }; 185 186 template<> struct JNICaller<jdouble> { 187 static jdouble callA(jobject obj, jmethodID mid, jvalue* args) 188 { 189 return getJNIEnv()->CallDoubleMethodA(obj, mid, args); 190 } 191 static jdouble callV(jobject obj, jmethodID mid, va_list args) 192 { 193 return getJNIEnv()->CallDoubleMethodV(obj, mid, args); 194 } 195 }; 196 197 template<typename T> T callJNIMethodIDA(jobject obj, jmethodID mid, jvalue *args) 198 { 199 return JNICaller<T>::callA(obj, mid, args); 200 } 201 202 template<typename T> 203 static T callJNIMethodV(jobject obj, const char *name, const char *sig, va_list args) 204 { 205 JavaVM *jvm = getJavaVM(); 206 JNIEnv *env = getJNIEnv(); 207 208 if ( obj != NULL && jvm != NULL && env != NULL) { 209 jclass cls = env->GetObjectClass(obj); 210 if ( cls != NULL ) { 211 jmethodID mid = env->GetMethodID(cls, name, sig); 212 if ( mid != NULL ) 213 { 214 env->DeleteLocalRef(cls); 215 return JNICaller<T>::callV(obj, mid, args); 216 } 217 else 218 { 219 fprintf(stderr, "%s: Could not find method: %s for %p\n", __PRETTY_FUNCTION__, name, obj); 220 env->ExceptionDescribe(); 221 env->ExceptionClear(); 222 fprintf (stderr, "\n"); 223 } 224 225 env->DeleteLocalRef(cls); 226 } 227 else { 228 fprintf(stderr, "%s: Could not find class for %p\n", __PRETTY_FUNCTION__, obj); 229 } 230 } 231 232 return 0; 233 } 234 235 template<typename T> 236 T callJNIMethod(jobject obj, const char* methodName, const char* methodSignature, ...) 237 { 238 va_list args; 239 va_start(args, methodSignature); 240 241 T result= callJNIMethodV<T>(obj, methodName, methodSignature, args); 242 243 va_end(args); 244 245 return result; 246 } 247 248 template<typename T> 249 T callJNIStaticMethod(jclass cls, const char* methodName, const char* methodSignature, ...) 250 { 251 JavaVM *jvm = getJavaVM(); 252 JNIEnv *env = getJNIEnv(); 253 va_list args; 254 255 va_start(args, methodSignature); 256 257 T result = 0; 258 259 if (cls != NULL && jvm != NULL && env != NULL) { 260 jmethodID mid = env->GetStaticMethodID(cls, methodName, methodSignature); 261 if (mid != NULL) 262 result = JNICaller<T>::callStaticV(cls, mid, args); 263 else { 264 fprintf(stderr, "%s: Could not find method: %s for %p\n", __PRETTY_FUNCTION__, methodName, cls); 265 env->ExceptionDescribe(); 266 env->ExceptionClear(); 267 fprintf (stderr, "\n"); 268 } 269 } 270 271 va_end(args); 272 273 return result; 274 } 275 276 } // namespace Bindings 277 278 } // namespace JSC 279 280 #endif // _JNI_UTILITY_H_ 281