diff options
author | Kent Hansen <kent.hansen@nokia.com> | 2012-08-16 12:16:38 +0200 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-08-20 13:24:10 +0200 |
commit | 2791a13757912cfd0d5cc6a83f228fab5c1645ae (patch) | |
tree | b2af45be626615d645deb8a7240846c524c94828 /src/qml/qml | |
parent | 1af0e1ec5110e4226e2525970c5a2761e5c781f4 (diff) |
Get rid of engine-wide state of visited objects for type conversion
Pass the state through to internal conversion functions instead.
Change-Id: Ifab9a9472d7271ee5da103ed915427dfd4f2b15b
Reviewed-by: Michael Brasser <michael.brasser@nokia.com>
Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@nokia.com>
Diffstat (limited to 'src/qml/qml')
-rw-r--r-- | src/qml/qml/v8/qv8engine.cpp | 30 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8engine_p.h | 14 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8jsonwrapper.cpp | 34 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8jsonwrapper_p.h | 22 |
4 files changed, 58 insertions, 42 deletions
diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp index d86fc6b12f..96110ed847 100644 --- a/src/qml/qml/v8/qv8engine.cpp +++ b/src/qml/qml/v8/qv8engine.cpp @@ -924,18 +924,19 @@ v8::Local<v8::Array> QV8Engine::variantListToJS(const QVariantList &lst) // The result is a QVariantList with length equal to the length // of the JS Array, and elements being the JS Array's elements // converted to QVariants, recursively. -QVariantList QV8Engine::variantListFromJS(v8::Handle<v8::Array> jsArray) +QVariantList QV8Engine::variantListFromJS(v8::Handle<v8::Array> jsArray, + QSet<int> &visitedObjects) { QVariantList result; int hash = jsArray->GetIdentityHash(); - if (visitedConversionObjects.contains(hash)) + if (visitedObjects.contains(hash)) return result; // Avoid recursion. v8::HandleScope handleScope; - visitedConversionObjects.insert(hash); + visitedObjects.insert(hash); uint32_t length = jsArray->Length(); for (uint32_t i = 0; i < length; ++i) - result.append(variantFromJS(jsArray->Get(i))); - visitedConversionObjects.remove(hash); + result.append(variantFromJS(jsArray->Get(i), visitedObjects)); + visitedObjects.remove(hash); return result; } @@ -956,7 +957,8 @@ v8::Local<v8::Object> QV8Engine::variantMapToJS(const QVariantMap &vmap) // The result is a QVariantMap with keys being the property names // of the object, and values being the values of the JS object's // properties converted to QVariants, recursively. -QVariantMap QV8Engine::variantMapFromJS(v8::Handle<v8::Object> jsObject) +QVariantMap QV8Engine::variantMapFromJS(v8::Handle<v8::Object> jsObject, + QSet<int> &visitedObjects) { QVariantMap result; @@ -967,16 +969,17 @@ QVariantMap QV8Engine::variantMapFromJS(v8::Handle<v8::Object> jsObject) return result; int hash = jsObject->GetIdentityHash(); - if (visitedConversionObjects.contains(hash)) + if (visitedObjects.contains(hash)) return result; // Avoid recursion. - visitedConversionObjects.insert(hash); + visitedObjects.insert(hash); // TODO: Only object's own property names. Include non-enumerable properties. for (uint32_t i = 0; i < length; ++i) { v8::Handle<v8::Value> name = propertyNames->Get(i); - result.insert(QJSConverter::toString(name->ToString()), variantFromJS(jsObject->Get(name))); + result.insert(QJSConverter::toString(name->ToString()), + variantFromJS(jsObject->Get(name), visitedObjects)); } - visitedConversionObjects.remove(hash); + visitedObjects.remove(hash); return result; } @@ -1261,7 +1264,8 @@ v8::Handle<v8::Value> QV8Engine::variantToJS(const QVariant &value) // Date -> QVariant(QDateTime) // RegExp -> QVariant(QRegExp) // [Any other object] -> QVariantMap(...) -QVariant QV8Engine::variantFromJS(v8::Handle<v8::Value> value) +QVariant QV8Engine::variantFromJS(v8::Handle<v8::Value> value, + QSet<int> &visitedObjects) { Q_ASSERT(!value.IsEmpty()); if (value->IsUndefined()) @@ -1278,7 +1282,7 @@ QVariant QV8Engine::variantFromJS(v8::Handle<v8::Value> value) return QJSConverter::toString(value->ToString()); Q_ASSERT(value->IsObject()); if (value->IsArray()) - return variantListFromJS(v8::Handle<v8::Array>::Cast(value)); + return variantListFromJS(v8::Handle<v8::Array>::Cast(value), visitedObjects); if (value->IsDate()) return QJSConverter::toDateTime(v8::Handle<v8::Date>::Cast(value)); if (value->IsRegExp()) @@ -1287,7 +1291,7 @@ QVariant QV8Engine::variantFromJS(v8::Handle<v8::Value> value) return variantValue(value); if (isQObject(value)) return qVariantFromValue(qtObjectFromJS(value)); - return variantMapFromJS(value->ToObject()); + return variantMapFromJS(value->ToObject(), visitedObjects); } v8::Handle<v8::Value> QV8Engine::jsonValueToJS(const QJsonValue &value) diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h index 7b0afafe7f..d885c777f7 100644 --- a/src/qml/qml/v8/qv8engine_p.h +++ b/src/qml/qml/v8/qv8engine_p.h @@ -371,13 +371,16 @@ public: v8::Local<v8::Object> newVariant(const QVariant &variant); v8::Local<v8::Array> variantListToJS(const QVariantList &lst); - QVariantList variantListFromJS(v8::Handle<v8::Array> jsArray); + inline QVariantList variantListFromJS(v8::Handle<v8::Array> jsArray) + { QSet<int> visitedObjects; return variantListFromJS(jsArray, visitedObjects); } v8::Local<v8::Object> variantMapToJS(const QVariantMap &vmap); - QVariantMap variantMapFromJS(v8::Handle<v8::Object> jsObject); + inline QVariantMap variantMapFromJS(v8::Handle<v8::Object> jsObject) + { QSet<int> visitedObjects; return variantMapFromJS(jsObject, visitedObjects); } v8::Handle<v8::Value> variantToJS(const QVariant &value); - QVariant variantFromJS(v8::Handle<v8::Value> value); + inline QVariant variantFromJS(v8::Handle<v8::Value> value) + { QSet<int> visitedObjects; return variantFromJS(value, visitedObjects); } v8::Handle<v8::Value> jsonValueToJS(const QJsonValue &value); QJsonValue jsonValueFromJS(v8::Handle<v8::Value> value); @@ -405,7 +408,6 @@ public: int consoleCountHelper(const QString &file, quint16 line, quint16 column); QObject *qtObjectFromJS(v8::Handle<v8::Value> value); - QSet<int> visitedConversionObjects; static QDateTime qtDateTimeFromJsDate(double jsDate); @@ -472,6 +474,10 @@ protected: double qtDateTimeToJsDate(const QDateTime &dt); private: + QVariantList variantListFromJS(v8::Handle<v8::Array> jsArray, QSet<int> &visitedObjects); + QVariantMap variantMapFromJS(v8::Handle<v8::Object> jsObject, QSet<int> &visitedObjects); + QVariant variantFromJS(v8::Handle<v8::Value> value, QSet<int> &visitedObjects); + static v8::Persistent<v8::Object> *findOwnerAndStrength(QObject *object, bool *shouldBeStrong); typedef QScriptIntrusiveList<QJSValuePrivate, &QJSValuePrivate::m_node> ValueList; diff --git a/src/qml/qml/v8/qv8jsonwrapper.cpp b/src/qml/qml/v8/qv8jsonwrapper.cpp index ff8cc4faba..ff8b69f580 100644 --- a/src/qml/qml/v8/qv8jsonwrapper.cpp +++ b/src/qml/qml/v8/qv8jsonwrapper.cpp @@ -43,10 +43,6 @@ #include "qv8engine_p.h" #include "qjsconverter_impl_p.h" -#include <QtCore/qjsonarray.h> -#include <QtCore/qjsonobject.h> -#include <QtCore/qjsonvalue.h> - QT_BEGIN_NAMESPACE QV8JsonWrapper::QV8JsonWrapper() @@ -85,7 +81,8 @@ v8::Handle<v8::Value> QV8JsonWrapper::fromJsonValue(const QJsonValue &value) return v8::Undefined(); } -QJsonValue QV8JsonWrapper::toJsonValue(v8::Handle<v8::Value> value) +QJsonValue QV8JsonWrapper::toJsonValue(v8::Handle<v8::Value> value, + QSet<int> &visitedObjects) { if (value->IsString()) return QJsonValue(QJSConverter::toString(value.As<v8::String>())); @@ -94,9 +91,9 @@ QJsonValue QV8JsonWrapper::toJsonValue(v8::Handle<v8::Value> value) else if (value->IsBoolean()) return QJsonValue(value->BooleanValue()); else if (value->IsArray()) - return toJsonArray(value.As<v8::Array>()); + return toJsonArray(value.As<v8::Array>(), visitedObjects); else if (value->IsObject()) - return toJsonObject(value.As<v8::Object>()); + return toJsonObject(value.As<v8::Object>(), visitedObjects); else if (value->IsNull()) return QJsonValue(QJsonValue::Null); else @@ -111,7 +108,8 @@ v8::Local<v8::Object> QV8JsonWrapper::fromJsonObject(const QJsonObject &object) return v8object; } -QJsonObject QV8JsonWrapper::toJsonObject(v8::Handle<v8::Value> value) +QJsonObject QV8JsonWrapper::toJsonObject(v8::Handle<v8::Value> value, + QSet<int> &visitedObjects) { QJsonObject result; if (!value->IsObject() || value->IsArray() || value->IsFunction()) @@ -119,14 +117,14 @@ QJsonObject QV8JsonWrapper::toJsonObject(v8::Handle<v8::Value> value) v8::Handle<v8::Object> v8object(value.As<v8::Object>()); int hash = v8object->GetIdentityHash(); - if (m_visitedConversionObjects.contains(hash)) { + if (visitedObjects.contains(hash)) { // Avoid recursion. // For compatibility with QVariant{List,Map} conversion, we return an // empty object (and no error is thrown). return result; } - m_visitedConversionObjects.insert(hash); + visitedObjects.insert(hash); v8::Local<v8::Array> propertyNames = m_engine->getOwnPropertyNames(v8object); uint32_t length = propertyNames->Length(); @@ -134,10 +132,11 @@ QJsonObject QV8JsonWrapper::toJsonObject(v8::Handle<v8::Value> value) v8::Local<v8::Value> name = propertyNames->Get(i); v8::Local<v8::Value> propertyValue = v8object->Get(name); if (!propertyValue->IsFunction()) - result.insert(QJSConverter::toString(name->ToString()), toJsonValue(propertyValue)); + result.insert(QJSConverter::toString(name->ToString()), + toJsonValue(propertyValue, visitedObjects)); } - m_visitedConversionObjects.remove(hash); + visitedObjects.remove(hash); return result; } @@ -151,7 +150,8 @@ v8::Local<v8::Array> QV8JsonWrapper::fromJsonArray(const QJsonArray &array) return v8array; } -QJsonArray QV8JsonWrapper::toJsonArray(v8::Handle<v8::Value> value) +QJsonArray QV8JsonWrapper::toJsonArray(v8::Handle<v8::Value> value, + QSet<int> &visitedObjects) { QJsonArray result; if (!value->IsArray()) @@ -159,23 +159,23 @@ QJsonArray QV8JsonWrapper::toJsonArray(v8::Handle<v8::Value> value) v8::Handle<v8::Array> v8array(value.As<v8::Array>()); int hash = v8array->GetIdentityHash(); - if (m_visitedConversionObjects.contains(hash)) { + if (visitedObjects.contains(hash)) { // Avoid recursion. // For compatibility with QVariant{List,Map} conversion, we return an // empty array (and no error is thrown). return result; } - m_visitedConversionObjects.insert(hash); + visitedObjects.insert(hash); uint32_t length = v8array->Length(); for (uint32_t i = 0; i < length; ++i) { v8::Local<v8::Value> element = v8array->Get(i); if (!element->IsFunction()) - result.append(toJsonValue(element)); + result.append(toJsonValue(element, visitedObjects)); } - m_visitedConversionObjects.remove(hash); + visitedObjects.remove(hash); return result; } diff --git a/src/qml/qml/v8/qv8jsonwrapper_p.h b/src/qml/qml/v8/qv8jsonwrapper_p.h index 842a3aa5d5..887e1069f8 100644 --- a/src/qml/qml/v8/qv8jsonwrapper_p.h +++ b/src/qml/qml/v8/qv8jsonwrapper_p.h @@ -57,11 +57,11 @@ #include <QtCore/qset.h> #include <private/qv8_p.h> -QT_BEGIN_NAMESPACE +#include <QtCore/qjsonarray.h> +#include <QtCore/qjsonobject.h> +#include <QtCore/qjsonvalue.h> -class QJsonValue; -class QJsonObject; -class QJsonArray; +QT_BEGIN_NAMESPACE class QV8Engine; class QV8JsonWrapper @@ -74,17 +74,23 @@ public: void destroy(); v8::Handle<v8::Value> fromJsonValue(const QJsonValue &value); - QJsonValue toJsonValue(v8::Handle<v8::Value> value); + inline QJsonValue toJsonValue(v8::Handle<v8::Value> value) + { QSet<int> visitedObjects; return toJsonValue(value, visitedObjects); } v8::Local<v8::Object> fromJsonObject(const QJsonObject &object); - QJsonObject toJsonObject(v8::Handle<v8::Value> value); + inline QJsonObject toJsonObject(v8::Handle<v8::Value> value) + { QSet<int> visitedObjects; return toJsonObject(value, visitedObjects); } v8::Local<v8::Array> fromJsonArray(const QJsonArray &array); - QJsonArray toJsonArray(v8::Handle<v8::Value> value); + inline QJsonArray toJsonArray(v8::Handle<v8::Value> value) + { QSet<int> visitedObjects; return toJsonArray(value, visitedObjects); } private: + QJsonValue toJsonValue(v8::Handle<v8::Value> value, QSet<int> &visitedObjects); + QJsonObject toJsonObject(v8::Handle<v8::Value> value, QSet<int> &visitedObjects); + QJsonArray toJsonArray(v8::Handle<v8::Value> value, QSet<int> &visitedObjects); + QV8Engine *m_engine; - QSet<int> m_visitedConversionObjects; }; QT_END_NAMESPACE |