summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/script/api/qscriptengine.cpp30
-rw-r--r--src/script/api/qscriptengine_p.h6
-rw-r--r--src/script/api/qscriptvalue.cpp4
3 files changed, 23 insertions, 17 deletions
diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp
index f02ea52..e2999c1 100644
--- a/src/script/api/qscriptengine.cpp
+++ b/src/script/api/qscriptengine.cpp
@@ -1011,12 +1011,17 @@ JSC::JSValue QScriptEnginePrivate::arrayFromVariantList(JSC::ExecState *exec, co
return arr;
}
-QVariantList QScriptEnginePrivate::variantListFromArray(JSC::ExecState *exec, JSC::JSValue arr)
+QVariantList QScriptEnginePrivate::variantListFromArray(JSC::ExecState *exec, JSC::JSArray *arr)
{
+ QScriptEnginePrivate *eng = QScript::scriptEngineFromExec(exec);
+ if (eng->visitedConversionObjects.contains(arr))
+ return QVariantList(); // Avoid recursion.
+ eng->visitedConversionObjects.insert(arr);
QVariantList lst;
uint len = toUInt32(exec, property(exec, arr, exec->propertyNames().length));
for (uint i = 0; i < len; ++i)
lst.append(toVariant(exec, property(exec, arr, i)));
+ eng->visitedConversionObjects.remove(arr);
return lst;
}
@@ -1029,14 +1034,19 @@ JSC::JSValue QScriptEnginePrivate::objectFromVariantMap(JSC::ExecState *exec, co
return obj;
}
-QVariantMap QScriptEnginePrivate::variantMapFromObject(JSC::ExecState *exec, JSC::JSValue obj)
+QVariantMap QScriptEnginePrivate::variantMapFromObject(JSC::ExecState *exec, JSC::JSObject *obj)
{
+ QScriptEnginePrivate *eng = QScript::scriptEngineFromExec(exec);
+ if (eng->visitedConversionObjects.contains(obj))
+ return QVariantMap(); // Avoid recursion.
+ eng->visitedConversionObjects.insert(obj);
JSC::PropertyNameArray propertyNames(exec);
- JSC::asObject(obj)->getOwnPropertyNames(exec, propertyNames, JSC::IncludeDontEnumProperties);
+ obj->getOwnPropertyNames(exec, propertyNames, JSC::IncludeDontEnumProperties);
QVariantMap vmap;
JSC::PropertyNameArray::const_iterator it = propertyNames.begin();
for( ; it != propertyNames.end(); ++it)
vmap.insert(it->ustring(), toVariant(exec, property(exec, obj, *it)));
+ eng->visitedConversionObjects.remove(obj);
return vmap;
}
@@ -1661,16 +1671,10 @@ QVariant QScriptEnginePrivate::toVariant(JSC::ExecState *exec, JSC::JSValue valu
return QVariant(toRegExp(exec, value));
#endif
else if (isArray(value))
- return variantListFromArray(exec, value);
+ return variantListFromArray(exec, JSC::asArray(value));
else if (QScriptDeclarativeClass *dc = declarativeClass(value))
return dc->toVariant(declarativeObject(value));
- // try to convert to primitive
- JSC::JSValue savedException;
- saveException(exec, &savedException);
- JSC::JSValue prim = value.toPrimitive(exec);
- restoreException(exec, savedException);
- if (!prim.isObject())
- return toVariant(exec, prim);
+ return variantMapFromObject(exec, JSC::asObject(value));
} else if (value.isNumber()) {
return QVariant(toNumber(exec, value));
} else if (value.isString()) {
@@ -3129,12 +3133,12 @@ bool QScriptEnginePrivate::convertValue(JSC::ExecState *exec, JSC::JSValue value
} break;
case QMetaType::QVariantList:
if (isArray(value)) {
- *reinterpret_cast<QVariantList *>(ptr) = variantListFromArray(exec, value);
+ *reinterpret_cast<QVariantList *>(ptr) = variantListFromArray(exec, JSC::asArray(value));
return true;
} break;
case QMetaType::QVariantMap:
if (isObject(value)) {
- *reinterpret_cast<QVariantMap *>(ptr) = variantMapFromObject(exec, value);
+ *reinterpret_cast<QVariantMap *>(ptr) = variantMapFromObject(exec, JSC::asObject(value));
return true;
} break;
case QMetaType::QVariant:
diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h
index fd47208..56366e2 100644
--- a/src/script/api/qscriptengine_p.h
+++ b/src/script/api/qscriptengine_p.h
@@ -215,10 +215,10 @@ public:
static QStringList stringListFromArray(JSC::ExecState*, JSC::JSValue arr);
static JSC::JSValue arrayFromVariantList(JSC::ExecState*, const QVariantList &lst);
- static QVariantList variantListFromArray(JSC::ExecState*, JSC::JSValue arr);
+ static QVariantList variantListFromArray(JSC::ExecState*, JSC::JSArray *arr);
static JSC::JSValue objectFromVariantMap(JSC::ExecState*, const QVariantMap &vmap);
- static QVariantMap variantMapFromObject(JSC::ExecState*, JSC::JSValue obj);
+ static QVariantMap variantMapFromObject(JSC::ExecState*, JSC::JSObject *obj);
JSC::JSValue defaultPrototype(int metaTypeId) const;
void setDefaultPrototype(int metaTypeId, JSC::JSValue prototype);
@@ -378,6 +378,8 @@ public:
QHash<intptr_t, QScript::UStringSourceProviderWithFeedback*> loadedScripts;
QScriptValue m_currentException;
+ QSet<JSC::JSObject*> visitedConversionObjects;
+
#ifndef QT_NO_QOBJECT
QHash<QObject*, QScript::QObjectData*> m_qobjectData;
#endif
diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp
index 1310c8c..451d1b0 100644
--- a/src/script/api/qscriptvalue.cpp
+++ b/src/script/api/qscriptvalue.cpp
@@ -1215,8 +1215,8 @@ qsreal QScriptValue::toInteger() const
\row \o QObject Object \o A QVariant containing a pointer to the QObject.
\row \o Date Object \o A QVariant containing the date value (toDateTime()).
\row \o RegExp Object \o A QVariant containing the regular expression value (toRegExp()).
- \row \o Array Object \o The array is converted to a QVariantList.
- \row \o Object \o If the value is primitive, then the result is converted to a QVariant according to the above rules; otherwise, an invalid QVariant is returned.
+ \row \o Array Object \o The array is converted to a QVariantList. Each element is converted to a QVariant, recursively; cyclic references are not followed.
+ \row \o Object \o The object is converted to a QVariantMap. Each property is converted to a QVariant, recursively; cyclic references are not followed.
\endtable
\sa isVariant()