WebKit:
authorrjw <rjw@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 20 Aug 2004 21:57:16 +0000 (21:57 +0000)
committerrjw <rjw@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 20 Aug 2004 21:57:16 +0000 (21:57 +0000)
    Implemented new JNI abstraction.  We no longer invoke Java methods
    directly with JNI, rather we call into the plugin.  This allows the
    plugin to dispatch the call to the appropriate VM thread.  This
    change should (will?) fix a whole class of threading related problems with
    the Java VM.

        Reviewed by Hyatt.

        * WebCoreSupport.subproj/WebBridge.m:
        (-[WebBridge getAppletInView:]):

WebCore:
        Implemented new JNI abstraction.  We no longer invoke Java methods
        directly with JNI, rather we call into the plugin.  This allows the
        plugin to dispatch the call to the appropriate VM thread.  This
        change should (will?) fix a whole class of threading related problems with
        the Java VM.

        Reviewed by Hyatt.

        * kwq/KWQKHTMLPart.mm:
        (KWQKHTMLPart::getAppletInstanceForView):
        * kwq/WebCoreBridge.mm:
        (rootForView):
        (-[WebCoreBridge executionContextForView:]):

JavaScriptCore:
        Implemented new JNI abstraction.  We no longer invoke Java methods
        directly with JNI, rather we call into the plugin.  This allows the
        plugin to dispatch the call to the appropriate VM thread.  This
        change should (will?) fix a whole class of threading related problems with
        the Java VM.

        Reviewed by Hyatt.

        * JavaScriptCore.pbproj/project.pbxproj:
        * bindings/c/c_instance.h:
        (KJS::Bindings::CInstance::setExecutionContext):
        (KJS::Bindings::CInstance::executionContext):
        * bindings/jni/jni_instance.cpp:
        (JavaInstance::JavaInstance):
        (JavaInstance::invokeMethod):
        (JavaInstance::setExecutionContext):
        (JavaInstance::executionContext):
        * bindings/jni/jni_instance.h:
        * bindings/jni/jni_jsobject.cpp:
        (JSObject::convertJObjectToValue):
        * bindings/jni/jni_runtime.cpp:
        (JavaField::JavaField):
        (JavaArray::convertJObjectToArray):
        (JavaField::valueFromInstance):
        (JavaArray::JavaArray):
        (JavaArray::valueAt):
        * bindings/jni/jni_runtime.h:
        (KJS::Bindings::JavaArray::operator=):
        (KJS::Bindings::JavaArray::executionContext):
        * bindings/jni/jni_utility.h:
        * bindings/objc/objc_instance.h:
        (KJS::Bindings::ObjcInstance::setExecutionContext):
        (KJS::Bindings::ObjcInstance::executionContext):
        * bindings/runtime.cpp:
        (Instance::createBindingForLanguageInstance):
        * bindings/runtime.h:
        * bindings/runtime_root.h:
        (KJS::Bindings::RootObject::nativeHandle):

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

18 files changed:
JavaScriptCore/ChangeLog
JavaScriptCore/JavaScriptCore.pbproj/project.pbxproj
JavaScriptCore/bindings/c/c_instance.h
JavaScriptCore/bindings/jni/jni_instance.cpp
JavaScriptCore/bindings/jni/jni_instance.h
JavaScriptCore/bindings/jni/jni_jsobject.cpp
JavaScriptCore/bindings/jni/jni_runtime.cpp
JavaScriptCore/bindings/jni/jni_runtime.h
JavaScriptCore/bindings/jni/jni_utility.h
JavaScriptCore/bindings/objc/objc_instance.h
JavaScriptCore/bindings/runtime.cpp
JavaScriptCore/bindings/runtime.h
JavaScriptCore/bindings/runtime_root.h
WebCore/ChangeLog-2005-08-23
WebCore/kwq/KWQKHTMLPart.mm
WebCore/kwq/WebCoreBridge.mm
WebKit/ChangeLog
WebKit/WebCoreSupport.subproj/WebBridge.m

