[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677
rjw
rjw at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 08:18:35 UTC 2009
The following commit has been merged in the debian/unstable branch:
commit 2cb8ee22565a0dd55b44f925538601c691b03e78
Author: rjw <rjw at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Fri Dec 12 17:32:00 2003 +0000
JavaScriptCore:
Ensure that all calls from Java into JavaScript are
performed on a designated thread (the main thread).
Reviewed by Ken.
* bindings/jni_jsobject.cpp:
(isJavaScriptThread):
(rootForImp):
(Bindings::performJavaScriptAccess):
(Bindings::completedJavaScriptAccess):
(Bindings::initializeJavaScriptAccessLock):
(Bindings::lockJavaScriptAccess):
(Bindings::unlockJavaScriptAccess):
(Bindings::dispatchToJavaScriptThread):
(Bindings::RootObject::setFindRootObjectForNativeHandleFunction):
(Bindings::RootObject::removeAllJavaReferencesForRoot):
(Bindings::JSObject::invoke):
(Bindings::JSObject::JSObject):
(Bindings::JSObject::call):
(Bindings::JSObject::eval):
(Bindings::JSObject::getMember):
(Bindings::JSObject::setMember):
(Bindings::JSObject::removeMember):
(Bindings::JSObject::getSlot):
(Bindings::JSObject::setSlot):
(Bindings::JSObject::toString):
(Bindings::JSObject::finalize):
(Bindings::JSObject::getWindow):
* bindings/jni_jsobject.h:
(Bindings::RootObject::~RootObject):
(Bindings::RootObject::findRootObjectForNativeHandleFunction):
(Bindings::RootObject::runLoop):
(Bindings::RootObject::performJavaScriptSource):
(Bindings::):
WebCore:
Replace calls to global functions with static member functions.
Reviewed by Ken.
* kwq/KWQKHTMLPart.mm:
(KWQKHTMLPart::cleanupPluginRootObjects):
* kwq/WebCoreBridge.mm:
(rootForView):
(-[WebCoreBridge init]):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@5777 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index a93dae1..1f8d7ed 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,40 @@
+2003-12-12 Richard Williamson <rjw at apple.com>
+
+ Ensure that all calls from Java into JavaScript are
+ performed on a designated thread (the main thread).
+
+ Reviewed by Ken.
+
+ * bindings/jni_jsobject.cpp:
+ (isJavaScriptThread):
+ (rootForImp):
+ (Bindings::performJavaScriptAccess):
+ (Bindings::completedJavaScriptAccess):
+ (Bindings::initializeJavaScriptAccessLock):
+ (Bindings::lockJavaScriptAccess):
+ (Bindings::unlockJavaScriptAccess):
+ (Bindings::dispatchToJavaScriptThread):
+ (Bindings::RootObject::setFindRootObjectForNativeHandleFunction):
+ (Bindings::RootObject::removeAllJavaReferencesForRoot):
+ (Bindings::JSObject::invoke):
+ (Bindings::JSObject::JSObject):
+ (Bindings::JSObject::call):
+ (Bindings::JSObject::eval):
+ (Bindings::JSObject::getMember):
+ (Bindings::JSObject::setMember):
+ (Bindings::JSObject::removeMember):
+ (Bindings::JSObject::getSlot):
+ (Bindings::JSObject::setSlot):
+ (Bindings::JSObject::toString):
+ (Bindings::JSObject::finalize):
+ (Bindings::JSObject::getWindow):
+ * bindings/jni_jsobject.h:
+ (Bindings::RootObject::~RootObject):
+ (Bindings::RootObject::findRootObjectForNativeHandleFunction):
+ (Bindings::RootObject::runLoop):
+ (Bindings::RootObject::performJavaScriptSource):
+ (Bindings::):
+
2003-12-11 Richard Williamson <rjw at apple.com>
Added support for calling a JavaScript function from
diff --git a/JavaScriptCore/bindings/jni_jsobject.cpp b/JavaScriptCore/bindings/jni_jsobject.cpp
index 694e780..908f65f 100644
--- a/JavaScriptCore/bindings/jni_jsobject.cpp
+++ b/JavaScriptCore/bindings/jni_jsobject.cpp
@@ -24,6 +24,8 @@
*/
#include <CoreFoundation/CoreFoundation.h>
+#include <assert.h>
+
#include <identifier.h>
#include <internal.h>
#include <interpreter.h>
@@ -32,19 +34,22 @@
#include <jni_runtime.h>
#include <jni_utility.h>
+
using namespace Bindings;
using namespace KJS;
-static KJSFindRootObjectForNativeHandleFunctionPtr findRootObjectForNativeHandleFunctionPtr = 0;
-
-void KJS_setFindRootObjectForNativeHandleFunction(KJSFindRootObjectForNativeHandleFunctionPtr aFunc)
-{
- findRootObjectForNativeHandleFunctionPtr = aFunc;
+#ifdef NDEBUG
+#define JS_LOG(formatAndArgs...) ((void)0)
+#else
+#define JS_LOG(formatAndArgs...) { \
+ fprintf (stderr, "%s(%p,%p): ", __PRETTY_FUNCTION__, RootObject::runLoop(), CFRunLoopGetCurrent()); \
+ fprintf(stderr, formatAndArgs); \
}
+#endif
-KJSFindRootObjectForNativeHandleFunctionPtr KJS_findRootObjectForNativeHandleFunction()
+static bool isJavaScriptThread()
{
- return findRootObjectForNativeHandleFunctionPtr;
+ return (RootObject::runLoop() == CFRunLoopGetCurrent());
}
// Java does NOT always call finalize (and thus KJS_JSObject_JSFinalize) when
@@ -116,7 +121,7 @@ static CFMutableDictionaryRef findReferenceDictionary(ObjectImp *imp)
// FIXME: This is a potential performance bottleneck with many applets. We could fix be adding a
// imp to root dictionary.
-const Bindings::RootObject *rootForImp (ObjectImp *imp)
+static const Bindings::RootObject *rootForImp (ObjectImp *imp)
{
CFMutableDictionaryRef refsByRoot = getReferencesByRootDictionary ();
const Bindings::RootObject *rootObject = 0;
@@ -172,10 +177,145 @@ static void removeJavaReference (ObjectImp *imp)
}
}
-extern "C" {
+namespace Bindings
+{
+
+// May only be set by dispatchToJavaScriptThread().
+static CFRunLoopSourceRef completionSource;
+
+static void performJavaScriptAccess(void *info);
+static void performJavaScriptAccess(void *i)
+{
+ assert (CFRunLoopGetCurrent() == RootObject::runLoop());
+
+ JS_LOG ("completionSource = %p\n", completionSource);
+
+ // Dispatch JavaScript calls here.
+ CFRunLoopSourceContext sourceContext;
+ CFRunLoopSourceGetContext (completionSource, &sourceContext);
+ JSObjectCallContext *callContext = (JSObjectCallContext *)sourceContext.info;
+ CFRunLoopRef originatingLoop = callContext->originatingLoop;
+
+ JSObject::invoke (callContext);
+
+ JS_LOG ("originatingLoop = %p\n", originatingLoop);
+
+ // Signal the originating thread that we're done.
+ CFRunLoopSourceSignal (completionSource);
+ if (CFRunLoopIsWaiting(originatingLoop)) {
+ CFRunLoopWakeUp(originatingLoop);
+ }
+}
+
+static void completedJavaScriptAccess (void *i);
+static void completedJavaScriptAccess (void *i)
+{
+ assert (CFRunLoopGetCurrent() != RootObject::runLoop());
+
+ JSObjectCallContext *callContext = (JSObjectCallContext *)i;
+ CFRunLoopRef runLoop = (CFRunLoopRef)callContext->originatingLoop;
+
+ assert (CFRunLoopGetCurrent() == runLoop);
+
+ JS_LOG ("runLoop = %p\n", runLoop);
+ CFRunLoopStop(runLoop);
+}
+
+static pthread_once_t javaScriptAccessLockOnce = PTHREAD_ONCE_INIT;
+static pthread_mutex_t javaScriptAccessLock;
+static int javaScriptAccessLockCount = 0;
+
+static void initializeJavaScriptAccessLock()
+{
+ pthread_mutexattr_t attr;
+
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
+
+ pthread_mutex_init(&javaScriptAccessLock, &attr);
+}
+
+static inline void lockJavaScriptAccess()
+{
+ // Perhaps add deadlock detection?
+ pthread_once(&javaScriptAccessLockOnce, initializeJavaScriptAccessLock);
+ pthread_mutex_lock(&javaScriptAccessLock);
+ javaScriptAccessLockCount++;
+}
+
+static inline void unlockJavaScriptAccess()
+{
+ javaScriptAccessLockCount--;
+ pthread_mutex_unlock(&javaScriptAccessLock);
+}
+
+typedef struct JSObjectCallContext JSObjectCallContext;
+
+static void dispatchToJavaScriptThread(JSObjectCallContext *context)
+{
+ // This lock guarantees that only one thread can invoke
+ // at a time, and also guarantees that completionSource;
+ // won't get clobbered.
+ lockJavaScriptAccess();
+
+ CFRunLoopRef currentRunLoop = CFRunLoopGetCurrent();
+
+ assert (currentRunLoop != RootObject::runLoop());
+
+ // Setup a source to signal once the invocation of the JavaScript
+ // call completes.
+ //
+ // FIXME: This could be a potential performance issue. Creating and
+ // adding run loop sources is expensive. We could create one source
+ // per thread, as needed, instead.
+ context->originatingLoop = currentRunLoop;
+ CFRunLoopSourceContext sourceContext = {0, context, NULL, NULL, NULL, NULL, NULL, NULL, NULL, completedJavaScriptAccess};
+ completionSource = CFRunLoopSourceCreate(NULL, 0, &sourceContext);
+ CFRunLoopAddSource(currentRunLoop, completionSource, kCFRunLoopDefaultMode);
+
+ JS_LOG ("signalling, completionSource = %p\n", completionSource);
+
+ // Wakeup JavaScript access thread and make it do it's work.
+ CFRunLoopSourceSignal(RootObject::performJavaScriptSource());
+ if (CFRunLoopIsWaiting(RootObject::runLoop())) {
+ CFRunLoopWakeUp(RootObject::runLoop());
+ }
+
+ // Wait until the JavaScript access thread is done.
+ CFRunLoopRun ();
+
+ CFRunLoopRemoveSource(currentRunLoop, completionSource, kCFRunLoopDefaultMode);
+ CFRelease (completionSource);
+
+ JS_LOG ("done\n");
+
+ unlockJavaScriptAccess();
+}
+
+FindRootObjectForNativeHandleFunctionPtr RootObject::_findRootObjectForNativeHandleFunctionPtr = 0;
+CFRunLoopRef RootObject::_runLoop = 0;
+CFRunLoopSourceRef RootObject::_performJavaScriptSource = 0;
+
+// Must be called from the thread that will be used to access JavaScript.
+void RootObject::setFindRootObjectForNativeHandleFunction(FindRootObjectForNativeHandleFunctionPtr aFunc) {
+ // Should only be called once.
+ assert (_findRootObjectForNativeHandleFunctionPtr == 0);
+
+ _findRootObjectForNativeHandleFunctionPtr = aFunc;
+
+ // Assume that we can retain this run loop forever. It'll most
+ // likely (always?) be the main loop.
+ _runLoop = (CFRunLoopRef)CFRetain (CFRunLoopGetCurrent ());
+
+ // Setup a source the other threads can use to signal the _runLoop
+ // thread that a JavaScript call needs to be invoked.
+ CFRunLoopSourceContext sourceContext = {0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, performJavaScriptAccess};
+ _performJavaScriptSource = CFRunLoopSourceCreate(NULL, 0, &sourceContext);
+ CFRunLoopAddSource(_runLoop, _performJavaScriptSource, kCFRunLoopDefaultMode);
+}
// Must be called when the applet is shutdown.
-void KJS_removeAllJavaReferencesForRoot (Bindings::RootObject *root)
+void RootObject::removeAllJavaReferencesForRoot (Bindings::RootObject *root)
{
CFMutableDictionaryRef referencesDictionary = getReferencesDictionary (root);
@@ -199,37 +339,97 @@ void KJS_removeAllJavaReferencesForRoot (Bindings::RootObject *root)
}
}
-jlong KJS_JSCreateNativeJSObject (JNIEnv *env, jclass clazz, jstring jurl, jlong nativeHandle, jboolean ctx)
+jvalue JSObject::invoke (JSObjectCallContext *context)
{
- KJSFindRootObjectForNativeHandleFunctionPtr aFunc = KJS_findRootObjectForNativeHandleFunction();
- if (aFunc) {
- Bindings::RootObject *root = aFunc(jlong_to_ptr(nativeHandle));
- addJavaReference (root, root->rootObjectImp());
- return ptr_to_jlong(root->rootObjectImp());
+ jvalue result;
+
+ if (!isJavaScriptThread()) {
+ // Send the call context to the thread that is allowed to
+ // call JavaScript.
+ dispatchToJavaScriptThread(context);
+ result = context->result;
+ }
+ else {
+ jlong nativeHandle = context->nativeHandle;
+ switch (context->type){
+ case GetWindow: {
+ result.j = JSObject::getWindow(nativeHandle);
+ break;
+ }
+
+ case Call: {
+ result.l = JSObject(nativeHandle).call(JavaString(context->string).characters(), context->args);
+ break;
+ }
+
+ case Eval: {
+ result.l = JSObject(nativeHandle).eval(JavaString(context->string).characters());
+ break;
+ }
+
+ case GetMember: {
+ result.l = JSObject(nativeHandle).getMember(JavaString(context->string).characters());
+ break;
+ }
+
+ case SetMember: {
+ JSObject(nativeHandle).setMember(JavaString(context->string).characters(), context->value);
+ break;
+ }
+
+ case RemoveMember: {
+ JSObject(nativeHandle).removeMember(JavaString(context->string).characters());
+ break;
+ }
+
+ case GetSlot: {
+ result.l = JSObject(nativeHandle).getSlot(context->index);
+ break;
+ }
+
+ case SetSlot: {
+ JSObject(nativeHandle).setSlot(context->index, context->value);
+ break;
+ }
+
+ case ToString: {
+ result.l = (jobject) JSObject(nativeHandle).toString();
+ break;
+ }
+ default: {
+ fprintf (stderr, "%s: invalid JavaScript call\n", __PRETTY_FUNCTION__);
+ }
+ }
+ context->result = result;
}
-
- return ptr_to_jlong(0);
-}
-void KJS_JSObject_JSFinalize (JNIEnv *env, jclass jsClass, jlong nativeJSObject)
-{
- removeJavaReference (jlong_to_impptr(nativeJSObject));
+ return result;
}
-jobject KJS_JSObject_JSObjectCall (JNIEnv *env, jclass jsClass, jlong nativeJSObject, jstring jurl, jstring mName, jobjectArray args, jboolean ctx)
+
+JSObject::JSObject(jlong nativeJSObject)
{
- ObjectImp *imp = jlong_to_impptr(nativeJSObject);
- const Bindings::RootObject *root = rootForImp (imp);
+ _imp = jlong_to_impptr(nativeJSObject);
- // Change to assert.
- if (!root) {
- return 0;
- }
+ // If we are unable to cast the nativeJSObject to an ObjectImp something is
+ // terribly wrong.
+ assert (_imp != 0);
+ // Find the root (window) object associated with the imp.
+ _root = rootForImp (_imp);
+
+ // If we can't find the root for the object something is terrible wrong.
+ assert (_root != 0);
+}
+
+
+jobject JSObject::call(const char *methodName, jobjectArray args) const
+{
+ JS_LOG ("methodName = %s\n", methodName);
+
// Lookup the function object.
- ExecState *exec = root->interpreter()->globalExec();
- const char *methodName = JavaString(mName).characters();
- Value func = imp->get (exec, Identifier (methodName));
+ ExecState *exec = _root->interpreter()->globalExec();
+ Value func = _imp->get (exec, Identifier (methodName));
if (func.isNull() || func.type() == UndefinedType) {
// Maybe throw an exception here?
return 0;
@@ -237,7 +437,7 @@ jobject KJS_JSObject_JSObjectCall (JNIEnv *env, jclass jsClass, jlong nativeJSOb
// Call the function object.
ObjectImp *funcImp = static_cast<ObjectImp*>(func.imp());
- Object thisObj = Object(const_cast<ObjectImp*>(imp));
+ Object thisObj = Object(const_cast<ObjectImp*>(_imp));
List argList = listFromJArray(args);
Value result = funcImp->call (exec, thisObj, argList);
@@ -245,43 +445,165 @@ jobject KJS_JSObject_JSObjectCall (JNIEnv *env, jclass jsClass, jlong nativeJSOb
return convertValueToJObject (exec, result);
}
-jobject KJS_JSObject_JSObjectEval (JNIEnv *env, jclass jsClass, jlong nativeJSObject, jstring jurl, jstring jscript, jboolean ctx)
+jobject JSObject::eval(const char *script) const
{
- fprintf (stderr, "%s:\n", __PRETTY_FUNCTION__);
+ JS_LOG ("script = %s\n", script);
return 0;
}
-jobject KJS_JSObject_JSObjectGetMember (JNIEnv *env, jclass jsClass, jlong nativeJSObject, jstring jurl, jstring jname, jboolean ctx)
+jobject JSObject::getMember(const char *memberName) const
{
- fprintf (stderr, "%s:\n", __PRETTY_FUNCTION__);
+ JS_LOG ("memberName = %s\n", memberName);
return 0;
}
-void KJS_JSObject_JSObjectSetMember (JNIEnv *env, jclass jsClass, jlong nativeJSObject, jstring jurl, jstring jname, jobject value, jboolean ctx)
+void JSObject::setMember(const char *memberName, jobject value) const
{
- fprintf (stderr, "%s:\n", __PRETTY_FUNCTION__);
+ JS_LOG ("memberName = %s\n", memberName);
}
-void KJS_JSObject_JSObjectRemoveMember (JNIEnv *env, jclass jsClass, jlong nativeJSObject, jstring jurl, jstring jname, jboolean ctx)
+
+void JSObject::removeMember(const char *memberName) const
{
- fprintf (stderr, "%s:\n", __PRETTY_FUNCTION__);
+ JS_LOG ("memberName = %s\n", memberName);
}
-jobject KJS_JSObject_JSObjectGetSlot (JNIEnv *env, jclass jsClass, jlong nativeJSObject, jstring jurl, jint jindex, jboolean ctx)
+
+jobject JSObject::getSlot(jint index) const
{
- fprintf (stderr, "%s:\n", __PRETTY_FUNCTION__);
+ JS_LOG ("index = %d\n", index);
return 0;
}
-void KJS_JSObject_JSObjectSetSlot (JNIEnv *env, jclass jsClass, jlong nativeJSObject, jstring jurl, jint jindex, jobject value, jboolean ctx)
+
+void JSObject::setSlot(jint index, jobject value) const
{
- fprintf (stderr, "%s:\n", __PRETTY_FUNCTION__);
+ JS_LOG ("index = %d, value = %p\n", index, value);
}
-jstring KJS_JSObject_JSObjectToString (JNIEnv *env, jclass clazz, jlong nativeJSObject)
+
+jstring JSObject::toString() const
{
- fprintf (stderr, "%s:\n", __PRETTY_FUNCTION__);
- return 0;
+ JS_LOG ("\n");
+
+ Object thisObj = Object(const_cast<ObjectImp*>(_imp));
+ ExecState *exec = _root->interpreter()->globalExec();
+
+ return (jstring)convertValueToJValue (exec, thisObj, object_type, "java.lang.String").l;
+}
+
+void JSObject::finalize() const
+{
+ JS_LOG ("\n");
+
+ removeJavaReference (_imp);
+}
+
+jlong JSObject::getWindow(jlong nativeHandle)
+{
+ JS_LOG ("nativeHandle = %d\n", (int)nativeHandle);
+
+ FindRootObjectForNativeHandleFunctionPtr aFunc = RootObject::findRootObjectForNativeHandleFunction();
+ if (aFunc) {
+ Bindings::RootObject *root = aFunc(jlong_to_ptr(nativeHandle));
+ addJavaReference (root, root->rootObjectImp());
+ return ptr_to_jlong(root->rootObjectImp());
+ }
+
+ return ptr_to_jlong(0);
+}
+
+}
+
+extern "C" {
+
+jlong KJS_JSCreateNativeJSObject (JNIEnv *env, jclass clazz, jstring jurl, jlong nativeHandle, jboolean ctx)
+{
+ JSObjectCallContext context;
+ context.type = GetWindow;
+ context.nativeHandle = nativeHandle;
+ return JSObject::invoke (&context).j;
+}
+
+void KJS_JSObject_JSFinalize (JNIEnv *env, jclass jsClass, jlong nativeHandle)
+{
+ JSObjectCallContext context;
+ context.type = Finalize;
+ context.nativeHandle = nativeHandle;
+ JSObject::invoke (&context);
+}
+
+jobject KJS_JSObject_JSObjectCall (JNIEnv *env, jclass jsClass, jlong nativeHandle, jstring jurl, jstring methodName, jobjectArray args, jboolean ctx)
+{
+ JSObjectCallContext context;
+ context.type = Call;
+ context.nativeHandle = nativeHandle;
+ context.string = methodName;
+ return JSObject::invoke (&context).l;
+}
+
+jobject KJS_JSObject_JSObjectEval (JNIEnv *env, jclass jsClass, jlong nativeHandle, jstring jurl, jstring jscript, jboolean ctx)
+{
+ JSObjectCallContext context;
+ context.type = Eval;
+ context.nativeHandle = nativeHandle;
+ context.string = jscript;
+ return JSObject::invoke (&context).l;
+}
+
+jobject KJS_JSObject_JSObjectGetMember (JNIEnv *env, jclass jsClass, jlong nativeHandle, jstring jurl, jstring jname, jboolean ctx)
+{
+ JSObjectCallContext context;
+ context.type = GetMember;
+ context.nativeHandle = nativeHandle;
+ context.string = jname;
+ return JSObject::invoke (&context).l;
+}
+
+void KJS_JSObject_JSObjectSetMember (JNIEnv *env, jclass jsClass, jlong nativeHandle, jstring jurl, jstring jname, jobject value, jboolean ctx)
+{
+ JSObjectCallContext context;
+ context.type = SetMember;
+ context.nativeHandle = nativeHandle;
+ context.string = jname;
+ context.value = value;
+ JSObject::invoke (&context);
+}
+
+void KJS_JSObject_JSObjectRemoveMember (JNIEnv *env, jclass jsClass, jlong nativeHandle, jstring jurl, jstring jname, jboolean ctx)
+{
+ JSObjectCallContext context;
+ context.type = RemoveMember;
+ context.nativeHandle = nativeHandle;
+ context.string = jname;
+ JSObject::invoke (&context);
+}
+
+jobject KJS_JSObject_JSObjectGetSlot (JNIEnv *env, jclass jsClass, jlong nativeHandle, jstring jurl, jint jindex, jboolean ctx)
+{
+ JSObjectCallContext context;
+ context.type = GetSlot;
+ context.nativeHandle = nativeHandle;
+ context.index = jindex;
+ return JSObject::invoke (&context).l;
+}
+
+void KJS_JSObject_JSObjectSetSlot (JNIEnv *env, jclass jsClass, jlong nativeHandle, jstring jurl, jint jindex, jobject value, jboolean ctx)
+{
+ JSObjectCallContext context;
+ context.type = SetSlot;
+ context.nativeHandle = nativeHandle;
+ context.index = jindex;
+ context.value = value;
+ JSObject::invoke (&context);
+}
+
+jstring KJS_JSObject_JSObjectToString (JNIEnv *env, jclass clazz, jlong nativeHandle)
+{
+ JSObjectCallContext context;
+ context.type = ToString;
+ context.nativeHandle = nativeHandle;
+ return (jstring)JSObject::invoke (&context).l;
}
}
diff --git a/JavaScriptCore/bindings/jni_jsobject.h b/JavaScriptCore/bindings/jni_jsobject.h
index 2ebca42..a05ab2c 100644
--- a/JavaScriptCore/bindings/jni_jsobject.h
+++ b/JavaScriptCore/bindings/jni_jsobject.h
@@ -22,8 +22,10 @@
* (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 _JNI_JS_H_
-#define _JNI_JS_H_
+#ifndef _JNI_JSOBJECT_H_
+#define _JNI_JSOBJECT_H_
+
+#include <CoreFoundation/CoreFoundation.h>
#include <JavaScriptCore/interpreter.h>
#include <JavaScriptCore/object.h>
@@ -36,12 +38,17 @@
namespace Bindings {
+class RootObject;
+
+typedef RootObject *(*FindRootObjectForNativeHandleFunctionPtr)(void *);
+
class RootObject
{
public:
RootObject (const void *nativeHandle) : _nativeHandle(nativeHandle), _imp(0), _interpreter(0) {}
~RootObject (){
_imp->deref();
+ CFRelease (_runLoop);
}
void setRootObjectImp (KJS::ObjectImp *i) {
@@ -53,24 +60,82 @@ public:
void setInterpreter (KJS::Interpreter *i) { _interpreter = i; }
KJS::Interpreter *interpreter() const { return _interpreter; }
+
+ // Must be called from the thread that will be used to access JavaScript.
+ static void setFindRootObjectForNativeHandleFunction(FindRootObjectForNativeHandleFunctionPtr aFunc);
+ static FindRootObjectForNativeHandleFunctionPtr findRootObjectForNativeHandleFunction() {
+ return _findRootObjectForNativeHandleFunctionPtr;
+ }
+
+ static void removeAllJavaReferencesForRoot (Bindings::RootObject *root);
+ static CFRunLoopRef runLoop() { return _runLoop; }
+ static CFRunLoopSourceRef performJavaScriptSource() { return _performJavaScriptSource; }
private:
const void *_nativeHandle;
KJS::ObjectImp *_imp;
KJS::Interpreter *_interpreter;
+
+ static FindRootObjectForNativeHandleFunctionPtr _findRootObjectForNativeHandleFunctionPtr;
+ static CFRunLoopRef _runLoop;
+ static CFRunLoopSourceRef _performJavaScriptSource;
};
-}
+enum JSObjectCallType {
+ GetWindow,
+ Call,
+ Eval,
+ GetMember,
+ SetMember,
+ RemoveMember,
+ GetSlot,
+ SetSlot,
+ ToString,
+ Finalize
+};
-typedef Bindings::RootObject *(*KJSFindRootObjectForNativeHandleFunctionPtr)(void *);
+struct JSObjectCallContext
+{
+ JSObjectCallType type;
+ jlong nativeHandle;
+ jstring string;
+ jobjectArray args;
+ jint index;
+ jobject value;
+ CFRunLoopRef originatingLoop;
+ jvalue result;
+};
-void KJS_setFindRootObjectForNativeHandleFunction(KJSFindRootObjectForNativeHandleFunctionPtr aFunc);
-KJSFindRootObjectForNativeHandleFunctionPtr KJS_findRootObjectForNativeHandleFunction();
+class JSObject
+{
+public:
+ JSObject(jlong nativeHandle);
+
+ jobject call(const char *methodName, jobjectArray args) const;
+ jobject eval(const char *script) const;
+ jobject getMember(const char *memberName) const;
+ void setMember(const char *memberName, jobject value) const;
+ void removeMember(const char *memberName) const;
+ jobject getSlot(jint index) const;
+ void setSlot(jint index, jobject value) const;
+ jstring toString() const;
+ void finalize() const;
+
+ static jlong getWindow(jlong nativeHandle);
+
+ static jvalue invoke (JSObjectCallContext *context);
+
+private:
+ const Bindings::RootObject *_root;
+ KJS::ObjectImp *_imp;
+};
+}
+
extern "C" {
-// Functions called from the Java VM when making class to the JSObject class.
+// Functions called from the Java VM when making calls to the JSObject class.
jlong KJS_JSCreateNativeJSObject (JNIEnv *env, jclass clazz, jstring jurl, jlong nativeHandle, jboolean ctx);
void KJS_JSObject_JSFinalize (JNIEnv *env, jclass jsClass, jlong nativeJSObject);
jobject KJS_JSObject_JSObjectCall (JNIEnv *env, jclass jsClass, jlong nativeJSObject, jstring jurl, jstring methodName, jobjectArray args, jboolean ctx);
@@ -82,8 +147,6 @@ jobject KJS_JSObject_JSObjectGetSlot (JNIEnv *env, jclass jsClass, jlong nativeJ
void KJS_JSObject_JSObjectSetSlot (JNIEnv *env, jclass jsClass, jlong nativeJSObject, jstring jurl, jint jindex, jobject value, jboolean ctx);
jstring KJS_JSObject_JSObjectToString (JNIEnv *env, jclass clazz, jlong nativeJSObject);
-void KJS_removeAllJavaReferencesForRoot (Bindings::RootObject *root);
-
}
#endif
\ No newline at end of file
diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index 7bc38fb..aa2eb87 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,15 @@
+2003-12-12 Richard Williamson <rjw at apple.com>
+
+ Replace call to global functions with static member functions.
+
+ Reviewed by Ken.
+
+ * kwq/KWQKHTMLPart.mm:
+ (KWQKHTMLPart::cleanupPluginRootObjects):
+ * kwq/WebCoreBridge.mm:
+ (rootForView):
+ (-[WebCoreBridge init]):
+
2003-12-11 Maciej Stachowiak <mjs at apple.com>
Reviewed by Darin.
diff --git a/WebCore/kwq/KWQKHTMLPart.mm b/WebCore/kwq/KWQKHTMLPart.mm
index 11f6f92..70fa367 100644
--- a/WebCore/kwq/KWQKHTMLPart.mm
+++ b/WebCore/kwq/KWQKHTMLPart.mm
@@ -2787,7 +2787,7 @@ void KWQKHTMLPart::cleanupPluginRootObjects()
{
Bindings::RootObject *root;
while ((root = rootObjects.getLast())) {
- KJS_removeAllJavaReferencesForRoot (root);
+ Bindings::RootObject::removeAllJavaReferencesForRoot (root);
rootObjects.removeLast();
}
}
diff --git a/WebCore/kwq/WebCoreBridge.mm b/WebCore/kwq/WebCoreBridge.mm
index 803d514..00194ac 100644
--- a/WebCore/kwq/WebCoreBridge.mm
+++ b/WebCore/kwq/WebCoreBridge.mm
@@ -110,12 +110,12 @@ static RootObject *rootForView(void *v)
NSView *aView = (NSView *)v;
WebCoreBridge *aBridge = [[WebCoreViewFactory sharedFactory] bridgeForView:aView];
KWQKHTMLPart *part = [aBridge part];
- RootObject *root = new RootObject(v);
+ 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;
}
@@ -137,7 +137,7 @@ static bool initializedKJS = FALSE;
}
if (!initializedKJS) {
- KJS_setFindRootObjectForNativeHandleFunction (rootForView);
+ Bindings::RootObject::setFindRootObjectForNativeHandleFunction (rootForView);
initializedKJS = TRUE;
}
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list