[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:28:19 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit af79f50f6da70ff746bdb5a7cdb3f546e139dac3
Author: rjw <rjw at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Mar 3 00:17:26 2004 +0000

    WebKit:
    	Added WebJavaScriptObject API.  The location of this file may
    	change.
    
            Reviewed by Chris.
    
            * Plugins.subproj/NP_objc.h: Added.
            * WebKit.pbproj/project.pbxproj:
    
    WebCore:
    	Added NP_SAP API.  This API includes the new entry points
    	used to bind native interfaces to JavaScript.  It's final location
    	may change.
    
    	Made changes to KWQKHTMLPart.mm to reflect changes in names
    	on RootObject.
    
            Reviewed by Chris.
    
            * WebCore.pbproj/project.pbxproj:
            * khtml/ecma/NP_SAP.h: Added.
            * kwq/KWQKHTMLPart.mm:
            (KWQKHTMLPart::cleanupPluginRootObjects):
            * kwq/WebCoreBridge.mm:
    
    JavaScriptCore:
    	C binding API.  Partial implementation.
    
    	Completed ObjectiveC bindings (not based on the C API).  These will re-implemented over the C binding API, but I wanted to get this code in the tree.
    
    	Factored root object reference counting scheme.  It is now useful independent
    	of LiveConnect.
    
            Reviewed by Chris.
    
            * JavaScriptCore.pbproj/project.pbxproj:
            * bindings/NP_runtime.cpp: Added.
            (NP_IdentifierFromUTF8):
            (NP_GetIdentifiers):
            (NP_UTF8FromIdentifier):
            (NP_CreateObject):
            (NP_RetainObject):
            (NP_ReleaseObject):
            (NP_IsKindOfClass):
            (NP_SetException):
            (NP_Call):
            (NP_Evaluate):
            (NP_GetProperty):
            (NP_SetProperty):
            (NP_RemoveProperty):
            (NP_ToString):
            (NP_GetPropertyAtIndex):
            (NP_SetPropertyAtIndex):
            (NP_CreateNumberWithInt):
            (NP_CreateNumberWithFloat):
            (NP_CreateNumberWithDouble):
            (NP_IntFromNumber):
            (NP_FloatFromNumber):
            (NP_DoubleFromNumber):
            (NP_CreateStringWithUTF8):
            (NP_CreateStringWithUTF16):
            (NP_UTF8FromString):
            (NP_UTF16FromString):
            (NP_CreateBoolean):
            (NP_BoolFromBoolean):
            (NP_GetNull):
            (NP_GetUndefined):
            (NP_CreateArray):
            (NP_CreateArrayV):
            (NP_ObjectAtIndex):
            * bindings/NP_runtime.h: Added.
            * bindings/jni/jni_jsobject.cpp:
            (JSObject::invoke):
            (JSObject::finalize):
            (JSObject::createNative):
            (JSObject::convertValueToJObject):
            * bindings/jni/jni_jsobject.h:
            * bindings/objc/objc_jsobject.h:
            * bindings/objc/objc_jsobject.mm:
            (rootForView):
            (windowJavaScriptObject):
            (-[JavaScriptObject initWithObjectImp:KJS::root:Bindings::]):
            (-[JavaScriptObject dealloc]):
            (-[JavaScriptObject _convertValueToObjcValue:KJS::]):
            (-[JavaScriptObject call:arguments:]):
            (-[JavaScriptObject evaluate:]):
            (-[JavaScriptObject getMember:]):
            (-[JavaScriptObject setMember:value:]):
            (-[JavaScriptObject removeMember:]):
            (-[JavaScriptObject toString]):
            (-[JavaScriptObject getSlot:]):
            (-[JavaScriptObject setSlot:value:]):
            * bindings/objc/objc_utility.h:
            * bindings/objc/objc_utility.mm:
            (KJS::Bindings::convertValueToObjcValue):
            * bindings/runtime_root.cpp: Added.
            (getReferencesByRootDictionary):
            (getReferencesDictionary):
            (KJS::Bindings::findReferenceDictionary):
            (KJS::Bindings::rootForImp):
            (KJS::Bindings::addNativeReference):
            (KJS::Bindings::removeNativeReference):
            (completedJavaScriptAccess):
            (initializeJavaScriptAccessLock):
            (lockJavaScriptAccess):
            (unlockJavaScriptAccess):
            (RootObject::dispatchToJavaScriptThread):
            (performJavaScriptAccess):
            (RootObject::setFindRootObjectForNativeHandleFunction):
            (RootObject::removeAllNativeReferences):
            * bindings/runtime_root.h: Added.
            (KJS::Bindings::RootObject::RootObject):
            (KJS::Bindings::RootObject::~RootObject):
            (KJS::Bindings::RootObject::setRootObjectImp):
            (KJS::Bindings::RootObject::rootObjectImp):
            (KJS::Bindings::RootObject::setInterpreter):
            (KJS::Bindings::RootObject::interpreter):
            (KJS::Bindings::RootObject::findRootObjectForNativeHandleFunction):
            (KJS::Bindings::RootObject::runLoop):
            (KJS::Bindings::RootObject::performJavaScriptSource):
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@6157 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 0540f98..49e9e57 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,100 @@
+2004-03-02  Richard Williamson   <rjw at apple.com>
+
+	C binding API.  Partial implementation.
+
+	Completed ObjectiveC bindings (not based on the C API).  These will re-implemented over the C binding API, but I wanted to get this code in the tree.
+
+	Factored root object reference counting scheme.  It is now useful independent
+	of LiveConnect.
+
+        Reviewed by Chris.
+
+        * JavaScriptCore.pbproj/project.pbxproj:
+        * bindings/NP_runtime.cpp: Added.
+        (NP_IdentifierFromUTF8):
+        (NP_GetIdentifiers):
+        (NP_UTF8FromIdentifier):
+        (NP_CreateObject):
+        (NP_RetainObject):
+        (NP_ReleaseObject):
+        (NP_IsKindOfClass):
+        (NP_SetException):
+        (NP_Call):
+        (NP_Evaluate):
+        (NP_GetProperty):
+        (NP_SetProperty):
+        (NP_RemoveProperty):
+        (NP_ToString):
+        (NP_GetPropertyAtIndex):
+        (NP_SetPropertyAtIndex):
+        (NP_CreateNumberWithInt):
+        (NP_CreateNumberWithFloat):
+        (NP_CreateNumberWithDouble):
+        (NP_IntFromNumber):
+        (NP_FloatFromNumber):
+        (NP_DoubleFromNumber):
+        (NP_CreateStringWithUTF8):
+        (NP_CreateStringWithUTF16):
+        (NP_UTF8FromString):
+        (NP_UTF16FromString):
+        (NP_CreateBoolean):
+        (NP_BoolFromBoolean):
+        (NP_GetNull):
+        (NP_GetUndefined):
+        (NP_CreateArray):
+        (NP_CreateArrayV):
+        (NP_ObjectAtIndex):
+        * bindings/NP_runtime.h: Added.
+        * bindings/jni/jni_jsobject.cpp:
+        (JSObject::invoke):
+        (JSObject::finalize):
+        (JSObject::createNative):
+        (JSObject::convertValueToJObject):
+        * bindings/jni/jni_jsobject.h:
+        * bindings/objc/objc_jsobject.h:
+        * bindings/objc/objc_jsobject.mm:
+        (rootForView):
+        (windowJavaScriptObject):
+        (-[JavaScriptObject initWithObjectImp:KJS::root:Bindings::]):
+        (-[JavaScriptObject dealloc]):
+        (-[JavaScriptObject _convertValueToObjcValue:KJS::]):
+        (-[JavaScriptObject call:arguments:]):
+        (-[JavaScriptObject evaluate:]):
+        (-[JavaScriptObject getMember:]):
+        (-[JavaScriptObject setMember:value:]):
+        (-[JavaScriptObject removeMember:]):
+        (-[JavaScriptObject toString]):
+        (-[JavaScriptObject getSlot:]):
+        (-[JavaScriptObject setSlot:value:]):
+        * bindings/objc/objc_utility.h:
+        * bindings/objc/objc_utility.mm:
+        (KJS::Bindings::convertValueToObjcValue):
+        * bindings/runtime_root.cpp: Added.
+        (getReferencesByRootDictionary):
+        (getReferencesDictionary):
+        (KJS::Bindings::findReferenceDictionary):
+        (KJS::Bindings::rootForImp):
+        (KJS::Bindings::addNativeReference):
+        (KJS::Bindings::removeNativeReference):
+        (completedJavaScriptAccess):
+        (initializeJavaScriptAccessLock):
+        (lockJavaScriptAccess):
+        (unlockJavaScriptAccess):
+        (RootObject::dispatchToJavaScriptThread):
+        (performJavaScriptAccess):
+        (RootObject::setFindRootObjectForNativeHandleFunction):
+        (RootObject::removeAllNativeReferences):
+        * bindings/runtime_root.h: Added.
+        (KJS::Bindings::RootObject::RootObject):
+        (KJS::Bindings::RootObject::~RootObject):
+        (KJS::Bindings::RootObject::setRootObjectImp):
+        (KJS::Bindings::RootObject::rootObjectImp):
+        (KJS::Bindings::RootObject::setInterpreter):
+        (KJS::Bindings::RootObject::interpreter):
+        (KJS::Bindings::RootObject::findRootObjectForNativeHandleFunction):
+        (KJS::Bindings::RootObject::runLoop):
+        (KJS::Bindings::RootObject::performJavaScriptSource):
+
 === Safari-130 ===
 
 === Safari-129 ===
diff --git a/JavaScriptCore/JavaScriptCore.pbproj/project.pbxproj b/JavaScriptCore/JavaScriptCore.pbproj/project.pbxproj
index df2eccf..8ecfb61 100644
--- a/JavaScriptCore/JavaScriptCore.pbproj/project.pbxproj
+++ b/JavaScriptCore/JavaScriptCore.pbproj/project.pbxproj
@@ -249,6 +249,8 @@
 				51F0EC1105C86F3500E6DF1B,
 				51F0EC9805C88DC700E6DF1B,
 				7084D99505DD6211007E4C0E,
+				5114F47E05E4426200D1BBBD,
+				515B876B05F532B900EABBF9,
 			);
 			isa = PBXHeadersBuildPhase;
 			runOnlyForDeploymentPostprocessing = 0;
