diff options
Diffstat (limited to 'src/declarative')
-rw-r--r-- | src/declarative/qml/qdeclarativeintegercache_p.h | 4 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativepropertycache.cpp | 4 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativepropertycache_p.h | 6 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativetypenamecache_p.h | 4 | ||||
-rw-r--r-- | src/declarative/qml/v8/qhashedstring_p.h | 89 | ||||
-rw-r--r-- | src/declarative/qml/v8/qv8contextwrapper.cpp | 26 | ||||
-rw-r--r-- | src/declarative/qml/v8/qv8engine_p.h | 9 | ||||
-rw-r--r-- | src/declarative/qml/v8/qv8qobjectwrapper.cpp | 59 | ||||
-rw-r--r-- | src/declarative/qml/v8/qv8qobjectwrapper_p.h | 37 | ||||
-rw-r--r-- | src/declarative/qml/v8/qv8typewrapper.cpp | 12 |
10 files changed, 180 insertions, 70 deletions
diff --git a/src/declarative/qml/qdeclarativeintegercache_p.h b/src/declarative/qml/qdeclarativeintegercache_p.h index b6151ce1cc..a66457cede 100644 --- a/src/declarative/qml/qdeclarativeintegercache_p.h +++ b/src/declarative/qml/qdeclarativeintegercache_p.h @@ -70,7 +70,7 @@ public: void add(const QString &, int); int value(const QString &); - inline int value(v8::Handle<v8::String>); + inline int value(const QHashedV8String &); QString findId(int value) const; @@ -79,7 +79,7 @@ private: StringCache stringCache; }; -int QDeclarativeIntegerCache::value(v8::Handle<v8::String> name) +int QDeclarativeIntegerCache::value(const QHashedV8String &name) { int *result = stringCache.value(name); return result?*result:-1; diff --git a/src/declarative/qml/qdeclarativepropertycache.cpp b/src/declarative/qml/qdeclarativepropertycache.cpp index 783a66ef97..ace76166ee 100644 --- a/src/declarative/qml/qdeclarativepropertycache.cpp +++ b/src/declarative/qml/qdeclarativepropertycache.cpp @@ -412,7 +412,7 @@ QStringList QDeclarativePropertyCache::propertyNames() const QDeclarativePropertyCache::Data * QDeclarativePropertyCache::property(QDeclarativeEngine *engine, QObject *obj, - v8::Handle<v8::String> name, Data &local) + const QHashedV8String &name, Data &local) { // XXX Optimize for worker script case where engine isn't available QDeclarativePropertyCache *cache = 0; @@ -433,7 +433,7 @@ QDeclarativePropertyCache::property(QDeclarativeEngine *engine, QObject *obj, if (cache) { rv = cache->property(name); } else { - QString strname = QV8Engine::toStringStatic(name); + QString strname = QV8Engine::toStringStatic(name.string()); // QString strname = ep->v8engine.toString(name); local = QDeclarativePropertyCache::create(obj->metaObject(), strname); if (local.isValid()) diff --git a/src/declarative/qml/qdeclarativepropertycache_p.h b/src/declarative/qml/qdeclarativepropertycache_p.h index 87005eb8f4..b97c48b777 100644 --- a/src/declarative/qml/qdeclarativepropertycache_p.h +++ b/src/declarative/qml/qdeclarativepropertycache_p.h @@ -158,7 +158,7 @@ public: static Data create(const QMetaObject *, const QString &); - inline Data *property(v8::Handle<v8::String>) const; + inline Data *property(const QHashedV8String &) const; Data *property(const QString &) const; Data *property(int) const; Data *method(int) const; @@ -169,7 +169,7 @@ public: inline QDeclarativeEngine *qmlEngine() const; static Data *property(QDeclarativeEngine *, QObject *, const QString &, Data &); - static Data *property(QDeclarativeEngine *, QObject *, v8::Handle<v8::String>, Data &); + static Data *property(QDeclarativeEngine *, QObject *, const QHashedV8String &, Data &); protected: virtual void clear(); @@ -250,7 +250,7 @@ QDeclarativeEngine *QDeclarativePropertyCache::qmlEngine() const return engine; } -QDeclarativePropertyCache::Data *QDeclarativePropertyCache::property(v8::Handle<v8::String> str) const +QDeclarativePropertyCache::Data *QDeclarativePropertyCache::property(const QHashedV8String &str) const { QDeclarativePropertyCache::RData **rv = stringCache.value(str); return rv?*rv:0; diff --git a/src/declarative/qml/qdeclarativetypenamecache_p.h b/src/declarative/qml/qdeclarativetypenamecache_p.h index 97c69bae35..abf18ce384 100644 --- a/src/declarative/qml/qdeclarativetypenamecache_p.h +++ b/src/declarative/qml/qdeclarativetypenamecache_p.h @@ -86,7 +86,7 @@ public: void add(const QString &, QDeclarativeTypeNameCache *); Data *data(const QString &) const; - inline Data *data(v8::Handle<v8::String>) const; + inline Data *data(const QHashedV8String &) const; inline bool isEmpty() const; inline QDeclarativeMetaType::ModuleApiInstance *moduleApi() const; @@ -140,7 +140,7 @@ QDeclarativeMetaType::ModuleApiInstance *QDeclarativeTypeNameCache::moduleApi() return m_moduleApi; } -QDeclarativeTypeNameCache::Data *QDeclarativeTypeNameCache::data(v8::Handle<v8::String> name) const +QDeclarativeTypeNameCache::Data *QDeclarativeTypeNameCache::data(const QHashedV8String &name) const { return stringCache.value(name); } diff --git a/src/declarative/qml/v8/qhashedstring_p.h b/src/declarative/qml/v8/qhashedstring_p.h index acee03a9b5..ed00aea132 100644 --- a/src/declarative/qml/v8/qhashedstring_p.h +++ b/src/declarative/qml/v8/qhashedstring_p.h @@ -83,6 +83,26 @@ private: mutable quint32 m_hash; }; +class QHashedV8String +{ +public: + inline QHashedV8String(); + explicit inline QHashedV8String(v8::Handle<v8::String>); + inline QHashedV8String(const QHashedV8String &string); + inline QHashedV8String &operator=(const QHashedV8String &other); + + inline bool operator==(const QHashedV8String &string); + + inline quint32 hash() const; + inline int length() const; + inline v8::Handle<v8::String> string() const; + +private: + quint32 m_hash; + int m_length; + v8::Handle<v8::String> m_string; +}; + class QHashedStringRef { public: @@ -151,7 +171,7 @@ private: QStringHashData data; inline Node *findNode(const QHashedStringRef &) const; - inline Node *findNode(v8::Handle<v8::String> &, quint32) const; + inline Node *findNode(const QHashedV8String &) const; Node *createNode(const QHashedString &, const T &); public: @@ -172,8 +192,7 @@ public: inline T *value(const QString &) const; inline T *value(const QHashedString &) const; inline T *value(const QHashedStringRef &) const; - inline T *value(v8::Handle<v8::String> &) const; - inline T *value(v8::Handle<v8::String> &, quint32 hash) const; + inline T *value(const QHashedV8String &) const; inline bool contains(const QString &) const; inline bool contains(const QHashedString &) const; @@ -343,13 +362,15 @@ typename QStringHash<T>::Node *QStringHash<T>::findNode(const QHashedStringRef & } template<class T> -typename QStringHash<T>::Node *QStringHash<T>::findNode(v8::Handle<v8::String> &string, quint32 hash) const +typename QStringHash<T>::Node *QStringHash<T>::findNode(const QHashedV8String &string) const { QStringHashNode *node = 0; if (data.numBuckets) { + quint32 hash = string.hash(); node = data.buckets[hash % data.numBuckets]; - int length = string->Length(); - while (node && (length != node->key.length() || !string->Equals((uint16_t*)node->key.constData(), length))) + int length = string.length(); + while (node && (length != node->key.length() || hash != node->key.hash() || + !string.string()->Equals((uint16_t*)node->key.constData(), length))) node = node->next; } @@ -378,15 +399,9 @@ T *QStringHash<T>::value(const QHashedStringRef &key) const } template<class T> -T *QStringHash<T>::value(v8::Handle<v8::String> &key) const -{ - return value(key, (quint32)key->Hash()); -} - -template<class T> -T *QStringHash<T>::value(v8::Handle<v8::String> &key, quint32 hash) const +T *QStringHash<T>::value(const QHashedV8String &string) const { - Node *n = findNode(key, hash); + Node *n = findNode(string); return n?&n->value:0; } @@ -501,6 +516,52 @@ bool QHashedString::isUpper(const QChar &qc) ((c >= 'A' && c <= 'Z') || QChar::category(c) == QChar::Letter_Uppercase)); } +QHashedV8String::QHashedV8String() +: m_hash(0) +{ +} + +QHashedV8String::QHashedV8String(v8::Handle<v8::String> string) +: m_hash(string->Hash()), m_length(string->Length()), m_string(string) +{ + Q_ASSERT(!m_string.IsEmpty()); +} + +QHashedV8String::QHashedV8String(const QHashedV8String &string) +: m_hash(string.m_hash), m_length(string.m_length), m_string(string.m_string) +{ +} + +QHashedV8String &QHashedV8String::operator=(const QHashedV8String &other) +{ + m_hash = other.m_hash; + m_length = other.m_length; + m_string = other.m_string; + return *this; +} + +bool QHashedV8String::operator==(const QHashedV8String &string) +{ + return m_hash == string.m_hash && m_length == string.m_length && + m_string.IsEmpty() == m_string.IsEmpty() && + (m_string.IsEmpty() || m_string->StrictEquals(string.m_string)); +} + +quint32 QHashedV8String::hash() const +{ + return m_hash; +} + +int QHashedV8String::length() const +{ + return m_length; +} + +v8::Handle<v8::String> QHashedV8String::string() const +{ + return m_string; +} + QHashedStringRef::QHashedStringRef() : m_data(0), m_length(0), m_hash(0) { diff --git a/src/declarative/qml/v8/qv8contextwrapper.cpp b/src/declarative/qml/v8/qv8contextwrapper.cpp index f0e52b1d64..c8f4acf23f 100644 --- a/src/declarative/qml/v8/qv8contextwrapper.cpp +++ b/src/declarative/qml/v8/qv8contextwrapper.cpp @@ -260,9 +260,11 @@ v8::Handle<v8::Value> QV8ContextWrapper::Getter(v8::Local<v8::String> property, QV8Engine *engine = resource->engine; QObject *scopeObject = resource->scopeObject; + QHashedV8String propertystring(property); + if (context->imports && QV8Engine::startsWithUpper(property)) { // Search for attached properties, enums and imported scripts - QDeclarativeTypeNameCache::Data *data = context->imports->data(property); + QDeclarativeTypeNameCache::Data *data = context->imports->data(propertystring); if (data) { if (data->importedScriptIndex != -1) { @@ -286,7 +288,7 @@ v8::Handle<v8::Value> QV8ContextWrapper::Getter(v8::Local<v8::String> property, QV8QObjectWrapper *qobjectWrapper = engine->qobjectWrapper(); if (resource->secondaryScope) { - v8::Handle<v8::Value> result = qobjectWrapper->getProperty(resource->secondaryScope, property, + v8::Handle<v8::Value> result = qobjectWrapper->getProperty(resource->secondaryScope, propertystring, QV8QObjectWrapper::IgnoreRevision); if (!result.IsEmpty()) return result; } @@ -294,7 +296,7 @@ v8::Handle<v8::Value> QV8ContextWrapper::Getter(v8::Local<v8::String> property, while (context) { // Search context properties if (context->propertyNames) { - int propertyIdx = context->propertyNames->value(property); + int propertyIdx = context->propertyNames->value(propertystring); if (propertyIdx != -1) { typedef QDeclarativeEnginePrivate::CapturedProperty CapturedProperty; @@ -329,7 +331,7 @@ v8::Handle<v8::Value> QV8ContextWrapper::Getter(v8::Local<v8::String> property, // Search scope object if (scopeObject) { - v8::Handle<v8::Value> result = qobjectWrapper->getProperty(scopeObject, property, + v8::Handle<v8::Value> result = qobjectWrapper->getProperty(scopeObject, propertystring, QV8QObjectWrapper::CheckRevision); if (!result.IsEmpty()) return result; } @@ -338,7 +340,7 @@ v8::Handle<v8::Value> QV8ContextWrapper::Getter(v8::Local<v8::String> property, // Search context object if (context->contextObject) { - v8::Handle<v8::Value> result = qobjectWrapper->getProperty(context->contextObject, property, + v8::Handle<v8::Value> result = qobjectWrapper->getProperty(context->contextObject, propertystring, QV8QObjectWrapper::CheckRevision); if (!result.IsEmpty()) return result; } @@ -393,27 +395,31 @@ v8::Handle<v8::Value> QV8ContextWrapper::Setter(v8::Local<v8::String> property, QV8Engine *engine = resource->engine; QObject *scopeObject = resource->scopeObject; + QHashedV8String propertystring(property); + QV8QObjectWrapper *qobjectWrapper = engine->qobjectWrapper(); // Search scope object - if (resource->secondaryScope && qobjectWrapper->setProperty(resource->secondaryScope, property, value, - QV8QObjectWrapper::IgnoreRevision)) + if (resource->secondaryScope && + qobjectWrapper->setProperty(resource->secondaryScope, propertystring, value, + QV8QObjectWrapper::IgnoreRevision)) return value; while (context) { // Search context properties - if (context->propertyNames && -1 != context->propertyNames->value(property)) + if (context->propertyNames && -1 != context->propertyNames->value(propertystring)) return value; // Search scope object if (scopeObject && - qobjectWrapper->setProperty(scopeObject, property, value, QV8QObjectWrapper::CheckRevision)) + qobjectWrapper->setProperty(scopeObject, propertystring, value, QV8QObjectWrapper::CheckRevision)) return value; scopeObject = 0; // Search context object if (context->contextObject && - qobjectWrapper->setProperty(context->contextObject, property, value, QV8QObjectWrapper::CheckRevision)) + qobjectWrapper->setProperty(context->contextObject, propertystring, value, + QV8QObjectWrapper::CheckRevision)) return value; context = context->parent; diff --git a/src/declarative/qml/v8/qv8engine_p.h b/src/declarative/qml/v8/qv8engine_p.h index 7398944ff5..b29f465e95 100644 --- a/src/declarative/qml/v8/qv8engine_p.h +++ b/src/declarative/qml/v8/qv8engine_p.h @@ -429,12 +429,9 @@ v8::Handle<v8::Value> QV8Engine::newValueType(const QVariant &value, QDeclarativ // unqualified name in QV8ContextWrapper. bool QV8Engine::startsWithUpper(v8::Handle<v8::String> string) { - uint16_t buffer[2]; - int written = string->Write(buffer, 0, 1); - if (written == 0) return false; - uint16_t c = buffer[0]; - return ((c != '_' ) && (!(c >= 'a' && c <= 'z')) && - ((c >= 'A' && c <= 'Z') || QChar::category(c) == QChar::Letter_Uppercase)); + uint16_t c = string->GetCharacter(0); + return (c >= 'A' && c <= 'Z') || + (c > 127 && QChar::category(c) == QChar::Letter_Uppercase); } QV8Engine::Deletable *QV8Engine::extensionData(int index) const diff --git a/src/declarative/qml/v8/qv8qobjectwrapper.cpp b/src/declarative/qml/v8/qv8qobjectwrapper.cpp index 413a4a1181..e6c3b29bc5 100644 --- a/src/declarative/qml/v8/qv8qobjectwrapper.cpp +++ b/src/declarative/qml/v8/qv8qobjectwrapper.cpp @@ -207,6 +207,9 @@ void QV8QObjectWrapper::init(QV8Engine *engine) m_destroySymbol = qPersistentNew<v8::String>(v8::String::NewSymbol("destroy")); m_hiddenObject = qPersistentNew<v8::Object>(v8::Object::New()); + m_toStringString = QHashedV8String(m_toStringSymbol); + m_destroyString = QHashedV8String(m_destroySymbol); + { v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New(); ft->InstanceTemplate()->SetFallbackPropertyHandler(Getter, Setter, Query, 0, Enumerator); @@ -270,7 +273,7 @@ static v8::Handle<v8::Value> LoadProperty(QV8Engine *engine, QObject *object, } else if (property.isQList()) { return engine->listWrapper()->newList(object, property.coreIndex, property.propType); } else PROPERTY_LOAD(QReal, qreal, v8::Number::New) - else PROPERTY_LOAD(Int || property.isEnum(), int, v8::Number::New) + else PROPERTY_LOAD(Int || property.isEnum(), int, v8::Integer::New) else PROPERTY_LOAD(Bool, bool, v8::Boolean::New) else PROPERTY_LOAD(QString, QString, engine->toString) else PROPERTY_LOAD(UInt, uint, v8::Integer::NewFromUnsigned) @@ -294,7 +297,7 @@ static v8::Handle<v8::Value> LoadProperty(QV8Engine *engine, QObject *object, v8::Handle<v8::Value> QV8QObjectWrapper::GetProperty(QV8Engine *engine, QObject *object, v8::Handle<v8::Value> *objectHandle, - v8::Handle<v8::String> property, + const QHashedV8String &property, QV8QObjectWrapper::RevisionMode revisionMode) { // XXX More recent versions of V8 introduced "Callable" objects. It is possible that these @@ -321,15 +324,21 @@ v8::Handle<v8::Value> QV8QObjectWrapper::GetProperty(QV8Engine *engine, QObject } }; - if (engine->qobjectWrapper()->m_toStringSymbol->StrictEquals(property)) { + if (engine->qobjectWrapper()->m_toStringString == property) { return MethodClosure::create(engine, object, objectHandle, QOBJECT_TOSTRING_INDEX); - } else if (engine->qobjectWrapper()->m_destroySymbol->StrictEquals(property)) { + } else if (engine->qobjectWrapper()->m_destroyString == property) { return MethodClosure::create(engine, object, objectHandle, QOBJECT_DESTROY_INDEX); } QDeclarativePropertyCache::Data local; QDeclarativePropertyCache::Data *result = 0; - result = QDeclarativePropertyCache::property(engine->engine(), object, property, local); + { + QDeclarativeData *ddata = QDeclarativeData::get(object, false); + if (ddata && ddata->propertyCache) + result = ddata->propertyCache->property(property); + else + result = QDeclarativePropertyCache::property(engine->engine(), object, property, local); + } if (!result) return v8::Handle<v8::Value>(); @@ -447,11 +456,11 @@ static inline void StoreProperty(QV8Engine *engine, QObject *object, QDeclarativ } } -bool QV8QObjectWrapper::SetProperty(QV8Engine *engine, QObject *object, v8::Handle<v8::String> property, +bool QV8QObjectWrapper::SetProperty(QV8Engine *engine, QObject *object, const QHashedV8String &property, v8::Handle<v8::Value> value, QV8QObjectWrapper::RevisionMode revisionMode) { - if (engine->qobjectWrapper()->m_toStringSymbol->StrictEquals(property) || - engine->qobjectWrapper()->m_destroySymbol->StrictEquals(property)) + if (engine->qobjectWrapper()->m_toStringString == property || + engine->qobjectWrapper()->m_destroyString == property) return true; QDeclarativePropertyCache::Data local; @@ -469,7 +478,7 @@ bool QV8QObjectWrapper::SetProperty(QV8Engine *engine, QObject *object, v8::Hand if (!result->isWritable() && !result->isQList()) { QString error = QLatin1String("Cannot assign to read-only property \"") + - engine->toString(property) + QLatin1Char('\"'); + engine->toString(property.string()) + QLatin1Char('\"'); v8::ThrowException(v8::Exception::Error(engine->toString(error))); return true; } @@ -489,15 +498,19 @@ v8::Handle<v8::Value> QV8QObjectWrapper::Getter(v8::Local<v8::String> property, QObject *object = resource->object; + QHashedV8String propertystring(property); + QV8Engine *v8engine = resource->engine; - v8::Handle<v8::Value> result = GetProperty(v8engine, object, &This, property, QV8QObjectWrapper::IgnoreRevision); + v8::Handle<v8::Value> result = GetProperty(v8engine, object, &This, propertystring, + QV8QObjectWrapper::IgnoreRevision); if (!result.IsEmpty()) return result; if (QV8Engine::startsWithUpper(property)) { // Check for attached properties QDeclarativeContextData *context = v8engine->callingContext(); - QDeclarativeTypeNameCache::Data *data = context && (context->imports)?context->imports->data(property):0; + QDeclarativeTypeNameCache::Data *data = + context && (context->imports)?context->imports->data(propertystring):0; if (data) { if (data->type) { @@ -522,8 +535,10 @@ v8::Handle<v8::Value> QV8QObjectWrapper::Setter(v8::Local<v8::String> property, QObject *object = resource->object; + QHashedV8String propertystring(property); + QV8Engine *v8engine = resource->engine; - bool result = SetProperty(v8engine, object, property, value, QV8QObjectWrapper::IgnoreRevision); + bool result = SetProperty(v8engine, object, propertystring, value, QV8QObjectWrapper::IgnoreRevision); if (!result) { QString error = QLatin1String("Cannot assign to non-existent property \"") + @@ -546,9 +561,11 @@ v8::Handle<v8::Integer> QV8QObjectWrapper::Query(v8::Local<v8::String> property, QV8Engine *engine = resource->engine; QObject *object = resource->object; + QHashedV8String propertystring(property); + QDeclarativePropertyCache::Data local; QDeclarativePropertyCache::Data *result = 0; - result = QDeclarativePropertyCache::property(engine->engine(), object, property, local); + result = QDeclarativePropertyCache::property(engine->engine(), object, propertystring, local); if (!result) return v8::Handle<v8::Integer>(); @@ -643,7 +660,7 @@ static void FastValueSetterReadOnly(v8::Local<v8::String> property, v8::Local<v8 QV8Engine *v8engine = resource->engine; - QString error = QLatin1String("Cannot assign to non-existent property \"") + + QString error = QLatin1String("Cannot assign to read-only property \"") + v8engine->toString(property) + QLatin1Char('\"'); v8::ThrowException(v8::Exception::Error(v8engine->toString(error))); } @@ -1187,17 +1204,16 @@ v8::Handle<v8::Value> QV8QObjectWrapper::Disconnect(const v8::Arguments &args) } /*! + \fn v8::Handle<v8::Value> QV8QObjectWrapper::getProperty(QObject *object, const QHashedV8String &property, QV8QObjectWrapper::RevisionMode revisionMode) + Get the \a property of \a object. Returns an empty handle if the property doesn't exist. Only searches for real properties of \a object (including methods), not attached properties etc. */ -v8::Handle<v8::Value> QV8QObjectWrapper::getProperty(QObject *object, v8::Handle<v8::String> property, - QV8QObjectWrapper::RevisionMode revisionMode) -{ - return GetProperty(m_engine, object, 0, property, revisionMode); -} /* + \fn bool QV8QObjectWrapper::setProperty(QObject *object, const QHashedV8String &property, v8::Handle<v8::Value> value, RevisionMode revisionMode) + Set the \a property of \a object to \a value. Returns true if the property was "set" - even if this results in an exception being thrown - @@ -1205,11 +1221,6 @@ v8::Handle<v8::Value> QV8QObjectWrapper::getProperty(QObject *object, v8::Handle Only searches for real properties of \a object (including methods), not attached properties etc. */ -bool QV8QObjectWrapper::setProperty(QObject *object, v8::Handle<v8::String> property, - v8::Handle<v8::Value> value, RevisionMode revisionMode) -{ - return SetProperty(m_engine, object, property, value, revisionMode); -} namespace { struct CallArgs diff --git a/src/declarative/qml/v8/qv8qobjectwrapper_p.h b/src/declarative/qml/v8/qv8qobjectwrapper_p.h index 5100c3f51b..bc4eb443dc 100644 --- a/src/declarative/qml/v8/qv8qobjectwrapper_p.h +++ b/src/declarative/qml/v8/qv8qobjectwrapper_p.h @@ -58,6 +58,9 @@ #include <QtCore/qpair.h> #include <QtCore/qhash.h> #include <private/qv8_p.h> +#include <private/qhashedstring_p.h> +#include <private/qdeclarativedata_p.h> +#include <private/qdeclarativepropertycache_p.h> QT_BEGIN_NAMESPACE @@ -83,8 +86,8 @@ public: QObject *toQObject(QV8ObjectResource *); enum RevisionMode { IgnoreRevision, CheckRevision }; - v8::Handle<v8::Value> getProperty(QObject *, v8::Handle<v8::String>, RevisionMode); - bool setProperty(QObject *, v8::Handle<v8::String>, v8::Handle<v8::Value>, RevisionMode); + inline v8::Handle<v8::Value> getProperty(QObject *, const QHashedV8String &, RevisionMode); + inline bool setProperty(QObject *, const QHashedV8String &, v8::Handle<v8::Value>, RevisionMode); private: friend class QDeclarativePropertyCache; @@ -93,8 +96,8 @@ private: v8::Local<v8::Object> newQObject(QObject *, QDeclarativeData *, QV8Engine *); static v8::Handle<v8::Value> GetProperty(QV8Engine *, QObject *, v8::Handle<v8::Value> *, - v8::Handle<v8::String>, QV8QObjectWrapper::RevisionMode); - static bool SetProperty(QV8Engine *, QObject *, v8::Handle<v8::String>, + const QHashedV8String &, QV8QObjectWrapper::RevisionMode); + static bool SetProperty(QV8Engine *, QObject *, const QHashedV8String &, v8::Handle<v8::Value>, QV8QObjectWrapper::RevisionMode); static v8::Handle<v8::Value> Getter(v8::Local<v8::String> property, const v8::AccessorInfo &info); @@ -115,12 +118,38 @@ private: v8::Persistent<v8::Function> m_methodConstructor; v8::Persistent<v8::String> m_toStringSymbol; v8::Persistent<v8::String> m_destroySymbol; + QHashedV8String m_toStringString; + QHashedV8String m_destroyString; v8::Persistent<v8::Object> m_hiddenObject; QHash<QObject *, QV8QObjectConnectionList *> m_connections; typedef QHash<QObject *, QV8QObjectInstance *> TaintedHash; TaintedHash m_taintedObjects; }; +v8::Handle<v8::Value> QV8QObjectWrapper::getProperty(QObject *object, const QHashedV8String &string, + RevisionMode mode) +{ + QDeclarativeData *dd = QDeclarativeData::get(object, false); + if (!dd || !dd->propertyCache || m_toStringString == string || m_destroyString == string || + dd->propertyCache->property(string)) { + return GetProperty(m_engine, object, 0, string, mode); + } else { + return v8::Handle<v8::Value>(); + } +} + +bool QV8QObjectWrapper::setProperty(QObject *object, const QHashedV8String &string, + v8::Handle<v8::Value> value, RevisionMode mode) +{ + QDeclarativeData *dd = QDeclarativeData::get(object, false); + if (!dd || !dd->propertyCache || m_toStringString == string || m_destroyString == string || + dd->propertyCache->property(string)) { + return SetProperty(m_engine, object, string, value, mode); + } else { + return false; + } +} + QT_END_NAMESPACE #endif // QV8QOBJECTWRAPPER_P_H diff --git a/src/declarative/qml/v8/qv8typewrapper.cpp b/src/declarative/qml/v8/qv8typewrapper.cpp index 70af6037de..9aac7a30d7 100644 --- a/src/declarative/qml/v8/qv8typewrapper.cpp +++ b/src/declarative/qml/v8/qv8typewrapper.cpp @@ -130,6 +130,8 @@ v8::Handle<v8::Value> QV8TypeWrapper::Getter(v8::Local<v8::String> property, QV8Engine *v8engine = resource->engine; QObject *object = resource->object; + QHashedV8String propertystring(property); + if (resource->type) { QDeclarativeType *type = resource->type; @@ -153,7 +155,8 @@ v8::Handle<v8::Value> QV8TypeWrapper::Getter(v8::Local<v8::String> property, } else if (resource->object) { QObject *ao = qmlAttachedPropertiesObjectById(type->attachedPropertiesId(), object); if (ao) - return v8engine->qobjectWrapper()->getProperty(ao, property, QV8QObjectWrapper::IgnoreRevision); + return v8engine->qobjectWrapper()->getProperty(ao, propertystring, + QV8QObjectWrapper::IgnoreRevision); // Fall through to undefined } @@ -163,7 +166,7 @@ v8::Handle<v8::Value> QV8TypeWrapper::Getter(v8::Local<v8::String> property, } else if (resource->typeNamespace) { QDeclarativeTypeNameCache *typeNamespace = resource->typeNamespace; - QDeclarativeTypeNameCache::Data *d = typeNamespace->data(property); + QDeclarativeTypeNameCache::Data *d = typeNamespace->data(propertystring); Q_ASSERT(!d || !d->typeNamespace); // Nested namespaces not supported if (d && d->type) { @@ -197,12 +200,15 @@ v8::Handle<v8::Value> QV8TypeWrapper::Setter(v8::Local<v8::String> property, // XXX TODO: Implement writes to module API objects + QHashedV8String propertystring(property); + if (resource->type && resource->object) { QDeclarativeType *type = resource->type; QObject *object = resource->object; QObject *ao = qmlAttachedPropertiesObjectById(type->attachedPropertiesId(), object); if (ao) - v8engine->qobjectWrapper()->setProperty(ao, property, value, QV8QObjectWrapper::IgnoreRevision); + v8engine->qobjectWrapper()->setProperty(ao, propertystring, value, + QV8QObjectWrapper::IgnoreRevision); } return value; |