From 505dc33a4060b6fb2a80f3a3ab2a6702ec0b5f3b Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Wed, 17 Feb 2010 13:02:37 +0100 Subject: Make the licenseheader check pass trivial files. A file that contains so little doesn't have to have the copyright header. A good example usecase is a header file with nothing but an include line to another header. Reviewed-by: Thiago Macieira --- tests/auto/headers/tst_headers.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/auto/headers/tst_headers.cpp b/tests/auto/headers/tst_headers.cpp index 5f79923..bf7ec3f 100644 --- a/tests/auto/headers/tst_headers.cpp +++ b/tests/auto/headers/tst_headers.cpp @@ -192,19 +192,20 @@ void tst_Headers::licenseCheck() QByteArray data = f.readAll(); data.replace("\r\n", "\n"); // Windows data.replace('\r', '\n'); // Mac OS9 - QStringList content = QString::fromLocal8Bit(data).split("\n"); + QStringList content = QString::fromLocal8Bit(data).split("\n", QString::SkipEmptyParts); + + if (content.count() <= 2) // likely a #include line and empty line only. Not a copyright issue. + return; if (content.first().contains("generated")) { content.takeFirst(); - if (content.first().isEmpty()) - content.takeFirst(); } if (sourceFile.endsWith("/tests/auto/linguist/lupdate/testdata/good/merge_ordering/foo.cpp") || sourceFile.endsWith("/tests/auto/linguist/lupdate/testdata/good/mergecpp/finddialog.cpp")) { // These files are meant to start with empty lines. - while (content.first().isEmpty() || content.first().startsWith("//")) + while (content.first().startsWith("//")) content.takeFirst(); } -- cgit v0.12 From 8865e9cd3389956f2e5909a1261566f21eef128f Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 18 Feb 2010 12:15:00 +0100 Subject: Cleanup: Move exception helper functions to QScriptEnginePrivate Because that's where they belong. Reviewed-by: Jedrzej Nowacki --- src/script/api/qscriptengine_p.h | 7 +++-- src/script/api/qscriptvalue.cpp | 60 ++++++++++++++++++++-------------------- src/script/api/qscriptvalue_p.h | 3 -- 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index 6780b2c..86ac5df 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -177,6 +177,9 @@ 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(); } @@ -514,7 +517,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 +527,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); diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp index 5bfe46a..1faade9 100644 --- a/src/script/api/qscriptvalue.cpp +++ b/src/script/api/qscriptvalue.cpp @@ -910,9 +910,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 +1103,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; } } @@ -1192,16 +1192,16 @@ QString QScriptValue::toString() const case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); JSC::UString str = d->jscValue.toString(exec); if (exec && exec->hadException() && !str.size()) { JSC::JSValue savedException2; - QScriptValuePrivate::saveException(exec, &savedException2); + QScriptEnginePrivate::saveException(exec, &savedException2); str = savedException2.toString(exec); - QScriptValuePrivate::restoreException(exec, savedException2); + QScriptEnginePrivate::restoreException(exec, savedException2); } if (savedException) - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); return str; } case QScriptValuePrivate::Number: @@ -1233,9 +1233,9 @@ qsreal QScriptValue::toNumber() const case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); qsreal result = d->jscValue.toNumber(exec); - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); return result; } case QScriptValuePrivate::Number: @@ -1260,9 +1260,9 @@ bool QScriptValue::toBoolean() const case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); bool result = d->jscValue.toBoolean(exec); - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); return result; } case QScriptValuePrivate::Number: @@ -1296,9 +1296,9 @@ bool QScriptValue::toBool() const case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); bool result = d->jscValue.toBoolean(exec); - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); return result; } case QScriptValuePrivate::Number: @@ -1330,9 +1330,9 @@ qint32 QScriptValue::toInt32() const case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); qint32 result = d->jscValue.toInt32(exec); - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); return result; } case QScriptValuePrivate::Number: @@ -1364,9 +1364,9 @@ quint32 QScriptValue::toUInt32() const case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); quint32 result = d->jscValue.toUInt32(exec); - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); return result; } case QScriptValuePrivate::Number: @@ -1428,9 +1428,9 @@ qsreal QScriptValue::toInteger() const case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); qsreal result = d->jscValue.toInteger(exec); - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); return result; } case QScriptValuePrivate::Number: @@ -1490,9 +1490,9 @@ QVariant QScriptValue::toVariant() const // try to convert to primitive JSC::ExecState *exec = d->engine->currentFrame; JSC::JSValue savedException; - QScriptValuePrivate::saveException(exec, &savedException); + QScriptEnginePrivate::saveException(exec, &savedException); JSC::JSValue prim = d->jscValue.toPrimitive(exec); - QScriptValuePrivate::restoreException(exec, savedException); + QScriptEnginePrivate::restoreException(exec, savedException); if (!prim.isObject()) return d->engine->scriptValueFromJSCValue(prim).toVariant(); } else if (isNumber()) { @@ -1882,12 +1882,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 +1963,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 +2015,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 +2074,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); } diff --git a/src/script/api/qscriptvalue_p.h b/src/script/api/qscriptvalue_p.h index 7440d21..76fbc18 100644 --- a/src/script/api/qscriptvalue_p.h +++ b/src/script/api/qscriptvalue_p.h @@ -109,9 +109,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; -- cgit v0.12 From c86e7dfb0f6bcc0821ece5cf42a793d164d3f7a2 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 18 Feb 2010 12:25:50 +0100 Subject: Move some helper function declarations outside QT_NO_QOBJECT guard These are not dependent on QObject, I don't know how they ended up inside there. Reviewed-by: Jedrzej Nowacki --- src/script/api/qscriptengine_p.h | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index 86ac5df..9a357e5 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -184,6 +184,20 @@ public: 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(); + #ifndef QT_NO_QOBJECT JSC::JSValue newQObject(QObject *object, QScriptEngine::ValueOwnership ownership = QScriptEngine::QtOwnership, @@ -191,8 +205,6 @@ 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, const QByteArray &targetType, void **result); @@ -223,17 +235,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 -- cgit v0.12 From 0cad410d78758c79126d15664ec3d527883a9496 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 18 Feb 2010 12:36:32 +0100 Subject: Cleanup: Move number conversion functions to QScriptEnginePrivate Also rename ToUint{16,32} to ToUInt{16,32} to follow the Qt naming (it takes precedence over the ECMA one). Reviewed-by: Jedrzej Nowacki --- src/script/api/qscriptengine.cpp | 72 +++++++++++++++++++++++++++++++- src/script/api/qscriptengine_p.h | 5 +++ src/script/api/qscriptvalue.cpp | 88 +++------------------------------------- 3 files changed, 81 insertions(+), 84 deletions(-) diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 237b6fd..d8f7b3f 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,6 +40,9 @@ #include #include +#include +#include + #include "Error.h" #include "JSArray.h" #include "JSLock.h" @@ -328,6 +330,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); diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index 9a357e5..f55dc27 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -83,6 +83,11 @@ namespace QScript #endif class TimeoutCheckerProxy; + qint32 ToInt32(qsreal); + quint32 ToUInt32(qsreal); + quint16 ToUInt16(qsreal); + qsreal ToInteger(qsreal); + //some conversion helper functions inline QScriptEnginePrivate *scriptEngineFromExec(const JSC::ExecState *exec); bool isFunction(JSC::JSValue value); diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp index 1faade9..e8c2050 100644 --- a/src/script/api/qscriptvalue.cpp +++ b/src/script/api/qscriptvalue.cpp @@ -180,86 +180,8 @@ \omitvalue ResolveFull Check the object's own properties first, then search the prototype chain, and finally search the scope chain. */ -// ### move - -#include -#include - 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; @@ -1370,9 +1292,9 @@ quint32 QScriptValue::toUInt32() const return result; } 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(((JSC::UString)d->stringValue).toDouble()); } return 0; } @@ -1397,12 +1319,12 @@ quint16 QScriptValue::toUInt16() const switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { // ### no equivalent function in JSC - return QScript::ToUint16(toNumber()); + return QScript::ToUInt16(toNumber()); } 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(((JSC::UString)d->stringValue).toDouble()); } return 0; } -- cgit v0.12 From d65299511f80c67be4c326a91106ae273aad6d66 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 18 Feb 2010 12:59:48 +0100 Subject: Move implementation of QScriptValue construction functions to private class In preparation of getting rid of QScriptValue construction internally; the implementation should only call the private functions that operate directly on JSC::JSValues. Reviewed-by: Jedrzej Nowacki --- src/script/api/qscriptengine.cpp | 185 ++++++++++++++++++++------------------- src/script/api/qscriptengine_p.h | 39 +++++++++ 2 files changed, 133 insertions(+), 91 deletions(-) diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index d8f7b3f..988e362 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -44,11 +44,8 @@ #include #include "Error.h" -#include "JSArray.h" #include "JSLock.h" #include "Interpreter.h" -#include "DateConstructor.h" -#include "RegExpConstructor.h" #include "PrototypeFunction.h" #include "InitializeThreading.h" @@ -60,9 +57,7 @@ #include "Parser.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" @@ -1497,6 +1492,92 @@ 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; +} + #ifdef QT_NO_QOBJECT QScriptEngine::QScriptEngine() @@ -1669,56 +1750,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 @@ -1736,14 +1768,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)); } /*! @@ -1882,9 +1907,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()); } /*! @@ -2007,9 +2030,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)); } /*! @@ -2022,22 +2043,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)); } /*! @@ -2048,11 +2054,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)); } /*! @@ -2062,7 +2064,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 diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index f55dc27..46df429 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -41,10 +41,15 @@ #include #include "qscriptvalue_p.h" #include "qscriptstring_p.h" +#include "bridge/qscriptobject_p.h" +#include "utils/qscriptdate_p.h" +#include "DateConstructor.h" #include "Debugger.h" +#include "JSArray.h" #include "Lexer.h" #include "RefPtr.h" +#include "RegExpConstructor.h" #include "SourceProvider.h" #include "Structure.h" #include "JSGlobalObject.h" @@ -203,6 +208,18 @@ public: 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 &); + #ifndef QT_NO_QOBJECT JSC::JSValue newQObject(QObject *object, QScriptEngine::ValueOwnership ownership = QScriptEngine::QtOwnership, @@ -587,6 +604,28 @@ 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); +} + QT_END_NAMESPACE #endif -- cgit v0.12 From bc5c2c7362e0ad60990871e84426027a812937fc Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 18 Feb 2010 13:10:12 +0100 Subject: Cleanup: Move value conversion code to helper functions In preparation of doing this conversion in more places. Reviewed-by: Jedrzej Nowacki --- src/script/api/qscriptengine.cpp | 1 - src/script/api/qscriptengine_p.h | 50 ++++++++++++++++++++++++++++++++++++++++ src/script/api/qscriptvalue.cpp | 20 ++++++++-------- 3 files changed, 60 insertions(+), 11 deletions(-) diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 988e362..06233d9 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -40,7 +40,6 @@ #include #include -#include #include #include "Error.h" diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index 46df429..daf670f 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -38,6 +38,7 @@ #include "private/qobject_p.h" #include +#include #include #include "qscriptvalue_p.h" #include "qscriptstring_p.h" @@ -93,6 +94,15 @@ namespace QScript 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); @@ -396,6 +406,46 @@ inline QScriptEnginePrivate *scriptEngineFromExec(const JSC::ExecState *exec) return static_cast(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) diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp index e8c2050..724bbe3 100644 --- a/src/script/api/qscriptvalue.cpp +++ b/src/script/api/qscriptvalue.cpp @@ -1127,7 +1127,7 @@ QString QScriptValue::toString() const return str; } case QScriptValuePrivate::Number: - return JSC::UString::from(d->numberValue); + return QScript::ToString(d->numberValue); case QScriptValuePrivate::String: return d->stringValue; } @@ -1163,7 +1163,7 @@ qsreal QScriptValue::toNumber() const case QScriptValuePrivate::Number: return d->numberValue; case QScriptValuePrivate::String: - return ((JSC::UString)d->stringValue).toDouble(); + return QScript::ToNumber(d->stringValue); } return 0; } @@ -1188,9 +1188,9 @@ bool QScriptValue::toBoolean() const return result; } 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; } @@ -1224,9 +1224,9 @@ bool QScriptValue::toBool() const return result; } 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; } @@ -1260,7 +1260,7 @@ qint32 QScriptValue::toInt32() const 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; } @@ -1294,7 +1294,7 @@ quint32 QScriptValue::toUInt32() const case QScriptValuePrivate::Number: return QScript::ToUInt32(d->numberValue); case QScriptValuePrivate::String: - return QScript::ToUInt32(((JSC::UString)d->stringValue).toDouble()); + return QScript::ToUInt32(d->stringValue); } return 0; } @@ -1324,7 +1324,7 @@ quint16 QScriptValue::toUInt16() const case QScriptValuePrivate::Number: return QScript::ToUInt16(d->numberValue); case QScriptValuePrivate::String: - return QScript::ToUInt16(((JSC::UString)d->stringValue).toDouble()); + return QScript::ToUInt16(d->stringValue); } return 0; } @@ -1358,7 +1358,7 @@ qsreal QScriptValue::toInteger() const 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; } -- cgit v0.12 From af4ccb478650b7efd5de3d81439173cd31931bd2 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 18 Feb 2010 13:54:18 +0100 Subject: Move more script value conversion code to helper functions In preparation of operating purely on JSC::JSValue internally. Reviewed-by: Jedrzej Nowacki --- src/script/api/qscriptengine_p.h | 131 +++++++++++++++++++++++++++++++++++++++ src/script/api/qscriptvalue.cpp | 86 +++++++------------------ 2 files changed, 152 insertions(+), 65 deletions(-) diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index daf670f..5f079f4 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -37,8 +37,10 @@ #include "private/qobject_p.h" +#include #include #include +#include #include #include "qscriptvalue_p.h" #include "qscriptstring_p.h" @@ -46,11 +48,14 @@ #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" @@ -134,6 +139,23 @@ public: static QScriptEnginePrivate *get(QScriptEngine *q) { return q ? q->d_func() : 0; } static QScriptEngine *get(QScriptEnginePrivate *d) { return d ? d->q_func() : 0; } + 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 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); + static bool convert(const QScriptValue &value, int type, void *ptr, QScriptEnginePrivate *eng); @@ -676,6 +698,115 @@ 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(JSC::asObject(value)); + QScriptObjectDelegate *delegate = object->delegate(); + return (delegate && (delegate->type() == QScriptObjectDelegate::Variant)); +} + +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::asObject(value))->internalNumber(); + return QScript::ToDateTime(t, Qt::LocalTime); +} + QT_END_NAMESPACE #endif diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp index 724bbe3..929f606 100644 --- a/src/script/api/qscriptvalue.cpp +++ b/src/script/api/qscriptvalue.cpp @@ -29,21 +29,15 @@ #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 -#include #include #include #include @@ -629,9 +623,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); } /*! @@ -643,9 +637,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); } /*! @@ -657,9 +651,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); } /*! @@ -671,9 +665,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); } /*! @@ -1113,18 +1107,7 @@ QString QScriptValue::toString() const switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - JSC::JSValue savedException; - QScriptEnginePrivate::saveException(exec, &savedException); - JSC::UString str = d->jscValue.toString(exec); - if (exec && exec->hadException() && !str.size()) { - JSC::JSValue savedException2; - QScriptEnginePrivate::saveException(exec, &savedException2); - str = savedException2.toString(exec); - QScriptEnginePrivate::restoreException(exec, savedException2); - } - if (savedException) - QScriptEnginePrivate::restoreException(exec, savedException); - return str; + return QScriptEnginePrivate::toString(exec, d->jscValue); } case QScriptValuePrivate::Number: return QScript::ToString(d->numberValue); @@ -1154,11 +1137,7 @@ qsreal QScriptValue::toNumber() const switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - JSC::JSValue savedException; - QScriptEnginePrivate::saveException(exec, &savedException); - qsreal result = d->jscValue.toNumber(exec); - QScriptEnginePrivate::restoreException(exec, savedException); - return result; + return QScriptEnginePrivate::toNumber(exec, d->jscValue); } case QScriptValuePrivate::Number: return d->numberValue; @@ -1181,11 +1160,7 @@ bool QScriptValue::toBoolean() const switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - JSC::JSValue savedException; - QScriptEnginePrivate::saveException(exec, &savedException); - bool result = d->jscValue.toBoolean(exec); - QScriptEnginePrivate::restoreException(exec, savedException); - return result; + return QScriptEnginePrivate::toBool(exec, d->jscValue); } case QScriptValuePrivate::Number: return QScript::ToBool(d->numberValue); @@ -1217,11 +1192,7 @@ bool QScriptValue::toBool() const switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - JSC::JSValue savedException; - QScriptEnginePrivate::saveException(exec, &savedException); - bool result = d->jscValue.toBoolean(exec); - QScriptEnginePrivate::restoreException(exec, savedException); - return result; + return QScriptEnginePrivate::toBool(exec, d->jscValue); } case QScriptValuePrivate::Number: return QScript::ToBool(d->numberValue); @@ -1251,11 +1222,7 @@ qint32 QScriptValue::toInt32() const switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - JSC::JSValue savedException; - QScriptEnginePrivate::saveException(exec, &savedException); - qint32 result = d->jscValue.toInt32(exec); - QScriptEnginePrivate::restoreException(exec, savedException); - return result; + return QScriptEnginePrivate::toInt32(exec, d->jscValue); } case QScriptValuePrivate::Number: return QScript::ToInt32(d->numberValue); @@ -1285,11 +1252,7 @@ quint32 QScriptValue::toUInt32() const switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - JSC::JSValue savedException; - QScriptEnginePrivate::saveException(exec, &savedException); - quint32 result = d->jscValue.toUInt32(exec); - QScriptEnginePrivate::restoreException(exec, savedException); - return result; + return QScriptEnginePrivate::toUInt32(exec, d->jscValue); } case QScriptValuePrivate::Number: return QScript::ToUInt32(d->numberValue); @@ -1318,8 +1281,8 @@ 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); @@ -1349,11 +1312,7 @@ qsreal QScriptValue::toInteger() const switch (d->type) { case QScriptValuePrivate::JavaScriptCore: { JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; - JSC::JSValue savedException; - QScriptEnginePrivate::saveException(exec, &savedException); - qsreal result = d->jscValue.toInteger(exec); - QScriptEnginePrivate::restoreException(exec, savedException); - return result; + return QScriptEnginePrivate::toInteger(exec, d->jscValue); } case QScriptValuePrivate::Number: return QScript::ToInteger(d->numberValue); @@ -1456,10 +1415,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::asObject(d->jscValue))->internalNumber(); - return QScript::ToDateTime(t, Qt::LocalTime); + return QScriptEnginePrivate::toDateTime(d->engine->currentFrame, d->jscValue); } #ifndef QT_NO_REGEXP @@ -2151,11 +2109,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(JSC::asObject(d->jscValue)); - QScriptObjectDelegate *delegate = object->delegate(); - return (delegate && (delegate->type() == QScriptObjectDelegate::Variant)); + return QScriptEnginePrivate::isVariant(d->jscValue); } /*! -- cgit v0.12 From 8e0a364f7baed4bbc7ff711be2a15692a40c3e93 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 18 Feb 2010 14:23:42 +0100 Subject: Move property helper functions to QScriptEnginePrivate More preparation for operating purely on JSC::JSValue internally. Reviewed-by: Jedrzej Nowacki --- src/script/api/qscriptengine.cpp | 166 ++++++++++++++++++++++++++++++ src/script/api/qscriptengine_p.h | 99 +++++++++++++++--- src/script/api/qscriptvalue.cpp | 211 ++++++--------------------------------- src/script/api/qscriptvalue_p.h | 18 ++-- 4 files changed, 288 insertions(+), 206 deletions(-) diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 06233d9..a045bab 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -1577,6 +1577,172 @@ JSC::JSValue QScriptEnginePrivate::newVariant(const QVariant &value) return obj; } +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() diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index 5f079f4..4be9146 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -156,6 +156,24 @@ public: static inline QDateTime toDateTime(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 convert(const QScriptValue &value, int type, void *ptr, QScriptEnginePrivate *eng); @@ -568,32 +586,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) diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp index 929f606..a7d9f79 100644 --- a/src/script/api/qscriptvalue.cpp +++ b/src/script/api/qscriptvalue.cpp @@ -176,152 +176,6 @@ QT_BEGIN_NAMESPACE -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)); @@ -732,7 +586,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); } /*! @@ -1433,9 +1288,9 @@ QRegExp QScriptValue::toRegExp() const Q_D(const QScriptValue); if (!isRegExp()) return QRegExp(); - QString pattern = d->property(QLatin1String("source"), QScriptValue::ResolvePrototype).toString(); + QString pattern = property(QLatin1String("source"), QScriptValue::ResolvePrototype).toString(); Qt::CaseSensitivity kase = Qt::CaseSensitive; - if (d->property(QLatin1String("ignoreCase"), QScriptValue::ResolvePrototype).toBool()) + if (property(QLatin1String("ignoreCase"), QScriptValue::ResolvePrototype).toBool()) kase = Qt::CaseInsensitive; return QRegExp(pattern, kase, QRegExp::RegExp2); } @@ -1514,8 +1369,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); } /*! @@ -1539,7 +1401,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)); } /*! @@ -1561,7 +1423,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)); } /*! @@ -1588,33 +1450,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); } /*! @@ -1635,7 +1472,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)); } /*! @@ -1658,7 +1495,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); } /*! @@ -2177,7 +2022,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 76fbc18..dedc250 100644 --- a/src/script/api/qscriptvalue_p.h +++ b/src/script/api/qscriptvalue_p.h @@ -89,14 +89,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(); -- cgit v0.12 From d5af42b1b7d792188c689d5425493756f2dcb79e Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 18 Feb 2010 15:29:32 +0100 Subject: Avoid calling out to public API in the QtScript implementation There's no reason to construct QScriptValues when JSC::JSValues can be operated on directly. A benchmark showed that ~10% of the time for reading a QObject property from a script was spent just creating and destroying QScriptValue temporaries. It's time to finally get rid of this potential bottleneck, not just in the QObject integration but everywhere. This change refactors the code so that all internal operations are performed on JSC::JSValue (most importantly, conversion from/to Qt types), and the public API functions are just thin wrappers around these. E.g. instead of doing enginePrivate->scriptValueFromJSCValue(jsValue).toQObject() the implementation now does QScriptEnginePrivate::toQObject(jsValue) Other operations are delegated to the engine implementation in similar style. Task-number: QTBUG-8304 Reviewed-by: Jedrzej Nowacki --- src/script/api/qscriptengine.cpp | 487 ++++++++++++++++---------- src/script/api/qscriptengine_p.h | 150 +++++++- src/script/api/qscriptvalue.cpp | 106 +----- src/script/api/qscriptvalue_p.h | 3 - src/script/bridge/qscriptclassobject.cpp | 2 +- src/script/bridge/qscriptdeclarativeclass.cpp | 16 +- src/script/bridge/qscriptqobject.cpp | 106 +++--- src/script/bridge/qscriptvariant.cpp | 2 +- 8 files changed, 513 insertions(+), 359 deletions(-) diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index a045bab..739b3fc 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -54,6 +54,7 @@ #include "TimeoutChecker.h" #include "JSFunction.h" #include "Parser.h" +#include "PropertyNameArray.h" #include "Operations.h" #include "bridge/qscriptfunction_p.h" @@ -546,11 +547,9 @@ JSC::JSValue JSC_HOST_CALL functionDisconnect(JSC::ExecState *exec, JSC::JSObjec if (isFunction(arg1)) slot = arg1; else { - // ### don't go via QScriptValue QScript::SaveFrameHelper saveFrame(engine, exec); - QScriptValue tmp = engine->scriptValueFromJSCValue(arg0); - QString propertyName(arg1.toString(exec)); - slot = engine->scriptValueToJSCValue(tmp.property(propertyName, QScriptValue::ResolvePrototype)); + QString propertyName(QScriptEnginePrivate::toString(exec, arg1)); + slot = QScriptEnginePrivate::property(exec, arg0, propertyName, QScriptValue::ResolvePrototype); } } @@ -630,11 +629,9 @@ JSC::JSValue JSC_HOST_CALL functionConnect(JSC::ExecState *exec, JSC::JSObject * if (isFunction(arg1)) slot = arg1; else { - // ### don't go via QScriptValue QScript::SaveFrameHelper saveFrame(engine, exec); - QScriptValue tmp = engine->scriptValueFromJSCValue(arg0); - QString propertyName = arg1.toString(exec); - slot = engine->scriptValueToJSCValue(tmp.property(propertyName, QScriptValue::ResolvePrototype)); + QString propertyName = QScriptEnginePrivate::toString(exec, arg1); + slot = QScriptEnginePrivate::property(exec, arg0, propertyName, QScriptValue::ResolvePrototype); } } @@ -908,22 +905,15 @@ QScriptEnginePrivate::~QScriptEnginePrivate() } } -QScriptValue QScriptEnginePrivate::scriptValueFromVariant(const QVariant &v) -{ - QScriptValue result = create(v.userType(), v.data()); - Q_ASSERT(result.isValid()); - return result; -} - -QVariant QScriptEnginePrivate::scriptValueToVariant(const QScriptValue &value, int targetType) +QVariant QScriptEnginePrivate::jscValueToVariant(JSC::ExecState *exec, JSC::JSValue value, int targetType) { QVariant v(targetType, (void *)0); - if (QScriptEnginePrivate::convert(value, targetType, v.data(), this)) + if (convertValue(exec, value, targetType, v.data())) return v; if (uint(targetType) == QVariant::LastType) - return value.toVariant(); - if (value.isVariant()) { - v = value.toVariant(); + return toVariant(exec, value); + if (isVariant(value)) { + v = variantValue(value); if (v.canConvert(QVariant::Type(targetType))) { v.convert(QVariant::Type(targetType)); return v; @@ -934,88 +924,61 @@ QVariant QScriptEnginePrivate::scriptValueToVariant(const QScriptValue &value, i return QVariant(targetType, *reinterpret_cast(v.data())); } } - return QVariant(); } -JSC::JSValue QScriptEnginePrivate::jscValueFromVariant(const QVariant &v) -{ - // ### it's inefficient to convert to QScriptValue and then to JSValue - QScriptValue vv = scriptValueFromVariant(v); - QScriptValuePrivate *p = QScriptValuePrivate::get(vv); - switch (p->type) { - case QScriptValuePrivate::JavaScriptCore: - return p->jscValue; - case QScriptValuePrivate::Number: - return JSC::jsNumber(currentFrame, p->numberValue); - case QScriptValuePrivate::String: { - JSC::UString str = p->stringValue; - return JSC::jsString(currentFrame, str); - } - } - return JSC::JSValue(); -} - -QVariant QScriptEnginePrivate::jscValueToVariant(JSC::JSValue value, int targetType) +JSC::JSValue QScriptEnginePrivate::arrayFromStringList(JSC::ExecState *exec, const QStringList &lst) { - // ### it's inefficient to convert to QScriptValue and then to QVariant - return scriptValueToVariant(scriptValueFromJSCValue(value), targetType); -} - -QScriptValue QScriptEnginePrivate::arrayFromStringList(const QStringList &lst) -{ - Q_Q(QScriptEngine); - QScriptValue arr = q->newArray(lst.size()); + JSC::JSValue arr = newArray(exec, lst.size()); for (int i = 0; i < lst.size(); ++i) - arr.setProperty(i, QScriptValue(q, lst.at(i))); + setProperty(exec, arr, i, JSC::jsString(exec, lst.at(i))); return arr; } -QStringList QScriptEnginePrivate::stringListFromArray(const QScriptValue &arr) +QStringList QScriptEnginePrivate::stringListFromArray(JSC::ExecState *exec, JSC::JSValue arr) { QStringList lst; - uint len = arr.property(QLatin1String("length")).toUInt32(); + uint len = toUInt32(exec, property(exec, arr, exec->propertyNames().length)); for (uint i = 0; i < len; ++i) - lst.append(arr.property(i).toString()); + lst.append(toString(exec, property(exec, arr, i))); return lst; } -QScriptValue QScriptEnginePrivate::arrayFromVariantList(const QVariantList &lst) +JSC::JSValue QScriptEnginePrivate::arrayFromVariantList(JSC::ExecState *exec, const QVariantList &lst) { - Q_Q(QScriptEngine); - QScriptValue arr = q->newArray(lst.size()); + JSC::JSValue arr = newArray(exec, lst.size()); for (int i = 0; i < lst.size(); ++i) - arr.setProperty(i, scriptValueFromVariant(lst.at(i))); + setProperty(exec, arr, i, jscValueFromVariant(exec, lst.at(i))); return arr; } -QVariantList QScriptEnginePrivate::variantListFromArray(const QScriptValue &arr) +QVariantList QScriptEnginePrivate::variantListFromArray(JSC::ExecState *exec, JSC::JSValue arr) { QVariantList lst; - uint len = arr.property(QLatin1String("length")).toUInt32(); + uint len = toUInt32(exec, property(exec, arr, exec->propertyNames().length)); for (uint i = 0; i < len; ++i) - lst.append(arr.property(i).toVariant()); + lst.append(toVariant(exec, property(exec, arr, i))); return lst; } -QScriptValue QScriptEnginePrivate::objectFromVariantMap(const QVariantMap &vmap) +JSC::JSValue QScriptEnginePrivate::objectFromVariantMap(JSC::ExecState *exec, const QVariantMap &vmap) { - Q_Q(QScriptEngine); - QScriptValue obj = q->newObject(); + JSC::JSValue obj = JSC::constructEmptyObject(exec); QVariantMap::const_iterator it; for (it = vmap.constBegin(); it != vmap.constEnd(); ++it) - obj.setProperty(it.key(), scriptValueFromVariant(it.value())); + setProperty(exec, obj, it.key(), jscValueFromVariant(exec, it.value())); return obj; } -QVariantMap QScriptEnginePrivate::variantMapFromObject(const QScriptValue &obj) +QVariantMap QScriptEnginePrivate::variantMapFromObject(JSC::ExecState *exec, JSC::JSValue obj) { + JSC::PropertyNameArray propertyNames(exec); + propertyNames.setShouldCache(false); + JSC::asObject(obj)->getOwnPropertyNames(exec, propertyNames, /*includeNonEnumerable=*/true); QVariantMap vmap; - QScriptValueIterator it(obj); - while (it.hasNext()) { - it.next(); - vmap.insert(it.name(), it.value().toVariant()); - } + JSC::PropertyNameArray::const_iterator it = propertyNames.begin(); + for( ; it != propertyNames.end(); ++it) + vmap.insert(it->ustring(), toVariant(exec, property(exec, obj, *it))); return vmap; } @@ -1344,13 +1307,13 @@ JSC::JSValue QScriptEnginePrivate::newQMetaObject( return result; } -bool QScriptEnginePrivate::convertToNativeQObject(const QScriptValue &value, +bool QScriptEnginePrivate::convertToNativeQObject(JSC::ExecState *exec, JSC::JSValue value, const QByteArray &targetType, void **result) { if (!targetType.endsWith('*')) return false; - if (QObject *qobject = value.toQObject()) { + if (QObject *qobject = toQObject(exec, value)) { int start = targetType.startsWith("const ") ? 6 : 0; QByteArray className = targetType.mid(start, targetType.size()-start-1); if (void *instance = qobject->qt_metacast(className)) { @@ -1577,6 +1540,76 @@ JSC::JSValue QScriptEnginePrivate::newVariant(const QVariant &value) return obj; } +JSC::JSValue QScriptEnginePrivate::newVariant(JSC::JSValue objectValue, + const QVariant &value) +{ + if (!isObject(objectValue)) + return newVariant(value); + JSC::JSObject *jscObject = JSC::asObject(objectValue); + if (!jscObject->inherits(&QScriptObject::info)) { + qWarning("QScriptEngine::newVariant(): changing class of non-QScriptObject not supported"); + return JSC::JSValue(); + } + QScriptObject *jscScriptObject = static_cast(jscObject); + if (!isVariant(objectValue)) { + jscScriptObject->setDelegate(new QScript::QVariantDelegate(value)); + } else { + setVariantValue(objectValue, value); + } + return objectValue; +} + +#ifndef QT_NO_REGEXP + +QRegExp QScriptEnginePrivate::toRegExp(JSC::ExecState *exec, JSC::JSValue value) +{ + if (!isRegExp(value)) + return QRegExp(); + QString pattern = toString(exec, property(exec, value, QLatin1String("source"), QScriptValue::ResolvePrototype)); + Qt::CaseSensitivity kase = Qt::CaseSensitive; + if (toBool(exec, property(exec, value, QLatin1String("ignoreCase"), QScriptValue::ResolvePrototype))) + kase = Qt::CaseInsensitive; + return QRegExp(pattern, kase, QRegExp::RegExp2); +} + +#endif + +QVariant QScriptEnginePrivate::toVariant(JSC::ExecState *exec, JSC::JSValue value) +{ + if (isObject(value)) { + if (isVariant(value)) + return variantValue(value); +#ifndef QT_NO_QOBJECT + else if (isQObject(value)) + return qVariantFromValue(toQObject(exec, value)); +#endif + else if (isDate(value)) + return QVariant(toDateTime(exec, value)); +#ifndef QT_NO_REGEXP + else if (isRegExp(value)) + return QVariant(toRegExp(exec, value)); +#endif + else if (isArray(value)) + return variantListFromArray(exec, value); + else if (QScriptDeclarativeClass *dc = declarativeClass(value)) + return dc->toVariant(declarativeObject(value)); + // try to convert to primitive + JSC::JSValue savedException; + saveException(exec, &savedException); + JSC::JSValue prim = value.toPrimitive(exec); + restoreException(exec, savedException); + if (!prim.isObject()) + return toVariant(exec, prim); + } else if (value.isNumber()) { + return QVariant(toNumber(exec, value)); + } else if (value.isString()) { + return QVariant(toString(exec, value)); + } else if (value.isBoolean()) { + return QVariant(toBool(exec, value)); + } + return QVariant(); +} + JSC::JSValue QScriptEnginePrivate::propertyHelper(JSC::ExecState *exec, JSC::JSValue value, const JSC::Identifier &id, int resolveMode) { JSC::JSValue result; @@ -1963,20 +1996,9 @@ QScriptValue QScriptEngine::newVariant(const QVariant &value) QScriptValue QScriptEngine::newVariant(const QScriptValue &object, const QVariant &value) { - if (!object.isObject()) - return newVariant(value); - JSC::JSObject *jscObject = JSC::asObject(QScriptValuePrivate::get(object)->jscValue); - if (!jscObject->inherits(&QScriptObject::info)) { - qWarning("QScriptEngine::newVariant(): changing class of non-QScriptObject not supported"); - return QScriptValue(); - } - QScriptObject *jscScriptObject = static_cast(jscObject); - if (!object.isVariant()) { - jscScriptObject->setDelegate(new QScript::QVariantDelegate(value)); - } else { - QScriptValuePrivate::get(object)->setVariantValue(value); - } - return object; + Q_D(QScriptEngine); + JSC::JSValue jsObject = d->scriptValueToJSCValue(object); + return d->scriptValueFromJSCValue(d->newVariant(jsObject, value)); } #ifndef QT_NO_QOBJECT @@ -2789,128 +2811,126 @@ void QScriptEngine::setDefaultPrototype(int metaTypeId, const QScriptValue &prot QScriptValue QScriptEngine::create(int type, const void *ptr) { Q_D(QScriptEngine); - return d->create(type, ptr); + return d->scriptValueFromJSCValue(d->create(d->currentFrame, type, ptr)); } -QScriptValue QScriptEnginePrivate::create(int type, const void *ptr) +JSC::JSValue QScriptEnginePrivate::create(JSC::ExecState *exec, int type, const void *ptr) { - Q_Q(QScriptEngine); Q_ASSERT(ptr != 0); - QScriptValue result; - QScriptTypeInfo *info = m_typeInfos.value(type); + JSC::JSValue result; + QScriptEnginePrivate *eng = exec ? QScript::scriptEngineFromExec(exec) : 0; + QScriptTypeInfo *info = eng ? eng->m_typeInfos.value(type) : 0; if (info && info->marshal) { - result = info->marshal(q, ptr); + result = eng->scriptValueToJSCValue(info->marshal(eng->q_func(), ptr)); } else { // check if it's one of the types we know switch (QMetaType::Type(type)) { case QMetaType::Void: - return QScriptValue(q, QScriptValue::UndefinedValue); + return JSC::jsUndefined(); case QMetaType::Bool: - return QScriptValue(q, *reinterpret_cast(ptr)); + return JSC::jsBoolean(*reinterpret_cast(ptr)); case QMetaType::Int: - return QScriptValue(q, *reinterpret_cast(ptr)); + return JSC::jsNumber(exec, *reinterpret_cast(ptr)); case QMetaType::UInt: - return QScriptValue(q, *reinterpret_cast(ptr)); + return JSC::jsNumber(exec, *reinterpret_cast(ptr)); case QMetaType::LongLong: - return QScriptValue(q, qsreal(*reinterpret_cast(ptr))); + return JSC::jsNumber(exec, qsreal(*reinterpret_cast(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(ptr))); + return JSC::jsNumber(exec, qsreal((qlonglong)*reinterpret_cast(ptr))); #elif defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET) - return QScriptValue(q, qsreal((qlonglong)*reinterpret_cast(ptr))); + return JSC::jsNumber(exec, qsreal((qlonglong)*reinterpret_cast(ptr))); #else - return QScriptValue(q, qsreal(*reinterpret_cast(ptr))); + return JSC::jsNumber(exec, qsreal(*reinterpret_cast(ptr))); #endif case QMetaType::Double: - return QScriptValue(q, qsreal(*reinterpret_cast(ptr))); + return JSC::jsNumber(exec, qsreal(*reinterpret_cast(ptr))); case QMetaType::QString: - return QScriptValue(q, *reinterpret_cast(ptr)); + return JSC::jsString(exec, *reinterpret_cast(ptr)); case QMetaType::Float: - return QScriptValue(q, *reinterpret_cast(ptr)); + return JSC::jsNumber(exec, *reinterpret_cast(ptr)); case QMetaType::Short: - return QScriptValue(q, *reinterpret_cast(ptr)); + return JSC::jsNumber(exec, *reinterpret_cast(ptr)); case QMetaType::UShort: - return QScriptValue(q, *reinterpret_cast(ptr)); + return JSC::jsNumber(exec, *reinterpret_cast(ptr)); case QMetaType::Char: - return QScriptValue(q, *reinterpret_cast(ptr)); + return JSC::jsNumber(exec, *reinterpret_cast(ptr)); case QMetaType::UChar: - return QScriptValue(q, *reinterpret_cast(ptr)); + return JSC::jsNumber(exec, *reinterpret_cast(ptr)); case QMetaType::QChar: - return QScriptValue(q, (*reinterpret_cast(ptr)).unicode()); + return JSC::jsNumber(exec, (*reinterpret_cast(ptr)).unicode()); case QMetaType::QStringList: - result = arrayFromStringList(*reinterpret_cast(ptr)); + result = arrayFromStringList(exec, *reinterpret_cast(ptr)); break; case QMetaType::QVariantList: - result = arrayFromVariantList(*reinterpret_cast(ptr)); + result = arrayFromVariantList(exec, *reinterpret_cast(ptr)); break; case QMetaType::QVariantMap: - result = objectFromVariantMap(*reinterpret_cast(ptr)); + result = objectFromVariantMap(exec, *reinterpret_cast(ptr)); break; case QMetaType::QDateTime: - result = q->newDate(*reinterpret_cast(ptr)); + result = newDate(exec, *reinterpret_cast(ptr)); break; case QMetaType::QDate: - result = q->newDate(QDateTime(*reinterpret_cast(ptr))); + result = newDate(exec, QDateTime(*reinterpret_cast(ptr))); break; #ifndef QT_NO_REGEXP case QMetaType::QRegExp: - result = q->newRegExp(*reinterpret_cast(ptr)); + result = newRegExp(exec, *reinterpret_cast(ptr)); break; #endif #ifndef QT_NO_QOBJECT case QMetaType::QObjectStar: case QMetaType::QWidgetStar: - result = q->newQObject(*reinterpret_cast(ptr)); + result = eng->newQObject(*reinterpret_cast(ptr)); break; #endif default: if (type == qMetaTypeId()) { - result = *reinterpret_cast(ptr); - if (!result.isValid()) - return QScriptValue(q, QScriptValue::UndefinedValue); + result = eng->scriptValueToJSCValue(*reinterpret_cast(ptr)); + if (!result) + return JSC::jsUndefined(); } #ifndef QT_NO_QOBJECT // lazy registration of some common list types else if (type == qMetaTypeId()) { - qScriptRegisterSequenceMetaType(q); - return create(type, ptr); + qScriptRegisterSequenceMetaType(eng->q_func()); + return create(exec, type, ptr); } #endif else if (type == qMetaTypeId >()) { - qScriptRegisterSequenceMetaType >(q); - return create(type, ptr); + qScriptRegisterSequenceMetaType >(eng->q_func()); + return create(exec, type, ptr); } else { QByteArray typeName = QMetaType::typeName(type); if (typeName == "QVariant") - result = scriptValueFromVariant(*reinterpret_cast(ptr)); + result = jscValueFromVariant(exec, *reinterpret_cast(ptr)); if (typeName.endsWith('*') && !*reinterpret_cast(ptr)) - return QScriptValue(q, QScriptValue::NullValue); + return JSC::jsNull(); else - result = q->newVariant(QVariant(type, ptr)); + result = eng->newVariant(QVariant(type, ptr)); } } } - if (result.isObject() && info && info->prototype - && JSC::JSValue::strictEqual(scriptValueToJSCValue(result.prototype()), originalGlobalObject()->objectPrototype())) { - result.setPrototype(scriptValueFromJSCValue(info->prototype)); + if (result && result.isObject() && info && info->prototype + && JSC::JSValue::strictEqual(JSC::asObject(result)->prototype(), eng->originalGlobalObject()->objectPrototype())) { + JSC::asObject(result)->setPrototype(info->prototype); } return result; } -bool QScriptEnginePrivate::convert(const QScriptValue &value, - int type, void *ptr, - QScriptEnginePrivate *eng) +bool QScriptEnginePrivate::convertValue(JSC::ExecState *exec, JSC::JSValue value, + int type, void *ptr) { - if (!eng) - eng = QScriptValuePrivate::getEngine(value); + QScriptEnginePrivate *eng = exec ? QScript::scriptEngineFromExec(exec) : 0; if (eng) { QScriptTypeInfo *info = eng->m_typeInfos.value(type); if (info && info->demarshal) { - info->demarshal(value, ptr); + info->demarshal(eng->scriptValueFromJSCValue(value), ptr); return true; } } @@ -2918,78 +2938,78 @@ bool QScriptEnginePrivate::convert(const QScriptValue &value, // check if it's one of the types we know switch (QMetaType::Type(type)) { case QMetaType::Bool: - *reinterpret_cast(ptr) = value.toBoolean(); + *reinterpret_cast(ptr) = toBool(exec, value); return true; case QMetaType::Int: - *reinterpret_cast(ptr) = value.toInt32(); + *reinterpret_cast(ptr) = toInt32(exec, value); return true; case QMetaType::UInt: - *reinterpret_cast(ptr) = value.toUInt32(); + *reinterpret_cast(ptr) = toUInt32(exec, value); return true; case QMetaType::LongLong: - *reinterpret_cast(ptr) = qlonglong(value.toInteger()); + *reinterpret_cast(ptr) = qlonglong(toInteger(exec, value)); return true; case QMetaType::ULongLong: - *reinterpret_cast(ptr) = qulonglong(value.toInteger()); + *reinterpret_cast(ptr) = qulonglong(toInteger(exec, value)); return true; case QMetaType::Double: - *reinterpret_cast(ptr) = value.toNumber(); + *reinterpret_cast(ptr) = toNumber(exec, value); return true; case QMetaType::QString: if (value.isUndefined() || value.isNull()) *reinterpret_cast(ptr) = QString(); else - *reinterpret_cast(ptr) = value.toString(); + *reinterpret_cast(ptr) = toString(exec, value); return true; case QMetaType::Float: - *reinterpret_cast(ptr) = value.toNumber(); + *reinterpret_cast(ptr) = toNumber(exec, value); return true; case QMetaType::Short: - *reinterpret_cast(ptr) = short(value.toInt32()); + *reinterpret_cast(ptr) = short(toInt32(exec, value)); return true; case QMetaType::UShort: - *reinterpret_cast(ptr) = value.toUInt16(); + *reinterpret_cast(ptr) = QScript::ToUInt16(toNumber(exec, value)); return true; case QMetaType::Char: - *reinterpret_cast(ptr) = char(value.toInt32()); + *reinterpret_cast(ptr) = char(toInt32(exec, value)); return true; case QMetaType::UChar: - *reinterpret_cast(ptr) = (unsigned char)(value.toInt32()); + *reinterpret_cast(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(ptr) = str.isEmpty() ? QChar() : str.at(0); } else { - *reinterpret_cast(ptr) = QChar(value.toUInt16()); + *reinterpret_cast(ptr) = QChar(QScript::ToUInt16(toNumber(exec, value))); } return true; case QMetaType::QDateTime: - if (value.isDate()) { - *reinterpret_cast(ptr) = value.toDateTime(); + if (isDate(value)) { + *reinterpret_cast(ptr) = toDateTime(exec, value); return true; } break; case QMetaType::QDate: - if (value.isDate()) { - *reinterpret_cast(ptr) = value.toDateTime().date(); + if (isDate(value)) { + *reinterpret_cast(ptr) = toDateTime(exec, value).date(); return true; } break; #ifndef QT_NO_REGEXP case QMetaType::QRegExp: - if (value.isRegExp()) { - *reinterpret_cast(ptr) = value.toRegExp(); + if (isRegExp(value)) { + *reinterpret_cast(ptr) = toRegExp(exec, value); return true; } break; #endif #ifndef QT_NO_QOBJECT case QMetaType::QObjectStar: - if (value.isQObject() || value.isNull()) { - *reinterpret_cast(ptr) = value.toQObject(); + if (isQObject(value) || value.isNull()) { + *reinterpret_cast(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(ptr) = reinterpret_cast(qo); return true; @@ -2997,18 +3017,18 @@ bool QScriptEnginePrivate::convert(const QScriptValue &value, } break; #endif case QMetaType::QStringList: - if (value.isArray()) { - *reinterpret_cast(ptr) = stringListFromArray(value); + if (isArray(value)) { + *reinterpret_cast(ptr) = stringListFromArray(exec, value); return true; } break; case QMetaType::QVariantList: - if (value.isArray()) { - *reinterpret_cast(ptr) = variantListFromArray(value); + if (isArray(value)) { + *reinterpret_cast(ptr) = variantListFromArray(exec, value); return true; } break; case QMetaType::QVariantMap: - if (value.isObject()) { - *reinterpret_cast(ptr) = variantMapFromObject(value); + if (isObject(value)) { + *reinterpret_cast(ptr) = variantMapFromObject(exec, value); return true; } break; default: @@ -3017,28 +3037,28 @@ bool QScriptEnginePrivate::convert(const QScriptValue &value, QByteArray name = QMetaType::typeName(type); #ifndef QT_NO_QOBJECT - if (convertToNativeQObject(value, name, reinterpret_cast(ptr))) + if (convertToNativeQObject(exec, value, name, reinterpret_cast(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(ptr) = var.data(); return true; } else { // look in the prototype chain - QScriptValue proto = value.prototype(); + JSC::JSValue proto = JSC::asObject(value)->prototype(); while (proto.isObject()) { bool canCast = false; - if (proto.isVariant()) { - canCast = (type == proto.toVariant().userType()) - || (valueType && (valueType == proto.toVariant().userType())); + if (isVariant(proto)) { + canCast = (type == variantValue(proto).userType()) + || (valueType && (valueType == variantValue(proto).userType())); } #ifndef QT_NO_QOBJECT - else if (proto.isQObject()) { + else if (isQObject(proto)) { QByteArray className = name.left(name.size()-1); - if (QObject *qobject = proto.toQObject()) + if (QObject *qobject = toQObject(exec, proto)) canCast = qobject->qt_metacast(className) != 0; } #endif @@ -3050,7 +3070,7 @@ bool QScriptEnginePrivate::convert(const QScriptValue &value, *reinterpret_cast(ptr) = var.data(); return true; } - proto = proto.prototype(); + proto = JSC::asObject(proto)->prototype(); } } } else if (value.isNull() && name.endsWith('*')) { @@ -3059,10 +3079,10 @@ bool QScriptEnginePrivate::convert(const QScriptValue &value, } else if (type == qMetaTypeId()) { if (!eng) return false; - *reinterpret_cast(ptr) = value; + *reinterpret_cast(ptr) = eng->scriptValueFromJSCValue(value); return true; } else if (name == "QVariant") { - *reinterpret_cast(ptr) = value.toVariant(); + *reinterpret_cast(ptr) = toVariant(exec, value); return true; } @@ -3072,14 +3092,14 @@ bool QScriptEnginePrivate::convert(const QScriptValue &value, if (!eng) return false; qScriptRegisterSequenceMetaType(eng->q_func()); - return convert(value, type, ptr, eng); + return convertValue(exec, value, type, ptr); } #endif else if (type == qMetaTypeId >()) { if (!eng) return false; qScriptRegisterSequenceMetaType >(eng->q_func()); - return convert(value, type, ptr, eng); + return convertValue(exec, value, type, ptr); } #if 0 @@ -3091,6 +3111,102 @@ bool QScriptEnginePrivate::convert(const QScriptValue &value, return false; } +bool QScriptEnginePrivate::convertNumber(qsreal value, int type, void *ptr) +{ + switch (QMetaType::Type(type)) { + case QMetaType::Bool: + *reinterpret_cast(ptr) = QScript::ToBool(value); + return true; + case QMetaType::Int: + *reinterpret_cast(ptr) = QScript::ToInt32(value); + return true; + case QMetaType::UInt: + *reinterpret_cast(ptr) = QScript::ToUInt32(value); + return true; + case QMetaType::LongLong: + *reinterpret_cast(ptr) = qlonglong(QScript::ToInteger(value)); + return true; + case QMetaType::ULongLong: + *reinterpret_cast(ptr) = qulonglong(QScript::ToInteger(value)); + return true; + case QMetaType::Double: + *reinterpret_cast(ptr) = value; + return true; + case QMetaType::QString: + *reinterpret_cast(ptr) = QScript::ToString(value); + return true; + case QMetaType::Float: + *reinterpret_cast(ptr) = value; + return true; + case QMetaType::Short: + *reinterpret_cast(ptr) = short(QScript::ToInt32(value)); + return true; + case QMetaType::UShort: + *reinterpret_cast(ptr) = QScript::ToUInt16(value); + return true; + case QMetaType::Char: + *reinterpret_cast(ptr) = char(QScript::ToInt32(value)); + return true; + case QMetaType::UChar: + *reinterpret_cast(ptr) = (unsigned char)(QScript::ToInt32(value)); + return true; + case QMetaType::QChar: + *reinterpret_cast(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(ptr) = QScript::ToBool(value); + return true; + case QMetaType::Int: + *reinterpret_cast(ptr) = QScript::ToInt32(value); + return true; + case QMetaType::UInt: + *reinterpret_cast(ptr) = QScript::ToUInt32(value); + return true; + case QMetaType::LongLong: + *reinterpret_cast(ptr) = qlonglong(QScript::ToInteger(value)); + return true; + case QMetaType::ULongLong: + *reinterpret_cast(ptr) = qulonglong(QScript::ToInteger(value)); + return true; + case QMetaType::Double: + *reinterpret_cast(ptr) = QScript::ToNumber(value); + return true; + case QMetaType::QString: + *reinterpret_cast(ptr) = value; + return true; + case QMetaType::Float: + *reinterpret_cast(ptr) = QScript::ToNumber(value); + return true; + case QMetaType::Short: + *reinterpret_cast(ptr) = short(QScript::ToInt32(value)); + return true; + case QMetaType::UShort: + *reinterpret_cast(ptr) = QScript::ToUInt16(value); + return true; + case QMetaType::Char: + *reinterpret_cast(ptr) = char(QScript::ToInt32(value)); + return true; + case QMetaType::UChar: + *reinterpret_cast(ptr) = (unsigned char)(QScript::ToInt32(value)); + return true; + case QMetaType::QChar: + *reinterpret_cast(ptr) = QChar(QScript::ToUInt16(value)); + return true; + default: + break; + } + return false; +} + bool QScriptEnginePrivate::hasDemarshalFunction(int type) const { QScriptTypeInfo *info = m_typeInfos.value(type); @@ -3103,7 +3219,7 @@ bool QScriptEnginePrivate::hasDemarshalFunction(int type) const bool QScriptEngine::convert(const QScriptValue &value, int type, void *ptr) { Q_D(QScriptEngine); - return QScriptEnginePrivate::convert(value, type, ptr, d); + return QScriptEnginePrivate::convertValue(d->currentFrame, d->scriptValueToJSCValue(value), type, ptr); } /*! @@ -3111,7 +3227,20 @@ bool QScriptEngine::convert(const QScriptValue &value, int type, void *ptr) */ bool QScriptEngine::convertV2(const QScriptValue &value, int type, void *ptr) { - return QScriptEnginePrivate::convert(value, type, ptr, /*engine=*/0); + QScriptValuePrivate *vp = QScriptValuePrivate::get(value); + if (vp) { + switch (vp->type) { + case QScriptValuePrivate::JavaScriptCore: { + JSC::ExecState *exec = vp->engine ? vp->engine->currentFrame : 0; + return QScriptEnginePrivate::convertValue(exec, vp->jscValue, type, ptr); + } + case QScriptValuePrivate::Number: + return QScriptEnginePrivate::convertNumber(vp->numberValue, type, ptr); + case QScriptValuePrivate::String: + return QScriptEnginePrivate::convertString(vp->stringValue, type, ptr); + } + } + return false; } /*! diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index 4be9146..eff34af 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -44,7 +44,12 @@ #include #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" @@ -145,6 +150,8 @@ public: 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); @@ -155,6 +162,12 @@ public: 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); @@ -174,29 +187,29 @@ public: static inline QScriptValue::PropertyFlags propertyFlags(JSC::ExecState*, JSC::JSValue value, const QString &name, const QScriptValue::ResolveFlags &mode); - static bool convert(const QScriptValue &value, - int type, void *ptr, - QScriptEnginePrivate *eng); - QScriptValue create(int type, const void *ptr); + 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); @@ -269,6 +282,10 @@ public: 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, @@ -277,7 +294,7 @@ public: JSC::JSValue newQMetaObject(const QMetaObject *metaObject, JSC::JSValue ctor); - static bool convertToNativeQObject(const QScriptValue &value, + static bool convertToNativeQObject(JSC::ExecState*, JSC::JSValue, const QByteArray &targetType, void **result); @@ -525,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) @@ -801,6 +825,30 @@ inline bool QScriptEnginePrivate::isVariant(JSC::JSValue value) 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(JSC::asObject(value)); + QScriptObjectDelegate *delegate = object->delegate(); + return (delegate && (delegate->type() == QScriptObjectDelegate::QtObject || + (delegate->type() == QScriptObjectDelegate::DeclarativeClassObject && + static_cast(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; @@ -876,6 +924,76 @@ inline QDateTime QScriptEnginePrivate::toDateTime(JSC::ExecState *, JSC::JSValue 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(JSC::asObject(value)); + QScriptObjectDelegate *delegate = object->delegate(); + if (!delegate) + return 0; + if (delegate->type() == QScriptObjectDelegate::QtObject) + return static_cast(delegate)->value(); + if (delegate->type() == QScriptObjectDelegate::DeclarativeClassObject) + return static_cast(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(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(JSC::asObject(value))->value(); +#endif + return 0; +} + +inline QVariant &QScriptEnginePrivate::variantValue(JSC::JSValue value) +{ + Q_ASSERT(value.inherits(&QScriptObject::info)); + QScriptObjectDelegate *delegate = static_cast(JSC::asObject(value))->delegate(); + Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant)); + return static_cast(delegate)->value(); +} + +inline void QScriptEnginePrivate::setVariantValue(JSC::JSValue objectValue, const QVariant &value) +{ + Q_ASSERT(objectValue.inherits(&QScriptObject::info)); + QScriptObjectDelegate *delegate = static_cast(JSC::asObject(objectValue))->delegate(); + Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant)); + static_cast(delegate)->setValue(value); +} + +inline QScriptDeclarativeClass *QScriptEnginePrivate::declarativeClass(JSC::JSValue v) +{ + if (!QScriptEnginePrivate::isObject(v) || !v.inherits(&QScriptObject::info)) + return 0; + QScriptObject *scriptObject = static_cast(JSC::asObject(v)); + QScriptObjectDelegate *delegate = scriptObject->delegate(); + if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject)) + return 0; + return static_cast(delegate)->scriptClass(); +} + +inline QScriptDeclarativeClass::Object *QScriptEnginePrivate::declarativeObject(JSC::JSValue v) +{ + if (!QScriptEnginePrivate::isObject(v) || !v.inherits(&QScriptObject::info)) + return 0; + QScriptObject *scriptObject = static_cast(JSC::asObject(v)); + QScriptObjectDelegate *delegate = scriptObject->delegate(); + if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject)) + return 0; + return static_cast(delegate)->object(); +} + QT_END_NAMESPACE #endif diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp index a7d9f79..7f1fdaa 100644 --- a/src/script/api/qscriptvalue.cpp +++ b/src/script/api/qscriptvalue.cpp @@ -42,14 +42,6 @@ #include #include -#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 @@ -176,22 +168,6 @@ QT_BEGIN_NAMESPACE -QVariant &QScriptValuePrivate::variantValue() const -{ - Q_ASSERT(jscValue.inherits(&QScriptObject::info)); - QScriptObjectDelegate *delegate = static_cast(JSC::asObject(jscValue))->delegate(); - Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant)); - return static_cast(delegate)->value(); -} - -void QScriptValuePrivate::setVariantValue(const QVariant &value) -{ - Q_ASSERT(jscValue.inherits(&QScriptObject::info)); - QScriptObjectDelegate *delegate = static_cast(JSC::asObject(jscValue))->delegate(); - Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant)); - static_cast(delegate)->setValue(value); -} - void QScriptValuePrivate::detachFromEngine() { if (isJSC()) @@ -1205,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; - QScriptEnginePrivate::saveException(exec, &savedException); - JSC::JSValue prim = d->jscValue.toPrimitive(exec); - QScriptEnginePrivate::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: @@ -1286,13 +1232,9 @@ QDateTime QScriptValue::toDateTime() const QRegExp QScriptValue::toRegExp() const { Q_D(const QScriptValue); - if (!isRegExp()) - return QRegExp(); - QString pattern = property(QLatin1String("source"), QScriptValue::ResolvePrototype).toString(); - Qt::CaseSensitivity kase = Qt::CaseSensitive; - if (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 @@ -1309,19 +1251,9 @@ QRegExp QScriptValue::toRegExp() const QObject *QScriptValue::toQObject() const { Q_D(const QScriptValue); - if (isQObject()) { - QScriptObject *object = static_cast(JSC::asObject(d->jscValue)); - QScriptObjectDelegate *delegate = object->delegate(); - if (delegate->type() == QScriptObjectDelegate::DeclarativeClassObject) - return static_cast(delegate)->scriptClass()->toQObject(QScriptDeclarativeClass::object(*this)); - return static_cast(delegate)->value(); - } else if (isVariant()) { - QVariant var = toVariant(); - int type = var.userType(); - if ((type == QMetaType::QObjectStar) || (type == QMetaType::QWidgetStar)) - return *reinterpret_cast(var.constData()); - } - return 0; + if (!d || !d->engine) + return 0; + return QScriptEnginePrivate::toQObject(d->engine->currentFrame, d->jscValue); } /*! @@ -1333,9 +1265,9 @@ QObject *QScriptValue::toQObject() const const QMetaObject *QScriptValue::toQMetaObject() const { Q_D(const QScriptValue); - if (isQMetaObject()) - return static_cast(JSC::asObject(d->jscValue))->value(); - return 0; + if (!d || !d->engine) + return 0; + return QScriptEnginePrivate::toQMetaObject(d->engine->currentFrame, d->jscValue); } /*! @@ -1971,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(JSC::asObject(d->jscValue)); - QScriptObjectDelegate *delegate = object->delegate(); - return (delegate && (delegate->type() == QScriptObjectDelegate::QtObject || - (delegate->type() == QScriptObjectDelegate::DeclarativeClassObject && - static_cast(delegate)->scriptClass()->isQObject()))); + return QScriptEnginePrivate::isQObject(d->jscValue); } /*! @@ -1989,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); } /*! diff --git a/src/script/api/qscriptvalue_p.h b/src/script/api/qscriptvalue_p.h index dedc250..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(); 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(JSC::asObject(d->jscValue)); - QScriptObjectDelegate *delegate = scriptObject->delegate(); - if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject)) - return 0; - return static_cast(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(JSC::asObject(d->jscValue)); - QScriptObjectDelegate *delegate = scriptObject->delegate(); - if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject)) + if (!d || !d->isJSC()) return 0; - return static_cast(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(v.data())); + converted = QScriptEnginePrivate::convertToNativeQObject( + exec, actual, argType.name(), reinterpret_cast(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 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(arg)); + actual = QScriptEnginePrivate::jscValueFromVariant(exec, *reinterpret_cast(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 structure, -- cgit v0.12