Reviewed by Anders Carlsson.
Add binding language type to Instance.
Allows runtime determination of the type of an
Instance, to allow safe casting. Doesn't actually
add any safe casting yet, though.
Add a helper function to get an Instance from a JSObject*.
Given an object and the expected binding language, see if
the JSObject actually wraps an Instance of the given type
and return it. Otherwise return 0.
Move RuntimeObjectImp creations into Instance.
Make the ctor protected, and Instance a friend class, so
that all creation of RuntimeObjectImps goes through
one place.
Remove copy ctor/assignment operator for QtInstance.
Instance itself is Noncopyable, so QtInstance doesn't
need to have these.
Add caching for QtInstance and associated RuntimeObjectImps.
Push any dealings with QtLanguage bindings into QtInstance,
and cache them there, rather than in the Instance layer. Add
a QtRuntimeObjectImp to help with caching.
* JavaScriptCore.exp:
* bindings/c/c_instance.h:
* bindings/jni/jni_instance.h:
* bindings/objc/objc_instance.h:
* bindings/qt/qt_instance.cpp:
(KJS::Bindings::QtRuntimeObjectImp::QtRuntimeObjectImp):
(KJS::Bindings::QtRuntimeObjectImp::~QtRuntimeObjectImp):
(KJS::Bindings::QtRuntimeObjectImp::invalidate):
(KJS::Bindings::QtRuntimeObjectImp::removeFromCache):
(KJS::Bindings::QtInstance::QtInstance):
(KJS::Bindings::QtInstance::~QtInstance):
(KJS::Bindings::QtInstance::getQtInstance):
(KJS::Bindings::QtInstance::getRuntimeObject):
* bindings/qt/qt_instance.h:
(KJS::Bindings::QtInstance::getBindingLanguage):
* bindings/runtime.cpp:
(KJS::Bindings::Instance::createBindingForLanguageInstance):
(KJS::Bindings::Instance::createRuntimeObject):
(KJS::Bindings::Instance::getInstance):
* bindings/runtime.h:
* bindings/runtime_object.h:
(KJS::RuntimeObjectImp::getInternalInstance):
2008-01-13 Michael Goddard <michael.goddard@trolltech.com>
Reviewed by Anders Carlsson.
Move RuntimeObjectImp creations into Instance.
Make the ctor protected, and Instance a friend class, so
that all creation of RuntimeObjectImps goes through
one place.
* bindings/js/kjs_dom.cpp:
(WebCore::getRuntimeObject):
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@29447
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2008-01-13 Michael Goddard <michael.goddard@trolltech.com>
+
+ Reviewed by Anders Carlsson.
+
+ Add binding language type to Instance.
+ Allows runtime determination of the type of an
+ Instance, to allow safe casting. Doesn't actually
+ add any safe casting yet, though.
+
+ Add a helper function to get an Instance from a JSObject*.
+ Given an object and the expected binding language, see if
+ the JSObject actually wraps an Instance of the given type
+ and return it. Otherwise return 0.
+
+ Move RuntimeObjectImp creations into Instance.
+ Make the ctor protected, and Instance a friend class, so
+ that all creation of RuntimeObjectImps goes through
+ one place.
+
+ Remove copy ctor/assignment operator for QtInstance.
+ Instance itself is Noncopyable, so QtInstance doesn't
+ need to have these.
+
+ Add caching for QtInstance and associated RuntimeObjectImps.
+ Push any dealings with QtLanguage bindings into QtInstance,
+ and cache them there, rather than in the Instance layer. Add
+ a QtRuntimeObjectImp to help with caching.
+
+ * JavaScriptCore.exp:
+ * bindings/c/c_instance.h:
+ * bindings/jni/jni_instance.h:
+ * bindings/objc/objc_instance.h:
+ * bindings/qt/qt_instance.cpp:
+ (KJS::Bindings::QtRuntimeObjectImp::QtRuntimeObjectImp):
+ (KJS::Bindings::QtRuntimeObjectImp::~QtRuntimeObjectImp):
+ (KJS::Bindings::QtRuntimeObjectImp::invalidate):
+ (KJS::Bindings::QtRuntimeObjectImp::removeFromCache):
+ (KJS::Bindings::QtInstance::QtInstance):
+ (KJS::Bindings::QtInstance::~QtInstance):
+ (KJS::Bindings::QtInstance::getQtInstance):
+ (KJS::Bindings::QtInstance::getRuntimeObject):
+ * bindings/qt/qt_instance.h:
+ (KJS::Bindings::QtInstance::getBindingLanguage):
+ * bindings/runtime.cpp:
+ (KJS::Bindings::Instance::createBindingForLanguageInstance):
+ (KJS::Bindings::Instance::createRuntimeObject):
+ (KJS::Bindings::Instance::getInstance):
+ * bindings/runtime.h:
+ * bindings/runtime_object.h:
+ (KJS::RuntimeObjectImp::getInternalInstance):
+
2008-01-12 Alp Toker <alp@atoker.com>
Reviewed by Mark Rowe.
__ZN3KJS16ParserRefCounted3refEv
__ZN3KJS16ParserRefCounted5derefEv
__ZN3KJS16RuntimeObjectImp4infoE
-__ZN3KJS16RuntimeObjectImpC1EPNS_8Bindings8InstanceE
__ZN3KJS17PropertyNameArray3addERKNS_10IdentifierE
__ZN3KJS19InternalFunctionImp4infoE
__ZN3KJS19InternalFunctionImpC2EPNS_17FunctionPrototypeERKNS_10IdentifierE
__ZN3KJS8Bindings23convertValueToObjcValueEPNS_9ExecStateEPNS_7JSValueENS0_13ObjcValueTypeE
__ZN3KJS8Bindings24findProtectingRootObjectEPNS_8JSObjectE
__ZN3KJS8Bindings8Instance18didExecuteFunctionEv
+__ZN3KJS8Bindings8Instance19createRuntimeObjectEPS1_
__ZN3KJS8Bindings8Instance21setDidExecuteFunctionEPFvPNS_9ExecStateEPNS_8JSObjectEE
__ZN3KJS8Bindings8Instance32createBindingForLanguageInstanceENS1_15BindingLanguageEPvN3WTF10PassRefPtrINS0_10RootObjectEEE
__ZN3KJS8Debugger12sourceUnusedEPNS_9ExecStateEi
NPObject *getObject() const { return _object; }
+ virtual BindingLanguage getBindingLanguage() const { return CLanguage; }
+
private:
mutable CClass *_class;
NPObject *_object;
JSValue *stringValue() const;
JSValue *numberValue() const;
JSValue *booleanValue() const;
-
+
+ virtual BindingLanguage getBindingLanguage() const { return JavaLanguage; }
+
private:
RefPtr<JObjectWrapper> _instance;
mutable JavaClass *_class;
JSLock lock;
JavaInstance* javaInstance = new JavaInstance(theObject, _rootObject);
- RuntimeObjectImp* newImp = new RuntimeObjectImp(javaInstance);
-
- return newImp;
+ return KJS::Bindings::Instance::createRuntimeObject(javaInstance);
}
void JavaJSObject::getListFromJArray(jobjectArray jArray, List& list) const
JSValue *stringValue() const;
JSValue *numberValue() const;
JSValue *booleanValue() const;
-
+
+ virtual BindingLanguage getBindingLanguage() const { return ObjectiveCLanguage; }
+
private:
RetainPtr<ObjectStructPtr> _instance;
mutable ObjcClass *_class;
#include "config.h"
#include "qt_instance.h"
+#include "list.h"
#include "qt_class.h"
#include "qt_runtime.h"
-#include "list.h"
+#include "runtime_object.h"
#include <qmetaobject.h>
#include <qdebug.h>
+#include <qhash.h>
namespace KJS {
namespace Bindings {
-QtInstance::QtInstance(QObject* o, PassRefPtr<RootObject> rootObject)
- : Instance(rootObject),
- _class(0),
- _object(o)
+// Cache QtInstances
+typedef QMultiHash<void*, QtInstance*> QObjectInstanceMap;
+static QObjectInstanceMap cachedInstances;
+
+// Cache JSObjects
+typedef QHash<QtInstance*, JSObject*> InstanceJSObjectMap;
+static InstanceJSObjectMap cachedObjects;
+
+// Derived RuntimeObject
+class QtRuntimeObjectImp : public RuntimeObjectImp {
+ public:
+ QtRuntimeObjectImp(Instance*);
+ ~QtRuntimeObjectImp();
+ virtual void invalidate();
+ protected:
+ void removeFromCache();
+};
+
+QtRuntimeObjectImp::QtRuntimeObjectImp(Instance* instance)
+ : RuntimeObjectImp(instance)
+{
+}
+
+QtRuntimeObjectImp::~QtRuntimeObjectImp()
{
+ removeFromCache();
}
-QtInstance::~QtInstance()
+void QtRuntimeObjectImp::invalidate()
{
+ removeFromCache();
+ RuntimeObjectImp::invalidate();
}
-QtInstance::QtInstance(const QtInstance& other)
- : Instance(other.rootObject()), _class(0), _object(other._object)
+void QtRuntimeObjectImp::removeFromCache()
{
+ JSLock lock;
+ QtInstance* key = cachedObjects.key(this);
+ if (key)
+ cachedObjects.remove(key);
}
-QtInstance& QtInstance::operator=(const QtInstance& other)
+// QtInstance
+QtInstance::QtInstance(QObject* o, PassRefPtr<RootObject> rootObject)
+ : Instance(rootObject)
+ , _class(0)
+ , _object(o)
+ , _hashkey(o)
{
- if (this == &other)
- return *this;
+}
- _object = other._object;
- _class = 0;
+QtInstance::~QtInstance()
+{
+ JSLock lock;
+ cachedObjects.remove(this);
+ cachedInstances.remove(_hashkey);
+}
- return *this;
+QtInstance* QtInstance::getQtInstance(QObject* o, PassRefPtr<RootObject> rootObject)
+{
+ JSLock lock;
+
+ foreach(QtInstance* instance, cachedInstances.values(o)) {
+ if (instance->rootObject() == rootObject)
+ return instance;
+ }
+
+ QtInstance* ret = new QtInstance(o, rootObject);
+ cachedInstances.insert(o, ret);
+
+ return ret;
+}
+
+JSObject* QtInstance::getRuntimeObject(QtInstance* instance)
+{
+ JSLock lock;
+ JSObject* ret = cachedObjects.value(instance);
+ if (!ret) {
+ ret = new QtRuntimeObjectImp(instance);
+ cachedObjects.insert(instance, ret);
+ }
+ return ret;
}
Class* QtInstance::getClass() const
class QtInstance : public Instance
{
public:
- QtInstance(QObject* instance, PassRefPtr<RootObject>);
-
~QtInstance ();
virtual Class* getClass() const;
- QtInstance (const QtInstance &other);
-
- QtInstance &operator=(const QtInstance &other);
-
virtual void begin();
virtual void end();
QObject* getObject() const { return _object; }
+ virtual BindingLanguage getBindingLanguage() const { return QtLanguage; }
+
+ static QtInstance* getQtInstance(QObject*, PassRefPtr<RootObject>);
+ static JSObject* getRuntimeObject(QtInstance*);
+
private:
+ QtInstance(QObject*, PassRefPtr<RootObject>); // Factory produced only..
mutable QtClass* _class;
QPointer<QObject> _object;
+ QObject* _hashkey;
};
} // namespace Bindings
#endif
#if PLATFORM(QT)
case Instance::QtLanguage: {
- newInstance = new Bindings::QtInstance((QObject *)nativeInstance, rootObject);
+ newInstance = Bindings::QtInstance::getQtInstance((QObject *)nativeInstance, rootObject);
break;
}
#endif
JSObject* Instance::createRuntimeObject(BindingLanguage language, void* nativeInstance, PassRefPtr<RootObject> rootObject)
{
Instance* instance = Instance::createBindingForLanguageInstance(language, nativeInstance, rootObject);
-
+
+ return createRuntimeObject(instance);
+}
+
+JSObject* Instance::createRuntimeObject(Instance* instance)
+{
+#if PLATFORM(QT)
+ if (instance->getBindingLanguage() == QtLanguage)
+ return QtInstance::getRuntimeObject(static_cast<QtInstance*>(instance));
+#endif
JSLock lock;
return new RuntimeObjectImp(instance);
}
-RootObject* Instance::rootObject() const
-{
+Instance* Instance::getInstance(JSObject* object, BindingLanguage language)
+{
+ if (!object)
+ return 0;
+ if (!object->inherits(&RuntimeObjectImp::info))
+ return 0;
+ Instance* instance = (static_cast<RuntimeObjectImp*>(object))->getInternalInstance();
+ if (!instance)
+ return 0;
+ if (instance->getBindingLanguage() != language)
+ return 0;
+ return instance;
+}
+
+RootObject* Instance::rootObject() const
+{
return _rootObject && _rootObject->isValid() ? _rootObject.get() : 0;
}
static Instance* createBindingForLanguageInstance(BindingLanguage, void* nativeInstance, PassRefPtr<RootObject>);
static JSObject* createRuntimeObject(BindingLanguage, void* nativeInstance, PassRefPtr<RootObject>);
+ static JSObject* createRuntimeObject(Instance*);
+
+ static Instance* getInstance(JSObject*, BindingLanguage);
void ref() { _refCount++; }
void deref()
virtual ~Instance();
+ virtual BindingLanguage getBindingLanguage() const = 0;
+
protected:
RefPtr<RootObject> _rootObject;
unsigned _refCount;
class RuntimeObjectImp : public JSObject {
public:
- RuntimeObjectImp(Bindings::Instance *i);
virtual ~RuntimeObjectImp();
const ClassInfo *classInfo() const { return &info; }
virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args);
virtual void getPropertyNames(ExecState*, PropertyNameArray&);
- void invalidate();
+ virtual void invalidate();
Bindings::Instance *getInternalInstance() const { return instance.get(); }
static JSObject* throwInvalidAccessError(ExecState*);
static const ClassInfo info;
+protected:
+ friend class Bindings::Instance;
+ RuntimeObjectImp(Bindings::Instance*); // Only allow Instances and derived classes to create us
+
private:
RuntimeObjectImp(); // prevent default construction
+2008-01-13 Michael Goddard <michael.goddard@trolltech.com>
+
+ Reviewed by Anders Carlsson.
+
+ Move RuntimeObjectImp creations into Instance.
+ Make the ctor protected, and Instance a friend class, so
+ that all creation of RuntimeObjectImps goes through
+ one place.
+
+ * bindings/js/kjs_dom.cpp:
+ (WebCore::getRuntimeObject):
+
2008-01-12 Rodney Dawes <dobey@wayofthemonkey.com>
Gtk debug build fix. Reviewed by Mark Rowe.
HTMLPlugInElement* plugInElement = static_cast<HTMLPlugInElement*>(n);
if (plugInElement->getInstance() && plugInElement->getInstance()->rootObject())
// The instance is owned by the PlugIn element.
- return new RuntimeObjectImp(plugInElement->getInstance());
+ return KJS::Bindings::Instance::createRuntimeObject(plugInElement->getInstance());
}
#endif