summaryrefslogtreecommitdiffstats
path: root/src/script/api/qscriptengine.cpp
diff options
context:
space:
mode:
authorKent Hansen <kent.hansen@nokia.com>2010-02-18 14:29:32 (GMT)
committerKent Hansen <kent.hansen@nokia.com>2010-02-18 16:36:22 (GMT)
commitd5af42b1b7d792188c689d5425493756f2dcb79e (patch)
tree3b0874e3409b53efe881171272cd1342cbf98515 /src/script/api/qscriptengine.cpp
parent8e0a364f7baed4bbc7ff711be2a15692a40c3e93 (diff)
downloadQt-d5af42b1b7d792188c689d5425493756f2dcb79e.zip
Qt-d5af42b1b7d792188c689d5425493756f2dcb79e.tar.gz
Qt-d5af42b1b7d792188c689d5425493756f2dcb79e.tar.bz2
Avoid calling out to public API in the QtScript implementation
There's no reason to construct QScriptValues when JSC::JSValues can be operated on directly. A benchmark showed that ~10% of the time for reading a QObject property from a script was spent just creating and destroying QScriptValue temporaries. It's time to finally get rid of this potential bottleneck, not just in the QObject integration but everywhere. This change refactors the code so that all internal operations are performed on JSC::JSValue (most importantly, conversion from/to Qt types), and the public API functions are just thin wrappers around these. E.g. instead of doing enginePrivate->scriptValueFromJSCValue(jsValue).toQObject() the implementation now does QScriptEnginePrivate::toQObject(jsValue) Other operations are delegated to the engine implementation in similar style. Task-number: QTBUG-8304 Reviewed-by: Jedrzej Nowacki
Diffstat (limited to 'src/script/api/qscriptengine.cpp')
-rw-r--r--src/script/api/qscriptengine.cpp487
1 files changed, 308 insertions, 179 deletions
diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp
index a045bab..739b3fc 100644
--- a/src/script/api/qscriptengine.cpp
+++ b/src/script/api/qscriptengine.cpp
@@ -54,6 +54,7 @@
#include "TimeoutChecker.h"
#include "JSFunction.h"
#include "Parser.h"
+#include "PropertyNameArray.h"
#include "Operations.h"
#include "bridge/qscriptfunction_p.h"
@@ -546,11 +547,9 @@ JSC::JSValue JSC_HOST_CALL functionDisconnect(JSC::ExecState *exec, JSC::JSObjec
if (isFunction(arg1))
slot = arg1;
else {
- // ### don't go via QScriptValue
QScript::SaveFrameHelper saveFrame(engine, exec);
- QScriptValue tmp = engine->scriptValueFromJSCValue(arg0);
- QString propertyName(arg1.toString(exec));
- slot = engine->scriptValueToJSCValue(tmp.property(propertyName, QScriptValue::ResolvePrototype));
+ QString propertyName(QScriptEnginePrivate::toString(exec, arg1));
+ slot = QScriptEnginePrivate::property(exec, arg0, propertyName, QScriptValue::ResolvePrototype);
}
}
@@ -630,11 +629,9 @@ JSC::JSValue JSC_HOST_CALL functionConnect(JSC::ExecState *exec, JSC::JSObject *
if (isFunction(arg1))
slot = arg1;
else {
- // ### don't go via QScriptValue
QScript::SaveFrameHelper saveFrame(engine, exec);
- QScriptValue tmp = engine->scriptValueFromJSCValue(arg0);
- QString propertyName = arg1.toString(exec);
- slot = engine->scriptValueToJSCValue(tmp.property(propertyName, QScriptValue::ResolvePrototype));
+ QString propertyName = QScriptEnginePrivate::toString(exec, arg1);
+ slot = QScriptEnginePrivate::property(exec, arg0, propertyName, QScriptValue::ResolvePrototype);
}
}
@@ -908,22 +905,15 @@ QScriptEnginePrivate::~QScriptEnginePrivate()
}
}
-QScriptValue QScriptEnginePrivate::scriptValueFromVariant(const QVariant &v)
-{
- QScriptValue result = create(v.userType(), v.data());
- Q_ASSERT(result.isValid());
- return result;
-}
-
-QVariant QScriptEnginePrivate::scriptValueToVariant(const QScriptValue &value, int targetType)
+QVariant QScriptEnginePrivate::jscValueToVariant(JSC::ExecState *exec, JSC::JSValue value, int targetType)
{
QVariant v(targetType, (void *)0);
- if (QScriptEnginePrivate::convert(value, targetType, v.data(), this))
+ if (convertValue(exec, value, targetType, v.data()))
return v;
if (uint(targetType) == QVariant::LastType)
- return value.toVariant();
- if (value.isVariant()) {
- v = value.toVariant();
+ return toVariant(exec, value);
+ if (isVariant(value)) {
+ v = variantValue(value);
if (v.canConvert(QVariant::Type(targetType))) {
v.convert(QVariant::Type(targetType));
return v;
@@ -934,88 +924,61 @@ QVariant QScriptEnginePrivate::scriptValueToVariant(const QScriptValue &value, i
return QVariant(targetType, *reinterpret_cast<void* *>(v.data()));
}
}
-
return QVariant();
}
-JSC::JSValue QScriptEnginePrivate::jscValueFromVariant(const QVariant &v)
-{
- // ### it's inefficient to convert to QScriptValue and then to JSValue
- QScriptValue vv = scriptValueFromVariant(v);
- QScriptValuePrivate *p = QScriptValuePrivate::get(vv);
- switch (p->type) {
- case QScriptValuePrivate::JavaScriptCore:
- return p->jscValue;
- case QScriptValuePrivate::Number:
- return JSC::jsNumber(currentFrame, p->numberValue);
- case QScriptValuePrivate::String: {
- JSC::UString str = p->stringValue;
- return JSC::jsString(currentFrame, str);
- }
- }
- return JSC::JSValue();
-}
-
-QVariant QScriptEnginePrivate::jscValueToVariant(JSC::JSValue value, int targetType)
+JSC::JSValue QScriptEnginePrivate::arrayFromStringList(JSC::ExecState *exec, const QStringList &lst)
{
- // ### it's inefficient to convert to QScriptValue and then to QVariant
- return scriptValueToVariant(scriptValueFromJSCValue(value), targetType);
-}
-
-QScriptValue QScriptEnginePrivate::arrayFromStringList(const QStringList &lst)
-{
- Q_Q(QScriptEngine);
- QScriptValue arr = q->newArray(lst.size());
+ JSC::JSValue arr = newArray(exec, lst.size());
for (int i = 0; i < lst.size(); ++i)
- arr.setProperty(i, QScriptValue(q, lst.at(i)));
+ setProperty(exec, arr, i, JSC::jsString(exec, lst.at(i)));
return arr;
}
-QStringList QScriptEnginePrivate::stringListFromArray(const QScriptValue &arr)
+QStringList QScriptEnginePrivate::stringListFromArray(JSC::ExecState *exec, JSC::JSValue arr)
{
QStringList lst;
- uint len = arr.property(QLatin1String("length")).toUInt32();
+ uint len = toUInt32(exec, property(exec, arr, exec->propertyNames().length));
for (uint i = 0; i < len; ++i)
- lst.append(arr.property(i).toString());
+ lst.append(toString(exec, property(exec, arr, i)));
return lst;
}
-QScriptValue QScriptEnginePrivate::arrayFromVariantList(const QVariantList &lst)
+JSC::JSValue QScriptEnginePrivate::arrayFromVariantList(JSC::ExecState *exec, const QVariantList &lst)
{
- Q_Q(QScriptEngine);
- QScriptValue arr = q->newArray(lst.size());
+ JSC::JSValue arr = newArray(exec, lst.size());
for (int i = 0; i < lst.size(); ++i)
- arr.setProperty(i, scriptValueFromVariant(lst.at(i)));
+ setProperty(exec, arr, i, jscValueFromVariant(exec, lst.at(i)));
return arr;
}
-QVariantList QScriptEnginePrivate::variantListFromArray(const QScriptValue &arr)
+QVariantList QScriptEnginePrivate::variantListFromArray(JSC::ExecState *exec, JSC::JSValue arr)
{
QVariantList lst;
- uint len = arr.property(QLatin1String("length")).toUInt32();
+ uint len = toUInt32(exec, property(exec, arr, exec->propertyNames().length));
for (uint i = 0; i < len; ++i)
- lst.append(arr.property(i).toVariant());
+ lst.append(toVariant(exec, property(exec, arr, i)));
return lst;
}
-QScriptValue QScriptEnginePrivate::objectFromVariantMap(const QVariantMap &vmap)
+JSC::JSValue QScriptEnginePrivate::objectFromVariantMap(JSC::ExecState *exec, const QVariantMap &vmap)
{
- Q_Q(QScriptEngine);
- QScriptValue obj = q->newObject();
+ JSC::JSValue obj = JSC::constructEmptyObject(exec);
QVariantMap::const_iterator it;
for (it = vmap.constBegin(); it != vmap.constEnd(); ++it)
- obj.setProperty(it.key(), scriptValueFromVariant(it.value()));
+ setProperty(exec, obj, it.key(), jscValueFromVariant(exec, it.value()));
return obj;
}
-QVariantMap QScriptEnginePrivate::variantMapFromObject(const QScriptValue &obj)
+QVariantMap QScriptEnginePrivate::variantMapFromObject(JSC::ExecState *exec, JSC::JSValue obj)
{
+ JSC::PropertyNameArray propertyNames(exec);
+ propertyNames.setShouldCache(false);
+ JSC::asObject(obj)->getOwnPropertyNames(exec, propertyNames, /*includeNonEnumerable=*/true);
QVariantMap vmap;
- QScriptValueIterator it(obj);
- while (it.hasNext()) {
- it.next();
- vmap.insert(it.name(), it.value().toVariant());
- }
+ JSC::PropertyNameArray::const_iterator it = propertyNames.begin();
+ for( ; it != propertyNames.end(); ++it)
+ vmap.insert(it->ustring(), toVariant(exec, property(exec, obj, *it)));
return vmap;
}
@@ -1344,13 +1307,13 @@ JSC::JSValue QScriptEnginePrivate::newQMetaObject(
return result;
}
-bool QScriptEnginePrivate::convertToNativeQObject(const QScriptValue &value,
+bool QScriptEnginePrivate::convertToNativeQObject(JSC::ExecState *exec, JSC::JSValue value,
const QByteArray &targetType,
void **result)
{
if (!targetType.endsWith('*'))
return false;
- if (QObject *qobject = value.toQObject()) {
+ if (QObject *qobject = toQObject(exec, value)) {
int start = targetType.startsWith("const ") ? 6 : 0;
QByteArray className = targetType.mid(start, targetType.size()-start-1);
if (void *instance = qobject->qt_metacast(className)) {
@@ -1577,6 +1540,76 @@ JSC::JSValue QScriptEnginePrivate::newVariant(const QVariant &value)
return obj;
}
+JSC::JSValue QScriptEnginePrivate::newVariant(JSC::JSValue objectValue,
+ const QVariant &value)
+{
+ if (!isObject(objectValue))
+ return newVariant(value);
+ JSC::JSObject *jscObject = JSC::asObject(objectValue);
+ if (!jscObject->inherits(&QScriptObject::info)) {
+ qWarning("QScriptEngine::newVariant(): changing class of non-QScriptObject not supported");
+ return JSC::JSValue();
+ }
+ QScriptObject *jscScriptObject = static_cast<QScriptObject*>(jscObject);
+ if (!isVariant(objectValue)) {
+ jscScriptObject->setDelegate(new QScript::QVariantDelegate(value));
+ } else {
+ setVariantValue(objectValue, value);
+ }
+ return objectValue;
+}
+
+#ifndef QT_NO_REGEXP
+
+QRegExp QScriptEnginePrivate::toRegExp(JSC::ExecState *exec, JSC::JSValue value)
+{
+ if (!isRegExp(value))
+ return QRegExp();
+ QString pattern = toString(exec, property(exec, value, QLatin1String("source"), QScriptValue::ResolvePrototype));
+ Qt::CaseSensitivity kase = Qt::CaseSensitive;
+ if (toBool(exec, property(exec, value, QLatin1String("ignoreCase"), QScriptValue::ResolvePrototype)))
+ kase = Qt::CaseInsensitive;
+ return QRegExp(pattern, kase, QRegExp::RegExp2);
+}
+
+#endif
+
+QVariant QScriptEnginePrivate::toVariant(JSC::ExecState *exec, JSC::JSValue value)
+{
+ if (isObject(value)) {
+ if (isVariant(value))
+ return variantValue(value);
+#ifndef QT_NO_QOBJECT
+ else if (isQObject(value))
+ return qVariantFromValue(toQObject(exec, value));
+#endif
+ else if (isDate(value))
+ return QVariant(toDateTime(exec, value));
+#ifndef QT_NO_REGEXP
+ else if (isRegExp(value))
+ return QVariant(toRegExp(exec, value));
+#endif
+ else if (isArray(value))
+ return variantListFromArray(exec, 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);
+ } else if (value.isNumber()) {
+ return QVariant(toNumber(exec, value));
+ } else if (value.isString()) {
+ return QVariant(toString(exec, value));
+ } else if (value.isBoolean()) {
+ return QVariant(toBool(exec, value));
+ }
+ return QVariant();
+}
+
JSC::JSValue QScriptEnginePrivate::propertyHelper(JSC::ExecState *exec, JSC::JSValue value, const JSC::Identifier &id, int resolveMode)
{
JSC::JSValue result;
@@ -1963,20 +1996,9 @@ QScriptValue QScriptEngine::newVariant(const QVariant &value)
QScriptValue QScriptEngine::newVariant(const QScriptValue &object,
const QVariant &value)
{
- if (!object.isObject())
- return newVariant(value);
- JSC::JSObject *jscObject = JSC::asObject(QScriptValuePrivate::get(object)->jscValue);
- if (!jscObject->inherits(&QScriptObject::info)) {
- qWarning("QScriptEngine::newVariant(): changing class of non-QScriptObject not supported");
- return QScriptValue();
- }
- QScriptObject *jscScriptObject = static_cast<QScriptObject*>(jscObject);
- if (!object.isVariant()) {
- jscScriptObject->setDelegate(new QScript::QVariantDelegate(value));
- } else {
- QScriptValuePrivate::get(object)->setVariantValue(value);
- }
- return object;
+ Q_D(QScriptEngine);
+ JSC::JSValue jsObject = d->scriptValueToJSCValue(object);
+ return d->scriptValueFromJSCValue(d->newVariant(jsObject, value));
}
#ifndef QT_NO_QOBJECT
@@ -2789,128 +2811,126 @@ void QScriptEngine::setDefaultPrototype(int metaTypeId, const QScriptValue &prot
QScriptValue QScriptEngine::create(int type, const void *ptr)
{
Q_D(QScriptEngine);
- return d->create(type, ptr);
+ return d->scriptValueFromJSCValue(d->create(d->currentFrame, type, ptr));
}
-QScriptValue QScriptEnginePrivate::create(int type, const void *ptr)
+JSC::JSValue QScriptEnginePrivate::create(JSC::ExecState *exec, int type, const void *ptr)
{
- Q_Q(QScriptEngine);
Q_ASSERT(ptr != 0);
- QScriptValue result;
- QScriptTypeInfo *info = m_typeInfos.value(type);
+ JSC::JSValue result;
+ QScriptEnginePrivate *eng = exec ? QScript::scriptEngineFromExec(exec) : 0;
+ QScriptTypeInfo *info = eng ? eng->m_typeInfos.value(type) : 0;
if (info && info->marshal) {
- result = info->marshal(q, ptr);
+ result = eng->scriptValueToJSCValue(info->marshal(eng->q_func(), ptr));
} else {
// check if it's one of the types we know
switch (QMetaType::Type(type)) {
case QMetaType::Void:
- return QScriptValue(q, QScriptValue::UndefinedValue);
+ return JSC::jsUndefined();
case QMetaType::Bool:
- return QScriptValue(q, *reinterpret_cast<const bool*>(ptr));
+ return JSC::jsBoolean(*reinterpret_cast<const bool*>(ptr));
case QMetaType::Int:
- return QScriptValue(q, *reinterpret_cast<const int*>(ptr));
+ return JSC::jsNumber(exec, *reinterpret_cast<const int*>(ptr));
case QMetaType::UInt:
- return QScriptValue(q, *reinterpret_cast<const uint*>(ptr));
+ return JSC::jsNumber(exec, *reinterpret_cast<const uint*>(ptr));
case QMetaType::LongLong:
- return QScriptValue(q, qsreal(*reinterpret_cast<const qlonglong*>(ptr)));
+ return JSC::jsNumber(exec, qsreal(*reinterpret_cast<const qlonglong*>(ptr)));
case QMetaType::ULongLong:
#if defined(Q_OS_WIN) && defined(_MSC_FULL_VER) && _MSC_FULL_VER <= 12008804
#pragma message("** NOTE: You need the Visual Studio Processor Pack to compile support for 64bit unsigned integers.")
- return QScriptValue(q, qsreal((qlonglong)*reinterpret_cast<const qulonglong*>(ptr)));
+ return JSC::jsNumber(exec, qsreal((qlonglong)*reinterpret_cast<const qulonglong*>(ptr)));
#elif defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
- return QScriptValue(q, qsreal((qlonglong)*reinterpret_cast<const qulonglong*>(ptr)));
+ return JSC::jsNumber(exec, qsreal((qlonglong)*reinterpret_cast<const qulonglong*>(ptr)));
#else
- return QScriptValue(q, qsreal(*reinterpret_cast<const qulonglong*>(ptr)));
+ return JSC::jsNumber(exec, qsreal(*reinterpret_cast<const qulonglong*>(ptr)));
#endif
case QMetaType::Double:
- return QScriptValue(q, qsreal(*reinterpret_cast<const double*>(ptr)));
+ return JSC::jsNumber(exec, qsreal(*reinterpret_cast<const double*>(ptr)));
case QMetaType::QString:
- return QScriptValue(q, *reinterpret_cast<const QString*>(ptr));
+ return JSC::jsString(exec, *reinterpret_cast<const QString*>(ptr));
case QMetaType::Float:
- return QScriptValue(q, *reinterpret_cast<const float*>(ptr));
+ return JSC::jsNumber(exec, *reinterpret_cast<const float*>(ptr));
case QMetaType::Short:
- return QScriptValue(q, *reinterpret_cast<const short*>(ptr));
+ return JSC::jsNumber(exec, *reinterpret_cast<const short*>(ptr));
case QMetaType::UShort:
- return QScriptValue(q, *reinterpret_cast<const unsigned short*>(ptr));
+ return JSC::jsNumber(exec, *reinterpret_cast<const unsigned short*>(ptr));
case QMetaType::Char:
- return QScriptValue(q, *reinterpret_cast<const char*>(ptr));
+ return JSC::jsNumber(exec, *reinterpret_cast<const char*>(ptr));
case QMetaType::UChar:
- return QScriptValue(q, *reinterpret_cast<const unsigned char*>(ptr));
+ return JSC::jsNumber(exec, *reinterpret_cast<const unsigned char*>(ptr));
case QMetaType::QChar:
- return QScriptValue(q, (*reinterpret_cast<const QChar*>(ptr)).unicode());
+ return JSC::jsNumber(exec, (*reinterpret_cast<const QChar*>(ptr)).unicode());
case QMetaType::QStringList:
- result = arrayFromStringList(*reinterpret_cast<const QStringList *>(ptr));
+ result = arrayFromStringList(exec, *reinterpret_cast<const QStringList *>(ptr));
break;
case QMetaType::QVariantList:
- result = arrayFromVariantList(*reinterpret_cast<const QVariantList *>(ptr));
+ result = arrayFromVariantList(exec, *reinterpret_cast<const QVariantList *>(ptr));
break;
case QMetaType::QVariantMap:
- result = objectFromVariantMap(*reinterpret_cast<const QVariantMap *>(ptr));
+ result = objectFromVariantMap(exec, *reinterpret_cast<const QVariantMap *>(ptr));
break;
case QMetaType::QDateTime:
- result = q->newDate(*reinterpret_cast<const QDateTime *>(ptr));
+ result = newDate(exec, *reinterpret_cast<const QDateTime *>(ptr));
break;
case QMetaType::QDate:
- result = q->newDate(QDateTime(*reinterpret_cast<const QDate *>(ptr)));
+ result = newDate(exec, QDateTime(*reinterpret_cast<const QDate *>(ptr)));
break;
#ifndef QT_NO_REGEXP
case QMetaType::QRegExp:
- result = q->newRegExp(*reinterpret_cast<const QRegExp *>(ptr));
+ result = newRegExp(exec, *reinterpret_cast<const QRegExp *>(ptr));
break;
#endif
#ifndef QT_NO_QOBJECT
case QMetaType::QObjectStar:
case QMetaType::QWidgetStar:
- result = q->newQObject(*reinterpret_cast<QObject* const *>(ptr));
+ result = eng->newQObject(*reinterpret_cast<QObject* const *>(ptr));
break;
#endif
default:
if (type == qMetaTypeId<QScriptValue>()) {
- result = *reinterpret_cast<const QScriptValue*>(ptr);
- if (!result.isValid())
- return QScriptValue(q, QScriptValue::UndefinedValue);
+ result = eng->scriptValueToJSCValue(*reinterpret_cast<const QScriptValue*>(ptr));
+ if (!result)
+ return JSC::jsUndefined();
}
#ifndef QT_NO_QOBJECT
// lazy registration of some common list types
else if (type == qMetaTypeId<QObjectList>()) {
- qScriptRegisterSequenceMetaType<QObjectList>(q);
- return create(type, ptr);
+ qScriptRegisterSequenceMetaType<QObjectList>(eng->q_func());
+ return create(exec, type, ptr);
}
#endif
else if (type == qMetaTypeId<QList<int> >()) {
- qScriptRegisterSequenceMetaType<QList<int> >(q);
- return create(type, ptr);
+ qScriptRegisterSequenceMetaType<QList<int> >(eng->q_func());
+ return create(exec, type, ptr);
}
else {
QByteArray typeName = QMetaType::typeName(type);
if (typeName == "QVariant")
- result = scriptValueFromVariant(*reinterpret_cast<const QVariant*>(ptr));
+ result = jscValueFromVariant(exec, *reinterpret_cast<const QVariant*>(ptr));
if (typeName.endsWith('*') && !*reinterpret_cast<void* const *>(ptr))
- return QScriptValue(q, QScriptValue::NullValue);
+ return JSC::jsNull();
else
- result = q->newVariant(QVariant(type, ptr));
+ result = eng->newVariant(QVariant(type, ptr));
}
}
}
- if (result.isObject() && info && info->prototype
- && JSC::JSValue::strictEqual(scriptValueToJSCValue(result.prototype()), originalGlobalObject()->objectPrototype())) {
- result.setPrototype(scriptValueFromJSCValue(info->prototype));
+ if (result && result.isObject() && info && info->prototype
+ && JSC::JSValue::strictEqual(JSC::asObject(result)->prototype(), eng->originalGlobalObject()->objectPrototype())) {
+ JSC::asObject(result)->setPrototype(info->prototype);
}
return result;
}
-bool QScriptEnginePrivate::convert(const QScriptValue &value,
- int type, void *ptr,
- QScriptEnginePrivate *eng)
+bool QScriptEnginePrivate::convertValue(JSC::ExecState *exec, JSC::JSValue value,
+ int type, void *ptr)
{
- if (!eng)
- eng = QScriptValuePrivate::getEngine(value);
+ QScriptEnginePrivate *eng = exec ? QScript::scriptEngineFromExec(exec) : 0;
if (eng) {
QScriptTypeInfo *info = eng->m_typeInfos.value(type);
if (info && info->demarshal) {
- info->demarshal(value, ptr);
+ info->demarshal(eng->scriptValueFromJSCValue(value), ptr);
return true;
}
}
@@ -2918,78 +2938,78 @@ bool QScriptEnginePrivate::convert(const QScriptValue &value,
// check if it's one of the types we know
switch (QMetaType::Type(type)) {
case QMetaType::Bool:
- *reinterpret_cast<bool*>(ptr) = value.toBoolean();
+ *reinterpret_cast<bool*>(ptr) = toBool(exec, value);
return true;
case QMetaType::Int:
- *reinterpret_cast<int*>(ptr) = value.toInt32();
+ *reinterpret_cast<int*>(ptr) = toInt32(exec, value);
return true;
case QMetaType::UInt:
- *reinterpret_cast<uint*>(ptr) = value.toUInt32();
+ *reinterpret_cast<uint*>(ptr) = toUInt32(exec, value);
return true;
case QMetaType::LongLong:
- *reinterpret_cast<qlonglong*>(ptr) = qlonglong(value.toInteger());
+ *reinterpret_cast<qlonglong*>(ptr) = qlonglong(toInteger(exec, value));
return true;
case QMetaType::ULongLong:
- *reinterpret_cast<qulonglong*>(ptr) = qulonglong(value.toInteger());
+ *reinterpret_cast<qulonglong*>(ptr) = qulonglong(toInteger(exec, value));
return true;
case QMetaType::Double:
- *reinterpret_cast<double*>(ptr) = value.toNumber();
+ *reinterpret_cast<double*>(ptr) = toNumber(exec, value);
return true;
case QMetaType::QString:
if (value.isUndefined() || value.isNull())
*reinterpret_cast<QString*>(ptr) = QString();
else
- *reinterpret_cast<QString*>(ptr) = value.toString();
+ *reinterpret_cast<QString*>(ptr) = toString(exec, value);
return true;
case QMetaType::Float:
- *reinterpret_cast<float*>(ptr) = value.toNumber();
+ *reinterpret_cast<float*>(ptr) = toNumber(exec, value);
return true;
case QMetaType::Short:
- *reinterpret_cast<short*>(ptr) = short(value.toInt32());
+ *reinterpret_cast<short*>(ptr) = short(toInt32(exec, value));
return true;
case QMetaType::UShort:
- *reinterpret_cast<unsigned short*>(ptr) = value.toUInt16();
+ *reinterpret_cast<unsigned short*>(ptr) = QScript::ToUInt16(toNumber(exec, value));
return true;
case QMetaType::Char:
- *reinterpret_cast<char*>(ptr) = char(value.toInt32());
+ *reinterpret_cast<char*>(ptr) = char(toInt32(exec, value));
return true;
case QMetaType::UChar:
- *reinterpret_cast<unsigned char*>(ptr) = (unsigned char)(value.toInt32());
+ *reinterpret_cast<unsigned char*>(ptr) = (unsigned char)(toInt32(exec, value));
return true;
case QMetaType::QChar:
if (value.isString()) {
- QString str = value.toString();
+ QString str = toString(exec, value);
*reinterpret_cast<QChar*>(ptr) = str.isEmpty() ? QChar() : str.at(0);
} else {
- *reinterpret_cast<QChar*>(ptr) = QChar(value.toUInt16());
+ *reinterpret_cast<QChar*>(ptr) = QChar(QScript::ToUInt16(toNumber(exec, value)));
}
return true;
case QMetaType::QDateTime:
- if (value.isDate()) {
- *reinterpret_cast<QDateTime *>(ptr) = value.toDateTime();
+ if (isDate(value)) {
+ *reinterpret_cast<QDateTime *>(ptr) = toDateTime(exec, value);
return true;
} break;
case QMetaType::QDate:
- if (value.isDate()) {
- *reinterpret_cast<QDate *>(ptr) = value.toDateTime().date();
+ if (isDate(value)) {
+ *reinterpret_cast<QDate *>(ptr) = toDateTime(exec, value).date();
return true;
} break;
#ifndef QT_NO_REGEXP
case QMetaType::QRegExp:
- if (value.isRegExp()) {
- *reinterpret_cast<QRegExp *>(ptr) = value.toRegExp();
+ if (isRegExp(value)) {
+ *reinterpret_cast<QRegExp *>(ptr) = toRegExp(exec, value);
return true;
} break;
#endif
#ifndef QT_NO_QOBJECT
case QMetaType::QObjectStar:
- if (value.isQObject() || value.isNull()) {
- *reinterpret_cast<QObject* *>(ptr) = value.toQObject();
+ if (isQObject(value) || value.isNull()) {
+ *reinterpret_cast<QObject* *>(ptr) = toQObject(exec, value);
return true;
} break;
case QMetaType::QWidgetStar:
- if (value.isQObject() || value.isNull()) {
- QObject *qo = value.toQObject();
+ if (isQObject(value) || value.isNull()) {
+ QObject *qo = toQObject(exec, value);
if (!qo || qo->isWidgetType()) {
*reinterpret_cast<QWidget* *>(ptr) = reinterpret_cast<QWidget*>(qo);
return true;
@@ -2997,18 +3017,18 @@ bool QScriptEnginePrivate::convert(const QScriptValue &value,
} break;
#endif
case QMetaType::QStringList:
- if (value.isArray()) {
- *reinterpret_cast<QStringList *>(ptr) = stringListFromArray(value);
+ if (isArray(value)) {
+ *reinterpret_cast<QStringList *>(ptr) = stringListFromArray(exec, value);
return true;
} break;
case QMetaType::QVariantList:
- if (value.isArray()) {
- *reinterpret_cast<QVariantList *>(ptr) = variantListFromArray(value);
+ if (isArray(value)) {
+ *reinterpret_cast<QVariantList *>(ptr) = variantListFromArray(exec, value);
return true;
} break;
case QMetaType::QVariantMap:
- if (value.isObject()) {
- *reinterpret_cast<QVariantMap *>(ptr) = variantMapFromObject(value);
+ if (isObject(value)) {
+ *reinterpret_cast<QVariantMap *>(ptr) = variantMapFromObject(exec, value);
return true;
} break;
default:
@@ -3017,28 +3037,28 @@ bool QScriptEnginePrivate::convert(const QScriptValue &value,
QByteArray name = QMetaType::typeName(type);
#ifndef QT_NO_QOBJECT
- if (convertToNativeQObject(value, name, reinterpret_cast<void* *>(ptr)))
+ if (convertToNativeQObject(exec, value, name, reinterpret_cast<void* *>(ptr)))
return true;
#endif
- if (value.isVariant() && name.endsWith('*')) {
+ if (isVariant(value) && name.endsWith('*')) {
int valueType = QMetaType::type(name.left(name.size()-1));
- QVariant &var = QScriptValuePrivate::get(value)->variantValue();
+ QVariant &var = variantValue(value);
if (valueType == var.userType()) {
*reinterpret_cast<void* *>(ptr) = var.data();
return true;
} else {
// look in the prototype chain
- QScriptValue proto = value.prototype();
+ JSC::JSValue proto = JSC::asObject(value)->prototype();
while (proto.isObject()) {
bool canCast = false;
- if (proto.isVariant()) {
- canCast = (type == proto.toVariant().userType())
- || (valueType && (valueType == proto.toVariant().userType()));
+ if (isVariant(proto)) {
+ canCast = (type == variantValue(proto).userType())
+ || (valueType && (valueType == variantValue(proto).userType()));
}
#ifndef QT_NO_QOBJECT
- else if (proto.isQObject()) {
+ else if (isQObject(proto)) {
QByteArray className = name.left(name.size()-1);
- if (QObject *qobject = proto.toQObject())
+ if (QObject *qobject = toQObject(exec, proto))
canCast = qobject->qt_metacast(className) != 0;
}
#endif
@@ -3050,7 +3070,7 @@ bool QScriptEnginePrivate::convert(const QScriptValue &value,
*reinterpret_cast<void* *>(ptr) = var.data();
return true;
}
- proto = proto.prototype();
+ proto = JSC::asObject(proto)->prototype();
}
}
} else if (value.isNull() && name.endsWith('*')) {
@@ -3059,10 +3079,10 @@ bool QScriptEnginePrivate::convert(const QScriptValue &value,
} else if (type == qMetaTypeId<QScriptValue>()) {
if (!eng)
return false;
- *reinterpret_cast<QScriptValue*>(ptr) = value;
+ *reinterpret_cast<QScriptValue*>(ptr) = eng->scriptValueFromJSCValue(value);
return true;
} else if (name == "QVariant") {
- *reinterpret_cast<QVariant*>(ptr) = value.toVariant();
+ *reinterpret_cast<QVariant*>(ptr) = toVariant(exec, value);
return true;
}
@@ -3072,14 +3092,14 @@ bool QScriptEnginePrivate::convert(const QScriptValue &value,
if (!eng)
return false;
qScriptRegisterSequenceMetaType<QObjectList>(eng->q_func());
- return convert(value, type, ptr, eng);
+ return convertValue(exec, value, type, ptr);
}
#endif
else if (type == qMetaTypeId<QList<int> >()) {
if (!eng)
return false;
qScriptRegisterSequenceMetaType<QList<int> >(eng->q_func());
- return convert(value, type, ptr, eng);
+ return convertValue(exec, value, type, ptr);
}
#if 0
@@ -3091,6 +3111,102 @@ bool QScriptEnginePrivate::convert(const QScriptValue &value,
return false;
}
+bool QScriptEnginePrivate::convertNumber(qsreal value, int type, void *ptr)
+{
+ switch (QMetaType::Type(type)) {
+ case QMetaType::Bool:
+ *reinterpret_cast<bool*>(ptr) = QScript::ToBool(value);
+ return true;
+ case QMetaType::Int:
+ *reinterpret_cast<int*>(ptr) = QScript::ToInt32(value);
+ return true;
+ case QMetaType::UInt:
+ *reinterpret_cast<uint*>(ptr) = QScript::ToUInt32(value);
+ return true;
+ case QMetaType::LongLong:
+ *reinterpret_cast<qlonglong*>(ptr) = qlonglong(QScript::ToInteger(value));
+ return true;
+ case QMetaType::ULongLong:
+ *reinterpret_cast<qulonglong*>(ptr) = qulonglong(QScript::ToInteger(value));
+ return true;
+ case QMetaType::Double:
+ *reinterpret_cast<double*>(ptr) = value;
+ return true;
+ case QMetaType::QString:
+ *reinterpret_cast<QString*>(ptr) = QScript::ToString(value);
+ return true;
+ case QMetaType::Float:
+ *reinterpret_cast<float*>(ptr) = value;
+ return true;
+ case QMetaType::Short:
+ *reinterpret_cast<short*>(ptr) = short(QScript::ToInt32(value));
+ return true;
+ case QMetaType::UShort:
+ *reinterpret_cast<unsigned short*>(ptr) = QScript::ToUInt16(value);
+ return true;
+ case QMetaType::Char:
+ *reinterpret_cast<char*>(ptr) = char(QScript::ToInt32(value));
+ return true;
+ case QMetaType::UChar:
+ *reinterpret_cast<unsigned char*>(ptr) = (unsigned char)(QScript::ToInt32(value));
+ return true;
+ case QMetaType::QChar:
+ *reinterpret_cast<QChar*>(ptr) = QChar(QScript::ToUInt16(value));
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
+bool QScriptEnginePrivate::convertString(const QString &value, int type, void *ptr)
+{
+ switch (QMetaType::Type(type)) {
+ case QMetaType::Bool:
+ *reinterpret_cast<bool*>(ptr) = QScript::ToBool(value);
+ return true;
+ case QMetaType::Int:
+ *reinterpret_cast<int*>(ptr) = QScript::ToInt32(value);
+ return true;
+ case QMetaType::UInt:
+ *reinterpret_cast<uint*>(ptr) = QScript::ToUInt32(value);
+ return true;
+ case QMetaType::LongLong:
+ *reinterpret_cast<qlonglong*>(ptr) = qlonglong(QScript::ToInteger(value));
+ return true;
+ case QMetaType::ULongLong:
+ *reinterpret_cast<qulonglong*>(ptr) = qulonglong(QScript::ToInteger(value));
+ return true;
+ case QMetaType::Double:
+ *reinterpret_cast<double*>(ptr) = QScript::ToNumber(value);
+ return true;
+ case QMetaType::QString:
+ *reinterpret_cast<QString*>(ptr) = value;
+ return true;
+ case QMetaType::Float:
+ *reinterpret_cast<float*>(ptr) = QScript::ToNumber(value);
+ return true;
+ case QMetaType::Short:
+ *reinterpret_cast<short*>(ptr) = short(QScript::ToInt32(value));
+ return true;
+ case QMetaType::UShort:
+ *reinterpret_cast<unsigned short*>(ptr) = QScript::ToUInt16(value);
+ return true;
+ case QMetaType::Char:
+ *reinterpret_cast<char*>(ptr) = char(QScript::ToInt32(value));
+ return true;
+ case QMetaType::UChar:
+ *reinterpret_cast<unsigned char*>(ptr) = (unsigned char)(QScript::ToInt32(value));
+ return true;
+ case QMetaType::QChar:
+ *reinterpret_cast<QChar*>(ptr) = QChar(QScript::ToUInt16(value));
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
bool QScriptEnginePrivate::hasDemarshalFunction(int type) const
{
QScriptTypeInfo *info = m_typeInfos.value(type);
@@ -3103,7 +3219,7 @@ bool QScriptEnginePrivate::hasDemarshalFunction(int type) const
bool QScriptEngine::convert(const QScriptValue &value, int type, void *ptr)
{
Q_D(QScriptEngine);
- return QScriptEnginePrivate::convert(value, type, ptr, d);
+ return QScriptEnginePrivate::convertValue(d->currentFrame, d->scriptValueToJSCValue(value), type, ptr);
}
/*!
@@ -3111,7 +3227,20 @@ bool QScriptEngine::convert(const QScriptValue &value, int type, void *ptr)
*/
bool QScriptEngine::convertV2(const QScriptValue &value, int type, void *ptr)
{
- return QScriptEnginePrivate::convert(value, type, ptr, /*engine=*/0);
+ QScriptValuePrivate *vp = QScriptValuePrivate::get(value);
+ if (vp) {
+ switch (vp->type) {
+ case QScriptValuePrivate::JavaScriptCore: {
+ JSC::ExecState *exec = vp->engine ? vp->engine->currentFrame : 0;
+ return QScriptEnginePrivate::convertValue(exec, vp->jscValue, type, ptr);
+ }
+ case QScriptValuePrivate::Number:
+ return QScriptEnginePrivate::convertNumber(vp->numberValue, type, ptr);
+ case QScriptValuePrivate::String:
+ return QScriptEnginePrivate::convertString(vp->stringValue, type, ptr);
+ }
+ }
+ return false;
}
/*!