summaryrefslogtreecommitdiffstats
path: root/WebCore/bridge/qt
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/bridge/qt')
-rw-r--r--WebCore/bridge/qt/qt_class.h2
-rw-r--r--WebCore/bridge/qt/qt_instance.cpp76
-rw-r--r--WebCore/bridge/qt/qt_instance.h5
-rw-r--r--WebCore/bridge/qt/qt_runtime.cpp37
-rw-r--r--WebCore/bridge/qt/qt_runtime.h6
5 files changed, 54 insertions, 72 deletions
diff --git a/WebCore/bridge/qt/qt_class.h b/WebCore/bridge/qt/qt_class.h
index 19d4207..dc6b130 100644
--- a/WebCore/bridge/qt/qt_class.h
+++ b/WebCore/bridge/qt/qt_class.h
@@ -26,7 +26,7 @@
QT_BEGIN_NAMESPACE
class QObject;
-class QMetaObject;
+struct QMetaObject;
QT_END_NAMESPACE
namespace JSC {
diff --git a/WebCore/bridge/qt/qt_instance.cpp b/WebCore/bridge/qt/qt_instance.cpp
index 506697a..c6185e9 100644
--- a/WebCore/bridge/qt/qt_instance.cpp
+++ b/WebCore/bridge/qt/qt_instance.cpp
@@ -43,30 +43,29 @@ namespace Bindings {
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(ExecState*, PassRefPtr<Instance>);
- ~QtRuntimeObjectImp();
- virtual void invalidate();
static const ClassInfo s_info;
- virtual void mark()
+ virtual void markChildren(MarkStack& markStack)
{
+ RuntimeObjectImp::markChildren(markStack);
QtInstance* instance = static_cast<QtInstance*>(getInternalInstance());
if (instance)
- instance->mark();
- RuntimeObjectImp::mark();
+ instance->markAggregate(markStack);
+ }
+
+ static PassRefPtr<Structure> createStructure(JSValue prototype)
+ {
+ return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags));
}
protected:
- void removeFromCache();
-
+ static const unsigned StructureFlags = RuntimeObjectImp::StructureFlags | OverridesMarkChildren;
+
private:
virtual const ClassInfo* classInfo() const { return &s_info; }
};
@@ -78,25 +77,6 @@ QtRuntimeObjectImp::QtRuntimeObjectImp(ExecState* exec, PassRefPtr<Instance> ins
{
}
-QtRuntimeObjectImp::~QtRuntimeObjectImp()
-{
- removeFromCache();
-}
-
-void QtRuntimeObjectImp::invalidate()
-{
- removeFromCache();
- RuntimeObjectImp::invalidate();
-}
-
-void QtRuntimeObjectImp::removeFromCache()
-{
- JSLock lock(SilenceAssertionsOnly);
- QtInstance* key = cachedObjects.key(this);
- if (key)
- cachedObjects.remove(key);
-}
-
// QtInstance
QtInstance::QtInstance(QObject* o, PassRefPtr<RootObject> rootObject, QScriptEngine::ValueOwnership ownership)
: Instance(rootObject)
@@ -112,7 +92,6 @@ QtInstance::~QtInstance()
{
JSLock lock(SilenceAssertionsOnly);
- cachedObjects.remove(this);
cachedInstances.remove(m_hashkey);
// clean up (unprotect from gc) the JSValues we've created
@@ -140,10 +119,17 @@ PassRefPtr<QtInstance> QtInstance::getQtInstance(QObject* o, PassRefPtr<RootObje
{
JSLock lock(SilenceAssertionsOnly);
- foreach(QtInstance* instance, cachedInstances.values(o)) {
- if (instance->rootObject() == rootObject)
- return instance;
- }
+ foreach(QtInstance* instance, cachedInstances.values(o))
+ if (instance->rootObject() == rootObject) {
+ // The garbage collector removes instances, but it may happen that the wrapped
+ // QObject dies before the gc kicks in. To handle that case we have to do an additional
+ // check if to see if the instance's wrapped object is still alive. If it isn't, then
+ // we have to create a new wrapper.
+ if (!instance->getObject())
+ cachedInstances.remove(instance->hashKey());
+ else
+ return instance;
+ }
RefPtr<QtInstance> ret = QtInstance::create(o, rootObject, ownership);
cachedInstances.insert(o, ret.get());
@@ -190,25 +176,19 @@ Class* QtInstance::getClass() const
return m_class;
}
-RuntimeObjectImp* QtInstance::createRuntimeObject(ExecState* exec)
+RuntimeObjectImp* QtInstance::newRuntimeObject(ExecState* exec)
{
JSLock lock(SilenceAssertionsOnly);
- RuntimeObjectImp* ret = static_cast<RuntimeObjectImp*>(cachedObjects.value(this));
- if (!ret) {
- ret = new (exec) QtRuntimeObjectImp(exec, this);
- cachedObjects.insert(this, ret);
- ret = static_cast<RuntimeObjectImp*>(cachedObjects.value(this));
- }
- return ret;
+ return new (exec) QtRuntimeObjectImp(exec, this);
}
-void QtInstance::mark()
+void QtInstance::markAggregate(MarkStack& markStack)
{
- if (m_defaultMethod && !m_defaultMethod->marked())
- m_defaultMethod->mark();
+ if (m_defaultMethod)
+ markStack.append(m_defaultMethod);
foreach(JSObject* val, m_methods.values()) {
- if (val && !val->marked())
- val->mark();
+ if (val)
+ markStack.append(val);
}
}
diff --git a/WebCore/bridge/qt/qt_instance.h b/WebCore/bridge/qt/qt_instance.h
index 23766b1..0afc6c7 100644
--- a/WebCore/bridge/qt/qt_instance.h
+++ b/WebCore/bridge/qt/qt_instance.h
@@ -40,7 +40,7 @@ public:
~QtInstance();
virtual Class* getClass() const;
- virtual RuntimeObjectImp* createRuntimeObject(ExecState*);
+ virtual RuntimeObjectImp* newRuntimeObject(ExecState*);
virtual void begin();
virtual void end();
@@ -48,7 +48,7 @@ public:
virtual JSValue valueOf(ExecState*) const;
virtual JSValue defaultValue(ExecState*, PreferredPrimitiveType) const;
- virtual void mark(); // This isn't inherited
+ void markAggregate(MarkStack&);
virtual JSValue invokeMethod(ExecState*, const MethodList&, const ArgList&);
@@ -59,6 +59,7 @@ public:
JSValue booleanValue() const;
QObject* getObject() const { return m_object; }
+ QObject* hashKey() const { return m_hashkey; }
static PassRefPtr<QtInstance> getQtInstance(QObject*, PassRefPtr<RootObject>, QScriptEngine::ValueOwnership ownership);
diff --git a/WebCore/bridge/qt/qt_runtime.cpp b/WebCore/bridge/qt/qt_runtime.cpp
index 6be119c..94749b4 100644
--- a/WebCore/bridge/qt/qt_runtime.cpp
+++ b/WebCore/bridge/qt/qt_runtime.cpp
@@ -20,6 +20,7 @@
#include "config.h"
#include "qt_runtime.h"
+#include "BooleanObject.h"
#include "DateInstance.h"
#include "DateMath.h"
#include "DatePrototype.h"
@@ -46,9 +47,9 @@
#include <JSFunction.h>
#include <limits.h>
#include <runtime.h>
+#include <runtime/Error.h>
#include <runtime_array.h>
#include <runtime_object.h>
-#include "BooleanObject.h"
// QtScript has these
Q_DECLARE_METATYPE(QObjectList);
@@ -456,8 +457,8 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type
case QMetaType::QTime:
if (type == Date) {
DateInstance* date = static_cast<DateInstance*>(object);
- WTF::GregorianDateTime gdt;
- date->getUTCTime(gdt);
+ GregorianDateTime gdt;
+ msToGregorianDateTime(exec, date->internalNumber(), true, gdt);
if (hint == QMetaType::QDateTime) {
ret = QDateTime(QDate(gdt.year + 1900, gdt.month + 1, gdt.monthDay), QTime(gdt.hour, gdt.minute, gdt.second), Qt::UTC);
dist = 0;
@@ -470,8 +471,8 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type
}
} else if (type == Number) {
double b = value.toNumber(exec);
- WTF::GregorianDateTime gdt;
- msToGregorianDateTime(b, true, gdt);
+ GregorianDateTime gdt;
+ msToGregorianDateTime(exec, b, true, gdt);
if (hint == QMetaType::QDateTime) {
ret = QDateTime(QDate(gdt.year + 1900, gdt.month + 1, gdt.monthDay), QTime(gdt.hour, gdt.minute, gdt.second), Qt::UTC);
dist = 6;
@@ -823,7 +824,7 @@ JSValue convertQVariantToValue(ExecState* exec, PassRefPtr<RootObject> root, con
}
// Dates specified this way are in local time (we convert DateTimes above)
- WTF::GregorianDateTime dt;
+ GregorianDateTime dt;
dt.year = date.year() - 1900;
dt.month = date.month() - 1;
dt.monthDay = date.day();
@@ -831,11 +832,9 @@ JSValue convertQVariantToValue(ExecState* exec, PassRefPtr<RootObject> root, con
dt.minute = time.minute();
dt.second = time.second();
dt.isDST = -1;
- double ms = WTF::gregorianDateTimeToMS(dt, time.msec(), /*inputIsUTC*/ false);
+ double ms = gregorianDateTimeToMS(exec, dt, time.msec(), /*inputIsUTC*/ false);
- DateInstance* instance = new (exec) DateInstance(exec->lexicalGlobalObject()->dateStructure());
- instance->setInternalValue(jsNumber(exec, trunc(ms)));
- return instance;
+ return new (exec) DateInstance(exec, trunc(ms));
}
if (type == QMetaType::QByteArray) {
@@ -1162,7 +1161,7 @@ static int findMethodIndex(ExecState* exec,
}
// If the native method requires more arguments than what was passed from JavaScript
- if (jsArgs.size() < (types.count() - 1)) {
+ if (jsArgs.size() + 1 < static_cast<unsigned>(types.count())) {
qMatchDebug() << "Match:too few args for" << method.signature();
tooFewArgs.append(index);
continue;
@@ -1185,7 +1184,7 @@ static int findMethodIndex(ExecState* exec,
bool converted = true;
int matchDistance = 0;
- for (int i = 0; converted && i < types.count() - 1; ++i) {
+ for (unsigned i = 0; converted && i + 1 < static_cast<unsigned>(types.count()); ++i) {
JSValue arg = i < jsArgs.size() ? jsArgs.at(i) : jsUndefined();
int argdistance = -1;
@@ -1202,7 +1201,7 @@ static int findMethodIndex(ExecState* exec,
qMatchDebug() << "Match: " << method.signature() << (converted ? "converted":"failed to convert") << "distance " << matchDistance;
if (converted) {
- if ((jsArgs.size() == types.count() - 1)
+ if ((jsArgs.size() + 1 == static_cast<unsigned>(types.count()))
&& (matchDistance == 0)) {
// perfect match, use this one
chosenIndex = index;
@@ -1328,17 +1327,17 @@ QtRuntimeMetaMethod::QtRuntimeMetaMethod(ExecState* exec, const Identifier& iden
d->m_allowPrivate = allowPrivate;
}
-void QtRuntimeMetaMethod::mark()
+void QtRuntimeMetaMethod::markChildren(MarkStack& markStack)
{
- QtRuntimeMethod::mark();
+ QtRuntimeMethod::markChildren(markStack);
QW_D(QtRuntimeMetaMethod);
if (d->m_connect)
- d->m_connect->mark();
+ markStack.append(d->m_connect);
if (d->m_disconnect)
- d->m_disconnect->mark();
+ markStack.append(d->m_disconnect);
}
-JSValue QtRuntimeMetaMethod::call(ExecState* exec, JSObject* functionObject, JSValue thisValue, const ArgList& args)
+JSValue QtRuntimeMetaMethod::call(ExecState* exec, JSObject* functionObject, JSValue, const ArgList& args)
{
QtRuntimeMetaMethodData* d = static_cast<QtRuntimeMetaMethod *>(functionObject)->d_func();
@@ -1436,7 +1435,7 @@ QtRuntimeConnectionMethod::QtRuntimeConnectionMethod(ExecState* exec, const Iden
d->m_isConnect = isConnect;
}
-JSValue QtRuntimeConnectionMethod::call(ExecState* exec, JSObject* functionObject, JSValue thisValue, const ArgList& args)
+JSValue QtRuntimeConnectionMethod::call(ExecState* exec, JSObject* functionObject, JSValue, const ArgList& args)
{
QtRuntimeConnectionMethodData* d = static_cast<QtRuntimeConnectionMethod *>(functionObject)->d_func();
diff --git a/WebCore/bridge/qt/qt_runtime.h b/WebCore/bridge/qt/qt_runtime.h
index 72d93eb..dc55f61 100644
--- a/WebCore/bridge/qt/qt_runtime.h
+++ b/WebCore/bridge/qt/qt_runtime.h
@@ -151,10 +151,12 @@ public:
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType));
+ return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags));
}
protected:
+ static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags | OverridesMarkChildren;
+
QtRuntimeMethodData *d_func() const {return d_ptr;}
QtRuntimeMethod(QtRuntimeMethodData *dd, ExecState *exec, const Identifier &n, PassRefPtr<QtInstance> inst);
QtRuntimeMethodData *d_ptr;
@@ -167,7 +169,7 @@ public:
virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
- virtual void mark();
+ virtual void markChildren(MarkStack& markStack);
protected:
QtRuntimeMetaMethodData* d_func() const {return reinterpret_cast<QtRuntimeMetaMethodData*>(d_ptr);}