+2008-03-06 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Jon.
+
+ Templatize the JNI call code to reduce the amount of code that has
+ to be duplicated.
+
+ * bridge/jni/jni_class.cpp:
+ (JavaClass::JavaClass):
+ * bridge/jni/jni_instance.cpp:
+ (JavaInstance::stringValue):
+ (JavaInstance::numberValue):
+ (JavaInstance::booleanValue):
+ (JavaInstance::invokeMethod):
+ * bridge/jni/jni_jsobject.cpp:
+ (JavaJSObject::convertJObjectToValue):
+ * bridge/jni/jni_runtime.cpp:
+ (JavaField::JavaField):
+ (JavaMethod::JavaMethod):
+ * bridge/jni/jni_utility.cpp:
+ * bridge/jni/jni_utility.h:
+ (KJS::Bindings::):
+ (KJS::Bindings::callJNIMethodIDA):
+ (KJS::Bindings::callJNIMethodV):
+ (KJS::Bindings::callJNIMethod):
+ (KJS::Bindings::callJNIStaticMethod):
+
2008-03-06 Darin Adler <darin@apple.com>
Reviewed by Mitz.
JavaClass::JavaClass(jobject anInstance)
{
- jobject aClass = callJNIObjectMethod(anInstance, "getClass", "()Ljava/lang/Class;");
+ jobject aClass = callJNIMethod<jobject>(anInstance, "getClass", "()Ljava/lang/Class;");
if (!aClass) {
fprintf(stderr, "%s: unable to call getClass on instance %p\n", __PRETTY_FUNCTION__, anInstance);
return;
}
- jstring className = (jstring)callJNIObjectMethod(aClass, "getName", "()Ljava/lang/String;");
+ jstring className = (jstring)callJNIMethod<jobject>(aClass, "getName", "()Ljava/lang/String;");
const char *classNameC = getCharactersFromJString(className);
_name = strdup(classNameC);
releaseCharactersForJString(className, classNameC);
JNIEnv *env = getJNIEnv();
// Get the fields
- jarray fields = (jarray)callJNIObjectMethod(aClass, "getFields", "()[Ljava/lang/reflect/Field;");
+ jarray fields = (jarray)callJNIMethod<jobject>(aClass, "getFields", "()[Ljava/lang/reflect/Field;");
int numFields = env->GetArrayLength(fields);
for (i = 0; i < numFields; i++) {
jobject aJField = env->GetObjectArrayElement((jobjectArray)fields, i);
}
// Get the methods
- jarray methods = (jarray)callJNIObjectMethod(aClass, "getMethods", "()[Ljava/lang/reflect/Method;");
+ jarray methods = (jarray)callJNIMethod<jobject>(aClass, "getMethods", "()[Ljava/lang/reflect/Method;");
int numMethods = env->GetArrayLength(methods);
for (i = 0; i < numMethods; i++) {
jobject aJMethod = env->GetObjectArrayElement((jobjectArray)methods, i);
{
JSLock lock;
- jstring stringValue = (jstring)callJNIObjectMethod (_instance->_instance, "toString", "()Ljava/lang/String;");
+ jstring stringValue = (jstring)callJNIMethod<jobject>(_instance->_instance, "toString", "()Ljava/lang/String;");
JNIEnv *env = getJNIEnv();
const jchar *c = getUCharactersFromJStringInEnv(env, stringValue);
UString u((const UChar *)c, (int)env->GetStringLength(stringValue));
JSValue *JavaInstance::numberValue() const
{
- jdouble doubleValue = callJNIDoubleMethod (_instance->_instance, "doubleValue", "()D");
+ jdouble doubleValue = callJNIMethod<jdouble>(_instance->_instance, "doubleValue", "()D");
return jsNumber(doubleValue);
}
JSValue *JavaInstance::booleanValue() const
{
- jboolean booleanValue = callJNIBooleanMethod (_instance->_instance, "booleanValue", "()Z");
+ jboolean booleanValue = callJNIMethod<jboolean>(_instance->_instance, "booleanValue", "()Z");
return jsBoolean(booleanValue);
}
if (!handled) {
jobject obj = _instance->_instance;
switch (jMethod->JNIReturnType()){
- case void_type: {
- callJNIVoidMethodIDA (obj, jMethod->methodID(obj), jArgs);
- }
- break;
-
- case object_type: {
- result.l = callJNIObjectMethodIDA (obj, jMethod->methodID(obj), jArgs);
- }
- break;
-
- case boolean_type: {
- result.z = callJNIBooleanMethodIDA (obj, jMethod->methodID(obj), jArgs);
- }
- break;
+ case void_type:
+ callJNIMethodIDA<void>(obj, jMethod->methodID(obj), jArgs);
+ break;
+ case object_type:
+ result.l = callJNIMethodIDA<jobject>(obj, jMethod->methodID(obj), jArgs);
+ break;
+ case boolean_type:
+ result.z = callJNIMethodIDA<jboolean>(obj, jMethod->methodID(obj), jArgs);
+ break;
+ case byte_type:
+ result.b = callJNIMethodIDA<jbyte>(obj, jMethod->methodID(obj), jArgs);
+ break;
+ case char_type:
+ result.c = callJNIMethodIDA<jchar>(obj, jMethod->methodID(obj), jArgs);
+ break;
+ case short_type:
+ result.s = callJNIMethodIDA<jshort>(obj, jMethod->methodID(obj), jArgs);
+ break;
+ case int_type:
+ result.i = callJNIMethodIDA<jint>(obj, jMethod->methodID(obj), jArgs);
+ break;
- case byte_type: {
- result.b = callJNIByteMethodIDA (obj, jMethod->methodID(obj), jArgs);
- }
- break;
-
- case char_type: {
- result.c = callJNICharMethodIDA (obj, jMethod->methodID(obj), jArgs);
- }
- break;
-
- case short_type: {
- result.s = callJNIShortMethodIDA (obj, jMethod->methodID(obj), jArgs);
- }
- break;
-
- case int_type: {
- result.i = callJNIIntMethodIDA (obj, jMethod->methodID(obj), jArgs);
- }
- break;
-
- case long_type: {
- result.j = callJNILongMethodIDA (obj, jMethod->methodID(obj), jArgs);
- }
- break;
-
- case float_type: {
- result.f = callJNIFloatMethodIDA (obj, jMethod->methodID(obj), jArgs);
- }
- break;
-
- case double_type: {
- result.d = callJNIDoubleMethodIDA (obj, jMethod->methodID(obj), jArgs);
- }
- break;
-
+ case long_type:
+ result.j = callJNIMethodIDA<jlong>(obj, jMethod->methodID(obj), jArgs);
+ break;
+ case float_type:
+ result.f = callJNIMethodIDA<jfloat>(obj, jMethod->methodID(obj), jArgs);
+ break;
+ case double_type:
+ result.d = callJNIMethodIDA<jdouble>(obj, jMethod->methodID(obj), jArgs);
+ break;
case invalid_type:
- default: {
- }
- break;
+ default:
+ break;
}
}
// possible to pass primitive types from the Java to JavaScript.
// See section 22.7 of 'JavaScript: The Definitive Guide, 4th Edition',
// figure 22-4.
- jobject classOfInstance = callJNIObjectMethod(theObject, "getClass", "()Ljava/lang/Class;");
- jstring className = (jstring)callJNIObjectMethod(classOfInstance, "getName", "()Ljava/lang/String;");
+ jobject classOfInstance = callJNIMethod<jobject>(theObject, "getClass", "()Ljava/lang/Class;");
+ jstring className = (jstring)callJNIMethod<jobject>(classOfInstance, "getName", "()Ljava/lang/String;");
// Only the sun.plugin.javascript.webkit.JSObject has a member called nativeJSObject. This class is
// created above to wrap internal browser objects. The constructor of this class takes the native
JavaField::JavaField (JNIEnv *env, jobject aField)
{
// Get field type
- jobject fieldType = callJNIObjectMethod (aField, "getType", "()Ljava/lang/Class;");
- jstring fieldTypeName = (jstring)callJNIObjectMethod (fieldType, "getName", "()Ljava/lang/String;");
+ jobject fieldType = callJNIMethod<jobject>(aField, "getType", "()Ljava/lang/Class;");
+ jstring fieldTypeName = (jstring)callJNIMethod<jobject>(fieldType, "getName", "()Ljava/lang/String;");
_type = JavaString(env, fieldTypeName);
_JNIType = JNITypeFromClassName (_type.UTF8String());
// Get field name
- jstring fieldName = (jstring)callJNIObjectMethod (aField, "getName", "()Ljava/lang/String;");
+ jstring fieldName = (jstring)callJNIMethod<jobject>(aField, "getName", "()Ljava/lang/String;");
_name = JavaString(env, fieldName);
_field = new JObjectWrapper(aField);
JavaMethod::JavaMethod (JNIEnv *env, jobject aMethod)
{
// Get return type
- jobject returnType = callJNIObjectMethod (aMethod, "getReturnType", "()Ljava/lang/Class;");
- jstring returnTypeName = (jstring)callJNIObjectMethod (returnType, "getName", "()Ljava/lang/String;");
+ jobject returnType = callJNIMethod<jobject>(aMethod, "getReturnType", "()Ljava/lang/Class;");
+ jstring returnTypeName = (jstring)callJNIMethod<jobject>(returnType, "getName", "()Ljava/lang/String;");
_returnType =JavaString (env, returnTypeName);
_JNIReturnType = JNITypeFromClassName (_returnType.UTF8String());
env->DeleteLocalRef (returnType);
env->DeleteLocalRef (returnTypeName);
// Get method name
- jstring methodName = (jstring)callJNIObjectMethod (aMethod, "getName", "()Ljava/lang/String;");
+ jstring methodName = (jstring)callJNIMethod<jobject>(aMethod, "getName", "()Ljava/lang/String;");
_name = JavaString (env, methodName);
env->DeleteLocalRef (methodName);
// Get parameters
- jarray jparameters = (jarray)callJNIObjectMethod (aMethod, "getParameterTypes", "()[Ljava/lang/Class;");
+ jarray jparameters = (jarray)callJNIMethod<jobject>(aMethod, "getParameterTypes", "()[Ljava/lang/Class;");
_numParameters = env->GetArrayLength (jparameters);
_parameters = new JavaParameter[_numParameters];
int i;
for (i = 0; i < _numParameters; i++) {
jobject aParameter = env->GetObjectArrayElement ((jobjectArray)jparameters, i);
- jstring parameterName = (jstring)callJNIObjectMethod (aParameter, "getName", "()Ljava/lang/String;");
+ jstring parameterName = (jstring)callJNIMethod<jobject>(aParameter, "getName", "()Ljava/lang/String;");
_parameters[i] = JavaParameter(env, parameterName);
env->DeleteLocalRef (aParameter);
env->DeleteLocalRef (parameterName);
_methodID = 0;
jclass modifierClass = env->FindClass("java/lang/reflect/Modifier");
- int modifiers = callJNIIntMethod (aMethod, "getModifiers", "()I");
- _isStatic = (bool)callJNIStaticBooleanMethod (modifierClass, "isStatic", "(I)Z", modifiers);
+ int modifiers = callJNIMethod<jint>(aMethod, "getModifiers", "()I");
+ _isStatic = (bool)callJNIStaticMethod<jboolean>(modifierClass, "isStatic", "(I)Z", modifiers);
}
JavaMethod::~JavaMethod()
return NULL;
}
-static jvalue callJNIMethod (JNIType type, jobject obj, const char *name, const char *sig, va_list args)
-{
- JavaVM *jvm = getJavaVM();
- JNIEnv *env = getJNIEnv();
- jvalue result;
-
- bzero (&result, sizeof(jvalue));
- if ( obj != NULL && jvm != NULL && env != NULL) {
- jclass cls = env->GetObjectClass(obj);
- if ( cls != NULL ) {
- jmethodID mid = env->GetMethodID(cls, name, sig);
- if ( mid != NULL )
- {
- switch (type) {
- case void_type:
- env->functions->CallVoidMethodV(env, obj, mid, args);
- break;
- case array_type:
- case object_type:
- result.l = env->functions->CallObjectMethodV(env, obj, mid, args);
- break;
- case boolean_type:
- result.z = env->functions->CallBooleanMethodV(env, obj, mid, args);
- break;
- case byte_type:
- result.b = env->functions->CallByteMethodV(env, obj, mid, args);
- break;
- case char_type:
- result.c = env->functions->CallCharMethodV(env, obj, mid, args);
- break;
- case short_type:
- result.s = env->functions->CallShortMethodV(env, obj, mid, args);
- break;
- case int_type:
- result.i = env->functions->CallIntMethodV(env, obj, mid, args);
- break;
- case long_type:
- result.j = env->functions->CallLongMethodV(env, obj, mid, args);
- break;
- case float_type:
- result.f = env->functions->CallFloatMethodV(env, obj, mid, args);
- break;
- case double_type:
- result.d = env->functions->CallDoubleMethodV(env, obj, mid, args);
- break;
- default:
- fprintf(stderr, "%s: invalid function type (%d)\n", __PRETTY_FUNCTION__, (int)type);
- }
- }
- else
- {
- fprintf(stderr, "%s: Could not find method: %s for %p\n", __PRETTY_FUNCTION__, name, obj);
- env->ExceptionDescribe();
- env->ExceptionClear();
- fprintf (stderr, "\n");
- }
-
- env->DeleteLocalRef(cls);
- }
- else {
- fprintf(stderr, "%s: Could not find class for %p\n", __PRETTY_FUNCTION__, obj);
- }
- }
-
- return result;
-}
-
-static jvalue callJNIStaticMethod (JNIType type, jclass cls, const char *name, const char *sig, va_list args)
-{
- JavaVM *jvm = getJavaVM();
- JNIEnv *env = getJNIEnv();
- jvalue result;
-
- bzero (&result, sizeof(jvalue));
- if ( cls != NULL && jvm != NULL && env != NULL) {
- jmethodID mid = env->GetStaticMethodID(cls, name, sig);
- if ( mid != NULL )
- {
- switch (type) {
- case void_type:
- env->functions->CallStaticVoidMethodV(env, cls, mid, args);
- break;
- case array_type:
- case object_type:
- result.l = env->functions->CallStaticObjectMethodV(env, cls, mid, args);
- break;
- case boolean_type:
- result.z = env->functions->CallStaticBooleanMethodV(env, cls, mid, args);
- break;
- case byte_type:
- result.b = env->functions->CallStaticByteMethodV(env, cls, mid, args);
- break;
- case char_type:
- result.c = env->functions->CallStaticCharMethodV(env, cls, mid, args);
- break;
- case short_type:
- result.s = env->functions->CallStaticShortMethodV(env, cls, mid, args);
- break;
- case int_type:
- result.i = env->functions->CallStaticIntMethodV(env, cls, mid, args);
- break;
- case long_type:
- result.j = env->functions->CallStaticLongMethodV(env, cls, mid, args);
- break;
- case float_type:
- result.f = env->functions->CallStaticFloatMethodV(env, cls, mid, args);
- break;
- case double_type:
- result.d = env->functions->CallStaticDoubleMethodV(env, cls, mid, args);
- break;
- default:
- fprintf(stderr, "%s: invalid function type (%d)\n", __PRETTY_FUNCTION__, (int)type);
- }
- }
- else
- {
- fprintf(stderr, "%s: Could not find method: %s for %p\n", __PRETTY_FUNCTION__, name, cls);
- env->ExceptionDescribe();
- env->ExceptionClear();
- fprintf (stderr, "\n");
- }
- }
-
- return result;
-}
-
-static jvalue callJNIMethodIDA (JNIType type, jobject obj, jmethodID mid, jvalue *args)
-{
- JNIEnv *env = getJNIEnv();
- jvalue result;
-
- bzero (&result, sizeof(jvalue));
- if ( obj != NULL && mid != NULL )
- {
- switch (type) {
- case void_type:
- env->functions->CallVoidMethodA(env, obj, mid, args);
- break;
- case array_type:
- case object_type:
- result.l = env->functions->CallObjectMethodA(env, obj, mid, args);
- break;
- case boolean_type:
- result.z = env->functions->CallBooleanMethodA(env, obj, mid, args);
- break;
- case byte_type:
- result.b = env->functions->CallByteMethodA(env, obj, mid, args);
- break;
- case char_type:
- result.c = env->functions->CallCharMethodA(env, obj, mid, args);
- break;
- case short_type:
- result.s = env->functions->CallShortMethodA(env, obj, mid, args);
- break;
- case int_type:
- result.i = env->functions->CallIntMethodA(env, obj, mid, args);
- break;
- case long_type:
- result.j = env->functions->CallLongMethodA(env, obj, mid, args);
- break;
- case float_type:
- result.f = env->functions->CallFloatMethodA(env, obj, mid, args);
- break;
- case double_type:
- result.d = env->functions->CallDoubleMethodA(env, obj, mid, args);
- break;
- default:
- fprintf(stderr, "%s: invalid function type (%d)\n", __PRETTY_FUNCTION__, (int)type);
- }
- }
-
- return result;
-}
-
-static jvalue callJNIMethodA (JNIType type, jobject obj, const char *name, const char *sig, jvalue *args)
-{
- JavaVM *jvm = getJavaVM();
- JNIEnv *env = getJNIEnv();
- jvalue result;
-
- bzero (&result, sizeof(jvalue));
- if ( obj != NULL && jvm != NULL && env != NULL) {
- jclass cls = env->GetObjectClass(obj);
- if ( cls != NULL ) {
- jmethodID mid = env->GetMethodID(cls, name, sig);
- if ( mid != NULL ) {
- result = callJNIMethodIDA (type, obj, mid, args);
- }
- else {
- fprintf(stderr, "%s: Could not find method: %s\n", __PRETTY_FUNCTION__, name);
- env->ExceptionDescribe();
- env->ExceptionClear();
- fprintf (stderr, "\n");
- }
-
- env->DeleteLocalRef(cls);
- }
- else {
- fprintf(stderr, "%s: Could not find class for object\n", __PRETTY_FUNCTION__);
- }
- }
-
- return result;
-}
-
jmethodID getMethodID (jobject obj, const char *name, const char *sig)
{
JNIEnv *env = getJNIEnv();
return mid;
}
-
-#define CALL_JNI_METHOD(function_type,obj,name,sig) \
- va_list args;\
- va_start (args, sig);\
- \
- jvalue result = callJNIMethod(function_type, obj, name, sig, args);\
- \
- va_end (args);
-
-#define CALL_JNI_STATIC_METHOD(function_type,cls,name,sig) \
- va_list args;\
- va_start (args, sig);\
- \
- jvalue result = callJNIStaticMethod(function_type, cls, name, sig, args);\
- \
- va_end (args);
-
-void callJNIVoidMethod (jobject obj, const char *name, const char *sig, ... )
-{
- CALL_JNI_METHOD (void_type, obj, name, sig);
-}
-
-jobject callJNIObjectMethod (jobject obj, const char *name, const char *sig, ... )
-{
- CALL_JNI_METHOD (object_type, obj, name, sig);
- return result.l;
-}
-
-jboolean callJNIBooleanMethod( jobject obj, const char *name, const char *sig, ... )
-{
- CALL_JNI_METHOD (boolean_type, obj, name, sig);
- return result.z;
-}
-
-jboolean callJNIStaticBooleanMethod (jclass cls, const char *name, const char *sig, ... )
-{
- CALL_JNI_STATIC_METHOD (boolean_type, cls, name, sig);
- return result.z;
-}
-
-jbyte callJNIByteMethod( jobject obj, const char *name, const char *sig, ... )
-{
- CALL_JNI_METHOD (byte_type, obj, name, sig);
- return result.b;
-}
-
-jchar callJNICharMethod (jobject obj, const char *name, const char *sig, ... )
-{
- CALL_JNI_METHOD (char_type, obj, name, sig);
- return result.c;
-}
-
-jshort callJNIShortMethod (jobject obj, const char *name, const char *sig, ... )
-{
- CALL_JNI_METHOD (short_type, obj, name, sig);
- return result.s;
-}
-
-jint callJNIIntMethod (jobject obj, const char *name, const char *sig, ... )
-{
- CALL_JNI_METHOD (int_type, obj, name, sig);
- return result.i;
-}
-
-jlong callJNILongMethod (jobject obj, const char *name, const char *sig, ... )
-{
- CALL_JNI_METHOD (long_type, obj, name, sig);
- return result.j;
-}
-
-jfloat callJNIFloatMethod (jobject obj, const char *name, const char *sig, ... )
-{
- CALL_JNI_METHOD (float_type, obj, name, sig);
- return result.f;
-}
-
-jdouble callJNIDoubleMethod (jobject obj, const char *name, const char *sig, ... )
-{
- CALL_JNI_METHOD (double_type, obj, name, sig);
- return result.d;
-}
-
-void callJNIVoidMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
-{
- jvalue result = callJNIMethodA (void_type, obj, name, sig, args);
-}
-
-jobject callJNIObjectMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
-{
- jvalue result = callJNIMethodA (object_type, obj, name, sig, args);
- return result.l;
-}
-
-jbyte callJNIByteMethodA ( jobject obj, const char *name, const char *sig, jvalue *args)
-{
- jvalue result = callJNIMethodA (byte_type, obj, name, sig, args);
- return result.b;
-}
-
-jchar callJNICharMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
-{
- jvalue result = callJNIMethodA (char_type, obj, name, sig, args);
- return result.c;
-}
-
-jshort callJNIShortMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
-{
- jvalue result = callJNIMethodA (short_type, obj, name, sig, args);
- return result.s;
-}
-
-jint callJNIIntMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
-{
- jvalue result = callJNIMethodA (int_type, obj, name, sig, args);
- return result.i;
-}
-
-jlong callJNILongMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
-{
- jvalue result = callJNIMethodA (long_type, obj, name, sig, args);
- return result.j;
-}
-
-jfloat callJNIFloatMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
-{
- jvalue result = callJNIMethodA (float_type, obj, name, sig, args);
- return result.f;
-}
-
-jdouble callJNIDoubleMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
-{
- jvalue result = callJNIMethodA (double_type, obj, name, sig, args);
- return result.d;
-}
-
-jboolean callJNIBooleanMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
-{
- jvalue result = callJNIMethodA (boolean_type, obj, name, sig, args);
- return result.z;
-}
-
-void callJNIVoidMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
-{
- jvalue result = callJNIMethodIDA (void_type, obj, methodID, args);
-}
-
-jobject callJNIObjectMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
-{
- jvalue result = callJNIMethodIDA (object_type, obj, methodID, args);
- return result.l;
-}
-
-jbyte callJNIByteMethodIDA ( jobject obj, jmethodID methodID, jvalue *args)
-{
- jvalue result = callJNIMethodIDA (byte_type, obj, methodID, args);
- return result.b;
-}
-
-jchar callJNICharMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
-{
- jvalue result = callJNIMethodIDA (char_type, obj, methodID, args);
- return result.c;
-}
-
-jshort callJNIShortMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
-{
- jvalue result = callJNIMethodIDA (short_type, obj, methodID, args);
- return result.s;
-}
-
-jint callJNIIntMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
-{
- jvalue result = callJNIMethodIDA (int_type, obj, methodID, args);
- return result.i;
-}
-
-jlong callJNILongMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
-{
- jvalue result = callJNIMethodIDA (long_type, obj, methodID, args);
- return result.j;
-}
-
-jfloat callJNIFloatMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
-{
- jvalue result = callJNIMethodIDA (float_type, obj, methodID, args);
- return result.f;
-}
-
-jdouble callJNIDoubleMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
-{
- jvalue result = callJNIMethodIDA (double_type, obj, methodID, args);
- return result.d;
-}
-
-jboolean callJNIBooleanMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
-{
- jvalue result = callJNIMethodIDA (boolean_type, obj, methodID, args);
- return result.z;
-}
-
const char *getCharactersFromJString (jstring aJString)
{
return getCharactersFromJStringInEnv (getJNIEnv(), aJString);
jvalue getJNIField(jobject obj, JNIType type, const char *name, const char *signature);
jmethodID getMethodID(jobject obj, const char *name, const char *sig);
+JNIEnv* getJNIEnv();
+JavaVM* getJavaVM();
+void setJavaVM(JavaVM*);
+
+
+template <typename T> struct JNICaller;
-jobject callJNIObjectMethod(jobject obj, const char *name, const char *sig, ... );
-void callJNIVoidMethod(jobject obj, const char *name, const char *sig, ... );
-jboolean callJNIBooleanMethod(jobject obj, const char *name, const char *sig, ... );
-jboolean callJNIStaticBooleanMethod(jclass cls, const char *name, const char *sig, ... );
-jbyte callJNIByteMethod(jobject obj, const char *name, const char *sig, ... );
-jchar callJNICharMethod(jobject obj, const char *name, const char *sig, ... );
-jshort callJNIShortMethod(jobject obj, const char *name, const char *sig, ... );
-jint callJNIIntMethod(jobject obj, const char *name, const char *sig, ... );
-jlong callJNILongMethod(jobject obj, const char *name, const char *sig, ... );
-jfloat callJNIFloatMethod(jobject obj, const char *name, const char *sig, ... );
-jdouble callJNIDoubleMethod(jobject obj, const char *name, const char *sig, ... );
-
-jobject callJNIObjectMethodA(jobject obj, const char *name, const char *sig, jvalue *args);
-void callJNIVoidMethodA(jobject obj, const char *name, const char *sig, jvalue *args);
-jboolean callJNIBooleanMethodA(jobject obj, const char *name, const char *sig, jvalue *args);
-jbyte callJNIByteMethodA(jobject obj, const char *name, const char *sig, jvalue *args);
-jchar callJNICharMethodA(jobject obj, const char *name, const char *sig, jvalue *args);
-jshort callJNIShortMethodA(jobject obj, const char *name, const char *sig, jvalue *args);
-jint callJNIIntMethodA(jobject obj, const char *name, const char *sig, jvalue *args);
-jlong callJNILongMethodA(jobject obj, const char *name, const char *sig, jvalue *args);
-jfloat callJNIFloatMethodA(jobject obj, const char *name, const char *sig, jvalue *args);
-jdouble callJNIDoubleMethodA(jobject obj, const char *name, const char *sig, jvalue *args);
-
-jobject callJNIObjectMethodIDA(jobject obj, jmethodID methodID, jvalue *args);
-void callJNIVoidMethodIDA(jobject obj, jmethodID methodID, jvalue *args);
-jboolean callJNIBooleanMethodIDA(jobject obj, jmethodID methodID, jvalue *args);
-jbyte callJNIByteMethodIDA(jobject obj, jmethodID methodID, jvalue *args);
-jchar callJNICharMethodIDA(jobject obj, jmethodID methodID, jvalue *args);
-jshort callJNIShortMethodIDA(jobject obj, jmethodID methodID, jvalue *args);
-jint callJNIIntMethodIDA(jobject obj, jmethodID methodID, jvalue *args);
-jlong callJNILongMethodIDA(jobject obj, jmethodID methodID, jvalue *args);
-jfloat callJNIFloatMethodIDA(jobject obj, jmethodID methodID, jvalue *args);
-jdouble callJNIDoubleMethodIDA(jobject obj, jmethodID methodID, jvalue *args);
-
-JavaVM *getJavaVM();
-void setJavaVM(JavaVM *javaVM);
-JNIEnv *getJNIEnv();
+template<> struct JNICaller<void> {
+ static void callA(jobject obj, jmethodID mid, jvalue* args)
+ {
+ return getJNIEnv()->CallVoidMethodA(obj, mid, args);
+ }
+ static void callV(jobject obj, jmethodID mid, va_list args)
+ {
+ return 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 != NULL && jvm != NULL && env != NULL) {
+ jclass cls = env->GetObjectClass(obj);
+ if ( cls != NULL ) {
+ jmethodID mid = env->GetMethodID(cls, name, sig);
+ if ( mid != NULL )
+ {
+ return JNICaller<T>::callV(obj, mid, args);
+ }
+ else
+ {
+ fprintf(stderr, "%s: Could not find method: %s for %p\n", __PRETTY_FUNCTION__, name, obj);
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ fprintf (stderr, "\n");
+ }
+
+ env->DeleteLocalRef(cls);
+ }
+ else {
+ fprintf(stderr, "%s: Could not find class for %p\n", __PRETTY_FUNCTION__, 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 != NULL && jvm != NULL && env != NULL) {
+ jmethodID mid = env->GetStaticMethodID(cls, methodName, methodSignature);
+ if (mid != NULL)
+ result = JNICaller<T>::callStaticV(cls, mid, args);
+ else {
+ fprintf(stderr, "%s: Could not find method: %s for %p\n", __PRETTY_FUNCTION__, methodName, cls);
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ fprintf (stderr, "\n");
+ }
+ }
+
+ va_end(args);
+
+ return result;
+}
+
bool dispatchJNICall(const void *targetAppletView, jobject obj, bool isStatic, JNIType returnType, jmethodID methodID, jvalue *args, jvalue &result, const char *callingURL, JSValue *&exceptionDescription);
} // namespace Bindings