index 7290b36..aab8374 100644 (file)
@@ -1,3 +1,44 @@
+2004-08-20  Richard Williamson   <rjw@apple.com>
+
+        Implemented new JNI abstraction.  We no longer invoke Java methods
+        directly with JNI, rather we call into the plugin.  This allows the
+        plugin to dispatch the call to the appropriate VM thread.  This
+        change should (will?) fix a whole class of threading related problems with
+        the Java VM.
+
+        Reviewed by Hyatt.
+
+        * JavaScriptCore.pbproj/project.pbxproj:
+        * bindings/c/c_instance.h:
+        (KJS::Bindings::CInstance::setExecutionContext):
+        (KJS::Bindings::CInstance::executionContext):
+        * bindings/jni/jni_instance.cpp:
+        (JavaInstance::JavaInstance):
+        (JavaInstance::invokeMethod):
+        (JavaInstance::setExecutionContext):
+        (JavaInstance::executionContext):
+        * bindings/jni/jni_instance.h:
+        * bindings/jni/jni_jsobject.cpp:
+        (JSObject::convertJObjectToValue):
+        * bindings/jni/jni_runtime.cpp:
+        (JavaField::JavaField):
+        (JavaArray::convertJObjectToArray):
+        (JavaField::valueFromInstance):
+        (JavaArray::JavaArray):
+        (JavaArray::valueAt):
+        * bindings/jni/jni_runtime.h:
+        (KJS::Bindings::JavaArray::operator=):
+        (KJS::Bindings::JavaArray::executionContext):
+        * bindings/jni/jni_utility.h:
+        * bindings/objc/objc_instance.h:
+        (KJS::Bindings::ObjcInstance::setExecutionContext):
+        (KJS::Bindings::ObjcInstance::executionContext):
+        * bindings/runtime.cpp:
+        (Instance::createBindingForLanguageInstance):
+        * bindings/runtime.h:
+        * bindings/runtime_root.h:
+        (KJS::Bindings::RootObject::nativeHandle):
+
 === Safari-158 ===
 
 2004-08-19  Vicki Murley  <vicki@apple.com>
index c9bc4ce..87f870f 100644 (file)
                                65AB004A06261CBA0076DE63,
                                650B68DA0639033F009D42DE,
                                51863FC506542D3100E9E8DD,
+                               517EF37406D695930007C1BA,
                        );
                        isa = PBXSourcesBuildPhase;
                        runOnlyForDeploymentPostprocessing = 0;
                                );
                        };
                };
+               517EF37306D695930007C1BA = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.cpp.objcpp;
+                       name = jni_objc.mm;
+                       path = bindings/jni/jni_objc.mm;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               517EF37406D695930007C1BA = {
+                       fileRef = 517EF37306D695930007C1BA;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
                5182A45605FFCF4B00CBD2F2 = {
                        fileEncoding = 30;
                        isa = PBXFileReference;
                                517D5348056BFB5D003851BD,
                                513DF74005C0861F00F89391,
                                513DF74105C0861F00F89391,
+                               517EF37306D695930007C1BA,
                                511B0877056468BB0080E486,
                                511B0876056468BB0080E486,
                                51856D8F0562EE95008B9D83,
index 0111364..761593f 100644 (file)
@@ -61,10 +61,14 @@ public:
     KJS::Value booleanValue() const;
     
     NPObject *getObject() const { return _object; }
+
+    void setExecutionContext (RootObject *r) { _root = r; }
+    const RootObject *executionContext() const { return _root; }
     
 private:
     mutable CClass *_class;
     NPObject *_object;
+    RootObject *_root;
 };
 
 } // namespace Bindings
index a544226..0ca317f 100644 (file)
@@ -27,6 +27,7 @@
 #include <jni_runtime.h>
 #include <jni_utility.h>
 #include <runtime_object.h>
+#include <runtime_root.h>
 
 #ifdef NDEBUG
 #define JS_LOG(formatAndArgs...) ((void)0)
 using namespace KJS::Bindings;
 using namespace KJS;
 
-JavaInstance::JavaInstance (jobject instance) 
+JavaInstance::JavaInstance (jobject instance, const RootObject *r
 {
     _instance = new JObjectWrapper (instance);
     _class = 0;
+    _root = r;
 };
 
 JavaInstance::~JavaInstance () 
@@ -58,6 +60,7 @@ JavaInstance::JavaInstance (const JavaInstance &other) : Instance()
     _instance->ref();
     // Classes are kept around forever.
     _class = other._class;
+    _root = other._root;
 };
 
 #define NUM_LOCAL_REFS 64
