Fixed <rdar://problem/
3985118> DOM objects not being marshaled on JS->native calls
Re-factored how 'native' wrappers for JS objects are created. The interpreter now
creates these wrappers. The WebCore subclass of the interpreter now overrides
createLanguageInstanceForValue() and creates a DOM ObjC wrapper for DOM objects.
* WebCore.pbproj/project.pbxproj:
* khtml/ecma/kjs_binding.cpp:
(ScriptInterpreter::createLanguageInstanceForValue):
* khtml/ecma/kjs_binding.h:
* kwq/DOMUtility.mm: Added.
(KJS::ScriptInterpreter::createObjcInstanceForValue):
* kwq/KWQKHTMLPart.mm:
(KWQKHTMLPart::getAppletInstanceForView):
(getInstanceForView):
(KWQKHTMLPart::getEmbedInstanceForView):
(KWQKHTMLPart::getObjectInstanceForView):
JavaScriptCore:
Fixed <rdar://problem/
3985118> DOM objects not being marshaled on JS->native calls
Re-factored how 'native' wrappers for JS objects are created. The interpreter now
creates these wrappers. The WebCore subclass of the interpreter now overrides
createLanguageInstanceForValue() and creates a DOM ObjC wrapper for DOM objects.
Reviewed by Ken.
* bindings/c/c_utility.cpp:
(convertValueToNPVariant):
* bindings/jni/jni_instance.cpp:
(JavaInstance::invokeMethod):
* bindings/jni/jni_runtime.cpp:
(JavaField::valueFromInstance):
(JavaArray::valueAt):
* bindings/objc/WebScriptObject.mm:
(-[WebScriptObject _setExecutionContext:KJS::Bindings::]):
(+[WebScriptObject _convertValueToObjcValue:KJS::originExecutionContext:Bindings::executionContext:Bindings::]):
* bindings/objc/WebScriptObjectPrivate.h:
* bindings/objc/objc_utility.h:
* bindings/objc/objc_utility.mm:
(KJS::Bindings::convertObjcValueToValue):
(KJS::Bindings::createObjcInstanceForValue):
* bindings/runtime.cpp:
(Instance::createBindingForLanguageInstance):
(Instance::createRuntimeObject):
(Instance::createLanguageInstanceForValue):
* bindings/runtime.h:
* kjs/interpreter.cpp:
(Interpreter::createLanguageInstanceForValue):
* kjs/interpreter.h:
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@8585
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2005-02-11 Richard Williamson <rjw@apple.com>
+
+ Fixed <rdar://problem/3985118> DOM objects not being marshaled on JS->native calls
+
+ Re-factored how 'native' wrappers for JS objects are created. The interpreter now
+ creates these wrappers. The WebCore subclass of the interpreter now overrides
+ createLanguageInstanceForValue() and creates a DOM ObjC wrapper for DOM objects.
+
+ Reviewed by Ken.
+
+ * bindings/c/c_utility.cpp:
+ (convertValueToNPVariant):
+ * bindings/jni/jni_instance.cpp:
+ (JavaInstance::invokeMethod):
+ * bindings/jni/jni_objc.mm:
+ (KJS::Bindings::dispatchJNICall):
+ * bindings/jni/jni_runtime.cpp:
+ (JavaField::valueFromInstance):
+ (JavaArray::valueAt):
+ * bindings/objc/WebScriptObject.mm:
+ (-[WebScriptObject _setExecutionContext:KJS::Bindings::]):
+ (+[WebScriptObject _convertValueToObjcValue:KJS::originExecutionContext:Bindings::executionContext:Bindings::]):
+ * bindings/objc/WebScriptObjectPrivate.h:
+ * bindings/objc/objc_utility.h:
+ * bindings/objc/objc_utility.mm:
+ (KJS::Bindings::convertObjcValueToValue):
+ (KJS::Bindings::createObjcInstanceForValue):
+ * bindings/runtime.cpp:
+ (Instance::createBindingForLanguageInstance):
+ (Instance::createRuntimeObject):
+ (Instance::createLanguageInstanceForValue):
+ * bindings/runtime.h:
+ * kjs/interpreter.cpp:
+ (Interpreter::createLanguageInstanceForValue):
+ * kjs/interpreter.h:
+
=== Safari-186 ===
2005-02-10 Darin Adler <darin@apple.com>
executionContext = newExecutionContext;
}
- NPObject *obj = _NPN_CreateScriptObject (0, objectImp, originExecutionContext, executionContext);
+ NPObject *obj = (NPObject *)exec->interpreter()->createLanguageInstanceForValue (exec, Instance::CLanguage, value.toObject(exec), originExecutionContext, executionContext);
NPN_InitializeVariantWithObject (result, obj);
_NPN_ReleaseObject (obj);
}
resultValue = JavaArray::convertJObjectToArray (exec, result.l, arrayType, executionContext());
}
else {
- resultValue = Object(new RuntimeObjectImp(new JavaInstance (result.l, executionContext())));
+ resultValue = Instance::createRuntimeObject(Instance::JavaLanguage, result.l, executionContext());
}
}
else {
jsresult = JavaArray::convertJObjectToArray (exec, anObject, arrayType, instance->executionContext());
}
else {
- jsresult = KJS::Object(new RuntimeObjectImp(new JavaInstance ((jobject)anObject, instance->executionContext())));
+ jsresult = Instance::createRuntimeObject(Instance::JavaLanguage, anObject, instance->executionContext());
}
}
break;
return JavaArray::convertJObjectToArray (exec, anObject, _type+1, executionContext());
}
// or array of other object type?
- return KJS::Object(new RuntimeObjectImp(new JavaInstance ((jobject)anObject, executionContext())));
+ return Instance::createRuntimeObject(Instance::JavaLanguage, anObject, executionContext());
}
case boolean_type: {
return _private->executionContext;
}
+- (void)_setExecutionContext:(const KJS::Bindings::RootObject *)context
+{
+ _private->executionContext = context;
+}
+
+
- (const KJS::Bindings::RootObject *)_originExecutionContext
{
return _private->originExecutionContext;
exec->setException (err);
}
-+ (id)_convertValueToObjcValue:(KJS::Value)value originExecutionContext:(const Bindings::RootObject *)originExecutionContext executionContext:(const Bindings::RootObject *)root
++ (id)_convertValueToObjcValue:(KJS::Value)value originExecutionContext:(const Bindings::RootObject *)originExecutionContext executionContext:(const Bindings::RootObject *)executionContext
{
id result = 0;
// First see if we have a ObjC instance.
if (value.type() == KJS::ObjectType){
ObjectImp *objectImp = static_cast<ObjectImp*>(value.imp());
+ Interpreter *intepreter = executionContext->interpreter();
+ ExecState *exec = intepreter->globalExec();
if (objectImp->classInfo() != &KJS::RuntimeObjectImp::info) {
- Value runtimeObject = objectImp->get(root->interpreter()->globalExec(), "__apple_runtime_object");
+ Value runtimeObject = objectImp->get(exec, "__apple_runtime_object");
if (!runtimeObject.isNull() && runtimeObject.type() == KJS::ObjectType)
objectImp = static_cast<RuntimeObjectImp*>(runtimeObject.imp());
}
}
// Convert to a WebScriptObject
else {
- result = [[[WebScriptObject alloc] _initWithObjectImp:objectImp originExecutionContext:originExecutionContext executionContext:root] autorelease];
+ result = (id)intepreter->createLanguageInstanceForValue (exec, Instance::ObjectiveCLanguage, value.toObject(exec), originExecutionContext, executionContext);
}
}
- (void)_initializeWithObjectImp:(KJS::ObjectImp *)imp originExecutionContext:(const KJS::Bindings::RootObject *)originExecutionContext executionContext:(const KJS::Bindings::RootObject *)executionContext ;
- (void)_initializeScriptDOMNodeImp;
- (KJS::ObjectImp *)_imp;
+- (void)_setExecutionContext:(const KJS::Bindings::RootObject *)context;
- (const KJS::Bindings::RootObject *)_executionContext;
- (void)_setOriginExecutionContext:(const KJS::Bindings::RootObject *)originExecutionContext;
- (const KJS::Bindings::RootObject *)_originExecutionContext;
ObjcInvalidType
} ObjcValueType;
+class RootObject;
+
ObjcValue convertValueToObjcValue (KJS::ExecState *exec, const KJS::Value &value, ObjcValueType type);
Value convertNSStringToString(NSString *nsstring);
Value convertObjcValueToValue (KJS::ExecState *exec, void *buffer, ObjcValueType type);
void JSMethodNameToObjCMethodName(const char *name, char *name, unsigned int length);
+void *createObjcInstanceForValue (const Object &value, const RootObject *origin, const RootObject *current);
+
} // namespace Bindings
} // namespace KJS
return Undefined();
}
else {
- aValue = Object(new RuntimeObjectImp(new ObjcInstance (*obj)));
+ aValue = Instance::createRuntimeObject(Instance::ObjectiveCLanguage, (void *)*obj);
}
}
break;
}
+void *KJS::Bindings::createObjcInstanceForValue (const Object &value, const RootObject *origin, const RootObject *current)
+{
+ if (value.type() != ObjectType)
+ return 0;
+
+ ObjectImp *imp = static_cast<ObjectImp*>(value.imp());
+
+ return [[[WebScriptObject alloc] _initWithObjectImp:imp originExecutionContext:origin executionContext:current] autorelease];
+}
#include <jni_instance.h>
#include <objc_instance.h>
#include <c_instance.h>
+#include <NP_jsobject.h>
+#include <jni_jsobject.h>
using namespace KJS;
using namespace KJS::Bindings;
aField->setValueToInstance (exec, this, aValue);
}
-Instance *Instance::createBindingForLanguageInstance (BindingLanguage language, void *instance)
+Instance *Instance::createBindingForLanguageInstance (BindingLanguage language, void *nativeInstance, const RootObject *executionContext)
{
- if (language == Instance::JavaLanguage)
- return new Bindings::JavaInstance ((jobject)instance, 0);
- else if (language == Instance::ObjectiveCLanguage)
- return new Bindings::ObjcInstance ((struct objc_object *)instance);
-
- else if (language == Instance::CLanguage)
- return new Bindings::CInstance ((NPObject *)instance);
+ Instance *newInstance = 0;
+
+ switch (language) {
+ case Instance::JavaLanguage: {
+ newInstance = new Bindings::JavaInstance ((jobject)nativeInstance, executionContext);
+ break;
+ }
+ case Instance::ObjectiveCLanguage: {
+ newInstance = new Bindings::ObjcInstance ((struct objc_object *)nativeInstance);
+ break;
+ }
+ case Instance::CLanguage: {
+ newInstance = new Bindings::CInstance ((NPObject *)nativeInstance);
+ break;
+ }
+ default:
+ break;
+ }
- return 0;
+ if (newInstance)
+ newInstance->setExecutionContext (executionContext);
+
+ return newInstance;
}
-Object Instance::createRuntimeObject (BindingLanguage language, void *myInterface)
+Object Instance::createRuntimeObject (BindingLanguage language, void *nativeInstance, const RootObject *executionContext)
{
- Instance *interfaceObject = Instance::createBindingForLanguageInstance (language, (void *)myInterface);
+ Instance *interfaceObject = Instance::createBindingForLanguageInstance (language, (void *)nativeInstance, executionContext);
Interpreter::lock();
Object theObject(new RuntimeObjectImp(interfaceObject,true));
return theObject;
}
+void *Instance::createLanguageInstanceForValue (ExecState *exec, BindingLanguage language, const Object &value, const RootObject *origin, const RootObject *current)
+{
+ void *result = 0;
+
+ if (value.type() != ObjectType)
+ return 0;
+
+ ObjectImp *imp = static_cast<ObjectImp*>(value.imp());
+
+ switch (language) {
+ case Instance::ObjectiveCLanguage: {
+ result = createObjcInstanceForValue (value, origin, current);
+ break;
+ }
+ case Instance::CLanguage: {
+ result = _NPN_CreateScriptObject (0, imp, origin, current);
+ break;
+ }
+ case Instance::JavaLanguage: {
+ // FIXME: factor creation of jni_jsobjects, also remove unnecessary thread
+ // invocation code.
+ break;
+ }
+ default:
+ break;
+ }
+
+ return result;
+}
+
Instance::Instance (const Instance &other)
{
setExecutionContext (other.executionContext());
static void setDidExecuteFunction (KJSDidExecuteFunctionPtr func);
static KJSDidExecuteFunctionPtr didExecuteFunction ();
- static Instance *createBindingForLanguageInstance (BindingLanguage language, void *instance);
-
- static Object createRuntimeObject (BindingLanguage language, void *myInterface);
+ static Instance *createBindingForLanguageInstance (BindingLanguage language, void *nativeInstance, const RootObject *r = 0);
+ static void *createLanguageInstanceForValue (ExecState *exec, BindingLanguage language, const Object &value, const RootObject *origin, const RootObject *current);
+ static Object createRuntimeObject (BindingLanguage language, void *nativeInstance, const RootObject *r = 0);
Instance () : _executionContext(0) {};
const RootObject *executionContext() const { return _executionContext; }
virtual ~Instance() {};
-
+
protected:
const RootObject *_executionContext;
};
{
printExceptions = print;
}
+
+
+void *Interpreter::createLanguageInstanceForValue (ExecState *exec, Bindings::Instance::BindingLanguage language, const Object &value, const Bindings::RootObject *origin, const Bindings::RootObject *current)
+{
+ return Bindings::Instance::createLanguageInstanceForValue (exec, language, value, origin, current);
+}
+
#endif
void Interpreter::saveBuiltins (SavedBuiltins &builtins) const
#include "types.h"
#include "protect.h"
+#if APPLE_CHANGES
+
+#include "runtime.h"
+
+#endif
+
namespace KJS {
class ContextImp;
* not allowed unless isSafeScript returns true.
*/
virtual bool isSafeScript (const Interpreter *target) { return true; }
+
+ virtual void *createLanguageInstanceForValue (ExecState *exec, Bindings::Instance::BindingLanguage language, const Object &value, const Bindings::RootObject *origin, const Bindings::RootObject *current);
#endif
private:
+2005-02-11 Richard Williamson <rjw@apple.com>
+
+ Fixed <rdar://problem/3985118> DOM objects not being marshaled on JS->native calls
+
+ Re-factored how 'native' wrappers for JS objects are created. The interpreter now
+ creates these wrappers. The WebCore subclass of the interpreter now overrides
+ createLanguageInstanceForValue() and creates a DOM ObjC wrapper for DOM objects.
+
+ * WebCore.pbproj/project.pbxproj:
+ * khtml/ecma/kjs_binding.cpp:
+ (ScriptInterpreter::createLanguageInstanceForValue):
+ * khtml/ecma/kjs_binding.h:
+ * kwq/DOMUtility.mm: Added.
+ (KJS::ScriptInterpreter::createObjcInstanceForValue):
+ * kwq/KWQKHTMLPart.mm:
+ (KWQKHTMLPart::getAppletInstanceForView):
+ (getInstanceForView):
+ (KWQKHTMLPart::getEmbedInstanceForView):
+ (KWQKHTMLPart::getObjectInstanceForView):
+
2005-02-11 Chris Blumenberg <cblu@apple.com>
Fixed: <rdar://problem/3937352> Quote level not maintained when copied and pasted within a Mail message
939FF8EE0702B1B100979E5E,
BEA5DBDB075CEDA00098A432,
9378D9FB07640A46004B97BF,
+ 51111AC107BD812C00B7162C,
);
isa = PBXSourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
//512
//513
//514
+ 51111AC007BD812C00B7162C = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ lastKnownFileType = sourcecode.cpp.objcpp;
+ path = DOMUtility.mm;
+ refType = 4;
+ sourceTree = "<group>";
+ };
+ 51111AC107BD812C00B7162C = {
+ fileRef = 51111AC007BD812C00B7162C;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
5150C2A10702629000AF642C = {
fileEncoding = 30;
isa = PBXFileReference;
9321274F0606724900B62302,
932127510606724900B62302,
932127530606724900B62302,
+ 51111AC007BD812C00B7162C,
932127540606724900B62302,
931D7224065FC25900C966E1,
931D722A065FC40800C966E1,
const KJS::Window *win = static_cast<const KJS::Window *>(imp);
return win->interpreter();
}
+
+void *ScriptInterpreter::createLanguageInstanceForValue (ExecState *exec, Bindings::Instance::BindingLanguage language, const Object &value, const Bindings::RootObject *origin, const Bindings::RootObject *current)
+{
+ void *result = 0;
+
+ if (language == Bindings::Instance::ObjectiveCLanguage)
+ result = createObjcInstanceForValue (exec, value, origin, current);
+
+ if (!result)
+ result = Interpreter::createLanguageInstanceForValue (exec, language, value, origin, current);
+
+ return result;
+}
+
#endif
//////
#include <kjs/lookup.h>
#include <kjs/protect.h>
+#if APPLE_CHANGES
+#include <JavaScriptCore/runtime.h>
+#endif
+
class KHTMLPart;
namespace KJS {
virtual bool isGlobalObject(const Value &v);
virtual Interpreter *interpreterForGlobalObject (const ValueImp *imp);
virtual bool isSafeScript (const Interpreter *target);
+ virtual void *createLanguageInstanceForValue (ExecState *exec, Bindings::Instance::BindingLanguage language, const Object &value, const Bindings::RootObject *origin, const Bindings::RootObject *current);
+ void *createObjcInstanceForValue (ExecState *exec, const Object &value, const Bindings::RootObject *origin, const Bindings::RootObject *current);
#endif
private:
--- /dev/null
+/*
+ * 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.
+ */
+
+#import "kjs_binding.h"
+#import "kjs_dom.h"
+#import "DOM.h"
+#import "DOMInternal.h"
+
+#import <JavaScriptCore/WebScriptObjectPrivate.h>
+
+// This file makes use of the ObjC DOM API, and the C++ DOM API, so we need to be careful about what
+// headers are included to avoid naming conflicts.
+
+void *KJS::ScriptInterpreter::createObjcInstanceForValue (ExecState *exec, const Object &value, const KJS::Bindings::RootObject *origin, const KJS::Bindings::RootObject *current)
+{
+ if (value.inherits(&KJS::DOMNode::info)) {
+ KJS::DOMNode *imp = static_cast<KJS::DOMNode *>(value.imp());
+ DOM::Node node = imp->toNode();
+
+ id newObjcNode = [DOMNode _nodeWithImpl:node.handle()];
+ KJS::ObjectImp *scriptImp = static_cast<KJS::ObjectImp *>(KJS::getDOMNode (exec, node).imp());
+
+ [newObjcNode _initializeWithObjectImp:scriptImp originExecutionContext:origin executionContext:current];
+
+ return newObjcNode;
+ }
+ return 0;
+}
+
if (applet) {
// Wrap the Java instance in a language neutral binding and hand
// off ownership to the APPLET element.
- KJS::Bindings::Instance *instance = KJS::Bindings::Instance::createBindingForLanguageInstance (KJS::Bindings::Instance::JavaLanguage, applet);
-
- KJS::Bindings::RootObject *root = KJS::Bindings::RootObject::findRootObjectForNativeHandleFunction ()(aView);
- instance->setExecutionContext (root);
-
+ KJS::Bindings::RootObject *executionContext = KJS::Bindings::RootObject::findRootObjectForNativeHandleFunction ()(aView);
+ KJS::Bindings::Instance *instance = KJS::Bindings::Instance::createBindingForLanguageInstance (KJS::Bindings::Instance::JavaLanguage, applet, executionContext);
return instance;
}
- (void *)pluginScriptableObject;
@end
-KJS::Bindings::Instance *KWQKHTMLPart::getEmbedInstanceForView (NSView *aView)
+static KJS::Bindings::Instance *getInstanceForView(NSView *aView)
{
if ([aView respondsToSelector:@selector(objectForWebScript)]){
id object = [aView objectForWebScript];
- if (object)
- return KJS::Bindings::Instance::createBindingForLanguageInstance (KJS::Bindings::Instance::ObjectiveCLanguage, object);
+ if (object) {
+ KJS::Bindings::RootObject *executionContext = KJS::Bindings::RootObject::findRootObjectForNativeHandleFunction ()(aView);
+ return KJS::Bindings::Instance::createBindingForLanguageInstance (KJS::Bindings::Instance::ObjectiveCLanguage, object, executionContext);
+ }
}
else if ([aView respondsToSelector:@selector(pluginScriptableObject)]){
void *object = [aView pluginScriptableObject];
- if (object)
- return KJS::Bindings::Instance::createBindingForLanguageInstance (KJS::Bindings::Instance::CLanguage, object);
+ if (object) {
+ KJS::Bindings::RootObject *executionContext = KJS::Bindings::RootObject::findRootObjectForNativeHandleFunction ()(aView);
+ return KJS::Bindings::Instance::createBindingForLanguageInstance (KJS::Bindings::Instance::CLanguage, object, executionContext);
+ }
}
return 0;
}
+KJS::Bindings::Instance *KWQKHTMLPart::getEmbedInstanceForView (NSView *aView)
+{
+ return getInstanceForView(aView);
+}
+
KJS::Bindings::Instance *KWQKHTMLPart::getObjectInstanceForView (NSView *aView)
{
- if ([aView respondsToSelector:@selector(objectForWebScript)]){
- id object = [aView objectForWebScript];
- if (object)
- return KJS::Bindings::Instance::createBindingForLanguageInstance (KJS::Bindings::Instance::ObjectiveCLanguage, object);
- }
- else if ([aView respondsToSelector:@selector(pluginScriptableObject)]){
- void *object = [aView pluginScriptableObject];
- if (object)
- return KJS::Bindings::Instance::createBindingForLanguageInstance (KJS::Bindings::Instance::CLanguage, object);
- }
- return 0;
+ return getInstanceForView(aView);
}
void KWQKHTMLPart::addPluginRootObject(const KJS::Bindings::RootObject *root)