aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/corelib/language/scriptengine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/corelib/language/scriptengine.cpp')
-rw-r--r--src/lib/corelib/language/scriptengine.cpp66
1 files changed, 60 insertions, 6 deletions
diff --git a/src/lib/corelib/language/scriptengine.cpp b/src/lib/corelib/language/scriptengine.cpp
index 11d41b5c2..a89949bf4 100644
--- a/src/lib/corelib/language/scriptengine.cpp
+++ b/src/lib/corelib/language/scriptengine.cpp
@@ -58,6 +58,7 @@
#include <tools/stlutils.h>
#include <tools/stringconstants.h>
+#include <QtCore/qdatetime.h>
#include <QtCore/qdebug.h>
#include <QtCore/qdiriterator.h>
#include <QtCore/qfile.h>
@@ -196,6 +197,10 @@ void ScriptEngine::reset()
JS_FreeValue(m_context, e.second);
m_jsFileCache.clear();
+ for (const JSValue &s : std::as_const(m_jsValueCache))
+ JS_FreeValue(m_context, s);
+ m_jsValueCache.clear();
+
for (auto it = m_evalResults.cbegin(); it != m_evalResults.cend(); ++it) {
for (int i = 0; i < it.value(); ++i)
JS_FreeValue(m_context, it.key());
@@ -481,6 +486,37 @@ void ScriptEngine::addInternalExtension(const char *name, JSValue ext)
m_internalExtensions.insert(QLatin1String(name), JS_DupValue(m_context, ext));
}
+JSValue ScriptEngine::asJsValue(const QVariant &v, quintptr id, bool frozen)
+{
+ switch (static_cast<QMetaType::Type>(v.userType())) {
+ case QMetaType::QByteArray:
+ return asJsValue(v.toByteArray());
+ case QMetaType::QString:
+ return asJsValue(v.toString());
+ case QMetaType::QStringList:
+ return asJsValue(v.toStringList());
+ case QMetaType::QVariantList:
+ return asJsValue(v.toList(), id, frozen);
+ case QMetaType::Int:
+ case QMetaType::UInt:
+ return JS_NewInt32(m_context, v.toInt());
+ case QMetaType::Long:
+ case QMetaType::ULong:
+ case QMetaType::LongLong:
+ case QMetaType::ULongLong:
+ return JS_NewInt64(m_context, v.toInt());
+ case QMetaType::Bool:
+ return JS_NewBool(m_context, v.toBool());
+ case QMetaType::QDateTime:
+ return JS_NewDate(
+ m_context, v.toDateTime().toString(Qt::ISODateWithMs).toUtf8().constData());
+ case QMetaType::QVariantMap:
+ return asJsValue(v.toMap(), id, frozen);
+ default:
+ return JS_UNDEFINED;
+ }
+}
+
JSValue ScriptEngine::asJsValue(const QByteArray &s)
{
return JS_NewArrayBufferCopy(
@@ -506,12 +542,21 @@ JSValue ScriptEngine::asJsValue(const QStringList &l)
return array;
}
-JSValue ScriptEngine::asJsValue(const QVariantMap &m)
+JSValue ScriptEngine::asJsValue(const QVariantMap &m, quintptr id, bool frozen)
{
+ const auto it = id ? m_jsValueCache.constFind(id) : m_jsValueCache.constEnd();
+ if (it != m_jsValueCache.constEnd())
+ return JS_DupValue(m_context, it.value());
+ frozen = id || frozen;
JSValue obj = JS_NewObject(m_context);
for (auto it = m.begin(); it != m.end(); ++it)
- setJsProperty(m_context, obj, it.key(), makeJsVariant(m_context, it.value()));
- return obj;
+ setJsProperty(m_context, obj, it.key(), asJsValue(it.value(), 0, frozen));
+ if (frozen)
+ JS_ObjectSeal(m_context, obj, true);
+ if (!id)
+ return obj;
+ m_jsValueCache[id] = obj;
+ return JS_DupValue(m_context, obj);
}
void ScriptEngine::setPropertyOnGlobalObject(const QString &property, JSValue value)
@@ -520,13 +565,22 @@ void ScriptEngine::setPropertyOnGlobalObject(const QString &property, JSValue va
setJsProperty(m_context, globalObject, property, value);
}
-JSValue ScriptEngine::asJsValue(const QVariantList &l)
+JSValue ScriptEngine::asJsValue(const QVariantList &l, quintptr id, bool frozen)
{
+ const auto it = id ? m_jsValueCache.constFind(id) : m_jsValueCache.constEnd();
+ if (it != m_jsValueCache.constEnd())
+ return JS_DupValue(m_context, it.value());
+ frozen = id || frozen;
JSValue array = JS_NewArray(m_context);
setJsProperty(m_context, array, QLatin1String("length"), JS_NewInt32(m_context, l.size()));
for (int i = 0; i < l.size(); ++i)
- JS_SetPropertyUint32(m_context, array, i, makeJsVariant(m_context, l.at(i)));
- return array;
+ JS_SetPropertyUint32(m_context, array, i, asJsValue(l.at(i), 0, frozen));
+ if (frozen)
+ JS_ObjectSeal(m_context, array, true);
+ if (!id)
+ return array;
+ m_jsValueCache[id] = array;
+ return JS_DupValue(m_context, array);
}
JSValue ScriptEngine::loadInternalExtension(const QString &uri)