@@ -144,25 +147,96 @@ Value JavaInstance::invokeMethod (KJS::ExecState *exec, const MethodList &method
         JavaParameter *aParameter = static_cast<JavaParameter *>(jMethod->parameterAt(i));
         jArgs[i] = convertValueToJValue (exec, args.at(i), aParameter->getJNIType(), aParameter->type());
     }
-    
+        
+
     jvalue result;
-    jobject obj = _instance->_instance;
+
+    // Try to use the JNI abstraction first, otherwise fall back to
+    // nornmal JNI.  The JNI dispatch abstraction allows the Java plugin
+    // to dispatch the call on the appropriate internal VM thread.
+    const RootObject *execContext = executionContext();
+    bool handled = false;
+    if (execContext && execContext->nativeHandle()) {
+        jobject obj = _instance->_instance;
+        handled = dispatchJNICall (execContext->nativeHandle(), obj, jMethod->methodID(obj), jMethod->JNIReturnType(), jArgs, result);
+    }
+    
+    // The following code can be conditionally removed once we have a Tiger update that
+    // contains the new Java plugin.  It is needed for builds prior to Tiger.
+    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 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 invalid_type:
+            default: {
+            }
+            break;
+        }
+    }
+        
     switch (jMethod->JNIReturnType()){
         case void_type: {
-            callJNIVoidMethodIDA (obj, jMethod->methodID(obj), jArgs);
             resultValue = Undefined();
         }
         break;
         
         case object_type: {
-            result.l = callJNIObjectMethodIDA (obj, jMethod->methodID(obj), jArgs);
             if (result.l != 0) {
                 const char *arrayType = jMethod->returnType();
                 if (arrayType[0] == '[') {
-                    resultValue = JavaArray::convertJObjectToArray (exec, result.l, arrayType);
+                    resultValue = JavaArray::convertJObjectToArray (exec, result.l, arrayType, executionContext());
                 }
                 else {
-                    resultValue = Object(new RuntimeObjectImp(new JavaInstance (result.l)));
+                    resultValue = Object(new RuntimeObjectImp(new JavaInstance (result.l, executionContext())));
                 }
             }
             else {
@@ -172,49 +246,41 @@ Value JavaInstance::invokeMethod (KJS::ExecState *exec, const MethodList &method
         break;
         
         case boolean_type: {
-            result.z = callJNIBooleanMethodIDA (obj, jMethod->methodID(obj), jArgs);
             resultValue = KJS::Boolean(result.z);
         }
         break;
         
         case byte_type: {
-            result.b = callJNIByteMethodIDA (obj, jMethod->methodID(obj), jArgs);
             resultValue = Number(result.b);
         }
         break;
         
         case char_type: {
-            result.c = callJNICharMethodIDA (obj, jMethod->methodID(obj), jArgs);
             resultValue = Number(result.c);
         }
         break;
         
         case short_type: {
-            result.s = callJNIShortMethodIDA (obj, jMethod->methodID(obj), jArgs);
             resultValue = Number(result.s);
         }
         break;
         
         case int_type: {
-            result.i = callJNIIntMethodIDA (obj, jMethod->methodID(obj), jArgs);
             resultValue = Number(result.i);
         }
         break;
         
         case long_type: {
-            result.j = callJNILongMethodIDA (obj, jMethod->methodID(obj), jArgs);
             resultValue = Number((long int)result.j);
         }
         break;
         
         case float_type: {
-            result.f = callJNIFloatMethodIDA (obj, jMethod->methodID(obj), jArgs);
             resultValue = Number(result.f);
         }
         break;
         
         case double_type: {
-            result.d = callJNIDoubleMethodIDA (obj, jMethod->methodID(obj), jArgs);
             resultValue = Number(result.d);
         }
         break;
@@ -225,7 +291,7 @@ Value JavaInstance::invokeMethod (KJS::ExecState *exec, const MethodList &method
         }
         break;
     }
-        
+
     free (jArgs);
 
     return resultValue;
@@ -264,6 +330,9 @@ KJS::Value JavaInstance::valueOf() const
     return stringValue();
 };
 
+void JavaInstance::setExecutionContext (RootObject *r) { _root = r; }
+const RootObject *JavaInstance::executionContext() const { return _root; }
+
 JObjectWrapper::JObjectWrapper(jobject instance)
 {
     assert (instance != 0);
index 1c537a1..ec324d6 100644 (file)
@@ -64,7 +64,7 @@ private:
 class JavaInstance : public Instance
 {
 public:
-    JavaInstance (jobject instance);
+    JavaInstance (jobject instance, const RootObject *r);
         
     ~JavaInstance ();
     
@@ -95,15 +95,19 @@ public:
 
     virtual KJS::Value invokeMethod (KJS::ExecState *exec, const MethodList &method, const KJS::List &args);
 
+    virtual void setExecutionContext (RootObject *r);
+    virtual const RootObject *executionContext() const;
+
     jobject javaInstance() const { return _instance->_instance; }
     
     KJS::Value stringValue() const;
     KJS::Value numberValue() const;
     KJS::Value booleanValue() const;
-    
+        
 private:
     JObjectWrapper *_instance;
-       mutable JavaClass *_class;
+    mutable JavaClass *_class;
+    const RootObject *_root;
 };
 
 } // namespace Bindings
index a026ee4..95c0f91 100644 (file)
@@ -440,7 +440,7 @@ KJS::Value JSObject::convertJObjectToValue (jobject theObject) const
     }
 
     Interpreter::lock();
-    KJS::RuntimeObjectImp *newImp = new KJS::RuntimeObjectImp(new Bindings::JavaInstance (theObject));
+    KJS::RuntimeObjectImp *newImp = new KJS::RuntimeObjectImp(new Bindings::JavaInstance (theObject, _root));
     Interpreter::unlock();
 
     return KJS::Object(newImp);
index bb4dd25..edc1681 100644 (file)
@@ -54,15 +54,15 @@ JavaField::JavaField (JNIEnv *env, jobject aField)
     jstring fieldName = (jstring)callJNIObjectMethod (aField, "getName", "()Ljava/lang/String;");
     _name = JavaString(env, fieldName);
 
-    _field = new JavaInstance(aField);
+    _field = new JavaInstance(aField, 0);
 }
 
