Fixed <rdar://problem/3827799> repro. crash with IBM Rational ClearCase Web under...
authorrjw <rjw@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 14 Dec 2004 02:44:45 +0000 (02:44 +0000)
committerrjw <rjw@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 14 Dec 2004 02:44:45 +0000 (02:44 +0000)
Add support for calling static Java methods from JavaScript.

        Reviewed by Maciej.

        * bindings/jni/jni_instance.cpp:
        (JavaInstance::invokeMethod):
        * bindings/jni/jni_runtime.cpp:
        (JavaMethod::JavaMethod):
        * bindings/jni/jni_runtime.h:
        (KJS::Bindings::JavaMethod::isStatic):
        * bindings/jni/jni_utility.cpp:
        (callJNIStaticMethod):
        (KJS::Bindings::callJNIBooleanMethod):
        (KJS::Bindings::callJNIStaticBooleanMethod):
        * bindings/jni/jni_utility.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@8201 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/ChangeLog
JavaScriptCore/bindings/jni/jni_instance.cpp
JavaScriptCore/bindings/jni/jni_runtime.cpp
JavaScriptCore/bindings/jni/jni_runtime.h
JavaScriptCore/bindings/jni/jni_utility.cpp
JavaScriptCore/bindings/jni/jni_utility.h

index fecd7e8c0c117fa90225e6cd5705012539d7eb6f..95eec4d22bcf50b8ee58709c00b5331700af82da 100644 (file)
@@ -1,3 +1,23 @@
+2004-12-13  Richard Williamson   <rjw@apple.com>
+
+       Fixed <rdar://problem/3827799> repro. crash with IBM Rational ClearCase Web under Safari (Java/LiveConnect-related)
+
+       Add support for calling static Java methods from JavaScript.
+
+        Reviewed by Maciej.
+
+        * bindings/jni/jni_instance.cpp:
+        (JavaInstance::invokeMethod):
+        * bindings/jni/jni_runtime.cpp:
+        (JavaMethod::JavaMethod):
+        * bindings/jni/jni_runtime.h:
+        (KJS::Bindings::JavaMethod::isStatic):
+        * bindings/jni/jni_utility.cpp:
+        (callJNIStaticMethod):
+        (KJS::Bindings::callJNIBooleanMethod):
+        (KJS::Bindings::callJNIStaticBooleanMethod):
+        * bindings/jni/jni_utility.h:
+
 2004-12-13  Richard Williamson   <rjw@apple.com>
 
        Fixed <rdar://problem/3887767> LiveConnect doesn't propagate Java exceptions back to JavaScript (prevents security suite from running)
index 7d3e95af5e13729de5b9299ac318e9e498ca58c4..54e3295cb5d1f49f0a617b2e415c55522a51c1a3 100644 (file)
@@ -159,9 +159,8 @@ Value JavaInstance::invokeMethod (KJS::ExecState *exec, const MethodList &method
     if (execContext && execContext->nativeHandle()) {
         jobject obj = _instance->_instance;
         Value exceptionDescription;
-        bool isStatic = false;  // FIXME, need to get meta data from Java about static methods
         const char *callingURL = 0;  // FIXME, need to propagate calling URL to Java
-        handled = dispatchJNICall (execContext->nativeHandle(), obj, isStatic, jMethod->JNIReturnType(), jMethod->methodID(obj), jArgs, result, callingURL, exceptionDescription);
+        handled = dispatchJNICall (execContext->nativeHandle(), obj, jMethod->isStatic(), jMethod->JNIReturnType(), jMethod->methodID(obj), jArgs, result, callingURL, exceptionDescription);
         if (!exceptionDescription.isNull()) {
             Object error = Error::create(exec, GeneralError, exceptionDescription.toString(exec).UTF8String().c_str());
             
index edc1681b5bbcd668b2b8ca12c177d9156dd6e851..0b95f9b8fe65467504f851d15c56114b5d3f3add 100644 (file)
@@ -221,6 +221,10 @@ JavaMethod::JavaMethod (JNIEnv *env, jobject aMethod)
     // Created lazily.
     _signature = 0;
     _methodID = 0;
+    
+    jclass modifierClass = env->FindClass("java/lang/reflect/Modifier");
+    long modifiers = callJNIIntMethod (aMethod, "getModifiers", "()I");
+    _isStatic = (bool)callJNIStaticBooleanMethod (modifierClass, "isStatic", "(I)Z", modifiers);
 }
 
 // JNI method signatures use '/' between components of a class name, but
index 977a38f224e10b621aadedf657a4d7cd6d06f296..181fa68a07be51e3409094f9421c73c0c7572e60 100644 (file)
@@ -251,6 +251,8 @@ public:
     JNIType JNIReturnType() const;
 
     jmethodID methodID (jobject obj) const;
+    
+    bool isStatic() const { return _isStatic; }
        
 private:
     JavaParameter *_parameters;
@@ -260,6 +262,7 @@ private:
     JavaString _returnType;
     JNIType _JNIReturnType;
     mutable jmethodID _methodID;
+    bool _isStatic;
 };
 
 class JavaArray : public Array
index 5b7f0c955fd24d0270dbe4d32014562011be76a8..3f1adf791d137eb4599608201c39d835cc2c4cfc 100644 (file)
@@ -134,6 +134,64 @@ static jvalue callJNIMethod (JNIType type, jobject obj, const char *name, const
     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 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();
@@ -236,6 +294,14 @@ jmethodID KJS::Bindings::getMethodID (jobject obj, const char *name, const char
     \
     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 KJS::Bindings::callJNIVoidMethod (jobject obj, const char *name, const char *sig, ... )
 {
     CALL_JNI_METHOD (void_type, obj, name, sig);
@@ -253,6 +319,12 @@ jboolean KJS::Bindings::callJNIBooleanMethod( jobject obj, const char *name, con
     return result.z;
 }
 
+jboolean KJS::Bindings::callJNIStaticBooleanMethod (jclass cls, const char *name, const char *sig, ... )
+{
+    CALL_JNI_STATIC_METHOD (boolean_type, cls, name, sig);
+    return result.z;
+}
+
 jbyte KJS::Bindings::callJNIByteMethod( jobject obj, const char *name, const char *sig, ... )
 {
     CALL_JNI_METHOD (byte_type, obj, name, sig);
index 89d5def17bf3685b541b7f5593c76c247d81c1dc..58681f5f5aaa2edfe928b9b8a1a65455b711645e 100644 (file)
@@ -72,6 +72,7 @@ jmethodID getMethodID (jobject obj, const char *name, const char *sig);
 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, ... );