diff options
Diffstat (limited to 'src/script/api/qscriptengine.cpp')
-rw-r--r-- | src/script/api/qscriptengine.cpp | 487 |
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; } /*! |