-KJS::Value JavaArray::convertJObjectToArray (KJS::ExecState *exec, jobject anObject, const char *type)
+KJS::Value JavaArray::convertJObjectToArray (KJS::ExecState *exec, jobject anObject, const char *type, const RootObject *r)
 {
     if (type[0] != '[')
         return Undefined();
 
-    return KJS::Object(new RuntimeArrayImp(exec, new JavaArray ((jobject)anObject, type)));
+    return KJS::Object(new RuntimeArrayImp(exec, new JavaArray ((jobject)anObject, type, r)));
 }
 
 KJS::Value JavaField::valueFromInstance(KJS::ExecState *exec, const Instance *i) const 
@@ -77,10 +77,10 @@ KJS::Value JavaField::valueFromInstance(KJS::ExecState *exec, const Instance *i)
 
             const char *arrayType = type();
             if (arrayType[0] == '[') {
-                return JavaArray::convertJObjectToArray (0, anObject, arrayType);
+                return JavaArray::convertJObjectToArray (exec, anObject, arrayType, instance->executionContext());
             }
             else {
-                return KJS::Object(new RuntimeObjectImp(new JavaInstance ((jobject)anObject)));
+                return KJS::Object(new RuntimeObjectImp(new JavaInstance ((jobject)anObject, instance->executionContext())));
             }
         }
         break;
@@ -288,14 +288,14 @@ jmethodID JavaMethod::methodID (jobject obj) const
 }
 
 