@@ -315,6 +317,8 @@
 				51F0EB0605C85A9000E6DF1B,
 				51F0EC9905C88DC700E6DF1B,
 				7084D9BA05DD6CF8007E4C0E,
+				5114F47D05E4426200D1BBBD,
+				515B879305F535B300EABBF9,
 			);
 			isa = PBXSourcesBuildPhase;
 			runOnlyForDeploymentPostprocessing = 0;
@@ -451,6 +455,39 @@
 //512
 //513
 //514
+		5114F47B05E4426200D1BBBD = {
+			fileEncoding = 30;
+			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.cpp.cpp;
+			name = runtime_root.cpp;
+			path = bindings/runtime_root.cpp;
+			refType = 4;
+			sourceTree = "<group>";
+		};
+		5114F47C05E4426200D1BBBD = {
+			fileEncoding = 30;
+			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
+			name = runtime_root.h;
+			path = bindings/runtime_root.h;
+			refType = 4;
+			sourceTree = "<group>";
+		};
+		5114F47D05E4426200D1BBBD = {
+			fileRef = 5114F47B05E4426200D1BBBD;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		5114F47E05E4426200D1BBBD = {
+			fileRef = 5114F47C05E4426200D1BBBD;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
 		511B0870056468730080E486 = {
 			fileEncoding = 4;
 			isa = PBXFileReference;
@@ -532,6 +569,36 @@
 				);
 			};
 		};
