diff options
author | Martin Smith <msmith@trolltech.com> | 2010-02-19 11:39:34 (GMT) |
---|---|---|
committer | Martin Smith <msmith@trolltech.com> | 2010-02-19 11:39:34 (GMT) |
commit | 8c1dc03e611cea5bc942cbef0ca94c86efe91426 (patch) | |
tree | 789f04b9a06056918789bf1d3b153786a2b5d666 /src | |
parent | 83d7242271cf8196a8133de0406788135e16abbb (diff) | |
parent | 0d2a4bbf88db08ac641fcf96ff73fe93437517af (diff) | |
download | Qt-8c1dc03e611cea5bc942cbef0ca94c86efe91426.zip Qt-8c1dc03e611cea5bc942cbef0ca94c86efe91426.tar.gz Qt-8c1dc03e611cea5bc942cbef0ca94c86efe91426.tar.bz2 |
Merge branch 'master' of git@scm.dev.nokia.troll.no:qt/oslo-staging-1
Diffstat (limited to 'src')
-rw-r--r-- | src/script/api/qscriptengine.cpp | 909 | ||||
-rw-r--r-- | src/script/api/qscriptengine_p.h | 510 | ||||
-rw-r--r-- | src/script/api/qscriptvalue.cpp | 525 | ||||
-rw-r--r-- | src/script/api/qscriptvalue_p.h | 24 | ||||
-rw-r--r-- | src/script/bridge/qscriptclassobject.cpp | 2 | ||||
-rw-r--r-- | src/script/bridge/qscriptdeclarativeclass.cpp | 16 | ||||
-rw-r--r-- | src/script/bridge/qscriptqobject.cpp | 106 | ||||
-rw-r--r-- | src/script/bridge/qscriptvariant.cpp | 2 |
8 files changed, 1253 insertions, 841 deletions
diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 237b6fd..739b3fc 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -24,7 +24,6 @@ #include "config.h" #include "qscriptengine.h" #include "qscriptsyntaxchecker_p.h" -#include "qnumeric.h" #include "qscriptengine_p.h" #include "qscriptengineagent_p.h" @@ -41,12 +40,11 @@ #include <QtCore/qstringlist.h> #include <QtCore/qmetaobject.h> +#include <math.h> + #include "Error.h" -#include "JSArray.h" #include "JSLock.h" #include "Interpreter.h" -#include "DateConstructor.h" -#include "RegExpConstructor.h" #include "PrototypeFunction.h" #include "InitializeThreading.h" @@ -56,11 +54,10 @@ #include "TimeoutChecker.h" #include "JSFunction.h" #include "Parser.h" +#include "PropertyNameArray.h" #include "Operations.h" -#include "utils/qscriptdate_p.h" #include "bridge/qscriptfunction_p.h" -#include "bridge/qscriptobject_p.h" #include "bridge/qscriptclassobject_p.h" #include "bridge/qscriptvariant_p.h" #include "bridge/qscriptqobject_p.h" @@ -328,6 +325,74 @@ public: namespace QScript { +static const qsreal D32 = 4294967296.0; + +qint32 ToInt32(qsreal n) +{ + if (qIsNaN(n) || qIsInf(n) || (n == 0)) + return 0; + + qsreal sign = (n < 0) ? -1.0 : 1.0; + qsreal abs_n = fabs(n); + + n = ::fmod(sign * ::floor(abs_n), D32); + const double D31 = D32 / 2.0; + + if (sign == -1 && n < -D31) + n += D32; + + else if (sign != -1 && n >= D31) + n -= D32; + + return qint32 (n); +} + +quint32 ToUInt32(qsreal n) +{ + if (qIsNaN(n) || qIsInf(n) || (n == 0)) + return 0; + + qsreal sign = (n < 0) ? -1.0 : 1.0; + qsreal abs_n = fabs(n); + + n = ::fmod(sign * ::floor(abs_n), D32); + + if (n < 0) + n += D32; + + return quint32 (n); +} + +quint16 ToUInt16(qsreal n) +{ + static const qsreal D16 = 65536.0; + + if (qIsNaN(n) || qIsInf(n) || (n == 0)) + return 0; + + qsreal sign = (n < 0) ? -1.0 : 1.0; + qsreal abs_n = fabs(n); + + n = ::fmod(sign * ::floor(abs_n), D16); + + if (n < 0) + n += D16; + + return quint16 (n); +} + +qsreal ToInteger(qsreal n) +{ + if (qIsNaN(n)) + return 0; + + if (n == 0 || qIsInf(n)) + return n; + + int sign = n < 0 ? -1 : 1; + return sign * ::floor(::fabs(n)); +} + void GlobalClientData::mark(JSC::MarkStack& markStack) { engine->mark(markStack); @@ -482,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); } } @@ -566,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); } } @@ -844,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; @@ -870,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; } @@ -1280,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)) { @@ -1427,6 +1454,328 @@ void QScriptEnginePrivate::detachAllRegisteredScriptStrings() registeredScriptStrings = 0; } +#ifndef QT_NO_REGEXP + +extern QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax); + +JSC::JSValue QScriptEnginePrivate::newRegExp(JSC::ExecState *exec, const QRegExp ®exp) +{ + JSC::JSValue buf[2]; + JSC::ArgList args(buf, sizeof(buf)); + + //convert the pattern to a ECMAScript pattern + QString pattern = qt_regexp_toCanonical(regexp.pattern(), regexp.patternSyntax()); + if (regexp.isMinimal()) { + QString ecmaPattern; + int len = pattern.length(); + ecmaPattern.reserve(len); + int i = 0; + const QChar *wc = pattern.unicode(); + bool inBracket = false; + while (i < len) { + QChar c = wc[i++]; + ecmaPattern += c; + switch (c.unicode()) { + case '?': + case '+': + case '*': + case '}': + if (!inBracket) + ecmaPattern += QLatin1Char('?'); + break; + case '\\': + if (i < len) + ecmaPattern += wc[i++]; + break; + case '[': + inBracket = true; + break; + case ']': + inBracket = false; + break; + default: + break; + } + } + pattern = ecmaPattern; + } + + JSC::UString jscPattern = pattern; + QString flags; + if (regexp.caseSensitivity() == Qt::CaseInsensitive) + flags.append(QLatin1Char('i')); + JSC::UString jscFlags = flags; + buf[0] = JSC::jsString(exec, jscPattern); + buf[1] = JSC::jsString(exec, jscFlags); + return JSC::constructRegExp(exec, args); +} + +#endif + +JSC::JSValue QScriptEnginePrivate::newRegExp(JSC::ExecState *exec, const QString &pattern, const QString &flags) +{ + JSC::JSValue buf[2]; + JSC::ArgList args(buf, sizeof(buf)); + JSC::UString jscPattern = pattern; + QString strippedFlags; + if (flags.contains(QLatin1Char('i'))) + strippedFlags += QLatin1Char('i'); + if (flags.contains(QLatin1Char('m'))) + strippedFlags += QLatin1Char('m'); + if (flags.contains(QLatin1Char('g'))) + strippedFlags += QLatin1Char('g'); + JSC::UString jscFlags = strippedFlags; + buf[0] = JSC::jsString(exec, jscPattern); + buf[1] = JSC::jsString(exec, jscFlags); + return JSC::constructRegExp(exec, args); +} + +JSC::JSValue QScriptEnginePrivate::newVariant(const QVariant &value) +{ + QScriptObject *obj = new (currentFrame) QScriptObject(variantWrapperObjectStructure); + obj->setDelegate(new QScript::QVariantDelegate(value)); + JSC::JSValue proto = defaultPrototype(value.userType()); + if (proto) + obj->setPrototype(proto); + 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; + if (!(resolveMode & QScriptValue::ResolvePrototype)) { + // Look in the object's own properties + JSC::JSObject *object = JSC::asObject(value); + JSC::PropertySlot slot(object); + if (object->getOwnPropertySlot(exec, id, slot)) + result = slot.getValue(exec, id); + } + if (!result && (resolveMode & QScriptValue::ResolveScope)) { + // ### check if it's a function object and look in the scope chain + JSC::JSValue scope = property(exec, value, QString::fromLatin1("__qt_scope__"), QScriptValue::ResolveLocal); + if (isObject(scope)) + result = property(exec, scope, id, resolveMode); + } + return result; +} + +JSC::JSValue QScriptEnginePrivate::propertyHelper(JSC::ExecState *exec, JSC::JSValue value, quint32 index, int resolveMode) +{ + JSC::JSValue result; + if (!(resolveMode & QScriptValue::ResolvePrototype)) { + // Look in the object's own properties + JSC::JSObject *object = JSC::asObject(value); + JSC::PropertySlot slot(object); + if (object->getOwnPropertySlot(exec, index, slot)) + result = slot.getValue(exec, index); + } + return result; +} + +void QScriptEnginePrivate::setProperty(JSC::ExecState *exec, JSC::JSValue objectValue, const JSC::Identifier &id, + JSC::JSValue value, const QScriptValue::PropertyFlags &flags) +{ + JSC::JSObject *thisObject = JSC::asObject(objectValue); + JSC::JSValue setter = thisObject->lookupSetter(exec, id); + JSC::JSValue getter = thisObject->lookupGetter(exec, id); + if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) { + if (!value) { + // deleting getter/setter + if ((flags & QScriptValue::PropertyGetter) && (flags & QScriptValue::PropertySetter)) { + // deleting both: just delete the property + thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); + } else if (flags & QScriptValue::PropertyGetter) { + // preserve setter, if there is one + thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); + if (setter && setter.isObject()) + thisObject->defineSetter(exec, id, JSC::asObject(setter)); + } else { // flags & QScriptValue::PropertySetter + // preserve getter, if there is one + thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); + if (getter && getter.isObject()) + thisObject->defineGetter(exec, id, JSC::asObject(getter)); + } + } else { + if (value.isObject()) { // ### should check if it has callData() + // defining getter/setter + if (id == exec->propertyNames().underscoreProto) { + qWarning("QScriptValue::setProperty() failed: " + "cannot set getter or setter of native property `__proto__'"); + } else { + if (flags & QScriptValue::PropertyGetter) + thisObject->defineGetter(exec, id, JSC::asObject(value)); + if (flags & QScriptValue::PropertySetter) + thisObject->defineSetter(exec, id, JSC::asObject(value)); + } + } else { + qWarning("QScriptValue::setProperty(): getter/setter must be a function"); + } + } + } else { + // setting the value + if (getter && getter.isObject() && !(setter && setter.isObject())) { + qWarning("QScriptValue::setProperty() failed: " + "property '%s' has a getter but no setter", + qPrintable(QString(id.ustring()))); + return; + } + if (!value) { + // ### check if it's a getter/setter property + thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); + } else if (flags != QScriptValue::KeepExistingFlags) { + if (thisObject->hasOwnProperty(exec, id)) + thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); // ### hmmm - can't we just update the attributes? + unsigned attribs = 0; + if (flags & QScriptValue::ReadOnly) + attribs |= JSC::ReadOnly; + if (flags & QScriptValue::SkipInEnumeration) + attribs |= JSC::DontEnum; + if (flags & QScriptValue::Undeletable) + attribs |= JSC::DontDelete; + attribs |= flags & QScriptValue::UserRange; + thisObject->putWithAttributes(exec, id, value, attribs); + } else { + JSC::PutPropertySlot slot; + thisObject->put(exec, id, value, slot); + } + } +} + +void QScriptEnginePrivate::setProperty(JSC::ExecState *exec, JSC::JSValue objectValue, quint32 index, + JSC::JSValue value, const QScriptValue::PropertyFlags &flags) +{ + if (!value) { + JSC::asObject(objectValue)->deleteProperty(exec, index, /*checkDontDelete=*/false); + } else { + if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) { + // fall back to string-based setProperty(), since there is no + // JSC::JSObject::defineGetter(unsigned) + setProperty(exec, objectValue, JSC::Identifier::from(exec, index), value, flags); + } else { + if (flags != QScriptValue::KeepExistingFlags) { + // if (JSC::asObject(d->jscValue)->hasOwnProperty(exec, arrayIndex)) + // JSC::asObject(d->jscValue)->deleteProperty(exec, arrayIndex); + unsigned attribs = 0; + if (flags & QScriptValue::ReadOnly) + attribs |= JSC::ReadOnly; + if (flags & QScriptValue::SkipInEnumeration) + attribs |= JSC::DontEnum; + if (flags & QScriptValue::Undeletable) + attribs |= JSC::DontDelete; + attribs |= flags & QScriptValue::UserRange; + JSC::asObject(objectValue)->putWithAttributes(exec, index, value, attribs); + } else { + JSC::asObject(objectValue)->put(exec, index, value); + } + } + } +} + +QScriptValue::PropertyFlags QScriptEnginePrivate::propertyFlags(JSC::ExecState *exec, JSC::JSValue value, const JSC::Identifier &id, + const QScriptValue::ResolveFlags &mode) +{ + JSC::JSObject *object = JSC::asObject(value); + unsigned attribs = 0; + JSC::PropertyDescriptor descriptor; + if (object->getOwnPropertyDescriptor(exec, id, descriptor)) + attribs = descriptor.attributes(); + else if (!object->getPropertyAttributes(exec, id, attribs)) { + if ((mode & QScriptValue::ResolvePrototype) && object->prototype() && object->prototype().isObject()) { + JSC::JSValue proto = object->prototype(); + return propertyFlags(exec, proto, id, mode); + } + return 0; + } + QScriptValue::PropertyFlags result = 0; + if (attribs & JSC::ReadOnly) + result |= QScriptValue::ReadOnly; + if (attribs & JSC::DontEnum) + result |= QScriptValue::SkipInEnumeration; + if (attribs & JSC::DontDelete) + result |= QScriptValue::Undeletable; + //We cannot rely on attribs JSC::Setter/Getter because they are not necesserly set by JSC (bug?) + if (attribs & JSC::Getter || !object->lookupGetter(exec, id).isUndefinedOrNull()) + result |= QScriptValue::PropertyGetter; + if (attribs & JSC::Setter || !object->lookupSetter(exec, id).isUndefinedOrNull()) + result |= QScriptValue::PropertySetter; +#ifndef QT_NO_QOBJECT + if (attribs & QScript::QObjectMemberAttribute) + result |= QScriptValue::QObjectMember; +#endif + result |= QScriptValue::PropertyFlag(attribs & QScriptValue::UserRange); + return result; +} + #ifdef QT_NO_QOBJECT QScriptEngine::QScriptEngine() @@ -1599,56 +1948,7 @@ extern QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax); QScriptValue QScriptEngine::newRegExp(const QRegExp ®exp) { Q_D(QScriptEngine); - JSC::ExecState* exec = d->currentFrame; - JSC::JSValue buf[2]; - JSC::ArgList args(buf, sizeof(buf)); - - //convert the pattern to a ECMAScript pattern - QString pattern = qt_regexp_toCanonical(regexp.pattern(), regexp.patternSyntax()); - if (regexp.isMinimal()) { - QString ecmaPattern; - int len = pattern.length(); - ecmaPattern.reserve(len); - int i = 0; - const QChar *wc = pattern.unicode(); - bool inBracket = false; - while (i < len) { - QChar c = wc[i++]; - ecmaPattern += c; - switch (c.unicode()) { - case '?': - case '+': - case '*': - case '}': - if (!inBracket) - ecmaPattern += QLatin1Char('?'); - break; - case '\\': - if (i < len) - ecmaPattern += wc[i++]; - break; - case '[': - inBracket = true; - break; - case ']': - inBracket = false; - break; - default: - break; - } - } - pattern = ecmaPattern; - } - - JSC::UString jscPattern = pattern; - QString flags; - if (regexp.caseSensitivity() == Qt::CaseInsensitive) - flags.append(QLatin1Char('i')); - JSC::UString jscFlags = flags; - buf[0] = JSC::jsString(exec, jscPattern); - buf[1] = JSC::jsString(exec, jscFlags); - JSC::JSObject* result = JSC::constructRegExp(exec, args); - return d->scriptValueFromJSCValue(result); + return d->scriptValueFromJSCValue(d->newRegExp(d->currentFrame, regexp)); } #endif // QT_NO_REGEXP @@ -1666,14 +1966,7 @@ QScriptValue QScriptEngine::newRegExp(const QRegExp ®exp) QScriptValue QScriptEngine::newVariant(const QVariant &value) { Q_D(QScriptEngine); - JSC::ExecState* exec = d->currentFrame; - QScriptObject *obj = new (exec) QScriptObject(d->variantWrapperObjectStructure); - obj->setDelegate(new QScript::QVariantDelegate(value)); - QScriptValue result = d->scriptValueFromJSCValue(obj); - QScriptValue proto = defaultPrototype(value.userType()); - if (proto.isValid()) - result.setPrototype(proto); - return result; + return d->scriptValueFromJSCValue(d->newVariant(value)); } /*! @@ -1703,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 @@ -1812,9 +2094,7 @@ QScriptValue QScriptEngine::newQObject(const QScriptValue &scriptObject, QScriptValue QScriptEngine::newObject() { Q_D(QScriptEngine); - JSC::ExecState* exec = d->currentFrame; - JSC::JSObject *result = new (exec)QScriptObject(d->scriptObjectStructure); - return d->scriptValueFromJSCValue(result); + return d->scriptValueFromJSCValue(d->newObject()); } /*! @@ -1937,9 +2217,7 @@ QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionWithArgSignature QScriptValue QScriptEngine::newArray(uint length) { Q_D(QScriptEngine); - JSC::ExecState* exec = d->currentFrame; - JSC::JSArray* result = JSC::constructEmptyArray(exec, length); - return d->scriptValueFromJSCValue(result); + return d->scriptValueFromJSCValue(d->newArray(d->currentFrame, length)); } /*! @@ -1952,22 +2230,7 @@ QScriptValue QScriptEngine::newArray(uint length) QScriptValue QScriptEngine::newRegExp(const QString &pattern, const QString &flags) { Q_D(QScriptEngine); - JSC::ExecState* exec = d->currentFrame; - JSC::JSValue buf[2]; - JSC::ArgList args(buf, sizeof(buf)); - JSC::UString jscPattern = pattern; - QString strippedFlags; - if (flags.contains(QLatin1Char('i'))) - strippedFlags += QLatin1Char('i'); - if (flags.contains(QLatin1Char('m'))) - strippedFlags += QLatin1Char('m'); - if (flags.contains(QLatin1Char('g'))) - strippedFlags += QLatin1Char('g'); - JSC::UString jscFlags = strippedFlags; - buf[0] = JSC::jsString(exec, jscPattern); - buf[1] = JSC::jsString(exec, jscFlags); - JSC::JSObject* result = JSC::constructRegExp(exec, args); - return d->scriptValueFromJSCValue(result); + return d->scriptValueFromJSCValue(d->newRegExp(d->currentFrame, pattern, flags)); } /*! @@ -1978,11 +2241,7 @@ QScriptValue QScriptEngine::newRegExp(const QString &pattern, const QString &fla QScriptValue QScriptEngine::newDate(qsreal value) { Q_D(QScriptEngine); - JSC::ExecState* exec = d->currentFrame; - JSC::JSValue val = JSC::jsNumber(exec, value); - JSC::ArgList args(&val, 1); - JSC::JSObject *result = JSC::constructDate(exec, args); - return d->scriptValueFromJSCValue(result); + return d->scriptValueFromJSCValue(d->newDate(d->currentFrame, value)); } /*! @@ -1992,7 +2251,8 @@ QScriptValue QScriptEngine::newDate(qsreal value) */ QScriptValue QScriptEngine::newDate(const QDateTime &value) { - return newDate(QScript::FromDateTime(value)); + Q_D(QScriptEngine); + return d->scriptValueFromJSCValue(d->newDate(d->currentFrame, value)); } #ifndef QT_NO_QOBJECT @@ -2551,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; } } @@ -2680,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; @@ -2759,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: @@ -2779,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 @@ -2812,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('*')) { @@ -2821,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; } @@ -2834,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 @@ -2853,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); @@ -2865,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); } /*! @@ -2873,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; } /*! diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index 6780b2c..eff34af 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -37,14 +37,30 @@ #include "private/qobject_p.h" +#include <QtCore/qdatetime.h> #include <QtCore/qhash.h> +#include <QtCore/qnumeric.h> +#include <QtCore/qregexp.h> #include <QtCore/qset.h> #include "qscriptvalue_p.h" #include "qscriptstring_p.h" - +#include "bridge/qscriptclassobject_p.h" +#include "bridge/qscriptdeclarativeclass_p.h" +#include "bridge/qscriptdeclarativeobject_p.h" +#include "bridge/qscriptobject_p.h" +#include "bridge/qscriptqobject_p.h" +#include "bridge/qscriptvariant_p.h" +#include "utils/qscriptdate_p.h" + +#include "DateConstructor.h" +#include "DateInstance.h" #include "Debugger.h" +#include "ErrorInstance.h" +#include "JSArray.h" #include "Lexer.h" #include "RefPtr.h" +#include "RegExpConstructor.h" +#include "RegExpObject.h" #include "SourceProvider.h" #include "Structure.h" #include "JSGlobalObject.h" @@ -83,6 +99,20 @@ namespace QScript #endif class TimeoutCheckerProxy; + qint32 ToInt32(qsreal); + quint32 ToUInt32(qsreal); + quint16 ToUInt16(qsreal); + qsreal ToInteger(qsreal); + + inline bool ToBool(qsreal); + inline bool ToBool(const QString &); + inline qsreal ToNumber(const QString &); + inline qint32 ToInt32(const QString &); + inline quint32 ToUInt32(const QString &); + inline quint16 ToUInt16(const QString &); + inline qsreal ToInteger(const QString &); + inline QString ToString(qsreal); + //some conversion helper functions inline QScriptEnginePrivate *scriptEngineFromExec(const JSC::ExecState *exec); bool isFunction(JSC::JSValue value); @@ -114,29 +144,72 @@ public: static QScriptEnginePrivate *get(QScriptEngine *q) { return q ? q->d_func() : 0; } static QScriptEngine *get(QScriptEnginePrivate *d) { return d ? d->q_func() : 0; } - static bool convert(const QScriptValue &value, - int type, void *ptr, - QScriptEnginePrivate *eng); - QScriptValue create(int type, const void *ptr); + static inline bool isArray(JSC::JSValue); + static inline bool isDate(JSC::JSValue); + static inline bool isError(JSC::JSValue); + static inline bool isObject(JSC::JSValue); + static inline bool isRegExp(JSC::JSValue); + static inline bool isVariant(JSC::JSValue); + static inline bool isQObject(JSC::JSValue); + static inline bool isQMetaObject(JSC::JSValue); + + static inline bool toBool(JSC::ExecState *, JSC::JSValue); + static inline qsreal toInteger(JSC::ExecState *, JSC::JSValue); + static inline qsreal toNumber(JSC::ExecState *, JSC::JSValue); + static inline qint32 toInt32(JSC::ExecState *, JSC::JSValue); + static inline quint32 toUInt32(JSC::ExecState *, JSC::JSValue); + static inline quint16 toUInt16(JSC::ExecState *, JSC::JSValue); + static inline QString toString(JSC::ExecState *, JSC::JSValue); + + static inline QDateTime toDateTime(JSC::ExecState *, JSC::JSValue); +#ifndef QT_NO_REGEXP + static QRegExp toRegExp(JSC::ExecState*, JSC::JSValue); +#endif + static QVariant toVariant(JSC::ExecState *, JSC::JSValue); + static inline QObject *toQObject(JSC::ExecState *, JSC::JSValue); + static inline const QMetaObject *toQMetaObject(JSC::ExecState *, JSC::JSValue); + + static inline JSC::JSValue property(JSC::ExecState*, JSC::JSValue, const JSC::Identifier &id, + int resolveMode = QScriptValue::ResolvePrototype); + static JSC::JSValue propertyHelper(JSC::ExecState*, JSC::JSValue, const JSC::Identifier &id, int resolveMode); + static inline JSC::JSValue property(JSC::ExecState*, JSC::JSValue, quint32 index, + int resolveMode = QScriptValue::ResolvePrototype); + static JSC::JSValue propertyHelper(JSC::ExecState*, JSC::JSValue, quint32, int resolveMode); + static inline JSC::JSValue property(JSC::ExecState*, JSC::JSValue, const QString &, int resolveMode); + static inline void setProperty(JSC::ExecState*, JSC::JSValue object, const QString &name, JSC::JSValue, + const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags); + static void setProperty(JSC::ExecState*, JSC::JSValue object, const JSC::Identifier &id, JSC::JSValue, + const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags); + static void setProperty(JSC::ExecState*, JSC::JSValue object, quint32 index, JSC::JSValue, + const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags); + static QScriptValue::PropertyFlags propertyFlags(JSC::ExecState*, JSC::JSValue value, + const JSC::Identifier &id, const QScriptValue::ResolveFlags &mode); + static inline QScriptValue::PropertyFlags propertyFlags(JSC::ExecState*, JSC::JSValue value, + const QString &name, const QScriptValue::ResolveFlags &mode); + + static bool convertValue(JSC::ExecState*, JSC::JSValue value, + int type, void *ptr); + static bool convertNumber(qsreal, int type, void *ptr); + static bool convertString(const QString &, int type, void *ptr); + static JSC::JSValue create(JSC::ExecState*, int type, const void *ptr); bool hasDemarshalFunction(int type) const; inline QScriptValue scriptValueFromJSCValue(JSC::JSValue value); inline JSC::JSValue scriptValueToJSCValue(const QScriptValue &value); - QScriptValue scriptValueFromVariant(const QVariant &value); - QVariant scriptValueToVariant(const QScriptValue &value, int targetType); - - JSC::JSValue jscValueFromVariant(const QVariant &value); - QVariant jscValueToVariant(JSC::JSValue value, int targetType); + static inline JSC::JSValue jscValueFromVariant(JSC::ExecState*, const QVariant &value); + static QVariant jscValueToVariant(JSC::ExecState*, JSC::JSValue value, int targetType); + static inline QVariant &variantValue(JSC::JSValue value); + static inline void setVariantValue(JSC::JSValue objectValue, const QVariant &value); - QScriptValue arrayFromStringList(const QStringList &lst); - static QStringList stringListFromArray(const QScriptValue &arr); + static JSC::JSValue arrayFromStringList(JSC::ExecState*, const QStringList &lst); + static QStringList stringListFromArray(JSC::ExecState*, JSC::JSValue arr); - QScriptValue arrayFromVariantList(const QVariantList &lst); - static QVariantList variantListFromArray(const QScriptValue &arr); + static JSC::JSValue arrayFromVariantList(JSC::ExecState*, const QVariantList &lst); + static QVariantList variantListFromArray(JSC::ExecState*, JSC::JSValue arr); - QScriptValue objectFromVariantMap(const QVariantMap &vmap); - static QVariantMap variantMapFromObject(const QScriptValue &obj); + static JSC::JSValue objectFromVariantMap(JSC::ExecState*, const QVariantMap &vmap); + static QVariantMap variantMapFromObject(JSC::ExecState*, JSC::JSValue obj); JSC::JSValue defaultPrototype(int metaTypeId) const; void setDefaultPrototype(int metaTypeId, JSC::JSValue prototype); @@ -177,10 +250,43 @@ public: void agentDeleted(QScriptEngineAgent *agent); + static inline void saveException(JSC::ExecState *, JSC::JSValue *); + static inline void restoreException(JSC::ExecState *, JSC::JSValue); + void setCurrentException(QScriptValue exception) { m_currentException = exception; } QScriptValue currentException() const { return m_currentException; } void clearCurrentException() { m_currentException.d_ptr.reset(); } + static QScriptSyntaxCheckResult checkSyntax(const QString &program); + static bool canEvaluate(const QString &program); + + inline QScriptValuePrivate *allocateScriptValuePrivate(size_t); + inline void freeScriptValuePrivate(QScriptValuePrivate *p); + + inline void registerScriptValue(QScriptValuePrivate *value); + inline void unregisterScriptValue(QScriptValuePrivate *value); + void detachAllRegisteredScriptValues(); + + inline void registerScriptString(QScriptStringPrivate *value); + inline void unregisterScriptString(QScriptStringPrivate *value); + void detachAllRegisteredScriptStrings(); + + static inline JSC::JSValue newArray(JSC::ExecState *, uint length); + static inline JSC::JSValue newDate(JSC::ExecState *, qsreal value); + static inline JSC::JSValue newDate(JSC::ExecState *, const QDateTime &); + inline JSC::JSValue newObject(); + +#ifndef QT_NO_REGEXP + static JSC::JSValue newRegExp(JSC::ExecState *, const QRegExp &); +#endif + + static JSC::JSValue newRegExp(JSC::ExecState *, const QString &pattern, const QString &flags); + JSC::JSValue newVariant(const QVariant &); + JSC::JSValue newVariant(JSC::JSValue objectValue, const QVariant &); + + static inline QScriptDeclarativeClass *declarativeClass(JSC::JSValue); + static inline QScriptDeclarativeClass::Object *declarativeObject(JSC::JSValue); + #ifndef QT_NO_QOBJECT JSC::JSValue newQObject(QObject *object, QScriptEngine::ValueOwnership ownership = QScriptEngine::QtOwnership, @@ -188,9 +294,7 @@ public: JSC::JSValue newQMetaObject(const QMetaObject *metaObject, JSC::JSValue ctor); - static QScriptSyntaxCheckResult checkSyntax(const QString &program); - static bool canEvaluate(const QString &program); - static bool convertToNativeQObject(const QScriptValue &value, + static bool convertToNativeQObject(JSC::ExecState*, JSC::JSValue, const QByteArray &targetType, void **result); @@ -220,17 +324,6 @@ public: bool scriptDisconnect(JSC::JSValue signal, JSC::JSValue receiver, JSC::JSValue function); - inline QScriptValuePrivate *allocateScriptValuePrivate(size_t); - inline void freeScriptValuePrivate(QScriptValuePrivate *p); - - inline void registerScriptValue(QScriptValuePrivate *value); - inline void unregisterScriptValue(QScriptValuePrivate *value); - void detachAllRegisteredScriptValues(); - - inline void registerScriptString(QScriptStringPrivate *value); - inline void unregisterScriptString(QScriptStringPrivate *value); - void detachAllRegisteredScriptStrings(); - // private slots void _q_objectDestroyed(QObject *); #endif @@ -370,6 +463,46 @@ inline QScriptEnginePrivate *scriptEngineFromExec(const JSC::ExecState *exec) return static_cast<GlobalClientData*>(exec->globalData().clientData)->engine; } +inline QString ToString(qsreal value) +{ + return JSC::UString::from(value); +} + +inline qsreal ToNumber(const QString &value) +{ + return ((JSC::UString)value).toDouble(); +} + +inline qint32 ToInt32(const QString &value) +{ + return ToInt32(ToNumber(value)); +} + +inline quint32 ToUInt32(const QString &value) +{ + return ToUInt32(ToNumber(value)); +} + +inline quint16 ToUInt16(const QString &value) +{ + return ToUInt16(ToNumber(value)); +} + +inline qsreal ToInteger(const QString &value) +{ + return ToInteger(ToNumber(value)); +} + +inline bool ToBool(qsreal value) +{ + return (value != 0) && !qIsNaN(value); +} + +inline bool ToBool(const QString &value) +{ + return !value.isEmpty(); +} + } // namespace QScript inline QScriptValuePrivate *QScriptEnginePrivate::allocateScriptValuePrivate(size_t size) @@ -409,6 +542,13 @@ inline void QScriptEnginePrivate::unregisterScriptValue(QScriptValuePrivate *val value->next = 0; } +inline JSC::JSValue QScriptEnginePrivate::jscValueFromVariant(JSC::ExecState *exec, const QVariant &v) +{ + JSC::JSValue result = create(exec, v.userType(), v.data()); + Q_ASSERT(result); + return result; +} + inline QScriptValue QScriptEnginePrivate::scriptValueFromJSCValue(JSC::JSValue value) { if (!value) @@ -470,32 +610,83 @@ inline void QScriptValuePrivate::initFrom(const QString &value) engine->registerScriptValue(this); } -inline QScriptValue QScriptValuePrivate::property(const QString &name, int resolveMode) const +inline JSC::JSValue QScriptEnginePrivate::property(JSC::ExecState *exec, JSC::JSValue value, const QString &name, int resolveMode) { - JSC::ExecState *exec = engine->currentFrame; - return property(JSC::Identifier(exec, name), resolveMode); + return property(exec, value, JSC::Identifier(exec, name), resolveMode); } -inline QScriptValue QScriptValuePrivate::property(const JSC::Identifier &id, int resolveMode) const +inline JSC::JSValue QScriptEnginePrivate::property(JSC::ExecState *exec, JSC::JSValue value, const JSC::Identifier &id, int resolveMode) { - Q_ASSERT(isObject()); - JSC::ExecState *exec = engine->currentFrame; - JSC::JSObject *object = JSC::asObject(jscValue); + Q_ASSERT(isObject(value)); + JSC::JSObject *object = JSC::asObject(value); JSC::PropertySlot slot(object); if ((resolveMode & QScriptValue::ResolvePrototype) && object->getPropertySlot(exec, id, slot)) - return engine->scriptValueFromJSCValue(slot.getValue(exec, id)); - return propertyHelper(id, resolveMode); + return slot.getValue(exec, id); + return propertyHelper(exec, value, id, resolveMode); } -inline QScriptValue QScriptValuePrivate::property(quint32 index, int resolveMode) const +inline JSC::JSValue QScriptEnginePrivate::property(JSC::ExecState *exec, JSC::JSValue value, quint32 index, int resolveMode) { - Q_ASSERT(isObject()); - JSC::ExecState *exec = engine->currentFrame; - JSC::JSObject *object = JSC::asObject(jscValue); + Q_ASSERT(isObject(value)); + JSC::JSObject *object = JSC::asObject(value); JSC::PropertySlot slot(object); if ((resolveMode & QScriptValue::ResolvePrototype) && object->getPropertySlot(exec, index, slot)) - return engine->scriptValueFromJSCValue(slot.getValue(exec, index)); - return propertyHelper(index, resolveMode); + return slot.getValue(exec, index); + return propertyHelper(exec, value, index, resolveMode); +} + +inline QScriptValue::PropertyFlags QScriptEnginePrivate::propertyFlags(JSC::ExecState *exec, JSC::JSValue value, + const QString &name, + const QScriptValue::ResolveFlags &mode) +{ + return propertyFlags(exec, value, JSC::Identifier(exec, name), mode); +} + +inline void QScriptEnginePrivate::setProperty(JSC::ExecState *exec, JSC::JSValue objectValue, const QString &name, + JSC::JSValue value, const QScriptValue::PropertyFlags &flags) +{ + setProperty(exec, objectValue, JSC::Identifier(exec, name), value, flags); +} + +inline JSC::JSValue QScriptValuePrivate::property(const JSC::Identifier &id, int resolveMode) const +{ + return QScriptEnginePrivate::property(engine->currentFrame, jscValue, id, resolveMode); +} + +inline JSC::JSValue QScriptValuePrivate::property(quint32 index, int resolveMode) const +{ + return QScriptEnginePrivate::property(engine->currentFrame, jscValue, index, resolveMode); +} + +inline JSC::JSValue QScriptValuePrivate::property(const QString &name, int resolveMode) const +{ + JSC::ExecState *exec = engine->currentFrame; + return QScriptEnginePrivate::property(exec, jscValue, JSC::Identifier(exec, name), resolveMode); +} + +inline QScriptValue::PropertyFlags QScriptValuePrivate::propertyFlags( + const JSC::Identifier &id, const QScriptValue::ResolveFlags &mode) const +{ + return QScriptEnginePrivate::propertyFlags(engine->currentFrame, jscValue, id, mode); +} + +inline void QScriptValuePrivate::setProperty(const JSC::Identifier &id, const JSC::JSValue &value, + const QScriptValue::PropertyFlags &flags) +{ + QScriptEnginePrivate::setProperty(engine->currentFrame, jscValue, id, value, flags); +} + +inline void QScriptValuePrivate::setProperty(quint32 index, const JSC::JSValue &value, + const QScriptValue::PropertyFlags &flags) +{ + QScriptEnginePrivate::setProperty(engine->currentFrame, jscValue, index, value, flags); +} + +inline void QScriptValuePrivate::setProperty(const QString &name, const JSC::JSValue &value, + const QScriptValue::PropertyFlags &flags) +{ + JSC::ExecState *exec = engine->currentFrame; + QScriptEnginePrivate::setProperty(exec, jscValue, JSC::Identifier(exec, name), value, flags); } inline void* QScriptValuePrivate::operator new(size_t size, QScriptEnginePrivate *engine) @@ -514,7 +705,7 @@ inline void QScriptValuePrivate::operator delete(void *ptr) qFree(d); } -inline void QScriptValuePrivate::saveException(JSC::ExecState *exec, JSC::JSValue *val) +inline void QScriptEnginePrivate::saveException(JSC::ExecState *exec, JSC::JSValue *val) { if (exec) { *val = exec->exception(); @@ -524,7 +715,7 @@ inline void QScriptValuePrivate::saveException(JSC::ExecState *exec, JSC::JSValu } } -inline void QScriptValuePrivate::restoreException(JSC::ExecState *exec, JSC::JSValue val) +inline void QScriptEnginePrivate::restoreException(JSC::ExecState *exec, JSC::JSValue val) { if (exec && val) exec->setException(val); @@ -578,6 +769,231 @@ inline JSC::ExecState *QScriptEnginePrivate::globalExec() const return originalGlobalObject()->globalExec(); } +inline JSC::JSValue QScriptEnginePrivate::newArray(JSC::ExecState *exec, uint length) +{ + return JSC::constructEmptyArray(exec, length); +} + +inline JSC::JSValue QScriptEnginePrivate::newDate(JSC::ExecState *exec, qsreal value) +{ + JSC::JSValue val = JSC::jsNumber(exec, value); + JSC::ArgList args(&val, 1); + return JSC::constructDate(exec, args); +} + +inline JSC::JSValue QScriptEnginePrivate::newDate(JSC::ExecState *exec, const QDateTime &value) +{ + return newDate(exec, QScript::FromDateTime(value)); +} + +inline JSC::JSValue QScriptEnginePrivate::newObject() +{ + return new (currentFrame)QScriptObject(scriptObjectStructure); +} + +inline bool QScriptEnginePrivate::isObject(JSC::JSValue value) +{ + return value && value.isObject(); +} + +inline bool QScriptEnginePrivate::isArray(JSC::JSValue value) +{ + return isObject(value) && value.inherits(&JSC::JSArray::info); +} + +inline bool QScriptEnginePrivate::isDate(JSC::JSValue value) +{ + return isObject(value) && value.inherits(&JSC::DateInstance::info); +} + +inline bool QScriptEnginePrivate::isError(JSC::JSValue value) +{ + return isObject(value) && value.inherits(&JSC::ErrorInstance::info); +} + +inline bool QScriptEnginePrivate::isRegExp(JSC::JSValue value) +{ + return isObject(value) && value.inherits(&JSC::RegExpObject::info); +} + +inline bool QScriptEnginePrivate::isVariant(JSC::JSValue value) +{ + if (!isObject(value) || !value.inherits(&QScriptObject::info)) + return false; + QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(value)); + QScriptObjectDelegate *delegate = object->delegate(); + return (delegate && (delegate->type() == QScriptObjectDelegate::Variant)); +} + +inline bool QScriptEnginePrivate::isQObject(JSC::JSValue value) +{ +#ifndef QT_NO_QOBJECT + if (!isObject(value) || !value.inherits(&QScriptObject::info)) + return false; + QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(value)); + QScriptObjectDelegate *delegate = object->delegate(); + return (delegate && (delegate->type() == QScriptObjectDelegate::QtObject || + (delegate->type() == QScriptObjectDelegate::DeclarativeClassObject && + static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->scriptClass()->isQObject()))); +#else + return false; +#endif +} + +inline bool QScriptEnginePrivate::isQMetaObject(JSC::JSValue value) +{ +#ifndef QT_NO_QOBJECT + return JSC::asObject(value)->inherits(&QScript::QMetaObjectWrapperObject::info); +#else + return false; +#endif +} + +inline bool QScriptEnginePrivate::toBool(JSC::ExecState *exec, JSC::JSValue value) +{ + JSC::JSValue savedException; + saveException(exec, &savedException); + bool result = value.toBoolean(exec); + restoreException(exec, savedException); + return result; +} + +inline qsreal QScriptEnginePrivate::toInteger(JSC::ExecState *exec, JSC::JSValue value) +{ + JSC::JSValue savedException; + saveException(exec, &savedException); + qsreal result = value.toInteger(exec); + restoreException(exec, savedException); + return result; +} + +inline qsreal QScriptEnginePrivate::toNumber(JSC::ExecState *exec, JSC::JSValue value) +{ + JSC::JSValue savedException; + saveException(exec, &savedException); + qsreal result = value.toNumber(exec); + restoreException(exec, savedException); + return result; +} + +inline qint32 QScriptEnginePrivate::toInt32(JSC::ExecState *exec, JSC::JSValue value) +{ + JSC::JSValue savedException; + saveException(exec, &savedException); + qint32 result = value.toInt32(exec); + restoreException(exec, savedException); + return result; +} + +inline quint32 QScriptEnginePrivate::toUInt32(JSC::ExecState *exec, JSC::JSValue value) +{ + JSC::JSValue savedException; + saveException(exec, &savedException); + quint32 result = value.toUInt32(exec); + restoreException(exec, savedException); + return result; +} + +inline quint16 QScriptEnginePrivate::toUInt16(JSC::ExecState *exec, JSC::JSValue value) +{ + // ### no equivalent function in JSC + return QScript::ToUInt16(toNumber(exec, value)); +} + +inline QString QScriptEnginePrivate::toString(JSC::ExecState *exec, JSC::JSValue value) +{ + JSC::JSValue savedException; + saveException(exec, &savedException); + JSC::UString str = value.toString(exec); + if (exec && exec->hadException() && !str.size()) { + JSC::JSValue savedException2; + saveException(exec, &savedException2); + str = savedException2.toString(exec); + restoreException(exec, savedException2); + } + if (savedException) + restoreException(exec, savedException); + return str; +} + +inline QDateTime QScriptEnginePrivate::toDateTime(JSC::ExecState *, JSC::JSValue value) +{ + if (!isDate(value)) + return QDateTime(); + qsreal t = static_cast<JSC::DateInstance*>(JSC::asObject(value))->internalNumber(); + return QScript::ToDateTime(t, Qt::LocalTime); +} + +inline QObject *QScriptEnginePrivate::toQObject(JSC::ExecState *exec, JSC::JSValue value) +{ +#ifndef QT_NO_QOBJECT + if (isObject(value) && value.inherits(&QScriptObject::info)) { + QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(value)); + QScriptObjectDelegate *delegate = object->delegate(); + if (!delegate) + return 0; + if (delegate->type() == QScriptObjectDelegate::QtObject) + return static_cast<QScript::QObjectDelegate*>(delegate)->value(); + if (delegate->type() == QScriptObjectDelegate::DeclarativeClassObject) + return static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->scriptClass()->toQObject(declarativeObject(value)); + if (delegate->type() == QScriptObjectDelegate::Variant) { + QVariant var = variantValue(value); + int type = var.userType(); + if ((type == QMetaType::QObjectStar) || (type == QMetaType::QWidgetStar)) + return *reinterpret_cast<QObject* const *>(var.constData()); + } + } +#endif + return 0; +} + +inline const QMetaObject *QScriptEnginePrivate::toQMetaObject(JSC::ExecState*, JSC::JSValue value) +{ +#ifndef QT_NO_QOBJECT + if (isQMetaObject(value)) + return static_cast<QScript::QMetaObjectWrapperObject*>(JSC::asObject(value))->value(); +#endif + return 0; +} + +inline QVariant &QScriptEnginePrivate::variantValue(JSC::JSValue value) +{ + Q_ASSERT(value.inherits(&QScriptObject::info)); + QScriptObjectDelegate *delegate = static_cast<QScriptObject*>(JSC::asObject(value))->delegate(); + Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant)); + return static_cast<QScript::QVariantDelegate*>(delegate)->value(); +} + +inline void QScriptEnginePrivate::setVariantValue(JSC::JSValue objectValue, const QVariant &value) +{ + Q_ASSERT(objectValue.inherits(&QScriptObject::info)); + QScriptObjectDelegate *delegate = static_cast<QScriptObject*>(JSC::asObject(objectValue))->delegate(); + Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant)); + static_cast<QScript::QVariantDelegate*>(delegate)->setValue(value); +} + +inline QScriptDeclarativeClass *QScriptEnginePrivate::declarativeClass(JSC::JSValue v) +{ + if (!QScriptEnginePrivate::isObject(v) || !v.inherits(&QScriptObject::info)) + return 0; + QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(v)); + QScriptObjectDelegate *delegate = scriptObject->delegate(); + if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject)) + return 0; + return static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->scriptClass(); +} + +inline QScriptDeclarativeClass::Object *QScriptEnginePrivate::declarativeObject(JSC::JSValue v) +{ + if (!QScriptEnginePrivate::isObject(v) || !v.inherits(&QScriptObject::info)) + return 0; + QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(v)); + QScriptObjectDelegate *delegate = scriptObject->delegate(); + if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject)) + return 0; + return static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->object(); +} + QT_END_NAMESPACE #endif diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp index 5bfe46a..7f1fdaa 100644 --- a/src/script/api/qscriptvalue.cpp +++ b/src/script/api/qscriptvalue.cpp @@ -29,33 +29,19 @@ #include "qscriptengine_p.h" #include "qscriptstring_p.h" -#include "JSArray.h" #include "JSGlobalObject.h" #include "JSImmediate.h" #include "JSObject.h" #include "JSValue.h" #include "JSFunction.h" -#include "DateInstance.h" -#include "ErrorInstance.h" -#include "RegExpObject.h" #include "Identifier.h" #include "Operations.h" #include "Arguments.h" -#include <QtCore/qdatetime.h> -#include <QtCore/qregexp.h> #include <QtCore/qvariant.h> #include <QtCore/qvarlengtharray.h> #include <QtCore/qnumeric.h> -#include "utils/qscriptdate_p.h" -#include "bridge/qscriptobject_p.h" -#include "bridge/qscriptclassobject_p.h" -#include "bridge/qscriptvariant_p.h" -#include "bridge/qscriptqobject_p.h" -#include "bridge/qscriptdeclarativeclass_p.h" -#include "bridge/qscriptdeclarativeobject_p.h" - /*! \since 4.3 \class QScriptValue @@ -180,248 +166,8 @@ \omitvalue ResolveFull Check the object's own properties first, then search the prototype chain, and finally search the scope chain. */ -// ### move - -#include <QtCore/qnumeric.h> -#include <math.h> - QT_BEGIN_NAMESPACE -namespace QScript -{ - -static const qsreal D32 = 4294967296.0; - -qint32 ToInt32(qsreal n) -{ - if (qIsNaN(n) || qIsInf(n) || (n == 0)) - return 0; - - qsreal sign = (n < 0) ? -1.0 : 1.0; - qsreal abs_n = fabs(n); - - n = ::fmod(sign * ::floor(abs_n), D32); - const double D31 = D32 / 2.0; - - if (sign == -1 && n < -D31) - n += D32; - - else if (sign != -1 && n >= D31) - n -= D32; - - return qint32 (n); -} - -quint32 ToUint32(qsreal n) -{ - if (qIsNaN(n) || qIsInf(n) || (n == 0)) - return 0; - - qsreal sign = (n < 0) ? -1.0 : 1.0; - qsreal abs_n = fabs(n); - - n = ::fmod(sign * ::floor(abs_n), D32); - - if (n < 0) - n += D32; - - return quint32 (n); -} - -quint16 ToUint16(qsreal n) -{ - static const qsreal D16 = 65536.0; - - if (qIsNaN(n) || qIsInf(n) || (n == 0)) - return 0; - - qsreal sign = (n < 0) ? -1.0 : 1.0; - qsreal abs_n = fabs(n); - - n = ::fmod(sign * ::floor(abs_n), D16); - - if (n < 0) - n += D16; - - return quint16 (n); -} - -qsreal ToInteger(qsreal n) -{ - if (qIsNaN(n)) - return 0; - - if (n == 0 || qIsInf(n)) - return n; - - int sign = n < 0 ? -1 : 1; - return sign * ::floor(::fabs(n)); -} - -} // namespace QScript - -QScriptValue QScriptValuePrivate::propertyHelper(const JSC::Identifier &id, int resolveMode) const -{ - JSC::JSValue result; - if (!(resolveMode & QScriptValue::ResolvePrototype)) { - // Look in the object's own properties - JSC::ExecState *exec = engine->currentFrame; - JSC::JSObject *object = JSC::asObject(jscValue); - JSC::PropertySlot slot(object); - if (object->getOwnPropertySlot(exec, id, slot)) - result = slot.getValue(exec, id); - } - if (!result && (resolveMode & QScriptValue::ResolveScope)) { - // ### check if it's a function object and look in the scope chain - QScriptValue scope = property(QString::fromLatin1("__qt_scope__"), QScriptValue::ResolveLocal); - if (scope.isObject()) - result = engine->scriptValueToJSCValue(QScriptValuePrivate::get(scope)->property(id, resolveMode)); - } - return engine->scriptValueFromJSCValue(result); -} - -QScriptValue QScriptValuePrivate::propertyHelper(quint32 index, int resolveMode) const -{ - JSC::JSValue result; - if (!(resolveMode & QScriptValue::ResolvePrototype)) { - // Look in the object's own properties - JSC::ExecState *exec = engine->currentFrame; - JSC::JSObject *object = JSC::asObject(jscValue); - JSC::PropertySlot slot(object); - if (object->getOwnPropertySlot(exec, index, slot)) - result = slot.getValue(exec, index); - } - return engine->scriptValueFromJSCValue(result); -} - -void QScriptValuePrivate::setProperty(const JSC::Identifier &id, const QScriptValue &value, - const QScriptValue::PropertyFlags &flags) -{ - QScriptEnginePrivate *valueEngine = QScriptValuePrivate::getEngine(value); - if (valueEngine && (valueEngine != engine)) { - qWarning("QScriptValue::setProperty(%s) failed: " - "cannot set value created in a different engine", - qPrintable(QString(id.ustring()))); - return; - } - JSC::ExecState *exec = engine->currentFrame; - JSC::JSValue jsValue = engine->scriptValueToJSCValue(value); - JSC::JSObject *thisObject = JSC::asObject(jscValue); - JSC::JSValue setter = thisObject->lookupSetter(exec, id); - JSC::JSValue getter = thisObject->lookupGetter(exec, id); - if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) { - if (!jsValue) { - // deleting getter/setter - if ((flags & QScriptValue::PropertyGetter) && (flags & QScriptValue::PropertySetter)) { - // deleting both: just delete the property - thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); - } else if (flags & QScriptValue::PropertyGetter) { - // preserve setter, if there is one - thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); - if (setter && setter.isObject()) - thisObject->defineSetter(exec, id, JSC::asObject(setter)); - } else { // flags & QScriptValue::PropertySetter - // preserve getter, if there is one - thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); - if (getter && getter.isObject()) - thisObject->defineGetter(exec, id, JSC::asObject(getter)); - } - } else { - if (jsValue.isObject()) { // ### should check if it has callData() - // defining getter/setter - if (id == exec->propertyNames().underscoreProto) { - qWarning("QScriptValue::setProperty() failed: " - "cannot set getter or setter of native property `__proto__'"); - } else { - if (flags & QScriptValue::PropertyGetter) - thisObject->defineGetter(exec, id, JSC::asObject(jsValue)); - if (flags & QScriptValue::PropertySetter) - thisObject->defineSetter(exec, id, JSC::asObject(jsValue)); - } - } else { - qWarning("QScriptValue::setProperty(): getter/setter must be a function"); - } - } - } else { - // setting the value - if (getter && getter.isObject() && !(setter && setter.isObject())) { - qWarning("QScriptValue::setProperty() failed: " - "property '%s' has a getter but no setter", - qPrintable(QString(id.ustring()))); - return; - } - if (!jsValue) { - // ### check if it's a getter/setter property - thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); - } else if (flags != QScriptValue::KeepExistingFlags) { - if (thisObject->hasOwnProperty(exec, id)) - thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); // ### hmmm - can't we just update the attributes? - unsigned attribs = 0; - if (flags & QScriptValue::ReadOnly) - attribs |= JSC::ReadOnly; - if (flags & QScriptValue::SkipInEnumeration) - attribs |= JSC::DontEnum; - if (flags & QScriptValue::Undeletable) - attribs |= JSC::DontDelete; - attribs |= flags & QScriptValue::UserRange; - thisObject->putWithAttributes(exec, id, jsValue, attribs); - } else { - JSC::PutPropertySlot slot; - thisObject->put(exec, id, jsValue, slot); - } - } -} - -QScriptValue::PropertyFlags QScriptValuePrivate::propertyFlags(const JSC::Identifier &id, - const QScriptValue::ResolveFlags &mode) const -{ - JSC::ExecState *exec = engine->currentFrame; - JSC::JSObject *object = JSC::asObject(jscValue); - unsigned attribs = 0; - JSC::PropertyDescriptor descriptor; - if (object->getOwnPropertyDescriptor(exec, id, descriptor)) - attribs = descriptor.attributes(); - else if (!object->getPropertyAttributes(exec, id, attribs)) { - if ((mode & QScriptValue::ResolvePrototype) && object->prototype() && object->prototype().isObject()) { - QScriptValue proto = engine->scriptValueFromJSCValue(object->prototype()); - return QScriptValuePrivate::get(proto)->propertyFlags(id, mode); - } - return 0; - } - QScriptValue::PropertyFlags result = 0; - if (attribs & JSC::ReadOnly) - result |= QScriptValue::ReadOnly; - if (attribs & JSC::DontEnum) - result |= QScriptValue::SkipInEnumeration; - if (attribs & JSC::DontDelete) - result |= QScriptValue::Undeletable; - //We cannot rely on attribs JSC::Setter/Getter because they are not necesserly set by JSC (bug?) - if (attribs & JSC::Getter || !object->lookupGetter(exec, id).isUndefinedOrNull()) - result |= QScriptValue::PropertyGetter; - if (attribs & JSC::Setter || !object->lookupSetter(exec, id).isUndefinedOrNull()) - result |= QScriptValue::PropertySetter; - if (attribs & QScript::QObjectMemberAttribute) - result |= QScriptValue::QObjectMember; - result |= QScriptValue::PropertyFlag(attribs & QScriptValue::UserRange); - return result; -} - -QVariant &QScriptValuePrivate::variantValue() const -{ - Q_ASSERT(jscValue.inherits(&QScriptObject::info)); - QScriptObjectDelegate *delegate = static_cast<QScriptObject*>(JSC::asObject(jscValue))->delegate(); - Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant)); - return static_cast<QScript::QVariantDelegate*>(delegate)->value(); -} - -void QScriptValuePrivate::setVariantValue(const QVariant &value) -{ - Q_ASSERT(jscValue.inherits(&QScriptObject::info)); - QScriptObjectDelegate *delegate = static_cast<QScriptObject*>(JSC::asObject(jscValue))->delegate(); - Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant)); - static_cast<QScript::QVariantDelegate*>(delegate)->setValue(value); -} - void QScriptValuePrivate::detachFromEngine() { if (isJSC()) @@ -707,9 +453,9 @@ QScriptValue &QScriptValue::operator=(const QScriptValue &other) bool QScriptValue::isError() const { Q_D(const QScriptValue); - if (!d || !d->isObject()) + if (!d || !d->isJSC()) return false; - return d->jscValue.inherits(&JSC::ErrorInstance::info); + return QScriptEnginePrivate::isError(d->jscValue); } /*! @@ -721,9 +467,9 @@ bool QScriptValue::isError() const bool QScriptValue::isArray() const { Q_D(const QScriptValue); - if (!d || !d->isObject()) + if (!d || !d->isJSC()) return false; - return d->jscValue.inherits(&JSC::JSArray::info); + return QScriptEnginePrivate::isArray(d->jscValue); } /*! @@ -735,9 +481,9 @@ bool QScriptValue::isArray() const bool QScriptValue::isDate() const { Q_D(const QScriptValue); - if (!d || !d->isObject()) + if (!d || !d->isJSC()) return false; - return d->jscValue.inherits(&JSC::DateInstance::info); + return QScriptEnginePrivate::isDate(d->jscValue); } /*! @@ -749,9 +495,9 @@ bool QScriptValue::isDate() const bool QScriptValue::isRegExp() const { Q_D(const QScriptValue); - if (!d || !d->isObject()) + if (!d || !d->isJSC()) return false; - return d->jscValue.inherits(&JSC::RegExpObject::info); + return QScriptEnginePrivate::isRegExp(d->jscValue); } /*! @@ -816,7 +562,8 @@ QScriptValue QScriptValue::scope() const if (!d || !d->isObject()) return QScriptValue(); // ### make hidden property - return d->property(QLatin1String("__qt_scope__"), QScriptValue::ResolveLocal); + JSC::JSValue result = d->property(QLatin1String("__qt_scope__"), QScriptValue::ResolveLocal); + return d->engine->scriptValueFromJSCValue(result); } /*! @@ -910,9 +657,9 @@ QScriptValue ToPrimitive(const QScriptValue &object, JSC::PreferredPrimitiveType Q_ASSERT(pp->engine != 0); JSC::ExecState *exec = pp->engine->currentFrame; JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); JSC::JSValue result = JSC::asObject(pp->jscValue)->toPrimitive(exec, hint); - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); return pp->engine->scriptValueFromJSCValue(result); } @@ -1103,9 +850,9 @@ bool QScriptValue::equals(const QScriptValue &other) const if (eng_p) { JSC::ExecState *exec = eng_p->currentFrame; JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); bool result = JSC::JSValue::equal(exec, d->jscValue, other.d_ptr->jscValue); - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); return result; } } @@ -1191,21 +938,10 @@ QString QScriptValue::toString() const switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); - JSC::UString str = d->jscValue.toString(exec); - if (exec && exec->hadException() && !str.size()) { - JSC::JSValue savedException2; - QScriptValuePrivate::saveException(exec, &savedException2); - str = savedException2.toString(exec); - QScriptValuePrivate::restoreException(exec, savedException2); - } - if (savedException) - QScriptValuePrivate::restoreException(exec, savedException); - return str; + return QScriptEnginePrivate::toString(exec, d->jscValue); } case QScriptValuePrivate::Number: - return JSC::UString::from(d->numberValue); + return QScript::ToString(d->numberValue); case QScriptValuePrivate::String: return d->stringValue; } @@ -1232,16 +968,12 @@ qsreal QScriptValue::toNumber() const switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); - qsreal result = d->jscValue.toNumber(exec); - QScriptValuePrivate::restoreException(exec, savedException); - return result; + return QScriptEnginePrivate::toNumber(exec, d->jscValue); } case QScriptValuePrivate::Number: return d->numberValue; case QScriptValuePrivate::String: - return ((JSC::UString)d->stringValue).toDouble(); + return QScript::ToNumber(d->stringValue); } return 0; } @@ -1259,16 +991,12 @@ bool QScriptValue::toBoolean() const switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); - bool result = d->jscValue.toBoolean(exec); - QScriptValuePrivate::restoreException(exec, savedException); - return result; + return QScriptEnginePrivate::toBool(exec, d->jscValue); } case QScriptValuePrivate::Number: - return (d->numberValue != 0) && !qIsNaN(d->numberValue); + return QScript::ToBool(d->numberValue); case QScriptValuePrivate::String: - return (!d->stringValue.isEmpty()); + return QScript::ToBool(d->stringValue); } return false; } @@ -1295,16 +1023,12 @@ bool QScriptValue::toBool() const switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); - bool result = d->jscValue.toBoolean(exec); - QScriptValuePrivate::restoreException(exec, savedException); - return result; + return QScriptEnginePrivate::toBool(exec, d->jscValue); } case QScriptValuePrivate::Number: - return (d->numberValue != 0) && !qIsNaN(d->numberValue); + return QScript::ToBool(d->numberValue); case QScriptValuePrivate::String: - return (!d->stringValue.isEmpty()); + return QScript::ToBool(d->stringValue); } return false; } @@ -1329,16 +1053,12 @@ qint32 QScriptValue::toInt32() const switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); - qint32 result = d->jscValue.toInt32(exec); - QScriptValuePrivate::restoreException(exec, savedException); - return result; + return QScriptEnginePrivate::toInt32(exec, d->jscValue); } case QScriptValuePrivate::Number: return QScript::ToInt32(d->numberValue); case QScriptValuePrivate::String: - return QScript::ToInt32(((JSC::UString)d->stringValue).toDouble()); + return QScript::ToInt32(d->stringValue); } return 0; } @@ -1363,16 +1083,12 @@ quint32 QScriptValue::toUInt32() const switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); - quint32 result = d->jscValue.toUInt32(exec); - QScriptValuePrivate::restoreException(exec, savedException); - return result; + return QScriptEnginePrivate::toUInt32(exec, d->jscValue); } case QScriptValuePrivate::Number: - return QScript::ToUint32(d->numberValue); + return QScript::ToUInt32(d->numberValue); case QScriptValuePrivate::String: - return QScript::ToUint32(((JSC::UString)d->stringValue).toDouble()); + return QScript::ToUInt32(d->stringValue); } return 0; } @@ -1396,13 +1112,13 @@ quint16 QScriptValue::toUInt16() const return 0; switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { - // ### no equivalent function in JSC - return QScript::ToUint16(toNumber()); + JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; + return QScriptEnginePrivate::toUInt16(exec, d->jscValue); } case QScriptValuePrivate::Number: - return QScript::ToUint16(d->numberValue); + return QScript::ToUInt16(d->numberValue); case QScriptValuePrivate::String: - return QScript::ToUint16(((JSC::UString)d->stringValue).toDouble()); + return QScript::ToUInt16(d->stringValue); } return 0; } @@ -1427,16 +1143,12 @@ qsreal QScriptValue::toInteger() const switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); - qsreal result = d->jscValue.toInteger(exec); - QScriptValuePrivate::restoreException(exec, savedException); - return result; + return QScriptEnginePrivate::toInteger(exec, d->jscValue); } case QScriptValuePrivate::Number: return QScript::ToInteger(d->numberValue); case QScriptValuePrivate::String: - return QScript::ToInteger(((JSC::UString)d->stringValue).toDouble()); + return QScript::ToInteger(d->stringValue); } return 0; } @@ -1469,40 +1181,10 @@ QVariant QScriptValue::toVariant() const if (!d) return QVariant(); switch (d->type) { - case QScriptValuePrivate::JavaScriptCore: - if (isObject()) { - if (isVariant()) - return d->variantValue(); -#ifndef QT_NO_QOBJECT - else if (isQObject()) - return qVariantFromValue(toQObject()); -#endif - else if (isDate()) - return QVariant(toDateTime()); -#ifndef QT_NO_REGEXP - else if (isRegExp()) - return QVariant(toRegExp()); -#endif - else if (isArray()) - return QScriptEnginePrivate::variantListFromArray(*this); - else if (QScriptDeclarativeClass *dc = QScriptDeclarativeClass::scriptClass(*this)) - return dc->toVariant(QScriptDeclarativeClass::object(*this)); - // try to convert to primitive - JSC::ExecState *exec = d->engine->currentFrame; - JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); - JSC::JSValue prim = d->jscValue.toPrimitive(exec); - QScriptValuePrivate::restoreException(exec, savedException); - if (!prim.isObject()) - return d->engine->scriptValueFromJSCValue(prim).toVariant(); - } else if (isNumber()) { - return QVariant(toNumber()); - } else if (isString()) { - return QVariant(toString()); - } else if (isBool()) { - return QVariant(toBool()); - } - return QVariant(); + case QScriptValuePrivate::JavaScriptCore: { + JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; + return QScriptEnginePrivate::toVariant(exec, d->jscValue); + } case QScriptValuePrivate::Number: return QVariant(d->numberValue); case QScriptValuePrivate::String: @@ -1534,10 +1216,9 @@ QScriptValue QScriptValue::toObject() const QDateTime QScriptValue::toDateTime() const { Q_D(const QScriptValue); - if (!isDate()) + if (!d || !d->engine) return QDateTime(); - qsreal t = static_cast<JSC::DateInstance*>(JSC::asObject(d->jscValue))->internalNumber(); - return QScript::ToDateTime(t, Qt::LocalTime); + return QScriptEnginePrivate::toDateTime(d->engine->currentFrame, d->jscValue); } #ifndef QT_NO_REGEXP @@ -1551,13 +1232,9 @@ QDateTime QScriptValue::toDateTime() const QRegExp QScriptValue::toRegExp() const { Q_D(const QScriptValue); - if (!isRegExp()) - return QRegExp(); - QString pattern = d->property(QLatin1String("source"), QScriptValue::ResolvePrototype).toString(); - Qt::CaseSensitivity kase = Qt::CaseSensitive; - if (d->property(QLatin1String("ignoreCase"), QScriptValue::ResolvePrototype).toBool()) - kase = Qt::CaseInsensitive; - return QRegExp(pattern, kase, QRegExp::RegExp2); + if (!d || !d->engine) + return QRegExp(); + return QScriptEnginePrivate::toRegExp(d->engine->currentFrame, d->jscValue); } #endif // QT_NO_REGEXP @@ -1574,19 +1251,9 @@ QRegExp QScriptValue::toRegExp() const QObject *QScriptValue::toQObject() const { Q_D(const QScriptValue); - if (isQObject()) { - QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(d->jscValue)); - QScriptObjectDelegate *delegate = object->delegate(); - if (delegate->type() == QScriptObjectDelegate::DeclarativeClassObject) - return static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->scriptClass()->toQObject(QScriptDeclarativeClass::object(*this)); - return static_cast<QScript::QObjectDelegate*>(delegate)->value(); - } else if (isVariant()) { - QVariant var = toVariant(); - int type = var.userType(); - if ((type == QMetaType::QObjectStar) || (type == QMetaType::QWidgetStar)) - return *reinterpret_cast<QObject* const *>(var.constData()); - } - return 0; + if (!d || !d->engine) + return 0; + return QScriptEnginePrivate::toQObject(d->engine->currentFrame, d->jscValue); } /*! @@ -1598,9 +1265,9 @@ QObject *QScriptValue::toQObject() const const QMetaObject *QScriptValue::toQMetaObject() const { Q_D(const QScriptValue); - if (isQMetaObject()) - return static_cast<QScript::QMetaObjectWrapperObject*>(JSC::asObject(d->jscValue))->value(); - return 0; + if (!d || !d->engine) + return 0; + return QScriptEnginePrivate::toQMetaObject(d->engine->currentFrame, d->jscValue); } /*! @@ -1634,8 +1301,15 @@ void QScriptValue::setProperty(const QString &name, const QScriptValue &value, Q_D(QScriptValue); if (!d || !d->isObject()) return; - JSC::ExecState *exec = d->engine->currentFrame; - d->setProperty(JSC::Identifier(exec, name), value, flags); + QScriptEnginePrivate *valueEngine = QScriptValuePrivate::getEngine(value); + if (valueEngine && (valueEngine != d->engine)) { + qWarning("QScriptValue::setProperty(%s) failed: " + "cannot set value created in a different engine", + qPrintable(name)); + return; + } + JSC::JSValue jsValue = d->engine->scriptValueToJSCValue(value); + d->setProperty(name, jsValue, flags); } /*! @@ -1659,7 +1333,7 @@ QScriptValue QScriptValue::property(const QString &name, Q_D(const QScriptValue); if (!d || !d->isObject()) return QScriptValue(); - return d->property(name, mode); + return d->engine->scriptValueFromJSCValue(d->property(name, mode)); } /*! @@ -1681,7 +1355,7 @@ QScriptValue QScriptValue::property(quint32 arrayIndex, Q_D(const QScriptValue); if (!d || !d->isObject()) return QScriptValue(); - return d->property(arrayIndex, mode); + return d->engine->scriptValueFromJSCValue(d->property(arrayIndex, mode)); } /*! @@ -1708,33 +1382,8 @@ void QScriptValue::setProperty(quint32 arrayIndex, const QScriptValue &value, "cannot set value created in a different engine"); return; } - JSC::ExecState *exec = d->engine->currentFrame; - JSC::JSValue jscValue = d->engine->scriptValueToJSCValue(value); - if (!jscValue) { - JSC::asObject(d->jscValue)->deleteProperty(exec, arrayIndex, /*checkDontDelete=*/false); - } else { - if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) { - // fall back to string-based setProperty(), since there is no - // JSC::JSObject::defineGetter(unsigned) - d->setProperty(JSC::Identifier::from(exec, arrayIndex), value, flags); - } else { - if (flags != QScriptValue::KeepExistingFlags) { -// if (JSC::asObject(d->jscValue)->hasOwnProperty(exec, arrayIndex)) -// JSC::asObject(d->jscValue)->deleteProperty(exec, arrayIndex); - unsigned attribs = 0; - if (flags & QScriptValue::ReadOnly) - attribs |= JSC::ReadOnly; - if (flags & QScriptValue::SkipInEnumeration) - attribs |= JSC::DontEnum; - if (flags & QScriptValue::Undeletable) - attribs |= JSC::DontDelete; - attribs |= flags & QScriptValue::UserRange; - JSC::asObject(d->jscValue)->putWithAttributes(exec, arrayIndex, jscValue, attribs); - } else { - JSC::asObject(d->jscValue)->put(exec, arrayIndex, jscValue); - } - } - } + JSC::JSValue jsValue = d->engine->scriptValueToJSCValue(value); + d->setProperty(arrayIndex, jsValue, flags); } /*! @@ -1755,7 +1404,7 @@ QScriptValue QScriptValue::property(const QScriptString &name, Q_D(const QScriptValue); if (!d || !d->isObject() || !QScriptStringPrivate::isValid(name)) return QScriptValue(); - return d->property(name.d_ptr->identifier, mode); + return d->engine->scriptValueFromJSCValue(d->property(name.d_ptr->identifier, mode)); } /*! @@ -1778,7 +1427,15 @@ void QScriptValue::setProperty(const QScriptString &name, Q_D(QScriptValue); if (!d || !d->isObject() || !QScriptStringPrivate::isValid(name)) return; - d->setProperty(name.d_ptr->identifier, value, flags); + QScriptEnginePrivate *valueEngine = QScriptValuePrivate::getEngine(value); + if (valueEngine && (valueEngine != d->engine)) { + qWarning("QScriptValue::setProperty(%s) failed: " + "cannot set value created in a different engine", + qPrintable(name.toString())); + return; + } + JSC::JSValue jsValue = d->engine->scriptValueToJSCValue(value); + d->setProperty(name.d_ptr->identifier, jsValue, flags); } /*! @@ -1882,12 +1539,12 @@ QScriptValue QScriptValue::call(const QScriptValue &thisObject, JSC::ArgList jscArgs(argsVector.data(), argsVector.size()); JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); JSC::JSValue result = JSC::call(exec, callee, callType, callData, jscThisObject, jscArgs); if (exec->hadException()) { result = exec->exception(); } else { - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); } return d->engine->scriptValueFromJSCValue(result); } @@ -1963,12 +1620,12 @@ QScriptValue QScriptValue::call(const QScriptValue &thisObject, } JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); JSC::JSValue result = JSC::call(exec, callee, callType, callData, jscThisObject, applyArgs); if (exec->hadException()) { result = exec->exception(); } else { - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); } return d->engine->scriptValueFromJSCValue(result); } @@ -2015,12 +1672,12 @@ QScriptValue QScriptValue::construct(const QScriptValueList &args) JSC::ArgList jscArgs(argsVector.data(), argsVector.size()); JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); JSC::JSObject *result = JSC::construct(exec, callee, constructType, constructData, jscArgs); if (exec->hadException()) { result = JSC::asObject(exec->exception()); } else { - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); } return d->engine->scriptValueFromJSCValue(result); } @@ -2074,13 +1731,13 @@ QScriptValue QScriptValue::construct(const QScriptValue &arguments) } JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); JSC::JSObject *result = JSC::construct(exec, callee, constructType, constructData, applyArgs); if (exec->hadException()) { if (exec->exception().isObject()) result = JSC::asObject(exec->exception()); } else { - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); } return d->engine->scriptValueFromJSCValue(result); } @@ -2229,11 +1886,9 @@ bool QScriptValue::isObject() const bool QScriptValue::isVariant() const { Q_D(const QScriptValue); - if (!d || !d->isJSC() || !d->jscValue.inherits(&QScriptObject::info)) + if (!d || !d->isJSC()) return false; - QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(d->jscValue)); - QScriptObjectDelegate *delegate = object->delegate(); - return (delegate && (delegate->type() == QScriptObjectDelegate::Variant)); + return QScriptEnginePrivate::isVariant(d->jscValue); } /*! @@ -2248,13 +1903,9 @@ bool QScriptValue::isVariant() const bool QScriptValue::isQObject() const { Q_D(const QScriptValue); - if (!d || !d->isJSC() || !d->jscValue.inherits(&QScriptObject::info)) + if (!d || !d->isJSC()) return false; - QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(d->jscValue)); - QScriptObjectDelegate *delegate = object->delegate(); - return (delegate && (delegate->type() == QScriptObjectDelegate::QtObject || - (delegate->type() == QScriptObjectDelegate::DeclarativeClassObject && - static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->scriptClass()->isQObject()))); + return QScriptEnginePrivate::isQObject(d->jscValue); } /*! @@ -2266,9 +1917,9 @@ bool QScriptValue::isQObject() const bool QScriptValue::isQMetaObject() const { Q_D(const QScriptValue); - if (!d || !d->isObject()) + if (!d || !d->isJSC()) return false; - return JSC::asObject(d->jscValue)->inherits(&QScript::QMetaObjectWrapperObject::info); + return QScriptEnginePrivate::isQMetaObject(d->jscValue); } /*! @@ -2299,7 +1950,7 @@ QScriptValue QScriptValue::data() const return d->engine->scriptValueFromJSCValue(scriptObject->data()); } else { // ### make hidden property - return d->property(QLatin1String("__qt_data__"), QScriptValue::ResolveLocal); + return property(QLatin1String("__qt_data__"), QScriptValue::ResolveLocal); } } diff --git a/src/script/api/qscriptvalue_p.h b/src/script/api/qscriptvalue_p.h index 7440d21..77b7330 100644 --- a/src/script/api/qscriptvalue_p.h +++ b/src/script/api/qscriptvalue_p.h @@ -69,9 +69,6 @@ public: inline bool isJSC() const; inline bool isObject() const; - QVariant &variantValue() const; - void setVariantValue(const QVariant &value); - static inline QScriptValuePrivate *get(const QScriptValue &q) { return q.d_ptr.data(); @@ -89,14 +86,16 @@ public: return q.d_ptr->engine; } - inline QScriptValue property(const JSC::Identifier &id, int resolveMode) const; - QScriptValue propertyHelper(const JSC::Identifier &id, int resolveMode) const; - inline QScriptValue property(quint32 index, int resolveMode) const; - QScriptValue propertyHelper(quint32, int resolveMode) const; - inline QScriptValue property(const QString &, int resolveMode) const; - void setProperty(const JSC::Identifier &id, const QScriptValue &value, - const QScriptValue::PropertyFlags &flags); - QScriptValue::PropertyFlags propertyFlags( + inline JSC::JSValue property(const JSC::Identifier &id, int resolveMode) const; + inline JSC::JSValue property(quint32 index, int resolveMode) const; + inline JSC::JSValue property(const QString &, int resolveMode) const; + inline void setProperty(const QString &name, const JSC::JSValue &value, + const QScriptValue::PropertyFlags &flags); + inline void setProperty(const JSC::Identifier &id, const JSC::JSValue &value, + const QScriptValue::PropertyFlags &flags); + inline void setProperty(quint32 index, const JSC::JSValue &value, + const QScriptValue::PropertyFlags &flags); + inline QScriptValue::PropertyFlags propertyFlags( const JSC::Identifier &id, const QScriptValue::ResolveFlags &mode) const; void detachFromEngine(); @@ -109,9 +108,6 @@ public: return -1; } - static inline void saveException(JSC::ExecState*, JSC::JSValue*); - static inline void restoreException(JSC::ExecState*, JSC::JSValue); - QScriptEnginePrivate *engine; Type type; JSC::JSValue jscValue; diff --git a/src/script/bridge/qscriptclassobject.cpp b/src/script/bridge/qscriptclassobject.cpp index a3dd239..ce0a08e 100644 --- a/src/script/bridge/qscriptclassobject.cpp +++ b/src/script/bridge/qscriptclassobject.cpp @@ -206,7 +206,7 @@ JSC::JSValue JSC_HOST_CALL ClassObjectDelegate::call(JSC::ExecState *exec, JSC:: QVariant result = scriptClass->extension(QScriptClass::Callable, qVariantFromValue(ctx)); eng_p->popContext(); eng_p->currentFrame = oldFrame; - return eng_p->jscValueFromVariant(result); + return QScriptEnginePrivate::jscValueFromVariant(exec, result); } JSC::ConstructType ClassObjectDelegate::getConstructData(QScriptObject*, JSC::ConstructData &constructData) diff --git a/src/script/bridge/qscriptdeclarativeclass.cpp b/src/script/bridge/qscriptdeclarativeclass.cpp index ce2fc23..1d11ede 100644 --- a/src/script/bridge/qscriptdeclarativeclass.cpp +++ b/src/script/bridge/qscriptdeclarativeclass.cpp @@ -207,25 +207,17 @@ QScriptDeclarativeClass::newObjectValue(QScriptEngine *engine, QScriptDeclarativeClass *QScriptDeclarativeClass::scriptClass(const QScriptValue &v) { QScriptValuePrivate *d = QScriptValuePrivate::get(v); - if (!d || !d->isJSC() || !d->jscValue.inherits(&QScriptObject::info)) + if (!d || !d->isJSC()) return 0; - QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(d->jscValue)); - QScriptObjectDelegate *delegate = scriptObject->delegate(); - if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject)) - return 0; - return static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->scriptClass(); + return QScriptEnginePrivate::declarativeClass(d->jscValue); } QScriptDeclarativeClass::Object *QScriptDeclarativeClass::object(const QScriptValue &v) { QScriptValuePrivate *d = QScriptValuePrivate::get(v); - if (!d || !d->isJSC() || !d->jscValue.inherits(&QScriptObject::info)) - return 0; - QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(d->jscValue)); - QScriptObjectDelegate *delegate = scriptObject->delegate(); - if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject)) + if (!d || !d->isJSC()) return 0; - return static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->object(); + return QScriptEnginePrivate::declarativeObject(d->jscValue); } QScriptValue QScriptDeclarativeClass::function(const QScriptValue &v, const Identifier &name) diff --git a/src/script/bridge/qscriptqobject.cpp b/src/script/bridge/qscriptqobject.cpp index db312bc..30e5a26 100644 --- a/src/script/bridge/qscriptqobject.cpp +++ b/src/script/bridge/qscriptqobject.cpp @@ -169,17 +169,15 @@ static inline QByteArray methodName(const QMetaMethod &method) return signature.left(signature.indexOf('(')); } -static QVariant variantFromValue(QScriptEnginePrivate *eng, - int targetType, const QScriptValue &value) +static QVariant variantFromValue(JSC::ExecState *exec, int targetType, JSC::JSValue value) { QVariant v(targetType, (void *)0); - Q_ASSERT(eng); - if (QScriptEnginePrivate::convert(value, targetType, v.data(), eng)) + if (QScriptEnginePrivate::convertValue(exec, value, targetType, v.data())) return v; if (uint(targetType) == QVariant::LastType) - return value.toVariant(); - if (value.isVariant()) { - v = value.toVariant(); + return QScriptEnginePrivate::toVariant(exec, value); + if (QScriptEnginePrivate::isVariant(value)) { + v = QScriptEnginePrivate::variantValue(value); if (v.canConvert(QVariant::Type(targetType))) { v.convert(QVariant::Type(targetType)); return v; @@ -591,38 +589,38 @@ static JSC::JSValue callQtMethod(JSC::ExecState *exec, QMetaMethod::MethodType c bool converted = true; int matchDistance = 0; for (int i = 0; converted && i < mtd.argumentCount(); ++i) { - QScriptValue actual; + JSC::JSValue actual; if (i < (int)scriptArgs.size()) - actual = engine->scriptValueFromJSCValue(scriptArgs.at(i)); + actual = scriptArgs.at(i); else - actual = QScriptValue(QScriptValue::UndefinedValue); + actual = JSC::jsUndefined(); QScriptMetaType argType = mtd.argumentType(i); int tid = -1; QVariant v; if (argType.isUnresolved()) { v = QVariant(QMetaType::QObjectStar, (void *)0); - converted = engine->convertToNativeQObject( - actual, argType.name(), reinterpret_cast<void* *>(v.data())); + converted = QScriptEnginePrivate::convertToNativeQObject( + exec, actual, argType.name(), reinterpret_cast<void* *>(v.data())); } else if (argType.isVariant()) { - if (actual.isVariant()) { - v = actual.toVariant(); + if (QScriptEnginePrivate::isVariant(actual)) { + v = QScriptEnginePrivate::variantValue(actual); } else { - v = actual.toVariant(); + v = QScriptEnginePrivate::toVariant(exec, actual); converted = v.isValid() || actual.isUndefined() || actual.isNull(); } } else { tid = argType.typeId(); v = QVariant(tid, (void *)0); - converted = QScriptEnginePrivate::convert(actual, tid, v.data(), engine); + converted = QScriptEnginePrivate::convertValue(exec, actual, tid, v.data()); if (exec->hadException()) return exec->exception(); } if (!converted) { - if (actual.isVariant()) { + if (QScriptEnginePrivate::isVariant(actual)) { if (tid == -1) tid = argType.typeId(); - QVariant vv = actual.toVariant(); + QVariant vv = QScriptEnginePrivate::variantValue(actual); if (vv.canConvert(QVariant::Type(tid))) { v = vv; converted = v.convert(QVariant::Type(tid)); @@ -649,14 +647,14 @@ static JSC::JSValue callQtMethod(JSC::ExecState *exec, QMetaMethod::MethodType c } if (m.isValid()) { if (actual.isNumber()) { - int ival = actual.toInt32(); + int ival = QScriptEnginePrivate::toInt32(exec, actual); if (m.valueToKey(ival) != 0) { qVariantSetValue(v, ival); converted = true; matchDistance += 10; } } else { - QString sval = actual.toString(); + QString sval = QScriptEnginePrivate::toString(exec, actual); int ival = m.keyToValue(sval.toLatin1()); if (ival != -1) { qVariantSetValue(v, ival); @@ -718,7 +716,7 @@ static JSC::JSValue callQtMethod(JSC::ExecState *exec, QMetaMethod::MethodType c matchDistance += 10; break; } - } else if (actual.isDate()) { + } else if (QScriptEnginePrivate::isDate(actual)) { switch (tid) { case QMetaType::QDateTime: // perfect @@ -733,7 +731,7 @@ static JSC::JSValue callQtMethod(JSC::ExecState *exec, QMetaMethod::MethodType c matchDistance += 10; break; } - } else if (actual.isRegExp()) { + } else if (QScriptEnginePrivate::isRegExp(actual)) { switch (tid) { case QMetaType::QRegExp: // perfect @@ -742,14 +740,14 @@ static JSC::JSValue callQtMethod(JSC::ExecState *exec, QMetaMethod::MethodType c matchDistance += 10; break; } - } else if (actual.isVariant()) { + } else if (QScriptEnginePrivate::isVariant(actual)) { if (argType.isVariant() - || (actual.toVariant().userType() == tid)) { + || (QScriptEnginePrivate::toVariant(exec, actual).userType() == tid)) { // perfect } else { matchDistance += 10; } - } else if (actual.isArray()) { + } else if (QScriptEnginePrivate::isArray(actual)) { switch (tid) { case QMetaType::QStringList: case QMetaType::QVariantList: @@ -759,7 +757,7 @@ static JSC::JSValue callQtMethod(JSC::ExecState *exec, QMetaMethod::MethodType c matchDistance += 10; break; } - } else if (actual.isQObject()) { + } else if (QScriptEnginePrivate::isQObject(actual)) { switch (tid) { case QMetaType::QObjectStar: case QMetaType::QWidgetStar: @@ -953,13 +951,11 @@ static JSC::JSValue callQtMethod(JSC::ExecState *exec, QMetaMethod::MethodType c } else { QScriptMetaType retType = chosenMethod.returnType(); if (retType.isVariant()) { - result = engine->jscValueFromVariant(*(QVariant *)params[0]); + result = QScriptEnginePrivate::jscValueFromVariant(exec, *(QVariant *)params[0]); } else if (retType.typeId() != 0) { - result = engine->scriptValueToJSCValue(engine->create(retType.typeId(), params[0])); - if (!result) { - QScriptValue sv = QScriptEnginePrivate::get(engine)->newVariant(QVariant(retType.typeId(), params[0])); - result = engine->scriptValueToJSCValue(sv); - } + result = QScriptEnginePrivate::create(exec, retType.typeId(), params[0]); + if (!result) + result = engine->newVariant(QVariant(retType.typeId(), params[0])); } else { result = JSC::jsUndefined(); } @@ -1065,15 +1061,13 @@ JSC::JSValue QtPropertyFunction::execute(JSC::ExecState *exec, { JSC::JSValue result = JSC::jsUndefined(); - // ### don't go via QScriptValue QScriptEnginePrivate *engine = scriptEngineFromExec(exec); thisValue = engine->toUsableValue(thisValue); - QScriptValue object = engine->scriptValueFromJSCValue(thisValue); - QObject *qobject = object.toQObject(); + QObject *qobject = QScriptEnginePrivate::toQObject(exec, thisValue); while ((!qobject || (qobject->metaObject() != data->meta)) - && object.prototype().isObject()) { - object = object.prototype(); - qobject = object.toQObject(); + && JSC::asObject(thisValue)->prototype().isObject()) { + thisValue = JSC::asObject(thisValue)->prototype(); + qobject = QScriptEnginePrivate::toQObject(exec, thisValue); } Q_ASSERT_X(qobject, Q_FUNC_INFO, "this-object must be a QObject"); @@ -1094,7 +1088,7 @@ JSC::JSValue QtPropertyFunction::execute(JSC::ExecState *exec, if (scriptable) QScriptablePrivate::get(scriptable)->engine = oldEngine; - result = engine->jscValueFromVariant(v); + result = QScriptEnginePrivate::jscValueFromVariant(exec, v); } } else { // set @@ -1106,9 +1100,7 @@ JSC::JSValue QtPropertyFunction::execute(JSC::ExecState *exec, // string to enum value v = (QString)arg.toString(exec); } else { - // ### don't go via QScriptValue - QScriptValue tmp = engine->scriptValueFromJSCValue(arg); - v = variantFromValue(engine, prop.userType(), tmp); + v = variantFromValue(exec, prop.userType(), arg); } QScriptable *scriptable = scriptableFromQObject(qobject); @@ -1237,7 +1229,7 @@ bool QObjectDelegate::getOwnPropertySlot(QScriptObject *object, JSC::ExecState * if (!prop.isValid()) val = JSC::jsUndefined(); else - val = eng->jscValueFromVariant(prop.read(qobject)); + val = QScriptEnginePrivate::jscValueFromVariant(exec, prop.read(qobject)); slot.setValue(val); } return true; @@ -1247,7 +1239,7 @@ bool QObjectDelegate::getOwnPropertySlot(QScriptObject *object, JSC::ExecState * index = qobject->dynamicPropertyNames().indexOf(name); if (index != -1) { - JSC::JSValue val = eng->jscValueFromVariant(qobject->property(name)); + JSC::JSValue val = QScriptEnginePrivate::jscValueFromVariant(exec, qobject->property(name)); slot.setValue(val); return true; } @@ -1274,8 +1266,7 @@ bool QObjectDelegate::getOwnPropertySlot(QScriptObject *object, JSC::ExecState * QObject *child = children.at(index); if (child->objectName() == QString(propertyName.ustring())) { QScriptEngine::QObjectWrapOptions opt = QScriptEngine::PreferExistingWrapperObject; - QScriptValue tmp = QScriptEnginePrivate::get(eng)->newQObject(child, QScriptEngine::QtOwnership, opt); - slot.setValue(eng->scriptValueToJSCValue(tmp)); + slot.setValue(eng->newQObject(child, QScriptEngine::QtOwnership, opt)); return true; } } @@ -1370,7 +1361,7 @@ bool QObjectDelegate::getOwnPropertyDescriptor(QScriptObject *object, JSC::ExecS if (!prop.isValid()) val = JSC::jsUndefined(); else - val = eng->jscValueFromVariant(prop.read(qobject)); + val = QScriptEnginePrivate::jscValueFromVariant(exec, prop.read(qobject)); descriptor.setDescriptor(val, attributes); } return true; @@ -1380,7 +1371,7 @@ bool QObjectDelegate::getOwnPropertyDescriptor(QScriptObject *object, JSC::ExecS index = qobject->dynamicPropertyNames().indexOf(name); if (index != -1) { - JSC::JSValue val = eng->jscValueFromVariant(qobject->property(name)); + JSC::JSValue val = QScriptEnginePrivate::jscValueFromVariant(exec, qobject->property(name)); descriptor.setDescriptor(val, QObjectMemberAttribute); return true; } @@ -1410,8 +1401,8 @@ bool QObjectDelegate::getOwnPropertyDescriptor(QScriptObject *object, JSC::ExecS QObject *child = children.at(index); if (child->objectName() == QString(propertyName.ustring())) { QScriptEngine::QObjectWrapOptions opt = QScriptEngine::PreferExistingWrapperObject; - QScriptValue tmp = QScriptEnginePrivate::get(eng)->newQObject(child, QScriptEngine::QtOwnership, opt); - descriptor.setDescriptor(eng->scriptValueToJSCValue(tmp), JSC::ReadOnly | JSC::DontDelete | JSC::DontEnum); + descriptor.setDescriptor(eng->newQObject(child, QScriptEngine::QtOwnership, opt), + JSC::ReadOnly | JSC::DontDelete | JSC::DontEnum); return true; } } @@ -1490,7 +1481,7 @@ void QObjectDelegate::put(QScriptObject *object, JSC::ExecState* exec, // string to enum value v = (QString)value.toString(exec); } else { - v = eng->jscValueToVariant(value, prop.userType()); + v = QScriptEnginePrivate::jscValueToVariant(exec, value, prop.userType()); } (void)prop.write(qobject, v); } @@ -1512,7 +1503,7 @@ void QObjectDelegate::put(QScriptObject *object, JSC::ExecState* exec, index = qobject->dynamicPropertyNames().indexOf(name); if ((index != -1) || (opt & QScriptEngine::AutoCreateDynamicProperties)) { - QVariant v = eng->scriptValueFromJSCValue(value).toVariant(); + QVariant v = QScriptEnginePrivate::toVariant(exec, value); (void)qobject->setProperty(name, v); return; } @@ -2178,24 +2169,23 @@ void QObjectConnectionManager::execute(int slotIndex, void **argv) JSC::ExecState *exec = engine->currentFrame; QVarLengthArray<JSC::JSValue, 8> argsVector(argc); for (int i = 0; i < argc; ++i) { - // ### optimize -- no need to convert via QScriptValue - QScriptValue actual; + JSC::JSValue actual; void *arg = argv[i + 1]; QByteArray typeName = parameterTypes.at(i); int argType = QMetaType::type(parameterTypes.at(i)); if (!argType) { if (typeName == "QVariant") { - actual = engine->scriptValueFromVariant(*reinterpret_cast<QVariant*>(arg)); + actual = QScriptEnginePrivate::jscValueFromVariant(exec, *reinterpret_cast<QVariant*>(arg)); } else { qWarning("QScriptEngine: Unable to handle unregistered datatype '%s' " "when invoking handler of signal %s::%s", typeName.constData(), meta->className(), method.signature()); - actual = QScriptValue(QScriptValue::UndefinedValue); + actual = JSC::jsUndefined(); } } else { - actual = engine->create(argType, arg); + actual = QScriptEnginePrivate::create(exec, argType, arg); } - argsVector[i] = engine->scriptValueToJSCValue(actual); + argsVector[i] = actual; } JSC::ArgList jscArgs(argsVector.data(), argsVector.size()); diff --git a/src/script/bridge/qscriptvariant.cpp b/src/script/bridge/qscriptvariant.cpp index 0287d24..b4f0365 100644 --- a/src/script/bridge/qscriptvariant.cpp +++ b/src/script/bridge/qscriptvariant.cpp @@ -133,7 +133,7 @@ static JSC::JSValue JSC_HOST_CALL variantProtoFuncToString(JSC::ExecState *exec, bool QVariantDelegate::compareToObject(QScriptObject *, JSC::ExecState *exec, JSC::JSObject *o2) { const QVariant &variant1 = value(); - return variant1 == scriptEngineFromExec(exec)->scriptValueFromJSCValue(o2).toVariant(); + return variant1 == QScriptEnginePrivate::toVariant(exec, o2); } QVariantPrototype::QVariantPrototype(JSC::ExecState* exec, WTF::PassRefPtr<JSC::Structure> structure, |