diff options
Diffstat (limited to 'WebCore/bridge/qt')
| -rw-r--r-- | WebCore/bridge/qt/qt_class.h | 2 | ||||
| -rw-r--r-- | WebCore/bridge/qt/qt_instance.cpp | 76 | ||||
| -rw-r--r-- | WebCore/bridge/qt/qt_instance.h | 5 | ||||
| -rw-r--r-- | WebCore/bridge/qt/qt_runtime.cpp | 37 | ||||
| -rw-r--r-- | WebCore/bridge/qt/qt_runtime.h | 6 |
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);} |