+		515B876A05F532B900EABBF9 = {
+			fileEncoding = 30;
+			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
+			name = NP_runtime.h;
+			path = bindings/NP_runtime.h;
+			refType = 4;
+			sourceTree = "<group>";
+		};
+		515B876B05F532B900EABBF9 = {
+			fileRef = 515B876A05F532B900EABBF9;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		515B879205F535B300EABBF9 = {
+			fileEncoding = 30;
+			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.cpp.cpp;
+			name = NP_runtime.cpp;
+			path = bindings/NP_runtime.cpp;
+			refType = 4;
+			sourceTree = "<group>";
+		};
+		515B879305F535B300EABBF9 = {
+			fileRef = 515B879205F535B300EABBF9;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
 		517D52DC056BF2F5003851BD = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
@@ -626,6 +693,8 @@
 		};
 		51856D950562EE9C008B9D83 = {
 			children = (
+				515B876A05F532B900EABBF9,
+				515B879205F535B300EABBF9,
 				517D52DC056BF2F5003851BD,
 				517D52DD056BF2F6003851BD,
 				517D5347056BFB5D003851BD,
@@ -644,6 +713,8 @@
 				51A58A8E057D3A6A00A3E942,
 				70B16A260569A10900DB756D,
 				70B16A270569A10900DB756D,
+				5114F47B05E4426200D1BBBD,
+				5114F47C05E4426200D1BBBD,
 				518CF93605C72271003CF905,
 				518CF93705C72271003CF905,
 				51F0EC1005C86F3500E6DF1B,
diff --git a/JavaScriptCore/bindings/jni/jni_jsobject.cpp b/JavaScriptCore/bindings/jni/jni_jsobject.cpp
index 6e64c24..b5a32de 100644
--- a/JavaScriptCore/bindings/jni/jni_jsobject.cpp
+++ b/JavaScriptCore/bindings/jni/jni_jsobject.cpp
@@ -34,6 +34,7 @@
 #include <jni_runtime.h>
 #include <jni_utility.h>
 #include <runtime_object.h>
+#include <runtime_root.h>
 
 using namespace KJS::Bindings;
 using namespace KJS;
@@ -54,284 +55,6 @@ static bool isJavaScriptThread()
     return (RootObject::runLoop() == CFRunLoopGetCurrent());
 }
 
-// Java does NOT always call finalize (and thus KJS_JSObject_JSFinalize) when
-// it collects an objects.  This presents some difficulties.  We must ensure
-// the a JSObject's corresponding JavaScript object doesn't get collected.  We
-// do this by incrementing the JavaScript's reference count the first time we
-// create a JSObject for it, and decrementing the JavaScript reference count when
-// the last JSObject that refers to it is finalized, or when the applet is
-// shutdown.
-//
-// To do this we keep a dictionary that maps each applet instance
-// to the JavaScript objects it is referencing.  For each JavaScript instance
-// we also maintain a secondary reference count.  When that reference count reaches
-// 1 OR the applet is shutdown we deref the JavaScript instance.  Applet instances
-// are represented by a jlong.
-
-static CFMutableDictionaryRef referencesByRootDictionary = 0;
-
-static CFMutableDictionaryRef getReferencesByRootDictionary()
-{
-    if (!referencesByRootDictionary)
-        referencesByRootDictionary = CFDictionaryCreateMutable(NULL, 0, NULL, &kCFTypeDictionaryValueCallBacks);
-    return referencesByRootDictionary;
-}
-
-static CFMutableDictionaryRef getReferencesDictionary(const Bindings::RootObject *root)
-{
-    CFMutableDictionaryRef refsByRoot = getReferencesByRootDictionary();
-    CFMutableDictionaryRef referencesDictionary = 0;
-    
-    referencesDictionary = (CFMutableDictionaryRef)CFDictionaryGetValue (refsByRoot, (const void *)root);
-    if (!referencesDictionary) {
-        referencesDictionary = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
-        CFDictionaryAddValue (refsByRoot, root, referencesDictionary);
-        CFRelease (referencesDictionary);
-    }
-    return referencesDictionary;
-}
-
-// Scan all the dictionary for all the roots to see if any have a 
-// reference to the imp, and if so, return it's reference count
-// dictionary.
-// FIXME:  This is a potential performance bottleneck with many applets.  We could fix be adding a
-// imp to root dictionary.
-static CFMutableDictionaryRef findReferenceDictionary(ObjectImp *imp)
-{
-    CFMutableDictionaryRef refsByRoot = getReferencesByRootDictionary ();
-    CFMutableDictionaryRef foundDictionary = 0;
-    
-    if (refsByRoot) {
-        const void **allValues = 0;
-        CFIndex count, i;
-        
-        count = CFDictionaryGetCount(refsByRoot);
-        allValues = (const void **)malloc (sizeof(void *) * count);
-        CFDictionaryGetKeysAndValues (refsByRoot, NULL, allValues);
-        for(i = 0; i < count; i++) {
-            CFMutableDictionaryRef referencesDictionary = (CFMutableDictionaryRef)allValues[i];
-            if (CFDictionaryGetValue(referencesDictionary, imp) != 0) {
-                foundDictionary = referencesDictionary;
-                break;
-            }
-        }
-        
-        free ((void *)allValues);
-    }
-    return foundDictionary;
-}
-
-// FIXME:  This is a potential performance bottleneck with many applets.  We could fix be adding a
-// imp to root dictionary.
-static const Bindings::RootObject *rootForImp (ObjectImp *imp)
-{
-    CFMutableDictionaryRef refsByRoot = getReferencesByRootDictionary ();
-    const Bindings::RootObject *rootObject = 0;
-    
-    if (refsByRoot) {
-        const void **allValues = 0;
-        const void **allKeys = 0;
-        CFIndex count, i;
-        
-        count = CFDictionaryGetCount(refsByRoot);
-        allKeys = (const void **)malloc (sizeof(void *) * count);
-        allValues = (const void **)malloc (sizeof(void *) * count);
-        CFDictionaryGetKeysAndValues (refsByRoot, allKeys, allValues);
-        for(i = 0; i < count; i++) {
-            CFMutableDictionaryRef referencesDictionary = (CFMutableDictionaryRef)allValues[i];
-            if (CFDictionaryGetValue(referencesDictionary, imp) != 0) {
-                rootObject = (const Bindings::RootObject *)allKeys[0];
-                break;
-            }
-        }
-        
-        free ((void *)allKeys);
-        free ((void *)allValues);
-    }
-    return rootObject;
-}
-
-static void addJavaReference (const Bindings::RootObject *root, ObjectImp *imp)
-{
-    JS_LOG ("root = %p, imp %p\n", root, imp);
-
-    CFMutableDictionaryRef referencesDictionary = getReferencesDictionary (root);
-    
-    unsigned int numReferences = (unsigned int)CFDictionaryGetValue (referencesDictionary, imp);
-    if (numReferences == 0) {
-        imp->ref();
-        CFDictionaryAddValue (referencesDictionary, imp,  (const void *)1);
-    }
-    else {
-        CFDictionaryReplaceValue (referencesDictionary, imp, (const void *)(numReferences+1));
-    }
-}
-
-static void removeJavaReference (ObjectImp *imp)
-{
-    JS_LOG ("imp %p\n", imp);
-    CFMutableDictionaryRef referencesDictionary = findReferenceDictionary (imp);
-    
-    unsigned int numReferences = (unsigned int)CFDictionaryGetValue (referencesDictionary, imp);
-    if (numReferences == 1) {
-        imp->deref();
-        CFDictionaryRemoveValue (referencesDictionary, imp);
-    }
-    else {
-        CFDictionaryReplaceValue (referencesDictionary, imp, (const void *)(numReferences-1));
-    }
-}
-
-// May only be set by dispatchToJavaScriptThread().
-static CFRunLoopSourceRef completionSource;
-
-static void performJavaScriptAccess(void *info);
-static void performJavaScriptAccess(void *i)
-{
-    assert (CFRunLoopGetCurrent() == RootObject::runLoop());
-    
-    // Dispatch JavaScript calls here.
-    CFRunLoopSourceContext sourceContext;
-    CFRunLoopSourceGetContext (completionSource, &sourceContext);
-    JSObjectCallContext *callContext = (JSObjectCallContext *)sourceContext.info;    
-    CFRunLoopRef originatingLoop = callContext->originatingLoop;
-
-    JSObject::invoke (callContext);
-    
-    // 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);
-
-    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);
-}
-
-
-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);
-
-    // 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);
-
-    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 RootObject::removeAllJavaReferencesForRoot (Bindings::RootObject *root)
-{
-    JS_LOG ("_root == %p\n", root);
-    CFMutableDictionaryRef referencesDictionary = getReferencesDictionary (root);
-    
-    if (referencesDictionary) {
-        void **allImps = 0;
-        CFIndex count, i;
-        
-        count = CFDictionaryGetCount(referencesDictionary);
-        allImps = (void **)malloc (sizeof(void *) * count);
-        CFDictionaryGetKeysAndValues (referencesDictionary, (const void **)allImps, NULL);
-        for(i = 0; i < count; i++) {
-            ObjectImp *anImp = static_cast<ObjectImp*>(allImps[i]);
-            anImp->deref();
-        }
-        free ((void *)allImps);
-        CFDictionaryRemoveAllValues (referencesDictionary);
-
-        CFMutableDictionaryRef refsByRoot = getReferencesByRootDictionary();
-        CFDictionaryRemoveValue (refsByRoot, (const void *)root);
-        delete root;
-    }
-}
-
 jvalue JSObject::invoke (JSObjectCallContext *context)
 {
     jvalue result;
@@ -339,7 +62,7 @@ jvalue JSObject::invoke (JSObjectCallContext *context)
     if (!isJavaScriptThread()) {        
         // Send the call context to the thread that is allowed to
         // call JavaScript.
-        dispatchToJavaScriptThread(context);
+        RootObject::dispatchToJavaScriptThread(context);
         result = context->result;
     }
     else {
@@ -550,7 +273,7 @@ void JSObject::finalize() const
 {
     JS_LOG ("\n");
 
-    removeJavaReference (_imp);
+    removeNativeReference (_imp);
 }
 
 // We're either creating a 'Root' object (via a call to JSObject.getWindow()), or
@@ -564,7 +287,7 @@ jlong JSObject::createNative(jlong nativeHandle)
     else if (rootForImp(jlong_to_impptr(nativeHandle))){
         return nativeHandle;
     }
-        
+
     FindRootObjectForNativeHandleFunctionPtr aFunc = RootObject::findRootObjectForNativeHandleFunction();
     if (aFunc) {
         Bindings::RootObject *root = aFunc(jlong_to_ptr(nativeHandle));
@@ -572,7 +295,7 @@ jlong JSObject::createNative(jlong nativeHandle)
         // otherwise we are being called after creating a JSObject in
         // JSObject::convertValueToJObject().
         if (root) {
-            addJavaReference (root, root->rootObjectImp());        
+            addNativeReference (root, root->rootObjectImp());        
             return ptr_to_jlong(root->rootObjectImp());
         }
         else {
@@ -638,7 +361,7 @@ jobject JSObject::convertValueToJObject (KJS::Value value) const
                 
                 // Bump our 'meta' reference count for the imp.  We maintain the reference
                 // until either finalize is called or the applet shuts down.
-                addJavaReference (_root, imp);
+                addNativeReference (_root, imp);
             }
         }
         // All other types will result in an undefined object.
diff --git a/JavaScriptCore/bindings/jni/jni_jsobject.h b/JavaScriptCore/bindings/jni/jni_jsobject.h
index 4b56e14..f3cdca4 100644
--- a/JavaScriptCore/bindings/jni/jni_jsobject.h
+++ b/JavaScriptCore/bindings/jni/jni_jsobject.h
@@ -42,46 +42,6 @@ namespace Bindings {
 
 class RootObject;
 
-typedef RootObject *(*FindRootObjectForNativeHandleFunctionPtr)(void *);
-
-class RootObject
-{
-public:
-    RootObject (const void *nativeHandle) : _nativeHandle(nativeHandle), _imp(0), _interpreter(0) {}
-    ~RootObject (){
-        _imp->deref();
-    }
-    
-    void setRootObjectImp (KJS::ObjectImp *i) { 
-        _imp = i;
-        _imp->ref();
-    }
-    
-    KJS::ObjectImp *rootObjectImp() const { return _imp; }
-    
-    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 {
     CreateNative,
     Call,
@@ -107,6 +67,7 @@ struct JSObjectCallContext
     jvalue result;
 };
 
+
 typedef struct JSObjectCallContext JSObjectCallContext;
 
 class JSObject
diff --git a/JavaScriptCore/bindings/npruntime.cpp b/JavaScriptCore/bindings/npruntime.cpp
new file mode 100644
index 0000000..d378942
--- /dev/null
+++ b/JavaScriptCore/bindings/npruntime.cpp
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2004 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <NP_runtime.h>
+
+
+
+NP_Identifier NP_IdentifierFromUTF8 (NP_UTF8 name)
+{
+    return 0;
+}
+
+void NP_GetIdentifiers (NP_UTF8 *names, int nameCount, NP_Identifier *identifiers)
+{
+}
+
+NP_UTF8 NP_UTF8FromIdentifier (NP_Identifier identifier)
+{
+    return NULL;
+}
+
+NP_Object *NP_CreateObject (NP_Class *aClass)
+{
+    if (aClass->create != NULL)
+        return aClass->create ();
+
+    NP_Object *obj = (NP_Object *)malloc (sizeof(NP_Object));
+    obj->_class = aClass;
+    obj->referenceCount = 1;
+
+    return obj;
+}
+
+
+NP_Object *NP_RetainObject (NP_Object *obj)
+{
+    if (obj->_class->retain != NULL)
+        return obj->_class->retain (obj);
+
+    obj->referenceCount++;
+
+    return obj;
+}
+
+
+void NP_ReleaseObject (NP_Object *obj)
+{
+    if (obj->_class->release != NULL)
+        obj->_class->release (obj);
+    else {
+        assert (obj->referenceCount >= 1);
+
+        obj->referenceCount--;
+                
+        if (obj->referenceCount == 0) {
+            if (obj->_class->destroy)
+                obj->_class->destroy (obj);
+            else
+                free (obj);
+        }
+    }
+}
+
+bool NP_IsKindOfClass (NP_Object *obj, NP_Class *aClass)
+{
+    return false;
+}
+
+void NP_SetException (NP_Object *obj,  NP_String *message)
+{
+}
+
+// ---------------------------------- NP_JavaScriptObject ----------------------------------
+NP_Object *NP_Call (NP_JavaScriptObject *obj, NP_Identifier methodName, NP_Object **args, unsigned argCount)
+{
+    return NULL;
+}
+
+NP_Object *NP_Evaluate (NP_JavaScriptObject *obj, NP_String *script)
+{
+    return NULL;
+}
+
+NP_Object *NP_GetProperty (NP_JavaScriptObject *obj, NP_Identifier  propertyName)
+{
+    return NULL;
+}
+
+void NP_SetProperty (NP_JavaScriptObject *obj, NP_Identifier  propertyName, NP_Object value)
+{
+}
+
+
+void NP_RemoveProperty (NP_JavaScriptObject *obj, NP_Identifier propertyName)
+{
+}
+
+NP_UTF8 NP_ToString (NP_JavaScriptObject *obj)
+{
+    return NULL;
+}
+
+NP_Object *NP_GetPropertyAtIndex (NP_JavaScriptObject *obj, unsigned int index)
+{
+    return NULL;
+}
+
+void NP_SetPropertyAtIndex (NP_JavaScriptObject *obj, unsigned index, NP_Object value)
+{
+}
+
+
+// ---------------------------------- Types ----------------------------------
+
+
+NP_Number *NP_CreateNumberWithInt (int i)
+{
+    return NULL;
+}
+
+NP_Number *NP_CreateNumberWithFloat (float f)
+{
+    return NULL;
+}
+
+NP_Number *NP_CreateNumberWithDouble (double d)
+{
+    return NULL;
+}
+
+int NP_IntFromNumber (NP_Number *obj)
+{
+    return 0;
+}
+
+float NP_FloatFromNumber (NP_Number *obj)
+{
+    return 0.;
+}
+
+double NP_DoubleFromNumber (NP_Number *obj)
+{
+    return 0.;
+}
+
+
+NP_String *NP_CreateStringWithUTF8 (NP_UTF8 utf8String)
+{
+    return NULL;
+}
+
+NP_String *NP_CreateStringWithUTF16 (NP_UTF16 utf16String)
+{
+    return NULL;
+}
+
+
+NP_UTF8 NP_UTF8FromString (NP_String *obj)
+{
+    return NULL;
+}
+
+NP_UTF16 NP_UTF16FromString (NP_String *obj)
+{
+    return NULL;
+}
+
+NP_Boolean *NP_CreateBoolean (bool f)
+{
+    return NULL;
+}
+
+bool NP_BoolFromBoolean (NP_Boolean *aBool)
+{
+    return true;
+}
+
+NP_Null *NP_GetNull()
+{
+    return NULL;
+}
+
+NP_Undefined *NP_GetUndefined()
+{
+    return NULL;
+}
+
+NP_Array *NP_CreateArray (const NP_Object **, unsigned count)
+{
+    return NULL;
+}
+
+NP_Array *NP_CreateArrayV (unsigned count, ...)
+{
+    return NULL;
+}
+
+NP_Object *NP_ObjectAtIndex (NP_Array *array, unsigned index)
+{
+    return NULL;
+}
+
diff --git a/JavaScriptCore/bindings/npruntime.h b/JavaScriptCore/bindings/npruntime.h
new file mode 100644
index 0000000..1501326
--- /dev/null
+++ b/JavaScriptCore/bindings/npruntime.h
@@ -0,0 +1,439 @@
+/*
+ * Copyright (C) 2004 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 _NP_RUNTIME_H_
+#define _NP_RUNTIME_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+    This API is used to facilitate binding code written in 'C' to JavaScript
+    objects.  In particular it is used to support the extended Netscape 
+    script-ability API for plugins (NP-SAP).  NP-SAP is an extension of the 
+    Netscape plugin API.  As such we have adopted the use of the "NP_" prefix
+    for this API.  
+    
+    The following NP-SAP entry points were added to the Netscape plugin API:
+
+    typedef NP_Object *(*NPP_GetNativeObjectForJavaScript) (NPP instance);
+    typedef NP_JavaScriptObject *(*NPN_GetWindowJavaScriptObject) (NPP instance);
+    typedef NP_JavaScriptObject *(*NPN_GetInstanceJavaScriptObject) (NPP instance);
+    
+    See NP_SAP.h for more details regarding the above Interfaces.
+*/
+
+
+/*
+    Data passed between 'C' and JavaScript is always wrapped in an NP_Object.
+*/
+typedef struct NP_Object NP_Object;
+
+/*
+    A NP_JavaScriptObject wraps a JavaScript Object in an NP_Object.
+*/
+typedef NP_Object NP_JavaScriptObject;
+
+/*
+	Type mappings:
+
+	JavaScript		to			C
+	Boolean						NP_Boolean	
+	Number						NP_Number
+	String						NP_String
+	Undefined					NP_Undefined
+	Null						NP_Null
+	Object (including Array)	NP_JavaScriptObject
+	Object wrapper              NP_Object
+
+
+	C				to			JavaScript
+	NP_Boolean					Boolean	
+	NP_Number					Number
+	NP_String					String
+	NP_Undefined				Undefined
+	NP_Null						Null
+	NP_Array					Array (restricted)
+	NP_JavaScriptObject			Object
+	other NP_Object             Object wrapper
+
+*/
+
+typedef uint32_t NP_Identifier;
+typedef char *NP_UTF8;
+typedef int16_t *NP_UTF16;
+
+/*
+    NP_Objects have methods and properties.  Methods and properties are named with NP_Identifiers.
+    These identifiers may be reflected in JavaScript.  NP_Identifiers can be compared using ==.
+*/
+NP_Identifier NP_IdentifierFromUTF8 (NP_UTF8 name);
+void NP_GetIdentifiers (NP_UTF8 *names, int nameCount, NP_Identifier *identifiers);
+NP_UTF8 NP_UTF8FromIdentifier (NP_Identifier identifier);
+
+/*
+    NP_Object behavior is implemented using the following set of callback interfaces.
+*/
+typedef NP_Object *(*NP_CreateInterface)();
+typedef void *(*NP_DestroyInterface)(NP_Object *obj);
+typedef NP_Object *(*NP_RetainInterface)(NP_Object *obj);
+typedef void (*NP_ReleaseInterface)(NP_Object *obj);
+typedef void (*NP_InvalidateInterface)();
+typedef bool (*NP_HasMethodInterface)(NP_Object *obj, NP_Identifier name);
+typedef NP_Object *(*NP_InvokeInterface)(NP_Object *obj, NP_Identifier name, NP_Object **args, unsigned argCount);
+typedef bool (*NP_HasPropertyInterface)(NP_Object *obj, NP_Identifier name);
+typedef NP_Object (*NP_GetPropertyInterface)(NP_Object *obj, NP_Identifier name);
+typedef void (*NP_SetPropertyInterface)(NP_Object *obj, NP_Identifier name, NP_Object *value);
+
+/*
+    NP_Objects returned by create, retain, invoke, and getProperty 
+    pass a reference count to the caller.  That is, the callee adds a reference
+    count which passes to the caller.  It is the caller's responsibility
+    to release the returned object.
+
+    NP_InvokeInterface Interfaces may return 0 to indicate a void result.
+    
+    NP_InvalidateInterface is called by the plugin container when the plugin is
+    shutdown.  Any attempt to message a NP_JavaScriptObject instance after the invalidate
+    interface has been called will result in undefined behavior, even if the
+    plugin is still retaining those NP_JavaScriptObject instances.
+    (The runtime will typically return immediately, with 0 or NULL, from an attempt to
+    dispatch to a NP_JavaScriptObject, but this behavior should not be depended upon.)
+*/
+struct NP_Class
+{
+    int32_t structVersion;
+    NP_CreateInterface create;
+    NP_DestroyInterface destroy;
+    NP_RetainInterface retain;
+    NP_ReleaseInterface release;
+    NP_InvalidateInterface invalidate;
+    NP_HasMethodInterface hasMethod;
+    NP_InvokeInterface invoke;
+    NP_HasPropertyInterface hasProperty;
+    NP_SetPropertyInterface setProperty;
+    NP_GetPropertyInterface getProperty;
+};
+typedef struct NP_Class NP_Class;
+
+#define kNP_ClassStructVersion1             1
+#define kNP_ClassStructVersionCurrent       kNP_ClassStructVersionCurrent
+
+struct NP_Object {
+    NP_Class *_class;
+    uint32_t referenceCount;
+    // Additional space may be allocated here by types of NP_Objects
+};
+
+/*
+    If the class has a create interface this function invokes that interface,
+    otherwise a NP_Object is allocated and returned.
+*/
+NP_Object *NP_CreateObject (NP_Class *aClass);
+
+/*
+    If the class has a retain interface this function invokes that interface,
+    otherwise the NP_Object's reference count is incremented.
+*/
+NP_Object *NP_RetainObject (NP_Object *obj);
+
+/*
+    If the class has a release interface this function invokes that interface,
+    otherwise the NP_Object's reference count is decremented and if the reference
+    count goes to zero, the class's destroy interface is invoke.  Note,
+    that if a class implements it's own retain/release interfaces it must also
+    call the destroy interface.
+*/
+void NP_ReleaseObject (NP_Object *obj);
+
+/*
+    Built-in data types.  These classes can be passed to NP_IsKindOfClass().
+*/
+NP_Class *NP_BooleanClass;
+NP_Class *NP_NullClass;
+NP_Class *NP_UndefinedClass;
+NP_Class *NP_ArrayClass;
+NP_Class *NP_NumberClass;
+NP_Class *NP_StringClass;
+NP_Class *NP_JavaScriptObjectClass;
+
+typedef NP_Object NP_Boolean;
+typedef NP_Object NP_Null;
+typedef NP_Object NP_Undefined;
+typedef NP_Object NP_Array;
+typedef NP_Object NP_Number;
+typedef NP_Object NP_String;
+
+/*
+    Functions to access JavaScript Objects represented by NP_JavaScriptObject.
+*/
+NP_Object *NP_Call (NP_JavaScriptObject *obj, NP_Identifier methodName, NP_Object **args, unsigned argCount);
+NP_Object *NP_Evaluate (NP_JavaScriptObject *obj, NP_String *script);
+NP_Object *NP_GetProperty (NP_JavaScriptObject *obj, NP_Identifier  propertyName);
+void NP_SetProperty (NP_JavaScriptObject *obj, NP_Identifier  propertyName, NP_Object value);
+void NP_RemoveProperty (NP_JavaScriptObject *obj, NP_Identifier propertyName);
+NP_UTF8 NP_ToString (NP_JavaScriptObject *obj);
+NP_Object *NP_GetPropertyAtIndex (NP_JavaScriptObject *obj, unsigned int index);
+void NP_SetPropertyAtIndex (NP_JavaScriptObject *obj, unsigned index, NP_Object value);
+
+/*
+    Functions for dealing with data types.
+*/
+NP_Number *NP_CreateNumberWithInt (int i);
+NP_Number *NP_CreateNumberWithFloat (float f);
+NP_Number *NP_CreateNumberWithDouble (double d);
+int NP_IntFromNumber (NP_Number *obj);
+float NP_FloatFromNumber (NP_Number *obj);
+double NP_DoubleFromNumber (NP_Number *obj);
+
+NP_String *NP_CreateStringWithUTF8 (NP_UTF8 utf8String);
+NP_String *NP_CreateStringWithUTF16 (NP_UTF16 utf16String);
+
+/*
+    Memory returned from NP_UTF8FromString must be freed by the caller.
+*/
+NP_UTF8 NP_UTF8FromString (NP_String *obj);
+/*
+    Memory returned from NP_UTF16FromString must be freed by the caller.
+*/
+NP_UTF16 NP_UTF16FromString (NP_String *obj);
+
+NP_Boolean *NP_CreateBoolean (bool f);
+bool NP_BoolFromBoolean (NP_Boolean *aBool);
+
+/*
+    NP_Null returns a NP_Null singleton.
+*/
+NP_Null *NP_GetNull();
+
+/*
+    NP_Undefined returns a NP_Undefined singleton.
+*/
+NP_Undefined *NP_GetUndefined();
+
+/*
+    NP_Arrays are immutable.  They are used to pass arguments to 
+    JavaScription Interfaces that expect arrays, or to export 
+    arrays of properties.  NP_Array is represented in JavaScript
+    by a restricted Array.  The Array in JavaScript is read-only,
+    only has index accessors, and may not be resized.
+*/
+NP_Array *NP_CreateArray (const NP_Object **, unsigned count);
+NP_Array *NP_CreateArrayV (unsigned count, ...);
+NP_Object *NP_ObjectAtIndex (NP_Array *array, unsigned index);
+
+/*
+    Returns true if the object is a kind of class as specified by
+    aClass.
+*/
+bool NP_IsKindOfClass (NP_Object *obj, NP_Class *aClass);
+
+/*
+    NP_SetException may be called to trigger a JavaScript exception upon return
+    from entry points into NP_Objects.  A reference count of the message passes
+    to the callee.  Typical usage:
+
+    NP_SetException (obj, NP_CreateStringWithUTF8("invalid type"));
+*/
+void NP_SetException (NP_Object *obj,  NP_String *message);
+
+/*
+    Example usage:
+    
+    typedef NP_Object MyInterfaceObject;
+
+    typedef struct
+    {
+        NP_Object object;
+        // Properties needed by MyInterfaceObject are added here.
+        int numChapters;
+        ...
+    } MyInterfaceObject
+
+    void stop(MyInterfaceObject *obj)
+    {
+        ...
+    }
+
+    void start(MyInterfaceObject *obj)
+    {
+        ...
+    }
+
+    void setChapter(MyInterfaceObject *obj, int chapter)
+    {
+        ...
+    }
+
+    int getChapter(MyInterfaceObject *obj)
+    {
+        ...
+    }
+
+    static NP_Identifier stopIdentifier;
+    static NP_Identifier startIdentifier;
+    static NP_Identifier setChapterIdentifier;
+    static NP_Identifier getChapterIdentifier;
+    static NP_Identifier numChaptersIdentifier;
+
+    static initializeIdentifiers()
+    {
+        stopIdentifier = NP_IdentifierFromUTF8 ("stop");
+        startIdentifier = NP_IdentifierFromUTF8 ("start");
+        setChapterIdentifier = NP_IdentifierFromUTF8 ("setChapter");
+        getChapterIdentifier = NP_IdentifierFromUTF8 ("getChapter");
+        numChaptersIdentifier = NP_IdentifierFromUTF8 ("numChapters");
+    }
+
+    bool myInterfaceHasProperty (MyInterfaceObject *obj, NP_Identifier name)
+    {
+        if (name == numChaptersIdentifier){
+            return true;
+        }
+        return false;
+    }
+
+    bool myInterfaceHasMethod (MyInterfaceObject *obj, NP_Identifier name)
+    {
+        if (name == stopIdentifier ||
+            name == startIdentifier ||
+            name == setChapterIdentifier ||
+            name == getChapterIdentifier) {
+            return true;
+        }
+        return false;
+    }
+
+    NP_Object *myInterfaceGetProperty (MyInterfaceObject *obj, NP_Identifier name)
+    {
+        if (name == numChaptersIdentifier){
+            return NP_CreateNumberWithInt(obj->numChapters); 
+        }
+        return 0;
+    }
+
+    void myInterfaceSetProperty (MyInterfaceObject *obj, NP_Identifier name, NP_Object *obj)
+    {
+        if (name == numChaptersIdentifier){
+            obj->numChapters = NP_IntFromNumber(obj)
+        }
+        return 0;
+    }
+
+    NP_Object *myInterfaceInvoke (MyInterfaceObject *obj, NP_Identifier name, NP_Object **args, unsigned argCount)
+    {
+
+        if (name == stopIdentifier){
+            stop(obj);
+        }
+        else if (name == startIdentifier){
+            start(obj);
+        }
+        else if (name == setChapterIdentifier){
+            if (NP_IsKindOfClass (args[0], NP_NumberClass)) {
+                setChapter (obj, NP_IntFromNumber(args[0]));
+            }
+            else {
+                NP_SetException (obj, NP_CreateStringWithUTF8 ("invalid type"));
+            }
+        }
+        else if (name == getChapterIdentifier){
+            return NP_CreateNumberWithInt (getChapter (obj));
+        }
+        return 0;
+    }
+
+    NP_Object *myInterfaceCreate ()
+    {
+        MyInterfaceObject *newInstance = (MyInterfaceObject *)malloc (sizeof(MyInterfaceObject));
+        
+        if (stopIdentifier == 0)
+            initializeIdentifiers();
+        
+        newInstance->object->class = myInterface;
+        
+        return myInterfaceRetain (newInstance);
+    }
+
+    void myInterfaceInvalidate ()
+    {
+        // Make sure we've released any remainging references to JavaScript
+        // objects.
+    }
+    
+    void myInterfaceDestroy (MyInterfaceObject *obj) 
+    {
+        assert (obj->referenceCount == 0);
+        
+        free ((void *)obj);
+    }
+    
+    NP_Object *myInterfaceRetain (MyInterfaceObject *obj)
+    {
+        return referenceCount++;
+    }
+
+    void myInterfaceRelease (MyInterfaceObject *obj)
+    {
+        obj->referenceCount--;
+        
+        assert (obj->referenceCount >= 0)
+        
+        if (obj->referenceCount == 0) {
+            myDestroyInterface (obj);
+        }
+    }
+
+    static NP_Class _myInterface = { 
+        (NP_CreateInterface) myInterfaceCreate, 
+        (NP_DestroyInterface) myInterfaceDestroy, 
+        (NP_RetainInterface) myInterfaceRetain,
+        (NP_ReleaseInterface) myInterfaceRelease,
+        (NP_InvalidateInterface) myInterfaceInvalidate,
+        (NP_HasMethodInterface) myInterfaceHasMethod,
+        (NP_InvokeInterface) myInterfaceInvoke,
+        (NP_HasPropertyInterface) myInterfaceHasProperty,
+        (NP_GetPropertyInterface) myInterfaceGetProperty,
+        (NP_SetPropertyInterface) myInterfaceSetProperty,
+    };
+    static NP_Class *myInterface = &_myInterface;
+
+    // myGetNativeObjectForJavaScript would be set as the entry point for
+    // the plugin's NPP_GetNativeObjectForJavaScript function.
+    // It is invoked by the plugin container, i.e. the browser.
+    NP_Object *myGetNativeObjectForJavaScript(NPP_Instance instance)
+    {
+        NP_Object *myInterfaceObject = NP_CreateObject (myInterface);
+        return myInterfaceObject;
+    }
+
+*/
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/JavaScriptCore/bindings/objc/objc_jsobject.h b/JavaScriptCore/bindings/objc/objc_jsobject.h
index 4eb68f4..4a85b76 100644
--- a/JavaScriptCore/bindings/objc/objc_jsobject.h
+++ b/JavaScriptCore/bindings/objc/objc_jsobject.h
@@ -37,28 +37,47 @@
     long
     float
     double
-    NSString        string
-    NSArray         []
-    id              wrapper
+    NSNumber        Number
+    NSString        String
+    NSArray         Array
+    id              Object wrapper
     other           exception
     
     JavaScript to   ObjC
     Number          coerced char, short, int, long, float, or double
     String          NSString
-    wrapper         id
+    Object wrapper         id
     Object          JavaScriptObject
     [], other       exception
 */
 
-
- at interface NSObject (JavaScriptMethods)
+// This is intended to be a public API.
+ at interface NSObject (JavaScriptMethods) 
 
 + (NSString *)JavaScriptNameForSelector:(SEL)aSelector;
 + (BOOL)excludeSelectorFromJavaScript:(SEL)aSelector;
 
 @end
 
+ at class JavaScriptObjectPrivate;
+
+// This is intended to be a public API.
+ at interface JavaScriptObject : NSObject
+{
+    JavaScriptObjectPrivate *_private;
+}
+
+- (id)call:(NSString *)methodName arguments:(NSArray *)args;
+- (id)evaluate:(NSString *)script;
+- (id)getMember:(NSString *)name;
+- (void)setMember:(NSString *)name value:(id)value;
+- (void)removeMember:(NSString *)name;
+- (NSString *)toString;
+- (id)getSlot:(unsigned int)index;
+- (void)setSlot:(unsigned int)index value:(id)value;
+ at end
 
+// This is intended to be an SPI, as it exposes KJS::Value.
 @interface JavaScriptValueConverter
 
 + (void)registerConverter:(JavaScriptValueConverter *)aConverter;
@@ -69,8 +88,4 @@
 
 @end
 
-
- at interface JavaScriptObject
- at end
-
 #endif
\ No newline at end of file
diff --git a/JavaScriptCore/bindings/objc/objc_jsobject.mm b/JavaScriptCore/bindings/objc/objc_jsobject.mm
index 19a5f78..f3ecce8 100644
--- a/JavaScriptCore/bindings/objc/objc_jsobject.mm
+++ b/JavaScriptCore/bindings/objc/objc_jsobject.mm
@@ -22,4 +22,241 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
-#include <objc_jsobject.h>
\ No newline at end of file
+#include <JavaScriptCore/internal.h>
+#include <JavaScriptCore/list.h>
+#include <JavaScriptCore/value.h>
+
+#include <objc_jsobject.h>
+#include <objc_instance.h>
+#include <objc_utility.h>
+
+#include <runtime_object.h>
+#include <runtime_root.h>
+
+using namespace KJS;
+using namespace KJS::Bindings;
+
+
+#ifdef JAVASCRIPT_OBJECT_IN_WEBCORE
+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;
+    }
+    return 0;
+}
+
+JavaScriptObject *windowJavaScriptObject(RootObject *root)
+{
+    return [[[JavaScriptObject alloc] initWithObjectImp:root->rootObjectImp() root:root] autorelease];
+}
+
+typedef enum {
+    ObjectiveCLanaguage = 1,
+    CLanaguage
+}
+
+void *NPN_GetJavaScriptObjectForWindow (NPNativeLanguage lang)
+void *NPN_GetJavaScriptObjectForSelf (NPNativeLanguage lang)
+
+windowJavaScriptObject(root));
+
+#endif
+
+ at interface JavaScriptObjectPrivate : NSObject
+{
+    KJS::ObjectImp *imp;
+    const Bindings::RootObject *root;
+}
+ at end
+
+ at implementation JavaScriptObjectPrivate
+ at end
+
+ at interface JavaScriptObject (Private)
+- _initWithObjectImp:(KJS::ObjectImp *)imp root:(const Bindings::RootObject *)root;
+- (id)_convertValueToObjcValue:(KJS::Value)value;
+ at end
+
+ at implementation JavaScriptObject
+
+static KJS::List listFromNSArray(ExecState *exec, NSArray *array)
+{
+    long i, numObjects = array ? [array count] : 0;
+    KJS::List aList;
+    
+    for (i = 0; i < numObjects; i++) {
+        id anObject = [array objectAtIndex:i];
+        aList.append (convertObjcValueToValue(exec, anObject, ObjcObjectType));
+    }
+    return aList;
+}
+
+- initWithObjectImp:(KJS::ObjectImp *)imp root:(const Bindings::RootObject *)root
+{
+    assert (imp != 0);
+    assert (root != 0);
+
+    self = [super init];
+
+    _private = [[JavaScriptObjectPrivate alloc] init];
+    _private->imp = imp;
+    _private->root = root;    
+
+    addNativeReference (root, imp);
+    
+    return self;
+}
+
+- (void)dealloc
+{
+    removeNativeReference (_private->imp);
+    [_private release];
+    [super dealloc];
+}
+
+- (id)_convertValueToObjcValue:(KJS::Value)value
+{
+    id result = 0;
+   
+    // First see if we have a ObjC instance.
+    if (value.type() == KJS::ObjectType){
+        ObjectImp *objectImp = static_cast<ObjectImp*>(value.imp());
+        if (strcmp(objectImp->classInfo()->className, "RuntimeObject") == 0) {
+            RuntimeObjectImp *imp = static_cast<RuntimeObjectImp *>(value.imp());
+            ObjcInstance *instance = static_cast<ObjcInstance*>(imp->getInternalInstance());
+            if (instance)
+                result = instance->getObject();
+        }
+        // Convert to a JavaScriptObject
+        else {
+            result = [[[JavaScriptObject alloc] _initWithObjectImp:objectImp root:_private->root] autorelease];
+        }
+    }
+    
+    // Convert JavaScript String value to NSString?
+    else if (value.type() == KJS::StringType) {
+        StringImp *s = static_cast<KJS::StringImp*>(value.imp());
+        UString u = s->value();
+        
+        NSString *string = [NSString stringWithCharacters:(const unichar*)u.data() length:u.size()];
+        result = string;
+    }
+    
+    // Convert JavaScript Number value to NSNumber?
+    else if (value.type() == KJS::NumberType) {
+        Number n = Number::dynamicCast(value);
+        result = [NSNumber numberWithDouble:n.value()];
+    }
+    
+    // Boolean?
+    return result;
+}
+
+- (id)call:(NSString *)methodName arguments:(NSArray *)args
+{
+    // Lookup the function object.
+    ExecState *exec = _private->root->interpreter()->globalExec();
+    Interpreter::lock();
+    
+    Value v = convertObjcValueToValue(exec, &methodName, ObjcObjectType);
+    Identifier identifier(v.toString(exec));
+    Value func = _private->imp->get (exec, identifier);
+    Interpreter::unlock();
+    if (func.isNull() || func.type() == UndefinedType) {
+        // Maybe throw an exception here?
+        return 0;
+    }
+
+    // Call the function object.
+    ObjectImp *funcImp = static_cast<ObjectImp*>(func.imp());
+    Object thisObj = Object(const_cast<ObjectImp*>(_private->imp));
+    List argList = listFromNSArray(exec, args);
+    Interpreter::lock();
+    Value result = funcImp->call (exec, thisObj, argList);
+    Interpreter::unlock();
+
+    // Convert and return the result of the function call.
+    return [self _convertValueToObjcValue:result];
+}
+
+- (id)evaluate:(NSString *)script
+{
+    ExecState *exec = _private->root->interpreter()->globalExec();
+    Object thisObj = Object(const_cast<ObjectImp*>(_private->imp));
+    Interpreter::lock();
+    Value v = convertObjcValueToValue(exec, &script, ObjcObjectType);
+    KJS::Value result = _private->root->interpreter()->evaluate(v.toString(exec)).value();
+    Interpreter::unlock();
+    return [self _convertValueToObjcValue:result];
+}
+
+- (id)getMember:(NSString *)name
+{
+    ExecState *exec = _private->root->interpreter()->globalExec();
+    Interpreter::lock();
+    Value v = convertObjcValueToValue(exec, &name, ObjcObjectType);
+    Value result = _private->imp->get (exec, Identifier (v.toString(exec)));
+    Interpreter::unlock();
+    return [self _convertValueToObjcValue:result];
+}
+
+- (void)setMember:(NSString *)name value:(id)value
+{
+    ExecState *exec = _private->root->interpreter()->globalExec();
+    Interpreter::lock();
+    Value v = convertObjcValueToValue(exec, &name, ObjcObjectType);
+   _private->imp->put (exec, Identifier (v.toString(exec)), (convertObjcValueToValue(exec, &value, ObjcObjectType)));
+    Interpreter::unlock();
+}
+
+- (void)removeMember:(NSString *)name
+{
+    ExecState *exec = _private->root->interpreter()->globalExec();
+    Interpreter::lock();
+    Value v = convertObjcValueToValue(exec, &name, ObjcObjectType);
+    _private->imp->deleteProperty (exec, Identifier (v.toString(exec)));
+    Interpreter::unlock();
+}
+
+- (NSString *)toString
+{
+    Interpreter::lock();
+    Object thisObj = Object(const_cast<ObjectImp*>(_private->imp));
+    ExecState *exec = _private->root->interpreter()->globalExec();
+    
+    id result = convertValueToObjcValue(exec, thisObj, ObjcObjectType).objectValue;
+
+    Interpreter::unlock();
+    
+    return [result description];
+}
+
+- (id)getSlot:(unsigned int)index
+{
+    ExecState *exec = _private->root->interpreter()->globalExec();
+    Interpreter::lock();
+    Value result = _private->imp->get (exec, (unsigned)index);
+    Interpreter::unlock();
+
+    return [self _convertValueToObjcValue:result];
+}
+
+- (void)setSlot:(unsigned int)index value:(id)value
+{
+    ExecState *exec = _private->root->interpreter()->globalExec();
+    Interpreter::lock();
+    _private->imp->put (exec, (unsigned)index, (convertObjcValueToValue(exec, &value, ObjcObjectType)));
+    Interpreter::unlock();
+}
+
+ at end
diff --git a/JavaScriptCore/bindings/objc/objc_utility.h b/JavaScriptCore/bindings/objc/objc_utility.h
index ac43421..e0ed4cb 100644
--- a/JavaScriptCore/bindings/objc/objc_utility.h
+++ b/JavaScriptCore/bindings/objc/objc_utility.h
@@ -60,7 +60,7 @@ typedef enum {
     ObjcInvalidType
 } ObjcValueType;
 
-ObjcValue convertValueToObjcValue (KJS::ExecState *exec, KJS::Value value, ObjcValueType type);
+ObjcValue convertValueToObjcValue (KJS::ExecState *exec, const KJS::Value &value, ObjcValueType type);
 Value convertObjcValueToValue (KJS::ExecState *exec, void *buffer, ObjcValueType type);
 ObjcValueType objcValueTypeForType (const char *type);
 
diff --git a/JavaScriptCore/bindings/objc/objc_utility.mm b/JavaScriptCore/bindings/objc/objc_utility.mm
index 600ccd6..d783e4d 100644
--- a/JavaScriptCore/bindings/objc/objc_utility.mm
+++ b/JavaScriptCore/bindings/objc/objc_utility.mm
@@ -90,7 +90,7 @@ void KJS::Bindings::JSMethodNameToObjCMethodName(const char *name, char *buffer,
     [], other       exception
 
 */
-ObjcValue KJS::Bindings::convertValueToObjcValue (KJS::ExecState *exec, KJS::Value value, ObjcValueType type)
+ObjcValue KJS::Bindings::convertValueToObjcValue (KJS::ExecState *exec, const KJS::Value &value, ObjcValueType type)
 {
     ObjcValue result;
     double d = 0;
@@ -125,8 +125,6 @@ ObjcValue KJS::Bindings::convertValueToObjcValue (KJS::ExecState *exec, KJS::Val
                 Number n = Number::dynamicCast(value);
                 result.objectValue = [NSNumber numberWithDouble:n.value()];
             }
-            
-            // FIXME:  Deal with other Object types by creating a JavaScriptObjects
         }
         break;
         
diff --git a/JavaScriptCore/bindings/runtime_root.cpp b/JavaScriptCore/bindings/runtime_root.cpp
new file mode 100644
index 0000000..1a8fe75
--- /dev/null
+++ b/JavaScriptCore/bindings/runtime_root.cpp
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2004 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+                                        * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+                                        * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+#include <jni_jsobject.h>
+#include <runtime_root.h>
+
+using namespace KJS;
+using namespace KJS::Bindings;
+
+
+// Java does NOT always call finalize (and thus KJS_JSObject_JSFinalize) when
+// it collects an objects.  This presents some difficulties.  We must ensure
+// the a JSObject's corresponding JavaScript object doesn't get collected.  We
+// do this by incrementing the JavaScript's reference count the first time we
+// create a JSObject for it, and decrementing the JavaScript reference count when
+// the last JSObject that refers to it is finalized, or when the applet is
+// shutdown.
+//
+// To do this we keep a dictionary that maps each applet instance
+// to the JavaScript objects it is referencing.  For each JavaScript instance
+// we also maintain a secondary reference count.  When that reference count reaches
+// 1 OR the applet is shutdown we deref the JavaScript instance.  Applet instances
+// are represented by a jlong.
+
+static CFMutableDictionaryRef referencesByRootDictionary = 0;
+
+static CFMutableDictionaryRef getReferencesByRootDictionary()
+{
+    if (!referencesByRootDictionary)
+        referencesByRootDictionary = CFDictionaryCreateMutable(NULL, 0, NULL, &kCFTypeDictionaryValueCallBacks);
+    return referencesByRootDictionary;
+}
+
+static CFMutableDictionaryRef getReferencesDictionary(const Bindings::RootObject *root)
+{
+    CFMutableDictionaryRef refsByRoot = getReferencesByRootDictionary();
+    CFMutableDictionaryRef referencesDictionary = 0;
+    
+    referencesDictionary = (CFMutableDictionaryRef)CFDictionaryGetValue (refsByRoot, (const void *)root);
+    if (!referencesDictionary) {
+        referencesDictionary = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+        CFDictionaryAddValue (refsByRoot, root, referencesDictionary);
+        CFRelease (referencesDictionary);
+    }
+    return referencesDictionary;
+}
+
+// Scan all the dictionary for all the roots to see if any have a 
+// reference to the imp, and if so, return it's reference count
+// dictionary.
+// FIXME:  This is a potential performance bottleneck with many applets.  We could fix be adding a
+// imp to root dictionary.
+CFMutableDictionaryRef KJS::Bindings::findReferenceDictionary(ObjectImp *imp)
+{
+    CFMutableDictionaryRef refsByRoot = getReferencesByRootDictionary ();
+    CFMutableDictionaryRef foundDictionary = 0;
+    
+    if (refsByRoot) {
+        const void **allValues = 0;
+        CFIndex count, i;
+        
+        count = CFDictionaryGetCount(refsByRoot);
+        allValues = (const void **)malloc (sizeof(void *) * count);
+        CFDictionaryGetKeysAndValues (refsByRoot, NULL, allValues);
+        for(i = 0; i < count; i++) {
+            CFMutableDictionaryRef referencesDictionary = (CFMutableDictionaryRef)allValues[i];
+            if (CFDictionaryGetValue(referencesDictionary, imp) != 0) {
+                foundDictionary = referencesDictionary;
+                break;
+            }
+        }
+        
+        free ((void *)allValues);
+    }
+    return foundDictionary;
+}
+
+// FIXME:  This is a potential performance bottleneck with many applets.  We could fix be adding a
+// imp to root dictionary.
+const Bindings::RootObject *KJS::Bindings::rootForImp (ObjectImp *imp)
+{
+    CFMutableDictionaryRef refsByRoot = getReferencesByRootDictionary ();
+    const Bindings::RootObject *rootObject = 0;
+    
+    if (refsByRoot) {
+        const void **allValues = 0;
+        const void **allKeys = 0;
+        CFIndex count, i;
+        
+        count = CFDictionaryGetCount(refsByRoot);
+        allKeys = (const void **)malloc (sizeof(void *) * count);
+        allValues = (const void **)malloc (sizeof(void *) * count);
+        CFDictionaryGetKeysAndValues (refsByRoot, allKeys, allValues);
+        for(i = 0; i < count; i++) {
+            CFMutableDictionaryRef referencesDictionary = (CFMutableDictionaryRef)allValues[i];
+            if (CFDictionaryGetValue(referencesDictionary, imp) != 0) {
+                rootObject = (const Bindings::RootObject *)allKeys[0];
+                break;
+            }
+        }
+        
+        free ((void *)allKeys);
+        free ((void *)allValues);
+    }
+    return rootObject;
+}
+
+void KJS::Bindings::addNativeReference (const Bindings::RootObject *root, ObjectImp *imp)
+{
+    CFMutableDictionaryRef referencesDictionary = getReferencesDictionary (root);
+    
+    unsigned int numReferences = (unsigned int)CFDictionaryGetValue (referencesDictionary, imp);
+    if (numReferences == 0) {
+        imp->ref();
+        CFDictionaryAddValue (referencesDictionary, imp,  (const void *)1);
+    }
+    else {
+        CFDictionaryReplaceValue (referencesDictionary, imp, (const void *)(numReferences+1));
+    }
+}
+
+void KJS::Bindings::removeNativeReference (ObjectImp *imp)
+{
+    CFMutableDictionaryRef referencesDictionary = findReferenceDictionary (imp);
+    
+    unsigned int numReferences = (unsigned int)CFDictionaryGetValue (referencesDictionary, imp);
+    if (numReferences == 1) {
+        imp->deref();
+        CFDictionaryRemoveValue (referencesDictionary, imp);
+    }
+    else {
+        CFDictionaryReplaceValue (referencesDictionary, imp, (const void *)(numReferences-1));
+    }
+}
+
+// May only be set by dispatchToJavaScriptThread().
+static CFRunLoopSourceRef completionSource;
+
+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);
+
+    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);
+}
+
+
+void RootObject::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);
+
+    // 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);
+
+    unlockJavaScriptAccess();
+}
+
+static void performJavaScriptAccess(void *info);
+static void performJavaScriptAccess(void *i)
+{
+    assert (CFRunLoopGetCurrent() == RootObject::runLoop());
+    
+    // Dispatch JavaScript calls here.
+    CFRunLoopSourceContext sourceContext;
+    CFRunLoopSourceGetContext (completionSource, &sourceContext);
+    JSObjectCallContext *callContext = (JSObjectCallContext *)sourceContext.info;    
+    CFRunLoopRef originatingLoop = callContext->originatingLoop;
+
+    JSObject::invoke (callContext);
+    
+    // Signal the originating thread that we're done.
+    CFRunLoopSourceSignal (completionSource);
+    if (CFRunLoopIsWaiting(originatingLoop)) {
+        CFRunLoopWakeUp(originatingLoop);
+    }
+}
+
+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};
+    Bindings::RootObject::_performJavaScriptSource = CFRunLoopSourceCreate(NULL, 0, &sourceContext);
+    CFRunLoopAddSource(Bindings::RootObject::_runLoop, Bindings::RootObject::_performJavaScriptSource, kCFRunLoopDefaultMode);
+}
+
+// Must be called when the applet is shutdown.
+void RootObject::removeAllNativeReferences ()
+{
+    CFMutableDictionaryRef referencesDictionary = getReferencesDictionary (this);
+    
+    if (referencesDictionary) {
+        void **allImps = 0;
+        CFIndex count, i;
+        
+        count = CFDictionaryGetCount(referencesDictionary);
+        allImps = (void **)malloc (sizeof(void *) * count);
+        CFDictionaryGetKeysAndValues (referencesDictionary, (const void **)allImps, NULL);
+        for(i = 0; i < count; i++) {
+            ObjectImp *anImp = static_cast<ObjectImp*>(allImps[i]);
+            anImp->deref();
+        }
+        free ((void *)allImps);
+        CFDictionaryRemoveAllValues (referencesDictionary);
+
+        CFMutableDictionaryRef refsByRoot = getReferencesByRootDictionary();
+        CFDictionaryRemoveValue (refsByRoot, (const void *)this);
+        delete this;
+    }
+}
+
diff --git a/JavaScriptCore/bindings/runtime_root.h b/JavaScriptCore/bindings/runtime_root.h
new file mode 100644
index 0000000..112a5ec
--- /dev/null
+++ b/JavaScriptCore/bindings/runtime_root.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2004 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+                                        * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+                                        * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 _RUNTIME_ROOT_H_
+#define _RUNTIME_ROOT_H_
+
+#include <JavaScriptCore/interpreter.h>
+#include <JavaScriptCore/object.h>
+#include <JavaScriptCore/jni_jsobject.h>
+
+namespace KJS {
+
+namespace Bindings {
+
+class RootObject;
+
+typedef RootObject *(*FindRootObjectForNativeHandleFunctionPtr)(void *);
+
+extern CFMutableDictionaryRef findReferenceDictionary(ObjectImp *imp);
+extern const Bindings::RootObject *rootForImp (ObjectImp *imp);
+extern void addNativeReference (const Bindings::RootObject *root, ObjectImp *imp);
+extern void removeNativeReference (ObjectImp *imp);
+
+class RootObject
+{
+friend class JSObject;
+public:
+    RootObject (const void *nativeHandle) : _nativeHandle(nativeHandle), _imp(0), _interpreter(0) {}
+    ~RootObject (){
+        _imp->deref();
+    }
+    
+    void setRootObjectImp (KJS::ObjectImp *i) { 
+        _imp = i;
+        _imp->ref();
+    }
+    
+    KJS::ObjectImp *rootObjectImp() const { return _imp; }
+    
+    void setInterpreter (KJS::Interpreter *i) { _interpreter = i; }
+    KJS::Interpreter *interpreter() const { return _interpreter; }
+
+    void removeAllNativeReferences ();
+
+
+    // Must be called from the thread that will be used to access JavaScript.
+    static void setFindRootObjectForNativeHandleFunction(FindRootObjectForNativeHandleFunctionPtr aFunc);
+    static FindRootObjectForNativeHandleFunctionPtr findRootObjectForNativeHandleFunction() {
+        return _findRootObjectForNativeHandleFunctionPtr;
+    }
+    
+    static CFRunLoopRef runLoop() { return _runLoop; }
+    static CFRunLoopSourceRef performJavaScriptSource() { return _performJavaScriptSource; }
+    
+    static void dispatchToJavaScriptThread(JSObjectCallContext *context);
+    
+private:
+    const void *_nativeHandle;
+    KJS::ObjectImp *_imp;
+    KJS::Interpreter *_interpreter;
+
+    static FindRootObjectForNativeHandleFunctionPtr _findRootObjectForNativeHandleFunctionPtr;
+    static CFRunLoopRef _runLoop;
+    static CFRunLoopSourceRef _performJavaScriptSource;
+};
+
+} // namespace Bindings
+
+} // namespace KJS
+
+#endif
diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index f0428f6..690633c 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,20 @@
+2004-03-02  Richard Williamson   <rjw at apple.com>
+
+	Added NP_SAP API.  This API includes the new entry points
+	used to bind native interfaces to JavaScript.  It's final location
+	may change.
+
+	Made changes to KWQKHTMLPart.mm to reflect changes in names
+	on RootObject.
+	
+        Reviewed by Chris.
+
+        * WebCore.pbproj/project.pbxproj:
+        * khtml/ecma/NP_SAP.h: Added.
+        * kwq/KWQKHTMLPart.mm:
+        (KWQKHTMLPart::cleanupPluginRootObjects):
+        * kwq/WebCoreBridge.mm:
+
 2004-03-01  Maciej Stachowiak  <mjs at apple.com>
 
         Reviewed by Darin.