-JavaArray::JavaArray (jobject a, const char *t) 
+JavaArray::JavaArray (jobject a, const char *t, const RootObject *r
 {
     _array = new JObjectWrapper (a);
     // Java array are fixed length, so we can cache length.
     JNIEnv *env = getJNIEnv();
     _length = env->GetArrayLength((jarray)_array->_instance);
-
     _type = strdup(t);
+    _root = r;
 };
 
 JavaArray::~JavaArray () 
@@ -392,10 +392,10 @@ KJS::Value JavaArray::valueAt(KJS::ExecState *exec, unsigned int index) const
 
             // Nested array?
             if (_type[1] == '[') {
-                return JavaArray::convertJObjectToArray (0, anObject, _type+1);
+                return JavaArray::convertJObjectToArray (exec, anObject, _type+1, executionContext());
             }
             // or array of other object type?
-            return KJS::Object(new RuntimeObjectImp(new JavaInstance ((jobject)anObject)));
+            return KJS::Object(new RuntimeObjectImp(new JavaInstance ((jobject)anObject, executionContext())));
         }
             
         case boolean_type: {
index 454f7a3..a7edd39 100644 (file)
@@ -264,7 +264,7 @@ private:
 class JavaArray : public Array
 {
 public:
-    JavaArray (jobject a, const char *type);
+    JavaArray (jobject a, const char *type, const RootObject *r);
 
     JavaArray (const JavaArray &other);
 
@@ -274,6 +274,7 @@ public:
         
         free ((void *)_type);
         _type = strdup(other._type);
+        _root = other._root;
 
         JObjectWrapper *_oldArray = _array;
         _array = other._array;
@@ -291,12 +292,15 @@ public:
 
     jobject javaArray() const { return _array->_instance; }
 
-    static KJS::Value convertJObjectToArray (KJS::ExecState *exec, jobject anObject, const char *type);
+    static KJS::Value convertJObjectToArray (KJS::ExecState *exec, jobject anObject, const char *type, const RootObject *r);
 
+    const RootObject *executionContext() const { return _root; }
+    
 private:
     JObjectWrapper *_array;
     unsigned int _length;
     const char *_type;
+    const RootObject *_root;
 };
 
 } // namespace Bindings
index a1c6abb..6bf7805 100644 (file)
@@ -105,6 +105,8 @@ jdouble callJNIDoubleMethodIDA (jobject obj, jmethodID methodID, jvalue *args);
 JavaVM *getJavaVM();
 JNIEnv *getJNIEnv();
 
+bool dispatchJNICall (const void *targetAppletView, jobject obj, jmethodID methodID, JNIType returnType, jvalue *args, jvalue &result);
+
 } // namespace Bindings
 
 } // namespace KJS
index 95f46cf..b00376a 100644 (file)
@@ -70,11 +70,15 @@ public:
     KJS::Value numberValue() const;
     KJS::Value booleanValue() const;
     
+    void setExecutionContext (RootObject *r) { _root = r; }
+    const RootObject *executionContext() const { return _root; }
+
 private:
     ObjectStructPtr _instance;
     mutable ObjcClass *_class;
     ObjectStructPtr _pool;
     long _beginCount;
+    RootObject *_root;
 };
 
 } // namespace Bindings
index b703c78..a5bb2c7 100644 (file)
@@ -100,7 +100,7 @@ void Instance::setValueOfField (KJS::ExecState *exec, const Field *aField, const
 Instance *Instance::createBindingForLanguageInstance (BindingLanguage language, void *instance)
 {
     if (language == Instance::JavaLanguage)
-        return new Bindings::JavaInstance ((jobject)instance);
+        return new Bindings::JavaInstance ((jobject)instance, 0);
     else if (language == Instance::ObjectiveCLanguage)
         return new Bindings::ObjcInstance ((struct objc_object *)instance);
 
index d659414..56d4160 100644 (file)
@@ -159,7 +159,12 @@ public:
     
     virtual KJS::Value valueOf() const { return KJS::String(getClass()->name()); };
     
+    virtual void setExecutionContext (RootObject *r) = 0;
+    virtual const RootObject *executionContext () const = 0;
+    
     virtual ~Instance() {};
+    
+private:
 };
 
 class Array
index a1f7a0f..72996b6 100644 (file)
@@ -87,6 +87,8 @@ public:
     
     static void dispatchToJavaScriptThread(JSObjectCallContext *context);
     
+    const void *nativeHandle() const { return _nativeHandle; }
+    
 private:
     const void *_nativeHandle;
     KJS::ObjectImp *_imp;
index cb0d145..31a6c8f 100644 (file)
@@ -1,3 +1,19 @@
+2004-08-20  Richard Williamson   <rjw@apple.com>
+
+        Implemented new JNI abstraction.  We no longer invoke Java methods
+        directly with JNI, rather we call into the plugin.  This allows the
+        plugin to dispatch the call to the appropriate VM thread.  This
+        change should (will?) fix a whole class of threading related problems with
+        the Java VM.
+
+        Reviewed by Hyatt.
+
+        * kwq/KWQKHTMLPart.mm:
+        (KWQKHTMLPart::getAppletInstanceForView):
+        * kwq/WebCoreBridge.mm:
+        (rootForView):
+        (-[WebCoreBridge executionContextForView:]):
+
 2004-08-19  Maciej Stachowiak  <mjs@apple.com>
 
         Reviewed by Darin.
index 71b7bcb..ac538b4 100644 (file)
@@ -3543,10 +3543,16 @@ KJS::Bindings::Instance *KWQKHTMLPart::getAppletInstanceForView (NSView *aView)
     else
         applet = [_bridge pollForAppletInView:aView];
     
-    if (applet)
+    if (applet) {
         // Wrap the Java instance in a language neutral binding and hand
         // off ownership to the APPLET element.
-        return KJS::Bindings::Instance::createBindingForLanguageInstance (KJS::Bindings::Instance::JavaLanguage, applet);
+        KJS::Bindings::Instance *instance = KJS::Bindings::Instance::createBindingForLanguageInstance (KJS::Bindings::Instance::JavaLanguage, applet);
+
+        KJS::Bindings::RootObject *root = KJS::Bindings::RootObject::findRootObjectForNativeHandleFunction ()(aView);
+        instance->setExecutionContext (root);
+        
+        return instance;
+    }
     
     return 0;
 }
