diff options
Diffstat (limited to 'src/script/api')
-rw-r--r-- | src/script/api/api.pri | 3 | ||||
-rw-r--r-- | src/script/api/qscriptengine.cpp | 267 | ||||
-rw-r--r-- | src/script/api/qscriptengine.h | 3 | ||||
-rw-r--r-- | src/script/api/qscriptengine_p.h | 98 | ||||
-rw-r--r-- | src/script/api/qscriptprogram.cpp | 225 | ||||
-rw-r--r-- | src/script/api/qscriptprogram.h | 86 | ||||
-rw-r--r-- | src/script/api/qscriptprogram_p.h | 95 | ||||
-rw-r--r-- | src/script/api/qscriptstring.cpp | 32 | ||||
-rw-r--r-- | src/script/api/qscriptstring.h | 2 | ||||
-rw-r--r-- | src/script/api/qscriptstring_p.h | 7 | ||||
-rw-r--r-- | src/script/api/qscriptvalue.cpp | 111 | ||||
-rw-r--r-- | src/script/api/qscriptvalue_p.h | 21 |
12 files changed, 735 insertions, 215 deletions
diff --git a/src/script/api/api.pri b/src/script/api/api.pri index 17ec9b6..aebadd5 100644 --- a/src/script/api/api.pri +++ b/src/script/api/api.pri @@ -6,6 +6,7 @@ SOURCES += \ $$PWD/qscriptengine.cpp \ $$PWD/qscriptengineagent.cpp \ $$PWD/qscriptextensionplugin.cpp \ + $$PWD/qscriptprogram.cpp \ $$PWD/qscriptstring.cpp \ $$PWD/qscriptvalue.cpp \ $$PWD/qscriptvalueiterator.cpp \ @@ -23,6 +24,8 @@ HEADERS += \ $$PWD/qscriptengineagent_p.h \ $$PWD/qscriptextensioninterface.h \ $$PWD/qscriptextensionplugin.h \ + $$PWD/qscriptprogram.h \ + $$PWD/qscriptprogram_p.h \ $$PWD/qscriptstring.h \ $$PWD/qscriptstring_p.h \ $$PWD/qscriptvalue.h \ diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 360036a..2b60a46 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -51,6 +51,8 @@ #include "qscriptvalue_p.h" #include "qscriptvalueiterator.h" #include "qscriptclass.h" +#include "qscriptprogram.h" +#include "qscriptprogram_p.h" #include "qdebug.h" #include <QtCore/qstringlist.h> @@ -343,15 +345,10 @@ public: namespace QScript { -struct GlobalClientData : public JSC::JSGlobalData::ClientData +void GlobalClientData::mark(JSC::MarkStack& markStack) { - GlobalClientData(QScriptEnginePrivate *e) - : engine(e) {} - virtual ~GlobalClientData() {} - virtual void mark(JSC::MarkStack& markStack) { engine->mark(markStack); } - - QScriptEnginePrivate *engine; -}; + engine->mark(markStack); +} class TimeoutCheckerProxy : public JSC::TimeoutChecker { @@ -452,11 +449,6 @@ qsreal integerFromString(const QString &str, int radix) return integerFromString(ba.constData(), ba.size(), radix); } -QScriptEnginePrivate *scriptEngineFromExec(const JSC::ExecState *exec) -{ - return static_cast<GlobalClientData*>(exec->globalData().clientData)->engine; -} - bool isFunction(JSC::JSValue value) { if (!value || !value.isObject()) @@ -797,6 +789,10 @@ QScriptEnginePrivate::QScriptEnginePrivate() registeredScriptStrings(0), inEval(false) { qMetaTypeId<QScriptValue>(); + qMetaTypeId<QList<int> >(); +#ifndef QT_NO_QOBJECT + qMetaTypeId<QObjectList>(); +#endif JSC::initializeThreading(); // ### hmmm @@ -991,26 +987,6 @@ void QScriptEnginePrivate::setDefaultPrototype(int metaTypeId, JSC::JSValue prot info->prototype = prototype; } -QScriptContext *QScriptEnginePrivate::contextForFrame(JSC::ExecState *frame) -{ - if (frame && frame->callerFrame()->hasHostCallFrameFlag() && !frame->callee() - && frame->callerFrame()->removeHostCallFrameFlag() == QScript::scriptEngineFromExec(frame)->globalExec()) { - //skip the "fake" context created in Interpreter::execute. - frame = frame->callerFrame()->removeHostCallFrameFlag(); - } - return reinterpret_cast<QScriptContext *>(frame); -} - -JSC::ExecState *QScriptEnginePrivate::frameForContext(QScriptContext *context) -{ - return reinterpret_cast<JSC::ExecState*>(context); -} - -const JSC::ExecState *QScriptEnginePrivate::frameForContext(const QScriptContext *context) -{ - return reinterpret_cast<const JSC::ExecState*>(context); -} - JSC::JSGlobalObject *QScriptEnginePrivate::originalGlobalObject() const { return globalData->head; @@ -1052,11 +1028,6 @@ void QScriptEnginePrivate::setGlobalObject(JSC::JSObject *object) } } -JSC::ExecState *QScriptEnginePrivate::globalExec() const -{ - return originalGlobalObject()->globalExec(); -} - /*! \internal @@ -1186,6 +1157,73 @@ void QScriptEnginePrivate::agentDeleted(QScriptEngineAgent *agent) } } +JSC::JSValue QScriptEnginePrivate::evaluateHelper(JSC::ExecState *exec, intptr_t sourceId, + JSC::EvalExecutable *executable, + bool &compile) +{ + Q_Q(QScriptEngine); + JSC::JSLock lock(false); // ### hmmm + QBoolBlocker inEvalBlocker(inEval, true); + q->currentContext()->activationObject(); //force the creation of a context for native function; + + JSC::Debugger* debugger = originalGlobalObject()->debugger(); + if (debugger) + debugger->evaluateStart(sourceId); + + q->clearExceptions(); + JSC::DynamicGlobalObjectScope dynamicGlobalObjectScope(exec, exec->scopeChain()->globalObject()); + + if (compile) { + JSC::JSObject* error = executable->compile(exec, exec->scopeChain()); + if (error) { + compile = false; + exec->setException(error); + + if (debugger) { + debugger->exceptionThrow(JSC::DebuggerCallFrame(exec, error), sourceId, false); + debugger->evaluateStop(error, sourceId); + } + + return error; + } + } + + JSC::JSValue thisValue = thisForContext(exec); + JSC::JSObject* thisObject = (!thisValue || thisValue.isUndefinedOrNull()) + ? exec->dynamicGlobalObject() : thisValue.toObject(exec); + JSC::JSValue exceptionValue; + timeoutChecker()->setShouldAbort(false); + if (processEventsInterval > 0) + timeoutChecker()->reset(); + + JSC::JSValue result = exec->interpreter()->execute(executable, exec, thisObject, exec->scopeChain(), &exceptionValue); + + if (timeoutChecker()->shouldAbort()) { + if (abortResult.isError()) + exec->setException(scriptValueToJSCValue(abortResult)); + + if (debugger) + debugger->evaluateStop(scriptValueToJSCValue(abortResult), sourceId); + + return scriptValueToJSCValue(abortResult); + } + + if (exceptionValue) { + exec->setException(exceptionValue); + + if (debugger) + debugger->evaluateStop(exceptionValue, sourceId); + + return exceptionValue; + } + + if (debugger) + debugger->evaluateStop(result, sourceId); + + Q_ASSERT(!exec->hadException()); + return result; +} + #ifndef QT_NO_QOBJECT JSC::JSValue QScriptEnginePrivate::newQObject( @@ -2146,75 +2184,41 @@ QScriptSyntaxCheckResult QScriptEnginePrivate::checkSyntax(const QString &progra QScriptValue QScriptEngine::evaluate(const QString &program, const QString &fileName, int lineNumber) { Q_D(QScriptEngine); - - JSC::JSLock lock(false); // ### hmmm - QBoolBlocker inEval(d->inEval, true); - currentContext()->activationObject(); //force the creation of a context for native function; - - JSC::Debugger* debugger = d->originalGlobalObject()->debugger(); - - JSC::UString jscProgram = program; - JSC::UString jscFileName = fileName; - JSC::ExecState* exec = d->currentFrame; WTF::PassRefPtr<QScript::UStringSourceProviderWithFeedback> provider - = QScript::UStringSourceProviderWithFeedback::create(jscProgram, jscFileName, lineNumber, d); + = QScript::UStringSourceProviderWithFeedback::create(program, fileName, lineNumber, d); intptr_t sourceId = provider->asID(); JSC::SourceCode source(provider, lineNumber); //after construction of SourceCode provider variable will be null. - if (debugger) - debugger->evaluateStart(sourceId); - - clearExceptions(); - JSC::DynamicGlobalObjectScope dynamicGlobalObjectScope(exec, exec->scopeChain()->globalObject()); - + JSC::ExecState* exec = d->currentFrame; JSC::EvalExecutable executable(exec, source); - JSC::JSObject* error = executable.compile(exec, exec->scopeChain()); - if (error) { - exec->setException(error); - - if (debugger) { - debugger->exceptionThrow(JSC::DebuggerCallFrame(exec, error), sourceId, false); - debugger->evaluateStop(error, sourceId); - } - - return d->scriptValueFromJSCValue(error); - } - - JSC::JSValue thisValue = d->thisForContext(exec); - JSC::JSObject* thisObject = (!thisValue || thisValue.isUndefinedOrNull()) ? exec->dynamicGlobalObject() : thisValue.toObject(exec); - JSC::JSValue exceptionValue; - d->timeoutChecker()->setShouldAbort(false); - if (d->processEventsInterval > 0) - d->timeoutChecker()->reset(); - JSC::JSValue result = exec->interpreter()->execute(&executable, exec, thisObject, exec->scopeChain(), &exceptionValue); - - if (d->timeoutChecker()->shouldAbort()) { - if (d->abortResult.isError()) - exec->setException(d->scriptValueToJSCValue(d->abortResult)); - - if (debugger) - debugger->evaluateStop(d->scriptValueToJSCValue(d->abortResult), sourceId); - - return d->abortResult; - } - - if (exceptionValue) { - exec->setException(exceptionValue); - - if (debugger) - debugger->evaluateStop(exceptionValue, sourceId); + bool compile = true; + return d->scriptValueFromJSCValue(d->evaluateHelper(exec, sourceId, &executable, compile)); +} - return d->scriptValueFromJSCValue(exceptionValue); - } +/*! + \internal + \since 4.6 - if (debugger) - debugger->evaluateStop(result, sourceId); + Evaluates the given \a program and returns the result of the + evaluation. +*/ +QScriptValue QScriptEngine::evaluate(const QScriptProgram &program) +{ + Q_D(QScriptEngine); + QScriptProgramPrivate *program_d = QScriptProgramPrivate::get(program); + if (!program_d) + return QScriptValue(); - Q_ASSERT(!exec->hadException()); + JSC::ExecState* exec = d->currentFrame; + JSC::EvalExecutable *executable = program_d->executable(exec, d); + bool compile = !program_d->isCompiled; + JSC::JSValue result = d->evaluateHelper(exec, program_d->sourceId, + executable, compile); + if (compile) + program_d->isCompiled = true; return d->scriptValueFromJSCValue(result); } - /*! Returns the current context. @@ -2539,63 +2543,50 @@ QScriptValue QScriptEngine::create(int type, const void *ptr) QScriptValue QScriptEnginePrivate::create(int type, const void *ptr) { + Q_Q(QScriptEngine); Q_ASSERT(ptr != 0); QScriptValue result; QScriptTypeInfo *info = m_typeInfos.value(type); if (info && info->marshal) { - result = info->marshal(q_func(), ptr); + result = info->marshal(q, ptr); } else { // check if it's one of the types we know switch (QMetaType::Type(type)) { case QMetaType::Void: - result = QScriptValue(QScriptValue::UndefinedValue); - break; + return QScriptValue(q, QScriptValue::UndefinedValue); case QMetaType::Bool: - result = QScriptValue(*reinterpret_cast<const bool*>(ptr)); - break; + return QScriptValue(q, *reinterpret_cast<const bool*>(ptr)); case QMetaType::Int: - result = QScriptValue(*reinterpret_cast<const int*>(ptr)); - break; + return QScriptValue(q, *reinterpret_cast<const int*>(ptr)); case QMetaType::UInt: - result = QScriptValue(*reinterpret_cast<const uint*>(ptr)); - break; + return QScriptValue(q, *reinterpret_cast<const uint*>(ptr)); case QMetaType::LongLong: - result = QScriptValue(qsreal(*reinterpret_cast<const qlonglong*>(ptr))); - break; + return QScriptValue(q, qsreal(*reinterpret_cast<const qlonglong*>(ptr))); case QMetaType::ULongLong: #if defined(Q_OS_WIN) && defined(_MSC_FULL_VER) && _MSC_FULL_VER <= 12008804 #pragma message("** NOTE: You need the Visual Studio Processor Pack to compile support for 64bit unsigned integers.") - result = QScriptValue(qsreal((qlonglong)*reinterpret_cast<const qulonglong*>(ptr))); + return QScriptValue(q, qsreal((qlonglong)*reinterpret_cast<const qulonglong*>(ptr))); #elif defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET) - result = QScriptValue(qsreal((qlonglong)*reinterpret_cast<const qulonglong*>(ptr))); + return QScriptValue(q, qsreal((qlonglong)*reinterpret_cast<const qulonglong*>(ptr))); #else - result = QScriptValue(qsreal(*reinterpret_cast<const qulonglong*>(ptr))); + return QScriptValue(q, qsreal(*reinterpret_cast<const qulonglong*>(ptr))); #endif - break; case QMetaType::Double: - result = QScriptValue(*reinterpret_cast<const double*>(ptr)); - break; + return QScriptValue(q, qsreal(*reinterpret_cast<const double*>(ptr))); case QMetaType::QString: - result = QScriptValue(q_func(), *reinterpret_cast<const QString*>(ptr)); - break; + return QScriptValue(q, *reinterpret_cast<const QString*>(ptr)); case QMetaType::Float: - result = QScriptValue(*reinterpret_cast<const float*>(ptr)); - break; + return QScriptValue(q, *reinterpret_cast<const float*>(ptr)); case QMetaType::Short: - result = QScriptValue(*reinterpret_cast<const short*>(ptr)); - break; + return QScriptValue(q, *reinterpret_cast<const short*>(ptr)); case QMetaType::UShort: - result = QScriptValue(*reinterpret_cast<const unsigned short*>(ptr)); - break; + return QScriptValue(q, *reinterpret_cast<const unsigned short*>(ptr)); case QMetaType::Char: - result = QScriptValue(*reinterpret_cast<const char*>(ptr)); - break; + return QScriptValue(q, *reinterpret_cast<const char*>(ptr)); case QMetaType::UChar: - result = QScriptValue(*reinterpret_cast<const unsigned char*>(ptr)); - break; + return QScriptValue(q, *reinterpret_cast<const unsigned char*>(ptr)); case QMetaType::QChar: - result = QScriptValue((*reinterpret_cast<const QChar*>(ptr)).unicode()); - break; + return QScriptValue(q, (*reinterpret_cast<const QChar*>(ptr)).unicode()); case QMetaType::QStringList: result = arrayFromStringList(*reinterpret_cast<const QStringList *>(ptr)); break; @@ -2606,38 +2597,38 @@ QScriptValue QScriptEnginePrivate::create(int type, const void *ptr) result = objectFromVariantMap(*reinterpret_cast<const QVariantMap *>(ptr)); break; case QMetaType::QDateTime: - result = q_func()->newDate(*reinterpret_cast<const QDateTime *>(ptr)); + result = q->newDate(*reinterpret_cast<const QDateTime *>(ptr)); break; case QMetaType::QDate: - result = q_func()->newDate(QDateTime(*reinterpret_cast<const QDate *>(ptr))); + result = q->newDate(QDateTime(*reinterpret_cast<const QDate *>(ptr))); break; #ifndef QT_NO_REGEXP case QMetaType::QRegExp: - result = q_func()->newRegExp(*reinterpret_cast<const QRegExp *>(ptr)); + result = q->newRegExp(*reinterpret_cast<const QRegExp *>(ptr)); break; #endif #ifndef QT_NO_QOBJECT case QMetaType::QObjectStar: case QMetaType::QWidgetStar: - result = q_func()->newQObject(*reinterpret_cast<QObject* const *>(ptr)); + result = q->newQObject(*reinterpret_cast<QObject* const *>(ptr)); break; #endif default: if (type == qMetaTypeId<QScriptValue>()) { result = *reinterpret_cast<const QScriptValue*>(ptr); if (!result.isValid()) - result = QScriptValue(QScriptValue::UndefinedValue); + return QScriptValue(q, QScriptValue::UndefinedValue); } #ifndef QT_NO_QOBJECT // lazy registration of some common list types else if (type == qMetaTypeId<QObjectList>()) { - qScriptRegisterSequenceMetaType<QObjectList>(q_func()); + qScriptRegisterSequenceMetaType<QObjectList>(q); return create(type, ptr); } #endif else if (type == qMetaTypeId<QList<int> >()) { - qScriptRegisterSequenceMetaType<QList<int> >(q_func()); + qScriptRegisterSequenceMetaType<QList<int> >(q); return create(type, ptr); } @@ -2646,9 +2637,9 @@ QScriptValue QScriptEnginePrivate::create(int type, const void *ptr) if (typeName == "QVariant") result = scriptValueFromVariant(*reinterpret_cast<const QVariant*>(ptr)); if (typeName.endsWith('*') && !*reinterpret_cast<void* const *>(ptr)) - result = QScriptValue(QScriptValue::NullValue); + return QScriptValue(q, QScriptValue::NullValue); else - result = q_func()->newVariant(QVariant(type, ptr)); + result = q->newVariant(QVariant(type, ptr)); } } } @@ -2663,8 +2654,8 @@ bool QScriptEnginePrivate::convert(const QScriptValue &value, int type, void *ptr, QScriptEnginePrivate *eng) { - if (!eng && value.engine()) - eng = QScriptEnginePrivate::get(value.engine()); + if (!eng) + eng = QScriptValuePrivate::getEngine(value); if (eng) { QScriptTypeInfo *info = eng->m_typeInfos.value(type); if (info && info->demarshal) { diff --git a/src/script/api/qscriptengine.h b/src/script/api/qscriptengine.h index 701f9c6..3f438da 100644 --- a/src/script/api/qscriptengine.h +++ b/src/script/api/qscriptengine.h @@ -67,6 +67,7 @@ class QDateTime; class QScriptClass; class QScriptEngineAgent; class QScriptEnginePrivate; +class QScriptProgram; #ifndef QT_NO_QOBJECT @@ -166,6 +167,8 @@ public: QScriptValue evaluate(const QString &program, const QString &fileName = QString(), int lineNumber = 1); + QScriptValue evaluate(const QScriptProgram &program); + bool isEvaluating() const; void abortEvaluation(const QScriptValue &result = QScriptValue()); diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index cde116d..d12b0f4 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -70,6 +70,7 @@ namespace JSC { + class EvalExecutable; class ExecState; typedef ExecState CallFrame; class JSCell; @@ -101,11 +102,22 @@ namespace QScript class TimeoutCheckerProxy; //some conversion helper functions - QScriptEnginePrivate *scriptEngineFromExec(const JSC::ExecState *exec); + inline QScriptEnginePrivate *scriptEngineFromExec(const JSC::ExecState *exec); bool isFunction(JSC::JSValue value); class UStringSourceProviderWithFeedback; -} + +struct GlobalClientData : public JSC::JSGlobalData::ClientData +{ + GlobalClientData(QScriptEnginePrivate *e) + : engine(e) {} + virtual ~GlobalClientData() {} + virtual void mark(JSC::MarkStack& markStack); + + QScriptEnginePrivate *engine; +}; + +} // namespace QScript class QScriptEnginePrivate #ifndef QT_NO_QOBJECT @@ -147,16 +159,16 @@ public: JSC::JSValue defaultPrototype(int metaTypeId) const; void setDefaultPrototype(int metaTypeId, JSC::JSValue prototype); - static QScriptContext *contextForFrame(JSC::ExecState *frame); - static JSC::ExecState *frameForContext(QScriptContext *context); - static const JSC::ExecState *frameForContext(const QScriptContext *context); + static inline QScriptContext *contextForFrame(JSC::ExecState *frame); + static inline JSC::ExecState *frameForContext(QScriptContext *context); + static inline const JSC::ExecState *frameForContext(const QScriptContext *context); JSC::JSGlobalObject *originalGlobalObject() const; JSC::JSObject *getOriginalGlobalObjectProxy(); JSC::JSObject *customGlobalObject() const; JSC::JSObject *globalObject() const; void setGlobalObject(JSC::JSObject *object); - JSC::ExecState *globalExec() const; + inline JSC::ExecState *globalExec() const; JSC::JSValue toUsableValue(JSC::JSValue value); static JSC::JSValue thisForContext(JSC::ExecState *frame); static JSC::Register *thisRegisterForFrame(JSC::ExecState *frame); @@ -200,6 +212,10 @@ public: const QByteArray &targetType, void **result); + JSC::JSValue evaluateHelper(JSC::ExecState *exec, intptr_t sourceId, + JSC::EvalExecutable *executable, + bool &compile); + QScript::QObjectData *qobjectData(QObject *object); void disposeQObject(QObject *object); void emitSignalHandlerException(); @@ -367,6 +383,11 @@ private: JSC::ExecState *oldFrame; }; +inline QScriptEnginePrivate *scriptEngineFromExec(const JSC::ExecState *exec) +{ + return static_cast<GlobalClientData*>(exec->globalData().clientData)->engine; +} + } // namespace QScript inline QScriptValuePrivate *QScriptEnginePrivate::allocateScriptValuePrivate(size_t size) @@ -451,7 +472,7 @@ inline void QScriptValuePrivate::initFrom(JSC::JSValue value) engine->registerScriptValue(this); } -inline void QScriptValuePrivate::initFrom(double value) +inline void QScriptValuePrivate::initFrom(qsreal value) { type = Number; numberValue = value; @@ -473,6 +494,28 @@ inline QScriptValue QScriptValuePrivate::property(const QString &name, int resol return property(JSC::Identifier(exec, name), resolveMode); } +inline QScriptValue QScriptValuePrivate::property(const JSC::Identifier &id, int resolveMode) const +{ + Q_ASSERT(isObject()); + JSC::ExecState *exec = engine->currentFrame; + JSC::JSObject *object = JSC::asObject(jscValue); + JSC::PropertySlot slot(object); + if ((resolveMode & QScriptValue::ResolvePrototype) && object->getPropertySlot(exec, id, slot)) + return engine->scriptValueFromJSCValue(slot.getValue(exec, id)); + return propertyHelper(id, resolveMode); +} + +inline QScriptValue QScriptValuePrivate::property(quint32 index, int resolveMode) const +{ + Q_ASSERT(isObject()); + JSC::ExecState *exec = engine->currentFrame; + JSC::JSObject *object = JSC::asObject(jscValue); + JSC::PropertySlot slot(object); + if ((resolveMode & QScriptValue::ResolvePrototype) && object->getPropertySlot(exec, index, slot)) + return engine->scriptValueFromJSCValue(slot.getValue(exec, index)); + return propertyHelper(index, resolveMode); +} + inline void* QScriptValuePrivate::operator new(size_t size, QScriptEnginePrivate *engine) { if (engine) @@ -489,6 +532,22 @@ inline void QScriptValuePrivate::operator delete(void *ptr) qFree(d); } +inline void QScriptValuePrivate::saveException(JSC::ExecState *exec, JSC::JSValue *val) +{ + if (exec) { + *val = exec->exception(); + exec->clearException(); + } else { + *val = JSC::JSValue(); + } +} + +inline void QScriptValuePrivate::restoreException(JSC::ExecState *exec, JSC::JSValue val) +{ + if (exec && val) + exec->setException(val); +} + inline void QScriptEnginePrivate::registerScriptString(QScriptStringPrivate *value) { Q_ASSERT(value->type == QScriptStringPrivate::HeapAllocated); @@ -512,6 +571,31 @@ inline void QScriptEnginePrivate::unregisterScriptString(QScriptStringPrivate *v value->next = 0; } +inline QScriptContext *QScriptEnginePrivate::contextForFrame(JSC::ExecState *frame) +{ + if (frame && frame->callerFrame()->hasHostCallFrameFlag() && !frame->callee() + && frame->callerFrame()->removeHostCallFrameFlag() == QScript::scriptEngineFromExec(frame)->globalExec()) { + //skip the "fake" context created in Interpreter::execute. + frame = frame->callerFrame()->removeHostCallFrameFlag(); + } + return reinterpret_cast<QScriptContext *>(frame); +} + +inline JSC::ExecState *QScriptEnginePrivate::frameForContext(QScriptContext *context) +{ + return reinterpret_cast<JSC::ExecState*>(context); +} + +inline const JSC::ExecState *QScriptEnginePrivate::frameForContext(const QScriptContext *context) +{ + return reinterpret_cast<const JSC::ExecState*>(context); +} + +inline JSC::ExecState *QScriptEnginePrivate::globalExec() const +{ + return originalGlobalObject()->globalExec(); +} + QT_END_NAMESPACE #endif diff --git a/src/script/api/qscriptprogram.cpp b/src/script/api/qscriptprogram.cpp new file mode 100644 index 0000000..c30f381 --- /dev/null +++ b/src/script/api/qscriptprogram.cpp @@ -0,0 +1,225 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtScript module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "config.h" +#include "qscriptprogram.h" +#include "qscriptprogram_p.h" +#include "qscriptengine.h" +#include "qscriptengine_p.h" + +#include "Executable.h" + +QT_BEGIN_NAMESPACE + +/*! + \internal + + \since 4.6 + \class QScriptProgram + + \brief The QScriptProgram class encapsulates a Qt Script program. + + \ingroup script + + QScriptProgram retains the compiled representation of the script if + possible. Thus, QScriptProgram can be used to evaluate the same + script multiple times more efficiently. + + \code + QScriptEngine engine; + QScriptProgram program("1 + 2"); + QScriptValue result = engine.evaluate(program); + \endcode +*/ + +QScriptProgramPrivate::QScriptProgramPrivate(const QString &src, + const QString &fn, + int ln) + : sourceCode(src), fileName(fn), firstLineNumber(ln), + engine(0), _executable(0), sourceId(-1), isCompiled(false) +{ + ref = 0; +} + +QScriptProgramPrivate::~QScriptProgramPrivate() +{ + delete _executable; +} + +QScriptProgramPrivate *QScriptProgramPrivate::get(const QScriptProgram &q) +{ + return const_cast<QScriptProgramPrivate*>(q.d_func()); +} + +JSC::EvalExecutable *QScriptProgramPrivate::executable(JSC::ExecState *exec, + QScriptEnginePrivate *eng) +{ + if (_executable) { + if (eng == engine) + return _executable; + delete _executable; + } + WTF::PassRefPtr<QScript::UStringSourceProviderWithFeedback> provider + = QScript::UStringSourceProviderWithFeedback::create(sourceCode, fileName, firstLineNumber, eng); + sourceId = provider->asID(); + JSC::SourceCode source(provider, firstLineNumber); //after construction of SourceCode provider variable will be null. + _executable = new JSC::EvalExecutable(exec, source); + engine = eng; + isCompiled = false; + return _executable; +} + +/*! + Constructs a null QScriptProgram. +*/ +QScriptProgram::QScriptProgram() + : d_ptr(0) +{ +} + +/*! + Constructs a new QScriptProgram with the given \a sourceCode, \a + fileName and \a firstLineNumber. +*/ +QScriptProgram::QScriptProgram(const QString &sourceCode, + const QString fileName, + int firstLineNumber) + : d_ptr(new QScriptProgramPrivate(sourceCode, fileName, firstLineNumber)) +{ +} + +/*! + Constructs a new QScriptProgram that is a copy of \a other. +*/ +QScriptProgram::QScriptProgram(const QScriptProgram &other) + : d_ptr(other.d_ptr) +{ +} + +/*! + Destroys this QScriptProgram. +*/ +QScriptProgram::~QScriptProgram() +{ + Q_D(QScriptProgram); + // if (d->engine && (d->ref == 1)) + // d->engine->unregisterScriptProgram(d); +} + +/*! + Assigns the \a other value to this QScriptProgram. +*/ +QScriptProgram &QScriptProgram::operator=(const QScriptProgram &other) +{ + // if (d_func() && d_func()->engine && (d_func()->ref == 1)) + // d_func()->engine->unregisterScriptProgram(d_func()); + // } + d_ptr = other.d_ptr; + return *this; +} + +/*! + Returns true if this QScriptProgram is null; otherwise + returns false. +*/ +bool QScriptProgram::isNull() const +{ + Q_D(const QScriptProgram); + return (d == 0); +} + +/*! + Returns the source code of this program. +*/ +QString QScriptProgram::sourceCode() const +{ + Q_D(const QScriptProgram); + if (!d) + return QString(); + return d->sourceCode; +} + +/*! + Returns the filename associated with this program. +*/ +QString QScriptProgram::fileName() const +{ + Q_D(const QScriptProgram); + if (!d) + return QString(); + return d->fileName; +} + +/*! + Returns the line number associated with this program. +*/ +int QScriptProgram::firstLineNumber() const +{ + Q_D(const QScriptProgram); + if (!d) + return -1; + return d->firstLineNumber; +} + +/*! + Returns true if this QScriptProgram is equal to \a other; + otherwise returns false. +*/ +bool QScriptProgram::operator==(const QScriptProgram &other) const +{ + Q_D(const QScriptProgram); + if (d == other.d_func()) + return true; + return (sourceCode() == other.sourceCode()) + && (fileName() == other.fileName()) + && (firstLineNumber() == other.firstLineNumber()); +} + +/*! + Returns true if this QScriptProgram is not equal to \a other; + otherwise returns false. +*/ +bool QScriptProgram::operator!=(const QScriptProgram &other) const +{ + return !operator==(other); +} + +QT_END_NAMESPACE diff --git a/src/script/api/qscriptprogram.h b/src/script/api/qscriptprogram.h new file mode 100644 index 0000000..de891cd --- /dev/null +++ b/src/script/api/qscriptprogram.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtScript module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTPROGRAM_H +#define QSCRIPTPROGRAM_H + +#include <QtCore/qsharedpointer.h> + +#include <QtCore/qstring.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Script) + +class QScriptProgramPrivate; +class Q_SCRIPT_EXPORT QScriptProgram +{ +public: + QScriptProgram(); + QScriptProgram(const QString &sourceCode, + const QString fileName = QString(), + int firstLineNumber = 1); + QScriptProgram(const QScriptProgram &other); + ~QScriptProgram(); + + QScriptProgram &operator=(const QScriptProgram &other); + + bool isNull() const; + + QString sourceCode() const; + QString fileName() const; + int firstLineNumber() const; + + bool operator==(const QScriptProgram &other) const; + bool operator!=(const QScriptProgram &other) const; + +private: + QExplicitlySharedDataPointer<QScriptProgramPrivate> d_ptr; + Q_DECLARE_PRIVATE(QScriptProgram) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QSCRIPTPROGRAM_H diff --git a/src/script/api/qscriptprogram_p.h b/src/script/api/qscriptprogram_p.h new file mode 100644 index 0000000..5175079 --- /dev/null +++ b/src/script/api/qscriptprogram_p.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtScript module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTPROGRAM_P_H +#define QSCRIPTPROGRAM_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobjectdefs.h> + +namespace JSC +{ + class EvalExecutable; + class ExecState; +} + +QT_BEGIN_NAMESPACE + +class QScriptEnginePrivate; + +class QScriptProgramPrivate +{ +public: + QScriptProgramPrivate(const QString &sourceCode, + const QString &fileName, + int firstLineNumber); + ~QScriptProgramPrivate(); + + static QScriptProgramPrivate *get(const QScriptProgram &q); + + JSC::EvalExecutable *executable(JSC::ExecState *exec, + QScriptEnginePrivate *engine); + + QBasicAtomicInt ref; + + QString sourceCode; + QString fileName; + int firstLineNumber; + + QScriptEnginePrivate *engine; + JSC::EvalExecutable *_executable; + intptr_t sourceId; + bool isCompiled; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/script/api/qscriptstring.cpp b/src/script/api/qscriptstring.cpp index 2fb157f..10fccd0 100644 --- a/src/script/api/qscriptstring.cpp +++ b/src/script/api/qscriptstring.cpp @@ -68,6 +68,10 @@ QT_BEGIN_NAMESPACE Call the toString() function to obtain the string that a QScriptString represents. + + Call the toArrayIndex() function to convert a QScriptString to an + array index. This is useful when using QScriptClass to implement + array-like objects. */ /*! @@ -139,8 +143,7 @@ QScriptString &QScriptString::operator=(const QScriptString &other) */ bool QScriptString::isValid() const { - Q_D(const QScriptString); - return (d && d->engine); + return QScriptStringPrivate::isValid(*this); } /*! @@ -165,6 +168,31 @@ bool QScriptString::operator!=(const QScriptString &other) const } /*! + \since 4.6 + + Attempts to convert this QScriptString to a QtScript array index, + and returns the result. + + If a conversion error occurs, *\a{ok} is set to false; otherwise + *\a{ok} is set to true. +*/ +quint32 QScriptString::toArrayIndex(bool *ok) const +{ + Q_D(const QScriptString); + if (!d) { + if (ok) + *ok = false; + return -1; + } + bool tmp; + bool *okok = ok ? ok : &tmp; + quint32 result = d->identifier.toArrayIndex(okok); + if (!*okok) + result = -1; + return result; +} + +/*! Returns the string that this QScriptString represents, or a null string if this QScriptString is not valid. diff --git a/src/script/api/qscriptstring.h b/src/script/api/qscriptstring.h index 40d156c..bf5d1d5 100644 --- a/src/script/api/qscriptstring.h +++ b/src/script/api/qscriptstring.h @@ -67,6 +67,8 @@ public: bool operator==(const QScriptString &other) const; bool operator!=(const QScriptString &other) const; + quint32 toArrayIndex(bool *ok = 0) const; + QString toString() const; operator QString() const; diff --git a/src/script/api/qscriptstring_p.h b/src/script/api/qscriptstring_p.h index d3bb47d..8e344e8 100644 --- a/src/script/api/qscriptstring_p.h +++ b/src/script/api/qscriptstring_p.h @@ -77,6 +77,8 @@ public: inline void detachFromEngine(); + static inline bool isValid(const QScriptString &q); + QBasicAtomicInt ref; QScriptEnginePrivate *engine; JSC::Identifier identifier; @@ -114,6 +116,11 @@ inline void QScriptStringPrivate::detachFromEngine() identifier = JSC::Identifier(); } +inline bool QScriptStringPrivate::isValid(const QScriptString &q) +{ + return (q.d_ptr && q.d_ptr->engine); +} + QT_END_NAMESPACE #endif diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp index b8340a7..52a1e6d 100644 --- a/src/script/api/qscriptvalue.cpp +++ b/src/script/api/qscriptvalue.cpp @@ -213,7 +213,7 @@ qint32 ToInt32(qsreal n) if (qIsNaN(n) || qIsInf(n) || (n == 0)) return 0; - double sign = (n < 0) ? -1.0 : 1.0; + qsreal sign = (n < 0) ? -1.0 : 1.0; qsreal abs_n = fabs(n); n = ::fmod(sign * ::floor(abs_n), D32); @@ -233,7 +233,7 @@ quint32 ToUint32(qsreal n) if (qIsNaN(n) || qIsInf(n) || (n == 0)) return 0; - double sign = (n < 0) ? -1.0 : 1.0; + qsreal sign = (n < 0) ? -1.0 : 1.0; qsreal abs_n = fabs(n); n = ::fmod(sign * ::floor(abs_n), D32); @@ -251,7 +251,7 @@ quint16 ToUint16(qsreal n) if (qIsNaN(n) || qIsInf(n) || (n == 0)) return 0; - double sign = (n < 0) ? -1.0 : 1.0; + qsreal sign = (n < 0) ? -1.0 : 1.0; qsreal abs_n = fabs(n); n = ::fmod(sign * ::floor(abs_n), D16); @@ -276,41 +276,36 @@ qsreal ToInteger(qsreal n) } // namespace QScript -QScriptValue QScriptValuePrivate::property(const JSC::Identifier &id, int resolveMode) const +QScriptValue QScriptValuePrivate::propertyHelper(const JSC::Identifier &id, int resolveMode) const { - Q_ASSERT(isObject()); - JSC::ExecState *exec = engine->currentFrame; - JSC::JSObject *object = JSC::asObject(jscValue); - JSC::PropertySlot slot(const_cast<JSC::JSObject*>(object)); JSC::JSValue result; - if (const_cast<JSC::JSObject*>(object)->getOwnPropertySlot(exec, id, slot)) { - result = slot.getValue(exec, id); - } else { - if ((resolveMode & QScriptValue::ResolvePrototype) - && const_cast<JSC::JSObject*>(object)->getPropertySlot(exec, id, slot)) { + 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); - } else if (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)); - } + } + 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::property(quint32 index, int resolveMode) const +QScriptValue QScriptValuePrivate::propertyHelper(quint32 index, int resolveMode) const { - Q_ASSERT(isObject()); - JSC::ExecState *exec = engine->currentFrame; - JSC::JSObject *object = JSC::asObject(jscValue); - JSC::PropertySlot slot(const_cast<JSC::JSObject*>(object)); JSC::JSValue result; - if (const_cast<JSC::JSObject*>(object)->getOwnPropertySlot(exec, index, slot)) { - result = slot.getValue(exec, index); - } else if ((resolveMode & QScriptValue::ResolvePrototype) - && const_cast<JSC::JSObject*>(object)->getPropertySlot(exec, index, slot)) { - result = slot.getValue(exec, index); + 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); } @@ -318,8 +313,8 @@ QScriptValue QScriptValuePrivate::property(quint32 index, int resolveMode) const void QScriptValuePrivate::setProperty(const JSC::Identifier &id, const QScriptValue &value, const QScriptValue::PropertyFlags &flags) { - QScriptEngine *valueEngine = value.engine(); - if (valueEngine && (QScriptEnginePrivate::get(valueEngine) != engine)) { + 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()))); @@ -443,22 +438,6 @@ void QScriptValuePrivate::setVariantValue(const QVariant &value) static_cast<QScript::QVariantDelegate*>(delegate)->setValue(value); } -void QScriptValuePrivate::saveException(JSC::ExecState *exec, JSC::JSValue *val) -{ - if (exec) { - *val = exec->exception(); - exec->clearException(); - } else { - *val = JSC::JSValue(); - } -} - -void QScriptValuePrivate::restoreException(JSC::ExecState *exec, JSC::JSValue val) -{ - if (exec && val) - exec->setException(val); -} - void QScriptValuePrivate::detachFromEngine() { if (isJSC()) @@ -822,8 +801,8 @@ void QScriptValue::setPrototype(const QScriptValue &prototype) Q_D(QScriptValue); if (!d || !d->isObject()) return; - if (prototype.isValid() && prototype.engine() - && (prototype.engine() != engine())) { + if (prototype.isValid() && QScriptValuePrivate::getEngine(prototype) + && (QScriptValuePrivate::getEngine(prototype) != d->engine)) { qWarning("QScriptValue::setPrototype() failed: " "cannot set a prototype created in " "a different engine"); @@ -864,8 +843,8 @@ void QScriptValue::setScope(const QScriptValue &scope) Q_D(QScriptValue); if (!d || !d->isObject()) return; - if (scope.isValid() && scope.engine() - && (scope.engine() != engine())) { + if (scope.isValid() && QScriptValuePrivate::getEngine(scope) + && (QScriptValuePrivate::getEngine(scope) != d->engine)) { qWarning("QScriptValue::setScope() failed: " "cannot set a scope object created in " "a different engine"); @@ -896,7 +875,7 @@ bool QScriptValue::instanceOf(const QScriptValue &other) const Q_D(const QScriptValue); if (!d || !d->isObject() || !other.isObject()) return false; - if (other.engine() != engine()) { + if (QScriptValuePrivate::getEngine(other) != d->engine) { qWarning("QScriptValue::instanceof: " "cannot perform operation on a value created in " "a different engine"); @@ -1083,10 +1062,12 @@ static bool Equals(QScriptValue lhs, QScriptValue rhs) */ bool QScriptValue::lessThan(const QScriptValue &other) const { + Q_D(const QScriptValue); // no equivalent function in JSC? There's a jsLess() in VM/Machine.cpp if (!isValid() || !other.isValid()) return false; - if (other.engine() && engine() && (other.engine() != engine())) { + if (QScriptValuePrivate::getEngine(other) && d->engine + && (QScriptValuePrivate::getEngine(other) != d->engine)) { qWarning("QScriptValue::lessThan: " "cannot compare to a value created in " "a different engine"); @@ -1124,7 +1105,8 @@ bool QScriptValue::equals(const QScriptValue &other) const Q_D(const QScriptValue); if (!d || !other.d_ptr) return (d_ptr == other.d_ptr); - if (other.engine() && engine() && (other.engine() != engine())) { + if (QScriptValuePrivate::getEngine(other) && d->engine + && (QScriptValuePrivate::getEngine(other) != d->engine)) { qWarning("QScriptValue::equals: " "cannot compare to a value created in " "a different engine"); @@ -1173,7 +1155,8 @@ bool QScriptValue::strictlyEquals(const QScriptValue &other) const Q_D(const QScriptValue); if (!d || !other.d_ptr) return (d_ptr == other.d_ptr); - if (other.engine() && engine() && (other.engine() != engine())) { + if (QScriptValuePrivate::getEngine(other) && d->engine + && (QScriptValuePrivate::getEngine(other) != d->engine)) { qWarning("QScriptValue::strictlyEquals: " "cannot compare to a value created in " "a different engine"); @@ -1725,7 +1708,8 @@ void QScriptValue::setProperty(quint32 arrayIndex, const QScriptValue &value, Q_D(QScriptValue); if (!d || !d->isObject()) return; - if (value.engine() && (value.engine() != engine())) { + if (QScriptValuePrivate::getEngine(value) + && (QScriptValuePrivate::getEngine(value) != d->engine)) { qWarning("QScriptValue::setProperty() failed: " "cannot set value created in a different engine"); return; @@ -1775,7 +1759,7 @@ QScriptValue QScriptValue::property(const QScriptString &name, const ResolveFlags &mode) const { Q_D(const QScriptValue); - if (!d || !d->isObject() || !name.isValid()) + if (!d || !d->isObject() || !QScriptStringPrivate::isValid(name)) return QScriptValue(); return d->property(name.d_ptr->identifier, mode); } @@ -1798,7 +1782,7 @@ void QScriptValue::setProperty(const QScriptString &name, const PropertyFlags &flags) { Q_D(QScriptValue); - if (!d || !d->isObject() || !name.isValid()) + if (!d || !d->isObject() || !QScriptStringPrivate::isValid(name)) return; d->setProperty(name.d_ptr->identifier, value, flags); } @@ -1832,7 +1816,7 @@ QScriptValue::PropertyFlags QScriptValue::propertyFlags(const QScriptString &nam const ResolveFlags &mode) const { Q_D(const QScriptValue); - if (!d || !d->isObject() || !name.isValid()) + if (!d || !d->isObject() || !QScriptStringPrivate::isValid(name)) return 0; return d->propertyFlags(name.d_ptr->identifier, mode); } @@ -1872,7 +1856,8 @@ QScriptValue QScriptValue::call(const QScriptValue &thisObject, if (callType == JSC::CallTypeNone) return QScriptValue(); - if (thisObject.engine() && (thisObject.engine() != engine())) { + if (QScriptValuePrivate::getEngine(thisObject) + && (QScriptValuePrivate::getEngine(thisObject) != d->engine)) { qWarning("QScriptValue::call() failed: " "cannot call function with thisObject created in " "a different engine"); @@ -1890,7 +1875,8 @@ QScriptValue QScriptValue::call(const QScriptValue &thisObject, const QScriptValue &arg = args.at(i); if (!arg.isValid()) { argsVector[i] = JSC::jsUndefined(); - } else if (arg.engine() && (arg.engine() != engine())) { + } else if (QScriptValuePrivate::getEngine(arg) + && (QScriptValuePrivate::getEngine(arg) != d->engine)) { qWarning("QScriptValue::call() failed: " "cannot call function with argument created in " "a different engine"); @@ -1947,7 +1933,8 @@ QScriptValue QScriptValue::call(const QScriptValue &thisObject, if (callType == JSC::CallTypeNone) return QScriptValue(); - if (thisObject.engine() && (thisObject.engine() != engine())) { + if (QScriptValuePrivate::getEngine(thisObject) + && (QScriptValuePrivate::getEngine(thisObject) != d->engine)) { qWarning("QScriptValue::call() failed: " "cannot call function with thisObject created in " "a different engine"); diff --git a/src/script/api/qscriptvalue_p.h b/src/script/api/qscriptvalue_p.h index 77b5084..c322a37 100644 --- a/src/script/api/qscriptvalue_p.h +++ b/src/script/api/qscriptvalue_p.h @@ -81,7 +81,7 @@ public: inline ~QScriptValuePrivate(); inline void initFrom(JSC::JSValue value); - inline void initFrom(double value); + inline void initFrom(qsreal value); inline void initFrom(const QString &value); inline bool isJSC() const; @@ -100,8 +100,17 @@ public: return QScriptValue(d); } - QScriptValue property(const JSC::Identifier &id, int resolveMode) const; - QScriptValue property(quint32 index, int resolveMode) const; + static inline QScriptEnginePrivate *getEngine(const QScriptValue &q) + { + if (!q.d_ptr) + return 0; + 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); @@ -118,13 +127,13 @@ public: return -1; } - static void saveException(JSC::ExecState*, JSC::JSValue*); - static void restoreException(JSC::ExecState*, JSC::JSValue); + static inline void saveException(JSC::ExecState*, JSC::JSValue*); + static inline void restoreException(JSC::ExecState*, JSC::JSValue); QScriptEnginePrivate *engine; Type type; JSC::JSValue jscValue; - double numberValue; + qsreal numberValue; QString stringValue; // linked list of engine's script values |