diff --git a/WebCore/WebCore.pbproj/project.pbxproj b/WebCore/WebCore.pbproj/project.pbxproj
index ef23627..f1211c9 100644
--- a/WebCore/WebCore.pbproj/project.pbxproj
+++ b/WebCore/WebCore.pbproj/project.pbxproj
@@ -518,6 +518,7 @@
 				BE9185E205EE59B80081354D,
 				BE94EB6605EFFE6B0032DCB5,
 				BE94EB6705EFFE6B0032DCB5,
+				515B877605F5332F00EABBF9,
 			);
 			isa = PBXHeadersBuildPhase;
 			runOnlyForDeploymentPostprocessing = 0;
@@ -916,6 +917,20 @@
 //512
 //513
 //514
+		515B877505F5332F00EABBF9 = {
+			fileEncoding = 30;
+			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
+			path = NP_SAP.h;
+			refType = 4;
+			sourceTree = "<group>";
+		};
+		515B877605F5332F00EABBF9 = {
+			fileRef = 515B877505F5332F00EABBF9;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
 		517FA6B20370BD6100CA2D3A = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
@@ -4485,6 +4500,7 @@
 		};
 		F523D23402DE436B018635CA = {
 			children = (
+				515B877505F5332F00EABBF9,
 				F523D1F402DE4369018635CA,
 				F523D1F502DE4369018635CA,
 				F523D1F602DE4369018635CA,
diff --git a/WebCore/kwq/KWQCollection.h b/WebCore/khtml/ecma/NP_SAP.h
similarity index 72%
copy from WebCore/kwq/KWQCollection.h
copy to WebCore/khtml/ecma/NP_SAP.h
index a752f30..5989866 100644
--- a/WebCore/kwq/KWQCollection.h
+++ b/WebCore/khtml/ecma/NP_SAP.h
@@ -22,27 +22,26 @@
  * (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 _NP_SAP_H_
+#define _NP_SAP_H_
 
-#ifndef QCOLLECTION_H
-#define QCOLLECTION_H
+#include <NP_runtime.h>
 
-#include "KWQDef.h"
-
-class QPtrCollection {
- public:
-    typedef void *Item;
-
-    bool autoDelete() { return del_item; }
-    void setAutoDelete(bool autoDelete) { del_item = autoDelete; }
-
-    QPtrCollection(const QPtrCollection &) : del_item(false) { }
-    QPtrCollection &operator=(const QPtrCollection &) { return *this; }
+/*
+	NPP_GetNativeObjectForJavaScript allows user agents to retrieve a plugin's exported
+	interface.
+*/
+typedef NP_Object *(*NPP_GetNativeObjectForJavaScript) (NPP instance);
 
- protected:
-    QPtrCollection() : del_item(false) { }
-    virtual ~QPtrCollection();
+/*
+	Get the window object for the page that contains the plugin.
+*/
+typedef NP_JavaScriptObject *(*NPN_GetWindowJavaScriptObject) (NPP instance);
 
-    bool del_item;
-};
+/*
+	Get the JavaScript DOM object that refers to the plugin.
+*/
+typedef NP_JavaScriptObject *(*NPN_GetInstanceJavaScriptObject) (NPP instance);
 
 #endif
+
diff --git a/WebCore/kwq/KWQKHTMLPart.mm b/WebCore/kwq/KWQKHTMLPart.mm
index d506045..ff71018 100644
--- a/WebCore/kwq/KWQKHTMLPart.mm
+++ b/WebCore/kwq/KWQKHTMLPart.mm
@@ -57,6 +57,7 @@
 #import "render_text.h"
 #import "xml/dom2_eventsimpl.h"
 #import <JavaScriptCore/property_map.h>
+#import <JavaScriptCore/runtime_root.h>
 
 #undef _KWQ_TIMING
 
@@ -2842,7 +2843,7 @@ void KWQKHTMLPart::cleanupPluginRootObjects()
 {
     KJS::Bindings::RootObject *root;
     while ((root = rootObjects.getLast())) {
-        KJS::Bindings::RootObject::removeAllJavaReferencesForRoot (root);
+        root->removeAllNativeReferences ();
         rootObjects.removeLast();
     }
 }
diff --git a/WebCore/kwq/WebCoreBridge.mm b/WebCore/kwq/WebCoreBridge.mm
index 08de72a..7043ee9 100644
--- a/WebCore/kwq/WebCoreBridge.mm
+++ b/WebCore/kwq/WebCoreBridge.mm
@@ -51,6 +51,7 @@
 
 #import <JavaScriptCore/jni_jsobject.h>
 #import <JavaScriptCore/object.h>
+#import <JavaScriptCore/runtime_root.h>
 #import <JavaScriptCore/property_map.h>
 
 #import "KWQAssertions.h"
diff --git a/WebKit/ChangeLog b/WebKit/ChangeLog
index e520211..c0d4296 100644
--- a/WebKit/ChangeLog
+++ b/WebKit/ChangeLog
@@ -1,3 +1,13 @@
+2004-03-02  Richard Williamson   <rjw at apple.com>
+
+	Added WebJavaScriptObject API.  The location of this file may
+	change.
+
+        Reviewed by Chris.
+
+        * Plugins.subproj/NP_objc.h: Added.
+        * WebKit.pbproj/project.pbxproj:
+
 2004-03-02  Chris Blumenberg  <cblu at apple.com>
 
 	Fixed: <rdar://problem/3575598>: REGRESSION: Safari crashes at IS&T website
diff --git a/WebKit/Plugins.subproj/NP_objc.h b/WebKit/Plugins.subproj/NP_objc.h
new file mode 100644
index 0000000..f28e35d
--- /dev/null
+++ b/WebKit/Plugins.subproj/NP_objc.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2003 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 _NP_OBJC_H_
+#define _NP_OBJC_H_
+
+/*
+    These methods in WebJavaScriptMethods are optionally implemented by classes whose
+    interfaces are exported to JavaScript.
+*/
+ at interface NSObject (WebJavaScriptMethods)
+
+/*
+    Use the return string as the exported name for the selector
+    in JavaScript.  It is the responsibility of the class to ensure
+    uniqueness of the returned name.  If nil is returned or this
+    method is not implemented the default name for the selector will
+    be used.  The default name concatenates the components of the
+    ObjectiveC selector name and replaces ':' with '_'.  '_' characters
+    are escaped with an additional '$', i.e. '_' becomes "$_".  '$' are
+    also escaped, i.e.  moveTo:: becomes move__, moveTo_ becomes moveTo$_,
+    and moveTo$_ becomes moveTo$$$_.  It is strongly recommended that
+    exported interfaces are carefully chosen to avoid convoluted names,
+    and that for each exported interface an appropriate unique name is
+    return by JavaScriptNameForProperty.
+*/
+
++ (NSString *)JavaScriptNameForSelector:(SEL)aSelector;
+
+// Exclude the selector from visibility in JavaScript.
++ (BOOL)isSelectorExcludedFromJavaScript:(SEL)aSelector;
+
+// Provide an alternate name for a property.
++ (NSString *)JavaScriptNameForProperty:(const char *)name;
+
+// Exclude the property from visibility in JavaScript.
++ (BOOL)isPropertyExcludedFromJavaScript:(const char *)name;
+
+ at end
+
+
+ at interface WebFrame
+- (WebJavaScriptObject *)getJavaScriptObjectForWindow;
+- (WebJavaScriptObject *)getJavaScriptObjectForSelf;
+ at end
+
+ at class WebJavaScriptObjectPrivate;
+ at interface WebJavaScriptObject : NSObject
+{
+    WebJavaScriptObjectPrivate *_private;
+}
+
+- (id)callMethodNamed:(NSString *)name withArguments:(NSArray *)args;
+- (id)evaluateScript:(NSString *)script;
+- (id)getPropertyNamed:(NSString *)name;
+- (void)setPropertyNamed:(NSString *)name value:(id)value;
+- (void)removePropertyNamed:(NSString *)name;
+- (NSString *)toString;
+- (id)getPropertyAtIndex:(unsigned int)index;
+- (void)setPropertyAtIndex:(unsigned int)index value:(id)value;
+ at end
+
+
+/*
+    Extensions to WebKit
+
+    /*
+        WebNativeObjectForInstance can be used to export an instance via the 
+        Netscape plugin extension API, NPP_GetNativeObjectForJavaScript().
+    */
+    NP_Object *WebNativeObjectForInstance (id instance);
+    id WebInstanceFromNativeObject (NP_Object *obj);
+
+    @protocol WebPluginViewFactory <NSObject>
+    ..
+    + (id)getObjectForJavaScript;
+    ..
+    @end
+
+    @protocol WebPluginContainer <NSObject>
+    ..
+    - (WebFrame *)getWebFrame;
+    ..
+    @end
+*/
+
+/*
+    Example usage:
+    
+    
+    Any ObjectiveC instance may be exported to JavaScript via setMember
+    or setSlot.  All the methods on the exported instance will be
+    automatically exposed.  A typical cocoa plugin would set it's interface via
+    getObjectForJavaScript in it's WebPluginViewFactory.  A non-Cocoa plugin
+    could expose it's interface using WebJavaScriptBindingObjectForInstance() and
+    the Netscape extension NPP_GetNativeObjectForJavaScript().
+
+    Alternatively, could publish it's interface by calling setProperty:value:
+    on a WebJavaScriptObject.
+
+    WebJavaScriptObject *window;
+    window = [[container getWebFrame] getJavaScriptObjectForWindow]
+    [window setProperty:@"Interactual" value:myInterface];
+
+    Assuming a class for myInterface is something like:
+
+    @interface InteractualInterface
+    ...
+    - (void)stop;
+    - (void)start;
+    - (void)setChapter:(int)chapterNumber;
+    ...
+    @end
+
+    from JavaScript the plugin's interface can then be accessed like
+    this:
+
+    Interactual.stop();
+    Interactual.setChapter_(10);
+    Interactual.start();
+
+
+
+*/
diff --git a/WebKit/WebKit.pbproj/project.pbxproj b/WebKit/WebKit.pbproj/project.pbxproj
index 8dcb245..f76610d 100644
--- a/WebKit/WebKit.pbproj/project.pbxproj
+++ b/WebKit/WebKit.pbproj/project.pbxproj
@@ -333,6 +333,7 @@
 				84311AF205EAB12B0088EDA4,
 				BE91866005EE618F0081354D,
 				BE91866105EE618F0081354D,
+				515B878F05F5348600EABBF9,
 			);
 			isa = PBXHeadersBuildPhase;
 			runOnlyForDeploymentPostprocessing = 0;
@@ -1303,6 +1304,20 @@
 				);
 			};
 		};
+		515B878E05F5348600EABBF9 = {
+			fileEncoding = 30;
+			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
+			path = NP_objc.h;
+			refType = 4;
+			sourceTree = "<group>";
+		};
+		515B878F05F5348600EABBF9 = {
+			fileRef = 515B878E05F5348600EABBF9;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
 		515E27CC0458C86500CA2D3A = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
@@ -2229,6 +2244,7 @@
 		};
 		848DFF410365F6FB00CA2ACA = {
 			children = (
+				515B878E05F5348600EABBF9,
 				F5F717220288493C018635CA,
 				F5F717230288493C018635CA,
 				F5A672B90263866E01000102,

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list