index 57c97c1..46192b6 100644 (file)
@@ -139,20 +139,18 @@ NSString *WebCoreElementTitleKey =              @"WebCoreElementTitle"; // not i
 
 NSString *WebCorePageCacheStateKey =            @"WebCorePageCacheState";
 
+@interface WebCoreBridge (WebCoreBridgePrivate)
+- (RootObject *)executionContextForView:(NSView *)aView;
+@end
+
 static RootObject *rootForView(void *v)
 {
     NSView *aView = (NSView *)v;
     WebCoreBridge *aBridge = [[WebCoreViewFactory sharedFactory] bridgeForView:aView];
-    if (aBridge) {
-        KWQKHTMLPart *part = [aBridge part];
-        RootObject *root = new RootObject(v);    // The root gets deleted by JavaScriptCore.
-        
-        root->setRootObjectImp (static_cast<KJS::ObjectImp *>(KJS::Window::retrieveWindow(part)));
-        root->setInterpreter (KJSProxy::proxy(part)->interpreter());
-        part->addPluginRootObject (root);
-            
-        return root;
-    }
+
+    if (aBridge)
+        return [aBridge executionContextForView:aView];
+
     return 0;
 }
 
@@ -1774,3 +1772,20 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
 }
 
 @end
+
+
+@implementation WebCoreBridge (WebCoreBridgePrivate)
+
+- (RootObject *)executionContextForView:(NSView *)aView
+{
+    RootObject *root;
+    
+    KWQKHTMLPart *part = [self part];
+    root = new RootObject(aView);    // The root gets deleted by JavaScriptCore.
+    root->setRootObjectImp (static_cast<KJS::ObjectImp *>(KJS::Window::retrieveWindow(part)));
+    root->setInterpreter (KJSProxy::proxy(part)->interpreter());
+    part->addPluginRootObject (root);
+        
+    return root;
+}
+@end
index b801872..b0c6feb 100644 (file)
@@ -1,3 +1,16 @@
+2004-08-20  Richard Williamson   <rjw@apple.com>
+
+           Implemented new JNI abstraction.  We no longer invoke Java methods
+           directly with JNI, rather we call into the plugin.  This allows the
+           plugin to dispatch the call to the appropriate VM thread.  This
+           change should (will?) fix a whole class of threading related problems with
+           the Java VM.
+
+        Reviewed by Hyatt.
+
+        * WebCoreSupport.subproj/WebBridge.m:
+        (-[WebBridge getAppletInView:]):
+
 2004-08-20  Trey Matteson  <trey@apple.com>
 
        3655407 - Editing: -complete: method unimplemented (WebKit editing API)
index 12ce12b..991d3d6 100644 (file)
@@ -1248,7 +1248,7 @@ static id <WebFormDelegate> formDelegate(WebBridge *self)
 {
     jobject applet = 0;
 
-    if ([view respondsToSelector: @selector(webPlugInGetApplet:)])
+    if ([view respondsToSelector: @selector(webPlugInGetApplet)])
         applet = [view webPlugInGetApplet];
     else
         applet = [self pollForAppletInView:view];