diff options
author | Bjørn Erik Nilsen <bjorn.nilsen@nokia.com> | 2009-08-21 12:00:07 (GMT) |
---|---|---|
committer | Bjørn Erik Nilsen <bjorn.nilsen@nokia.com> | 2009-08-21 12:00:07 (GMT) |
commit | 8d00a0a21f245d15962191e0690d3619735d118b (patch) | |
tree | 7aaa66528f0ee40d0d2d885f94835d0f09ea4a68 /src/script | |
parent | 97cec103793a4b9aae8337ffc2ce9a2bd98fb5fc (diff) | |
parent | 508b447075fb852e61ddf88c92c9099dad292747 (diff) | |
download | Qt-8d00a0a21f245d15962191e0690d3619735d118b.zip Qt-8d00a0a21f245d15962191e0690d3619735d118b.tar.gz Qt-8d00a0a21f245d15962191e0690d3619735d118b.tar.bz2 |
Merge commit 'qt/master' into kinetic-graphicseffect
Conflicts:
src/gui/graphicsview/graphicsview.pri
Diffstat (limited to 'src/script')
138 files changed, 12816 insertions, 34106 deletions
diff --git a/src/script/api/api.pri b/src/script/api/api.pri new file mode 100644 index 0000000..17ec9b6 --- /dev/null +++ b/src/script/api/api.pri @@ -0,0 +1,32 @@ +SOURCES += \ + $$PWD/qscriptclass.cpp \ + $$PWD/qscriptclasspropertyiterator.cpp \ + $$PWD/qscriptcontext.cpp \ + $$PWD/qscriptcontextinfo.cpp \ + $$PWD/qscriptengine.cpp \ + $$PWD/qscriptengineagent.cpp \ + $$PWD/qscriptextensionplugin.cpp \ + $$PWD/qscriptstring.cpp \ + $$PWD/qscriptvalue.cpp \ + $$PWD/qscriptvalueiterator.cpp \ + $$PWD/qscriptable.cpp + +HEADERS += \ + $$PWD/qscriptclass.h \ + $$PWD/qscriptclasspropertyiterator.h \ + $$PWD/qscriptcontext.h \ + $$PWD/qscriptcontext_p.h \ + $$PWD/qscriptcontextinfo.h \ + $$PWD/qscriptengine.h \ + $$PWD/qscriptengine_p.h \ + $$PWD/qscriptengineagent.h \ + $$PWD/qscriptengineagent_p.h \ + $$PWD/qscriptextensioninterface.h \ + $$PWD/qscriptextensionplugin.h \ + $$PWD/qscriptstring.h \ + $$PWD/qscriptstring_p.h \ + $$PWD/qscriptvalue.h \ + $$PWD/qscriptvalue_p.h \ + $$PWD/qscriptvalueiterator.h \ + $$PWD/qscriptable.h \ + $$PWD/qscriptable_p.h diff --git a/src/script/qscriptable.cpp b/src/script/api/qscriptable.cpp index 97c0173..eb5972c 100644 --- a/src/script/qscriptable.cpp +++ b/src/script/api/qscriptable.cpp @@ -40,16 +40,8 @@ ****************************************************************************/ #include "qscriptable.h" - -#ifndef QT_NO_QOBJECT - -#ifndef QT_NO_SCRIPT - #include "qscriptable_p.h" - #include "qscriptengine.h" -#include "qscriptcontext.h" -#include "qscriptvalue.h" QT_BEGIN_NAMESPACE @@ -189,7 +181,4 @@ QScriptValue QScriptable::argument(int index) const return QScriptValue(); } -#endif // QT_NO_SCRIPT -#endif // QT_NO_QOBJECT - QT_END_NAMESPACE diff --git a/src/script/qscriptable.h b/src/script/api/qscriptable.h index eef7ae4..5434cd9 100644 --- a/src/script/qscriptable.h +++ b/src/script/api/qscriptable.h @@ -44,8 +44,6 @@ #include <QtCore/qobjectdefs.h> -#ifndef QT_NO_SCRIPT - QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -85,5 +83,4 @@ QT_END_NAMESPACE QT_END_HEADER -#endif // QT_NO_SCRIPT #endif // QSCRIPTABLE_H diff --git a/src/script/qscriptable_p.h b/src/script/api/qscriptable_p.h index c8400e0..a32422d 100644 --- a/src/script/qscriptable_p.h +++ b/src/script/api/qscriptable_p.h @@ -42,8 +42,6 @@ #ifndef QSCRIPTABLE_P_H #define QSCRIPTABLE_P_H -#include <QtCore/qobjectdefs.h> - // // W A R N I N G // ------------- @@ -55,12 +53,11 @@ // We mean it. // -#ifndef QT_NO_SCRIPT +#include <QtCore/qobjectdefs.h> QT_BEGIN_NAMESPACE -class QScriptEngine; - +class QScriptable; class QScriptablePrivate { Q_DECLARE_PUBLIC(QScriptable) @@ -79,6 +76,4 @@ public: QT_END_NAMESPACE -#endif // QT_NO_SCRIPT - #endif diff --git a/src/script/qscriptclass.cpp b/src/script/api/qscriptclass.cpp index 1df57d0..cff6ce5 100644 --- a/src/script/qscriptclass.cpp +++ b/src/script/api/qscriptclass.cpp @@ -34,31 +34,13 @@ ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. +** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qscriptclass.h" - -#ifndef QT_NO_SCRIPT - -#include <QtCore/qstringlist.h> - -#include "qscriptclasspropertyiterator.h" #include "qscriptstring.h" -#include "qscriptstring_p.h" -#include "qscriptclass_p.h" -#include "qscriptclassinfo_p.h" -#include "qscriptengine_p.h" -#include "qscriptcontext_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" -#include "qscriptfunction_p.h" - -Q_DECLARE_METATYPE(QScriptContext*) -Q_DECLARE_METATYPE(QScriptValueList) QT_BEGIN_NAMESPACE @@ -69,7 +51,7 @@ QT_BEGIN_NAMESPACE \brief The QScriptClass class provides an interface for defining custom behavior of (a class of) Qt Script objects. \ingroup script - + \mainclass The QScriptClass class defines an interface for handling various aspects of interaction with the Qt Script objects associated with @@ -149,292 +131,27 @@ QT_BEGIN_NAMESPACE \sa queryProperty() */ -class QScriptCustomClassData : public QScriptClassData +class QScriptClassPrivate { + Q_DECLARE_PUBLIC(QScriptClass) public: - QScriptCustomClassData(QScriptClass *klass); - ~QScriptCustomClassData(); - - virtual void mark(const QScriptValueImpl &object, int generation); - virtual bool resolve(const QScriptValueImpl &object, QScriptNameIdImpl *nameId, - QScript::Member *member, QScriptValueImpl *base, - QScript::AccessMode access); - virtual bool get(const QScriptValueImpl &obj, const QScript::Member &m, - QScriptValueImpl *result); - virtual bool put(QScriptValueImpl *object, const QScript::Member &member, - const QScriptValueImpl &value); - virtual bool removeMember(const QScriptValueImpl &object, - const QScript::Member &member); - virtual bool implementsHasInstance(const QScriptValueImpl &object); - virtual bool hasInstance(const QScriptValueImpl &object, - const QScriptValueImpl &value); - virtual QScriptClassDataIterator *newIterator(const QScriptValueImpl &object); - - QScriptClass *scriptClass() const; - -private: - QScriptClass *m_class; -}; + QScriptClassPrivate() {} + virtual ~QScriptClassPrivate() {} -class QScriptCustomClassDataIterator : public QScriptClassDataIterator -{ -public: - QScriptCustomClassDataIterator(const QScriptValueImpl &object, - QScriptClass *klass); - virtual ~QScriptCustomClassDataIterator(); + QScriptEngine *engine; - virtual bool hasNext() const; - virtual void next(QScript::Member *member); - - virtual bool hasPrevious() const; - virtual void previous(QScript::Member *member); - - virtual void toFront(); - virtual void toBack(); - -private: - void iteratorToMember(QScript::Member *member); - - QScriptClassPropertyIterator *m_it; + QScriptClass *q_ptr; }; -QScriptCustomClassData::QScriptCustomClassData(QScriptClass *klass) - : m_class(klass) -{ -} - -QScriptCustomClassData::~QScriptCustomClassData() -{ -} - -void QScriptCustomClassData::mark(const QScriptValueImpl &, int) -{ -} - -bool QScriptCustomClassData::resolve(const QScriptValueImpl &object, QScriptNameIdImpl *nameId, - QScript::Member *member, QScriptValueImpl *base, - QScript::AccessMode access) -{ - uint id = 0; - QScriptClass::QueryFlags queryIn = 0; - if (access & QScript::Read) - queryIn |= QScriptClass::HandlesReadAccess; - if (access & QScript::Write) - queryIn |= QScriptClass::HandlesWriteAccess; - QScriptEnginePrivate *eng = object.engine(); - QScriptString str = eng->internedString(nameId); - QScriptClass::QueryFlags queryOut; - queryOut = m_class->queryProperty(eng->toPublic(object), str, queryIn, &id); - if (queryOut & queryIn) { - if (base) - *base = object; - QScriptValue::PropertyFlags flags = m_class->propertyFlags(eng->toPublic(object), str, id); - member->native(nameId, id, flags); - return true; - } - return false; -} - -bool QScriptCustomClassData::get(const QScriptValueImpl &object, const QScript::Member &member, - QScriptValueImpl *result) -{ - QScriptEnginePrivate *eng = object.engine(); - QScriptString str = eng->internedString(member.nameId()); - *result = eng->toImpl(m_class->property(eng->toPublic(object), str, member.id())); - if (!result->isValid()) - *result = eng->undefinedValue(); - return true; -} - -bool QScriptCustomClassData::put(QScriptValueImpl *object, const QScript::Member &member, - const QScriptValueImpl &value) -{ - QScriptEnginePrivate *eng = object->engine(); - QScriptString str = eng->internedString(member.nameId()); - QScriptValue publicObject = eng->toPublic(*object); - m_class->setProperty(publicObject, str, member.id(), eng->toPublic(value)); - return true; -} - -bool QScriptCustomClassData::removeMember(const QScriptValueImpl &object, - const QScript::Member &member) -{ - QScriptEnginePrivate *eng = object.engine(); - QScriptString str = eng->internedString(member.nameId()); - QScriptValue publicObject = eng->toPublic(object); - m_class->setProperty(publicObject, str, member.id(), QScriptValue()); - return true; -} - -bool QScriptCustomClassData::implementsHasInstance(const QScriptValueImpl &object) -{ - if (object.classInfo() != QScriptClassPrivate::get(m_class)->classInfo()) - return false; - return m_class->supportsExtension(QScriptClass::HasInstance); -} - -bool QScriptCustomClassData::hasInstance(const QScriptValueImpl &object, - const QScriptValueImpl &value) -{ - QScriptEnginePrivate *eng = object.engine(); - QScriptValueList arguments; - arguments << eng->toPublic(object) << eng->toPublic(value); - QVariant ret = m_class->extension(QScriptClass::HasInstance, qVariantFromValue(arguments)); - return ret.toBool(); -} - -QScriptClassDataIterator *QScriptCustomClassData::newIterator(const QScriptValueImpl &object) -{ - return new QScriptCustomClassDataIterator(object, m_class); -} - -QScriptClass *QScriptCustomClassData::scriptClass() const -{ - return m_class; -} - - - -QScriptCustomClassDataIterator::QScriptCustomClassDataIterator(const QScriptValueImpl &object, - QScriptClass *klass) -{ - QScriptEnginePrivate *eng = object.engine(); - m_it = klass->newIterator(eng->toPublic(object)); -} - -QScriptCustomClassDataIterator::~QScriptCustomClassDataIterator() -{ - if (m_it) { - delete m_it; - m_it = 0; - } -} - -bool QScriptCustomClassDataIterator::hasNext() const -{ - return m_it && m_it->hasNext(); -} - -void QScriptCustomClassDataIterator::next(QScript::Member *member) -{ - if (m_it) { - m_it->next(); - iteratorToMember(member); - } -} - -bool QScriptCustomClassDataIterator::hasPrevious() const -{ - return m_it && m_it->hasPrevious(); -} - -void QScriptCustomClassDataIterator::previous(QScript::Member *member) -{ - if (m_it) { - m_it->previous(); - iteratorToMember(member); - } -} - -void QScriptCustomClassDataIterator::toFront() -{ - if (m_it) - m_it->toFront(); -} - -void QScriptCustomClassDataIterator::toBack() -{ - if (m_it) - m_it->toBack(); -} - -void QScriptCustomClassDataIterator::iteratorToMember(QScript::Member *member) -{ - QScriptString str = m_it->name(); - QScriptNameIdImpl *nameId = 0; - if (str.isValid()) - nameId = QScriptStringPrivate::get(str)->nameId; - member->native(nameId, m_it->id(), m_it->flags()); -} - - - -QScriptClassPrivate::QScriptClassPrivate(QScriptClass *q) - : engine(0), m_classInfo(0), q_ptr(q) -{ -} - -QScriptClassPrivate::~QScriptClassPrivate() -{ - if (m_classInfo) { - // classInfo is owned by engine - // set the data to the normal Object class data - delete m_classInfo->data(); - QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(engine); - m_classInfo->setData(eng_p->m_class_object->data()); - } -} - -QScriptClassPrivate *QScriptClassPrivate::get(QScriptClass *klass) -{ - return klass->d_func(); -} - -QScriptClassInfo *QScriptClassPrivate::classInfo() -{ - Q_Q(QScriptClass); - if (m_classInfo) - return m_classInfo; - QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(engine); - int classType = eng_p->registerCustomClassType(); - if (q->supportsExtension(QScriptClass::Callable)) - classType |= QScriptClassInfo::FunctionBased; - QString name = q->name(); - if (name.isEmpty()) - name = QLatin1String("Object"); - m_classInfo = eng_p->registerClass(name, classType); - m_classInfo->setData(new QScriptCustomClassData(q_func())); - return m_classInfo; -} - -QScriptClass *QScriptClassPrivate::classFromInfo(QScriptClassInfo *info) -{ - QScriptCustomClassData *data = static_cast<QScriptCustomClassData*>(info->data()); - Q_ASSERT(data != 0); - return data->scriptClass(); -} - -static QScriptValueImpl callScriptClassFunction(QScriptContextPrivate *ctx, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo) -{ - qMetaTypeId<QScriptContext*>(); - if (QScriptClassData *data = classInfo->data()) { - QScriptCustomClassData *customData = static_cast<QScriptCustomClassData*>(data); - QScriptClass *klass = customData->scriptClass(); - QVariant arg = qVariantFromValue(QScriptContextPrivate::get(ctx)); - QVariant ret = klass->extension(QScriptClass::Callable, arg); - QScriptValueImpl val = eng->valueFromVariant(ret); - if (val.isValid()) - return val; - } - return eng->undefinedValue(); -} - -QScriptFunction *QScriptClassPrivate::newFunction() -{ - return new QScript::C2Function(callScriptClassFunction, /*length=*/0, - classInfo(), /*name=*/QString()); -} - /*! Constructs a QScriptClass object to be used in the given \a engine. The engine does not take ownership of the QScriptClass object. */ QScriptClass::QScriptClass(QScriptEngine *engine) - : d_ptr(new QScriptClassPrivate(this)) + : d_ptr(new QScriptClassPrivate) { + d_ptr->q_ptr = this; d_ptr->engine = engine; } @@ -680,5 +397,3 @@ QVariant QScriptClass::extension(Extension extension, const QVariant &argument) } QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptclass.h b/src/script/api/qscriptclass.h index 0ad0535..ad41ada 100644 --- a/src/script/qscriptclass.h +++ b/src/script/api/qscriptclass.h @@ -44,8 +44,6 @@ #include <QtCore/qstring.h> -#ifndef QT_NO_SCRIPT - #include <QtCore/qvariant.h> #include <QtScript/qscriptvalue.h> @@ -116,6 +114,4 @@ QT_END_NAMESPACE QT_END_HEADER -#endif // QT_NO_SCRIPT - #endif diff --git a/src/script/qscriptclasspropertyiterator.cpp b/src/script/api/qscriptclasspropertyiterator.cpp index c6a7fff..4efbc19 100644 --- a/src/script/qscriptclasspropertyiterator.cpp +++ b/src/script/api/qscriptclasspropertyiterator.cpp @@ -41,9 +41,6 @@ #include "qscriptclasspropertyiterator.h" -#ifndef QT_NO_SCRIPT - -#include "qscriptclasspropertyiterator_p.h" #include "qscriptstring.h" QT_BEGIN_NAMESPACE @@ -74,14 +71,17 @@ QT_BEGIN_NAMESPACE \sa QScriptClass::newIterator(), QScriptValueIterator */ -QScriptClassPropertyIteratorPrivate::QScriptClassPropertyIteratorPrivate(QScriptClassPropertyIterator *q) - : q_ptr(q) +class QScriptClassPropertyIteratorPrivate { -} + Q_DECLARE_PUBLIC(QScriptClassPropertyIterator) +public: + QScriptClassPropertyIteratorPrivate() {} + virtual ~QScriptClassPropertyIteratorPrivate() {} -QScriptClassPropertyIteratorPrivate::~QScriptClassPropertyIteratorPrivate() -{ -} + QScriptValue object; + + QScriptClassPropertyIterator *q_ptr; +}; /*! Constructs an iterator for traversing \a object. @@ -90,8 +90,9 @@ QScriptClassPropertyIteratorPrivate::~QScriptClassPropertyIteratorPrivate() sequence of properties (before the first property). */ QScriptClassPropertyIterator::QScriptClassPropertyIterator(const QScriptValue &object) - : d_ptr(new QScriptClassPropertyIteratorPrivate(this)) + : d_ptr(new QScriptClassPropertyIteratorPrivate) { + d_ptr->q_ptr = this; d_ptr->object = object; } @@ -221,5 +222,3 @@ QScriptValue::PropertyFlags QScriptClassPropertyIterator::flags() const } QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptclasspropertyiterator.h b/src/script/api/qscriptclasspropertyiterator.h index 3f870b4..de416be 100644 --- a/src/script/qscriptclasspropertyiterator.h +++ b/src/script/api/qscriptclasspropertyiterator.h @@ -44,8 +44,6 @@ #include <QtCore/qstring.h> -#ifndef QT_NO_SCRIPT - #include <QtScript/qscriptvalue.h> QT_BEGIN_HEADER @@ -91,6 +89,4 @@ QT_END_NAMESPACE QT_END_HEADER -#endif // QT_NO_SCRIPT - #endif diff --git a/src/script/api/qscriptcontext.cpp b/src/script/api/qscriptcontext.cpp new file mode 100644 index 0000000..0b1ca33 --- /dev/null +++ b/src/script/api/qscriptcontext.cpp @@ -0,0 +1,764 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "config.h" +#include "qscriptcontext.h" + +#include "qscriptcontext_p.h" +#include "qscriptcontextinfo.h" +#include "qscriptengine.h" +#include "qscriptengine_p.h" +#include "../bridge/qscriptactivationobject_p.h" + +#include "Arguments.h" +#include "CodeBlock.h" +#include "Error.h" +#include "JSFunction.h" +#include "JSObject.h" +#include "JSGlobalObject.h" + +#include <QtCore/qstringlist.h> + +QT_BEGIN_NAMESPACE + +/*! + \since 4.3 + \class QScriptContext + + \brief The QScriptContext class represents a Qt Script function invocation. + + \ingroup script + \mainclass + + A QScriptContext provides access to the `this' object and arguments + passed to a script function. You typically want to access this + information when you're writing a native (C++) function (see + QScriptEngine::newFunction()) that will be called from script + code. For example, when the script code + + \snippet doc/src/snippets/code/src_script_qscriptcontext.cpp 0 + + is evaluated, a QScriptContext will be created, and the context will + carry the arguments as QScriptValues; in this particular case, the + arguments will be one QScriptValue containing the number 20.5, a second + QScriptValue containing the string \c{"hello"}, and a third QScriptValue + containing a Qt Script object. + + Use argumentCount() to get the number of arguments passed to the + function, and argument() to get an argument at a certain index. The + argumentsObject() function returns a Qt Script array object + containing all the arguments; you can use the QScriptValueIterator + to iterate over its elements, or pass the array on as arguments to + another script function using QScriptValue::call(). + + Use thisObject() to get the `this' object associated with the function call, + and setThisObject() to set the `this' object. If you are implementing a + native "instance method", you typically fetch the thisObject() and access + one or more of its properties: + + \snippet doc/src/snippets/code/src_script_qscriptcontext.cpp 1 + + Use isCalledAsConstructor() to determine if the function was called + as a constructor (e.g. \c{"new foo()"} (as constructor) or just + \c{"foo()"}). When a function is called as a constructor, the + thisObject() contains the newly constructed object that the function + is expected to initialize. + + Use throwValue() or throwError() to throw an exception. + + Use callee() to obtain the QScriptValue that represents the function being + called. This can for example be used to call the function recursively. + + Use parentContext() to get a pointer to the context that precedes + this context in the activation stack. This is mostly useful for + debugging purposes (e.g. when constructing some form of backtrace). + + The activationObject() function returns the object that is used to + hold the local variables associated with this function call. You can + replace the activation object by calling setActivationObject(). A + typical usage of these functions is when you want script code to be + evaluated in the context of the parent context, e.g. to implement an + include() function: + + \snippet doc/src/snippets/code/src_script_qscriptcontext.cpp 2 + + Use backtrace() to get a human-readable backtrace associated with + this context. This can be useful for debugging purposes when + implementing native functions. The toString() function provides a + string representation of the context. (QScriptContextInfo provides + more detailed debugging-related information about the + QScriptContext.) + + Use engine() to obtain a pointer to the QScriptEngine that this context + resides in. + + \sa QScriptContextInfo, QScriptEngine::newFunction(), QScriptable +*/ + +/*! + \enum QScriptContext::ExecutionState + + This enum specifies the frameution state of the context. + + \value NormalState The context is in a normal state. + + \value ExceptionState The context is in an exceptional state. +*/ + +/*! + \enum QScriptContext::Error + + This enum specifies types of error. + + \value ReferenceError A reference error. + + \value SyntaxError A syntax error. + + \value TypeError A type error. + + \value RangeError A range error. + + \value URIError A URI error. + + \value UnknownError An unknown error. +*/ + +/*! + \internal +*/ +QScriptContext::QScriptContext() +{ + //QScriptContext doesn't exist, pointer to QScriptContext are just pointer to JSC::CallFrame + Q_ASSERT(false); +} + +/*! + Throws an exception with the given \a value. + Returns the value thrown (the same as the argument). + + \sa throwError(), state() +*/ +QScriptValue QScriptContext::throwValue(const QScriptValue &value) +{ + JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); + JSC::JSValue jscValue = QScript::scriptEngineFromExec(frame)->scriptValueToJSCValue(value); + frame->setException(jscValue); + return value; +} + +/*! + Throws an \a error with the given \a text. + Returns the created error object. + + The \a text will be stored in the \c{message} property of the error + object. + + The error object will be initialized to contain information about + the location where the error occurred; specifically, it will have + properties \c{lineNumber}, \c{fileName} and \c{stack}. These + properties are described in \l {QtScript Extensions to ECMAScript}. + + \sa throwValue(), state() +*/ +QScriptValue QScriptContext::throwError(Error error, const QString &text) +{ + JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); + JSC::ErrorType jscError = JSC::GeneralError; + switch (error) { + case UnknownError: + break; + case ReferenceError: + jscError = JSC::ReferenceError; + break; + case SyntaxError: + jscError = JSC::SyntaxError; + break; + case TypeError: + jscError = JSC::TypeError; + break; + case RangeError: + jscError = JSC::RangeError; + break; + case URIError: + jscError = JSC::URIError; + break; + } + JSC::JSObject *result = JSC::throwError(frame, jscError, text); + return QScript::scriptEngineFromExec(frame)->scriptValueFromJSCValue(result); +} + +/*! + \overload + + Throws an error with the given \a text. + Returns the created error object. + + \sa throwValue(), state() +*/ +QScriptValue QScriptContext::throwError(const QString &text) +{ + JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); + JSC::JSObject *result = JSC::throwError(frame, JSC::GeneralError, text); + return QScript::scriptEngineFromExec(frame)->scriptValueFromJSCValue(result); +} + +/*! + Destroys this QScriptContext. +*/ +QScriptContext::~QScriptContext() +{ + //QScriptContext doesn't exist, pointer to QScriptContext are just pointer to JSC::CallFrame + Q_ASSERT(false); +} + +/*! + Returns the QScriptEngine that this QScriptContext belongs to. +*/ +QScriptEngine *QScriptContext::engine() const +{ + const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); + return QScriptEnginePrivate::get(QScript::scriptEngineFromExec(frame)); +} + +/*! + Returns the function argument at the given \a index. + + If \a index >= argumentCount(), a QScriptValue of + the primitive type Undefined is returned. + + \sa argumentCount() +*/ +QScriptValue QScriptContext::argument(int index) const +{ + if (index < 0) + return QScriptValue(); + if (index >= argumentCount()) + return QScriptValue(QScriptValue::UndefinedValue); + QScriptValue v = argumentsObject().property(index); + return v; +} + +/*! + Returns the callee. The callee is the function object that this + QScriptContext represents an invocation of. +*/ +QScriptValue QScriptContext::callee() const +{ + const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); + return QScript::scriptEngineFromExec(frame)->scriptValueFromJSCValue(frame->callee()); +} + +/*! + Returns the arguments object of this QScriptContext. + + The arguments object has properties \c callee (equal to callee()) + and \c length (equal to argumentCount()), and properties \c 0, \c 1, + ..., argumentCount() - 1 that provide access to the argument + values. Initially, property \c P (0 <= \c P < argumentCount()) has + the same value as argument(\c P). In the case when \c P is less + than the number of formal parameters of the function, \c P shares + its value with the corresponding property of the activation object + (activationObject()). This means that changing this property changes + the corresponding property of the activation object and vice versa. + + \sa argument(), activationObject() +*/ +QScriptValue QScriptContext::argumentsObject() const +{ + JSC::CallFrame *frame = const_cast<JSC::ExecState*>(QScriptEnginePrivate::frameForContext(this)); + + if (frame == frame->lexicalGlobalObject()->globalExec() || frame->callerFrame()->hasHostCallFrameFlag()) { + // <global> or <eval> context doesn't have arguments. return an empty object + return QScriptEnginePrivate::get(QScript::scriptEngineFromExec(frame))->newObject(); + } + + //for a js function + if (frame->codeBlock() && frame->callee()) { + JSC::JSValue result = frame->interpreter()->retrieveArguments(frame, JSC::asFunction(frame->callee())); + return QScript::scriptEngineFromExec(frame)->scriptValueFromJSCValue(result); + } + + //for a native function + if (!frame->optionalCalleeArguments()) { + Q_ASSERT(frame->argumentCount() > 0); //we need at least 'this' otherwise we'll crash later + JSC::Arguments* arguments = new (&frame->globalData())JSC::Arguments(frame, JSC::Arguments::NoParameters); + frame->setCalleeArguments(arguments); + } + return QScript::scriptEngineFromExec(frame)->scriptValueFromJSCValue(frame->optionalCalleeArguments()); +} + +/*! + Returns true if the function was called as a constructor + (e.g. \c{"new foo()"}); otherwise returns false. + + When a function is called as constructor, the thisObject() + contains the newly constructed object to be initialized. +*/ +bool QScriptContext::isCalledAsConstructor() const +{ + JSC::CallFrame *frame = const_cast<JSC::ExecState*>(QScriptEnginePrivate::frameForContext(this)); + + //For native functions, look up flags. + uint flags = QScriptEnginePrivate::contextFlags(frame); + if (flags & QScriptEnginePrivate::NativeContext) + return flags & QScriptEnginePrivate::CalledAsConstructorContext; + + //Not a native function, try to look up in the bytecode if we where called from op_construct + JSC::Instruction* returnPC = frame->returnPC(); + + if (!returnPC) + return false; + + JSC::CallFrame *callerFrame = QScriptEnginePrivate::frameForContext(parentContext()); + if (!callerFrame) + return false; + + if (returnPC[-JSC::op_construct_length].u.opcode == frame->interpreter()->getOpcode(JSC::op_construct)) { + //We are maybe called from the op_construct opcode which has 6 opperands. + //But we need to check we are not called from op_call with 4 opperands + + //we make sure that the returnPC[-1] (thisRegister) is smaller than the returnPC[-3] (registerOffset) + //as if it was an op_call, the returnPC[-1] would be the registerOffset, bigger than returnPC[-3] (funcRegister) + return returnPC[-1].u.operand < returnPC[-3].u.operand; + } + return false; +} + +/*! + Returns the parent context of this QScriptContext. +*/ +QScriptContext *QScriptContext::parentContext() const +{ + const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); + JSC::CallFrame *callerFrame = frame->callerFrame()->removeHostCallFrameFlag(); + if (callerFrame && callerFrame->callerFrame()->hasHostCallFrameFlag() + && callerFrame->callerFrame()->removeHostCallFrameFlag() == QScript::scriptEngineFromExec(frame)->globalExec()) { + //skip the "fake" context created in Interpreter::execute. + callerFrame = callerFrame->callerFrame()->removeHostCallFrameFlag(); + } + return reinterpret_cast<QScriptContext *>(callerFrame); +} + +/*! + Returns the number of arguments passed to the function + in this invocation. + + Note that the argument count can be different from the + formal number of arguments (the \c{length} property of + callee()). + + \sa argument() +*/ +int QScriptContext::argumentCount() const +{ + const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); + int argc = frame->argumentCount(); + if (argc != 0) + --argc; // -1 due to "this" + return argc; +} + +/*! + \internal +*/ +QScriptValue QScriptContext::returnValue() const +{ + qWarning("QScriptContext::returnValue() not implemented"); + return QScriptValue(); +} + +/*! + \internal +*/ +void QScriptContext::setReturnValue(const QScriptValue &result) +{ + JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); + JSC::CallFrame *callerFrame = frame->callerFrame(); + if (!callerFrame->codeBlock()) + return; + Q_ASSERT_X(false, Q_FUNC_INFO, "check me"); + int dst = frame->registers()[JSC::RegisterFile::ReturnValueRegister].i(); // returnValueRegister() is private + callerFrame[dst] = QScript::scriptEngineFromExec(frame)->scriptValueToJSCValue(result); +} + +/*! + Returns the activation object of this QScriptContext. The activation + object provides access to the local variables associated with this + context. + + \sa argument(), argumentsObject() +*/ + +QScriptValue QScriptContext::activationObject() const +{ + JSC::CallFrame *frame = const_cast<JSC::ExecState*>(QScriptEnginePrivate::frameForContext(this)); + JSC::JSObject *result = 0; + + uint flags = QScriptEnginePrivate::contextFlags(frame); + if ((flags & QScriptEnginePrivate::NativeContext) && !(flags & QScriptEnginePrivate::HasScopeContext)) { + //For native functions, lazily create it if needed + QScript::QScriptActivationObject *scope = new (frame) QScript::QScriptActivationObject(frame); + frame->setScopeChain(frame->scopeChain()->copy()->push(scope)); + result = scope; + QScriptEnginePrivate::setContextFlags(frame, flags | QScriptEnginePrivate::HasScopeContext); + } else { + // look in scope chain + JSC::ScopeChainNode *node = frame->scopeChain(); + JSC::ScopeChainIterator it(node); + for (it = node->begin(); it != node->end(); ++it) { + if ((*it) && (*it)->isVariableObject()) { + result = *it; + break; + } + } + } + if (!result) { + if (!parentContext()) + return engine()->globalObject(); + + qWarning("QScriptContext::activationObject: could not get activation object for frame"); + return QScriptValue(); + /*JSC::CodeBlock *codeBlock = frame->codeBlock(); + if (!codeBlock) { + // non-Qt native function + Q_ASSERT(true); //### this should in theorry not happen + result = new (frame)QScript::QScriptActivationObject(frame); + } else { + // ### this is wrong + JSC::FunctionBodyNode *body = static_cast<JSC::FunctionBodyNode*>(codeBlock->ownerNode()); + result = new (frame)JSC::JSActivation(frame, body); + }*/ + } + + if (result && result->isObject(&QScript::QScriptActivationObject::info) + && (static_cast<QScript::QScriptActivationObject*>(result)->delegate() != 0)) { + // Return the object that property access is being delegated to + result = static_cast<QScript::QScriptActivationObject*>(result)->delegate(); + } + + return QScript::scriptEngineFromExec(frame)->scriptValueFromJSCValue(result); +} + +/*! + Sets the activation object of this QScriptContext to be the given \a + activation. + + If \a activation is not an object, this function does nothing. +*/ +void QScriptContext::setActivationObject(const QScriptValue &activation) +{ + if (!activation.isObject()) + return; + else if (activation.engine() != engine()) { + qWarning("QScriptContext::setActivationObject() failed: " + "cannot set an object created in " + "a different engine"); + return; + } + JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); + QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame); + JSC::JSObject *object = JSC::asObject(engine->scriptValueToJSCValue(activation)); + if (object == engine->originalGlobalObjectProxy) + object = engine->originalGlobalObject(); + + uint flags = QScriptEnginePrivate::contextFlags(frame); + if ((flags & QScriptEnginePrivate::NativeContext) && !(flags & QScriptEnginePrivate::HasScopeContext)) { + //For native functions, we create a scope node + JSC::JSObject *scope = object; + if (!scope->isVariableObject()) { + // Create a QScriptActivationObject that acts as a proxy + scope = new (frame) QScript::QScriptActivationObject(frame, scope); + } + frame->setScopeChain(frame->scopeChain()->copy()->push(scope)); + QScriptEnginePrivate::setContextFlags(frame, flags | QScriptEnginePrivate::HasScopeContext); + return; + } + + // else replace the first activation object in the scope chain + JSC::ScopeChainNode *node = frame->scopeChain(); + while (node != 0) { + if (node->object && node->object->isVariableObject()) { + if (!object->isVariableObject()) { + if (node->object->isObject(&QScript::QScriptActivationObject::info)) { + static_cast<QScript::QScriptActivationObject*>(node->object)->setDelegate(object); + } else { + // Create a QScriptActivationObject that acts as a proxy + node->object = new (frame) QScript::QScriptActivationObject(frame, object); + } + } else { + node->object = object; + } + break; + } + node = node->next; + } +} + +/*! + Returns the `this' object associated with this QScriptContext. +*/ +QScriptValue QScriptContext::thisObject() const +{ + JSC::CallFrame *frame = const_cast<JSC::ExecState*>(QScriptEnginePrivate::frameForContext(this)); + QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame); + JSC::JSValue result = engine->thisForContext(frame); + if (!result || result.isNull()) + result = frame->globalThisValue(); + return engine->scriptValueFromJSCValue(result); +} + +/*! + Sets the `this' object associated with this QScriptContext to be + \a thisObject. + + If \a thisObject is not an object, this function does nothing. +*/ +void QScriptContext::setThisObject(const QScriptValue &thisObject) +{ + JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); + if (!thisObject.isObject()) + return; + if (thisObject.engine() != engine()) { + qWarning("QScriptContext::setThisObject() failed: " + "cannot set an object created in " + "a different engine"); + return; + } + if (frame == frame->lexicalGlobalObject()->globalExec()) { + engine()->setGlobalObject(thisObject); + return; + } + JSC::JSValue jscThisObject = QScript::scriptEngineFromExec(frame)->scriptValueToJSCValue(thisObject); + JSC::CodeBlock *cb = frame->codeBlock(); + if (cb != 0) { + frame[cb->thisRegister()] = jscThisObject; + } else { + JSC::Register* thisRegister = frame->registers() - JSC::RegisterFile::CallFrameHeaderSize - frame->argumentCount(); + thisRegister[0] = jscThisObject; + } +} + +/*! + Returns the frameution state of this QScriptContext. +*/ +QScriptContext::ExecutionState QScriptContext::state() const +{ + const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); + if (frame->hadException()) + return QScriptContext::ExceptionState; + return QScriptContext::NormalState; +} + +/*! + Returns a human-readable backtrace of this QScriptContext. + + Each line is of the form \c{<function-name>(<arguments>)@<file-name>:<line-number>}. + + To access individual pieces of debugging-related information (for + example, to construct your own backtrace representation), use + QScriptContextInfo. + + \sa QScriptEngine::uncaughtExceptionBacktrace(), QScriptContextInfo, toString() +*/ +QStringList QScriptContext::backtrace() const +{ + QStringList result; + const QScriptContext *ctx = this; + while (ctx) { + result.append(ctx->toString()); + ctx = ctx->parentContext(); + } + return result; +} + +/*! + \since 4.4 + + Returns a string representation of this context. + This is useful for debugging. + + \sa backtrace() +*/ +QString QScriptContext::toString() const +{ + QScriptContextInfo info(this); + QString result; + + QString functionName = info.functionName(); + if (functionName.isEmpty()) { + if (parentContext()) { + const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); + if (info.functionType() == QScriptContextInfo::ScriptFunction) + result.append(QLatin1String("<anonymous>")); + else if(frame->callerFrame()->hasHostCallFrameFlag()) + result.append(QLatin1String("<eval>")); + else + result.append(QLatin1String("<native>")); + } else { + result.append(QLatin1String("<global>")); + } + } else { + result.append(functionName); + } + + QStringList parameterNames = info.functionParameterNames(); + result.append(QLatin1Char('(')); + for (int i = 0; i < argumentCount(); ++i) { + if (i > 0) + result.append(QLatin1String(", ")); + if (i < parameterNames.count()) { + result.append(parameterNames.at(i)); + result.append(QLatin1String(" = ")); + } + QScriptValue arg = argument(i); + if (arg.isString()) + result.append(QLatin1Char('\'')); + result.append(arg.toString()); + if (arg.isString()) + result.append(QLatin1Char('\'')); + + } + result.append(QLatin1Char(')')); + + QString fileName = info.fileName(); + int lineNumber = info.lineNumber(); + result.append(QLatin1String(" at ")); + if (!fileName.isEmpty()) { + result.append(fileName); + result.append(QLatin1Char(':')); + } + result.append(QString::number(lineNumber)); + return result; +} + +/*! + \internal + \since 4.5 + + Returns the scope chain of this QScriptContext. +*/ +QScriptValueList QScriptContext::scopeChain() const +{ + activationObject(); //ensure the creation of the normal scope for native context + const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); + QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame); + QScriptValueList result; + JSC::ScopeChainNode *node = frame->scopeChain(); + JSC::ScopeChainIterator it(node); + for (it = node->begin(); it != node->end(); ++it) { + JSC::JSObject *object = *it; + if (!object) + continue; + if (object->isObject(&QScript::QScriptActivationObject::info) + && (static_cast<QScript::QScriptActivationObject*>(object)->delegate() != 0)) { + // Return the object that property access is being delegated to + object = static_cast<QScript::QScriptActivationObject*>(object)->delegate(); + } + result.append(engine->scriptValueFromJSCValue(object)); + } + return result; +} + +/*! + \internal + \since 4.5 + + Adds the given \a object to the front of this context's scope chain. + + If \a object is not an object, this function does nothing. +*/ +void QScriptContext::pushScope(const QScriptValue &object) +{ + activationObject(); //ensure the creation of the normal scope for native context + if (!object.isObject()) + return; + else if (object.engine() != engine()) { + qWarning("QScriptContext::pushScope() failed: " + "cannot push an object created in " + "a different engine"); + return; + } + JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); + QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame); + JSC::JSObject *jscObject = JSC::asObject(engine->scriptValueToJSCValue(object)); + if (jscObject == engine->originalGlobalObjectProxy) + jscObject = engine->originalGlobalObject(); + JSC::ScopeChainNode *scope = frame->scopeChain(); + Q_ASSERT(scope != 0); + if (!scope->object) { + // pushing to an "empty" chain + if (!jscObject->isGlobalObject()) { + qWarning("QScriptContext::pushScope() failed: initial object in scope chain has to be the Global Object"); + return; + } + scope->object = jscObject; + } + else + frame->setScopeChain(scope->push(jscObject)); +} + +/*! + \internal + \since 4.5 + + Removes the front object from this context's scope chain, and + returns the removed object. + + If the scope chain is already empty, this function returns an + invalid QScriptValue. +*/ +QScriptValue QScriptContext::popScope() +{ + JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); + JSC::ScopeChainNode *scope = frame->scopeChain(); + Q_ASSERT(scope != 0); + QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame); + QScriptValue result = engine->scriptValueFromJSCValue(scope->object); + if (!scope->next) { + // We cannot have a null scope chain, so just zap the object pointer. + scope->object = 0; + } else { + frame->setScopeChain(scope->pop()); + } + return result; +} + +QT_END_NAMESPACE diff --git a/src/script/qscriptcontext.h b/src/script/api/qscriptcontext.h index e0d158b..53d07cc 100644 --- a/src/script/qscriptcontext.h +++ b/src/script/api/qscriptcontext.h @@ -44,8 +44,6 @@ #include <QtCore/qobjectdefs.h> -#ifndef QT_NO_SCRIPT - #include <QtScript/qscriptvalue.h> QT_BEGIN_HEADER @@ -121,5 +119,4 @@ QT_END_NAMESPACE QT_END_HEADER -#endif // QT_NO_SCRIPT #endif diff --git a/src/script/qscriptobjectdata_p.h b/src/script/api/qscriptcontext_p.h index bc38ebd..e8cc47e 100644 --- a/src/script/qscriptobjectdata_p.h +++ b/src/script/api/qscriptcontext_p.h @@ -39,14 +39,8 @@ ** ****************************************************************************/ -#ifndef QSCRIPTOBJECTDATA_P_H -#define QSCRIPTOBJECTDATA_P_H - -#include <QtCore/qglobal.h> - -#ifndef QT_NO_SCRIPT - -QT_BEGIN_NAMESPACE +#ifndef QSCRIPTCONTEXT_P_H +#define QSCRIPTCONTEXT_P_H // // W A R N I N G @@ -59,23 +53,24 @@ QT_BEGIN_NAMESPACE // We mean it. // -class QScriptEnginePrivate; +#include <QtCore/qobjectdefs.h> -class QScriptObjectData +QT_BEGIN_NAMESPACE + +namespace JSC { -protected: - inline QScriptObjectData() {} + class JSObject; + class ArgList; + class ExecState; +} -public: - virtual void finalize(QScriptEnginePrivate *) {} - virtual ~QScriptObjectData() {} +#include "wtf/Platform.h" +#include "JSValue.h" -private: - Q_DISABLE_COPY(QScriptObjectData) -}; +class QScriptEnginePrivate; -QT_END_NAMESPACE +class QScriptContext; -#endif // QT_NO_SCRIPT +QT_END_NAMESPACE #endif diff --git a/src/script/qscriptcontextinfo.cpp b/src/script/api/qscriptcontextinfo.cpp index dd3dbab..0049680 100644 --- a/src/script/qscriptcontextinfo.cpp +++ b/src/script/api/qscriptcontextinfo.cpp @@ -39,17 +39,17 @@ ** ****************************************************************************/ +#include "config.h" #include "qscriptcontextinfo.h" -#ifndef QT_NO_SCRIPT - -#include "qscriptcontextinfo_p.h" -#include "qscriptengine_p.h" #include "qscriptcontext_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" +#include "qscriptengine.h" +#include "qscriptengine_p.h" +#include "../bridge/qscriptqobject_p.h" #include <QtCore/qdatastream.h> +#include <QtCore/qmetaobject.h> +#include "CodeBlock.h" +#include "JSFunction.h" QT_BEGIN_NAMESPACE @@ -97,11 +97,37 @@ QT_BEGIN_NAMESPACE \value NativeFunction The function is a built-in Qt Script function, or it was defined through a call to QScriptEngine::newFunction(). */ +class QScriptContextInfoPrivate +{ + Q_DECLARE_PUBLIC(QScriptContextInfo) +public: + QScriptContextInfoPrivate(); + QScriptContextInfoPrivate(const QScriptContext *context); + ~QScriptContextInfoPrivate(); + + qint64 scriptId; + int lineNumber; + int columnNumber; + QString fileName; + + QString functionName; + QScriptContextInfo::FunctionType functionType; + + int functionStartLineNumber; + int functionEndLineNumber; + int functionMetaIndex; + + QStringList parameterNames; + + QBasicAtomicInt ref; + + QScriptContextInfo *q_ptr; +}; + /*! \internal */ QScriptContextInfoPrivate::QScriptContextInfoPrivate() - : q_ptr(0) { ref = 0; functionType = QScriptContextInfo::NativeFunction; @@ -117,7 +143,6 @@ QScriptContextInfoPrivate::QScriptContextInfoPrivate() \internal */ QScriptContextInfoPrivate::QScriptContextInfoPrivate(const QScriptContext *context) - : q_ptr(0) { Q_ASSERT(context); ref = 0; @@ -125,67 +150,73 @@ QScriptContextInfoPrivate::QScriptContextInfoPrivate(const QScriptContext *conte functionMetaIndex = -1; functionStartLineNumber = -1; functionEndLineNumber = -1; + scriptId = -1; + lineNumber = -1; + columnNumber = -1; - const QScriptContextPrivate *ctx_p = QScriptContextPrivate::get(context); -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - scriptId = ctx_p->scriptId(); -#endif - fileName = ctx_p->fileName(); - lineNumber = ctx_p->currentLine; - columnNumber = ctx_p->currentColumn; - - QScriptValueImpl callee = ctx_p->engine()->toImpl(context->callee()); - QScriptFunction *fun = callee.toFunction(); - if (fun) { - functionName = fun->functionName(); - functionStartLineNumber = fun->startLineNumber(); - functionEndLineNumber = fun->endLineNumber(); - - switch (fun->type()) { - case QScriptFunction::Unknown: - functionType = QScriptContextInfo::NativeFunction; - break; - - case QScriptFunction::Script: - functionType = QScriptContextInfo::ScriptFunction; - for (int i = 0; i < fun->formals.count(); ++i) - parameterNames.append(fun->formals.at(i)->s); - break; - - case QScriptFunction::C: - functionType = QScriptContextInfo::NativeFunction; - break; - - case QScriptFunction::C2: - functionType = QScriptContextInfo::NativeFunction; - break; - - case QScriptFunction::C3: - functionType = QScriptContextInfo::NativeFunction; - break; - - case QScriptFunction::Qt: { - functionType = QScriptContextInfo::QtFunction; - functionMetaIndex = ctx_p->calleeMetaIndex; - -#ifndef QT_NO_QOBJECT - const QMetaObject *meta; - meta = static_cast<QScript::QtFunction*>(fun)->metaObject(); - if (meta) { - QMetaMethod method = meta->method(functionMetaIndex); - QList<QByteArray> formals = method.parameterNames(); - for (int i = 0; i < formals.count(); ++i) - parameterNames.append(QLatin1String(formals.at(i))); + const JSC::ExecState *frame = QScriptEnginePrivate::frameForContext(context); + + // Get the line number: + + //We need to know the context directly up in the backtrace, in order to get the line number, and adjust the global context + QScriptContext *rewindContext = context->engine()->currentContext(); + if (rewindContext != context) { //ignore top context (native function) + // rewind the stack from the top in order to find the frame from the caller where the returnPC is stored + while (rewindContext && rewindContext->parentContext() != context) + rewindContext = rewindContext->parentContext(); + if (rewindContext) { + JSC::ExecState *aboveFrame = QScriptEnginePrivate::frameForContext(rewindContext); + frame = aboveFrame->callerFrame()->removeHostCallFrameFlag(); //it will be different for the global context. + + JSC::Instruction *returnPC = aboveFrame->returnPC(); + JSC::CodeBlock *codeBlock = frame->codeBlock(); + if (returnPC && codeBlock) { + lineNumber = codeBlock->lineNumberForBytecodeOffset(const_cast<JSC::ExecState *>(frame), + returnPC - codeBlock->instructions().begin() -1); } -#endif - } break; + } + } else { + // An agent might have provided the line number. + lineNumber = QScript::scriptEngineFromExec(frame)->agentLineNumber; + } + + // Get the filename and the scriptId: + JSC::CodeBlock *codeBlock = frame->codeBlock(); + if (codeBlock) { + JSC::SourceProvider *source = codeBlock->source(); + scriptId = source->asID(); + fileName = source->url(); + } - case QScriptFunction::QtProperty: - functionType = QScriptContextInfo::QtPropertyFunction; - functionMetaIndex = ctx_p->calleeMetaIndex; - break; + // Get the others informations: + JSC::JSObject *callee = frame->callee(); + if (callee && callee->isObject(&JSC::InternalFunction::info)) + functionName = JSC::asInternalFunction(callee)->name(&frame->globalData()); + if (callee && callee->isObject(&JSC::JSFunction::info)) { + functionType = QScriptContextInfo::ScriptFunction; + JSC::FunctionBodyNode *body = JSC::asFunction(callee)->body(); + functionStartLineNumber = body->firstLine(); + functionEndLineNumber = body->lastLine(); + const JSC::Identifier* params = body->parameters(); + for (size_t i = 0; i < body->parameterCount(); ++i) + parameterNames.append(params[i].ustring()); + // ### get the function name from the AST + } else if (callee && callee->isObject(&QScript::QtFunction::info)) { + functionType = QScriptContextInfo::QtFunction; + // ### the slot can be overloaded -- need to get the particular overload from the context + functionMetaIndex = static_cast<QScript::QtFunction*>(callee)->initialIndex(); + const QMetaObject *meta = static_cast<QScript::QtFunction*>(callee)->metaObject(); + if (meta != 0) { + QMetaMethod method = meta->method(functionMetaIndex); + QList<QByteArray> formals = method.parameterNames(); + for (int i = 0; i < formals.count(); ++i) + parameterNames.append(QLatin1String(formals.at(i))); } } + else if (callee && callee->isObject(&QScript::QtPropertyFunction::info)) { + functionType = QScriptContextInfo::QtPropertyFunction; + functionMetaIndex = static_cast<QScript::QtPropertyFunction*>(callee)->propertyIndex(); + } } /*! @@ -549,5 +580,3 @@ Q_SCRIPT_EXPORT QDataStream &operator>>(QDataStream &in, QScriptContextInfo &inf #endif QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptcontextinfo.h b/src/script/api/qscriptcontextinfo.h index a82dfb5..78ac2a8 100644 --- a/src/script/qscriptcontextinfo.h +++ b/src/script/api/qscriptcontextinfo.h @@ -44,8 +44,6 @@ #include <QtCore/qobjectdefs.h> -#ifndef QT_NO_SCRIPT - #include <QtCore/qlist.h> #include <QtCore/qstringlist.h> @@ -120,6 +118,4 @@ QT_END_NAMESPACE QT_END_HEADER -#endif // QT_NO_SCRIPT - #endif diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp new file mode 100644 index 0000000..6fde08f --- /dev/null +++ b/src/script/api/qscriptengine.cpp @@ -0,0 +1,3851 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "config.h" +#include "qscriptengine.h" +#include "qscriptsyntaxchecker_p.h" +#include "qnumeric.h" + +#include "qscriptengine_p.h" +#include "qscriptengineagent_p.h" +#include "qscriptcontext_p.h" +#include "qscriptstring_p.h" +#include "qscriptvalue_p.h" +#include "qscriptvalueiterator.h" +#include "qscriptclass.h" +#include "qdebug.h" + +#include <QtCore/qstringlist.h> +#include <QtCore/qmetaobject.h> + +#include "Error.h" +#include "JSArray.h" +#include "JSLock.h" +#include "Interpreter.h" +#include "DateConstructor.h" +#include "RegExpConstructor.h" + +#include "PrototypeFunction.h" +#include "InitializeThreading.h" +#include "ObjectPrototype.h" +#include "SourceCode.h" +#include "FunctionPrototype.h" +#include "TimeoutChecker.h" +#include "JSFunction.h" +#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" +#include "bridge/qscriptglobalobject_p.h" +#include "bridge/qscriptactivationobject_p.h" + +#ifndef QT_NO_QOBJECT +#include <QtCore/qcoreapplication.h> +#include <QtCore/qdir.h> +#include <QtCore/qfile.h> +#include <QtCore/qfileinfo.h> +#include <QtCore/qpluginloader.h> +#include <QtCore/qset.h> +#include <QtCore/qtextstream.h> +#include "qscriptextensioninterface.h" +#endif + +Q_DECLARE_METATYPE(QScriptValue) +#ifndef QT_NO_QOBJECT +Q_DECLARE_METATYPE(QObjectList) +#endif +Q_DECLARE_METATYPE(QList<int>) + +QT_BEGIN_NAMESPACE + +/*! + \since 4.3 + \class QScriptEngine + \reentrant + + \brief The QScriptEngine class provides an environment for evaluating Qt Script code. + + \ingroup script + \mainclass + + See the \l{QtScript} documentation for information about the Qt Script language, + and how to get started with scripting your C++ application. + + \section1 Evaluating Scripts + + Use evaluate() to evaluate script code; this is the C++ equivalent + of the built-in script function \c{eval()}. + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 0 + + evaluate() returns a QScriptValue that holds the result of the + evaluation. The QScriptValue class provides functions for converting + the result to various C++ types (e.g. QScriptValue::toString() + and QScriptValue::toNumber()). + + The following code snippet shows how a script function can be + defined and then invoked from C++ using QScriptValue::call(): + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 1 + + As can be seen from the above snippets, a script is provided to the + engine in the form of a string. One common way of loading scripts is + by reading the contents of a file and passing it to evaluate(): + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 2 + + Here we pass the name of the file as the second argument to + evaluate(). This does not affect evaluation in any way; the second + argument is a general-purpose string that is used to identify the + script for debugging purposes (for example, our filename will now + show up in any uncaughtExceptionBacktrace() involving the script). + + \section1 Engine Configuration + + The globalObject() function returns the \bold {Global Object} + associated with the script engine. Properties of the Global Object + are accessible from any script code (i.e. they are global + variables). Typically, before evaluating "user" scripts, you will + want to configure a script engine by adding one or more properties + to the Global Object: + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 3 + + Adding custom properties to the scripting environment is one of the + standard means of providing a scripting API that is specific to your + application. Usually these custom properties are objects created by + the newQObject() or newObject() functions, or constructor functions + created by newFunction(). + + \section1 Script Exceptions + + evaluate() can throw a script exception (e.g. due to a syntax + error); in that case, the return value is the value that was thrown + (typically an \c{Error} object). You can check whether the + evaluation caused an exception by calling hasUncaughtException(). In + that case, you can call toString() on the error object to obtain an + error message. The current uncaught exception is also available + through uncaughtException(). You can obtain a human-readable + backtrace of the exception with uncaughtExceptionBacktrace(). + Calling clearExceptions() will cause any uncaught exceptions to be + cleared. + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 4 + + The checkSyntax() function can be used to determine whether code can be + usefully passed to evaluate(). + + \section1 Script Object Creation + + Use newObject() to create a standard Qt Script object; this is the + C++ equivalent of the script statement \c{new Object()}. You can use + the object-specific functionality in QScriptValue to manipulate the + script object (e.g. QScriptValue::setProperty()). Similarly, use + newArray() to create a Qt Script array object. Use newDate() to + create a \c{Date} object, and newRegExp() to create a \c{RegExp} + object. + + \section1 QObject Integration + + Use newQObject() to wrap a QObject (or subclass) + pointer. newQObject() returns a proxy script object; properties, + children, and signals and slots of the QObject are available as + properties of the proxy object. No binding code is needed because it + is done dynamically using the Qt meta object system. + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 5 + + Use qScriptConnect() to connect a C++ signal to a script function; + this is the Qt Script equivalent of QObject::connect(). When a + script function is invoked in response to a C++ signal, it can cause + a script exception; you can connect to the signalHandlerException() + signal to catch such an exception. + + Use newQMetaObject() to wrap a QMetaObject; this gives you a "script + representation" of a QObject-based class. newQMetaObject() returns a + proxy script object; enum values of the class are available as + properties of the proxy object. You can also specify a function that + will be used to construct objects of the class (e.g. when the + constructor is invoked from a script). For classes that have a + "standard" Qt constructor, Qt Script can provide a default script + constructor for you; see scriptValueFromQMetaObject(). + + See the \l{QtScript} documentation for more information on + the QObject integration. + + \section1 Support for Custom C++ Types + + Use newVariant() to wrap a QVariant. This can be used to store + values of custom (non-QObject) C++ types that have been registered + with the Qt meta-type system. To make such types scriptable, you + typically associate a prototype (delegate) object with the C++ type + by calling setDefaultPrototype(); the prototype object defines the + scripting API for the C++ type. Unlike the QObject integration, + there is no automatic binding possible here; i.e. you have to create + the scripting API yourself, for example by using the QScriptable + class. + + Use fromScriptValue() to cast from a QScriptValue to another type, + and toScriptValue() to create a QScriptValue from another value. + You can specify how the conversion of C++ types is to be performed + with qScriptRegisterMetaType() and qScriptRegisterSequenceMetaType(). + By default, Qt Script will use QVariant to store values of custom + types. + + \section1 Importing Extensions + + Use importExtension() to import plugin-based extensions into the + engine. Call availableExtensions() to obtain a list naming all the + available extensions, and importedExtensions() to obtain a list + naming only those extensions that have been imported. + + Call pushContext() to open up a new variable scope, and popContext() + to close the current scope. This is useful if you are implementing + an extension that evaluates script code containing temporary + variable definitions (e.g. \c{var foo = 123;}) that are safe to + discard when evaluation has completed. + + \section1 Native Functions + + Use newFunction() to wrap native (C++) functions, including + constructors for your own custom types, so that these can be invoked + from script code. Such functions must have the signature + QScriptEngine::FunctionSignature. You may then pass the function as + argument to newFunction(). Here is an example of a function that + returns the sum of its first two arguments: + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 6 + + To expose this function to script code, you can set it as a property + of the Global Object: + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 7 + + Once this is done, script code can call your function in the exact + same manner as a "normal" script function: + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 8 + + \section1 Long-running Scripts + + If you need to evaluate possibly long-running scripts from the main + (GUI) thread, you should first call setProcessEventsInterval() to + make sure that the GUI stays responsive. You can abort a currently + running script by calling abortEvaluation(). You can determine + whether an engine is currently running a script by calling + isEvaluating(). + + \section1 Core Debugging/Tracing Facilities + + Since Qt 4.4, you can be notified of events pertaining to script + execution (e.g. script function calls and statement execution) + through the QScriptEngineAgent interface; see the setAgent() + function. This can be used to implement debugging and profiling of a + QScriptEngine. + + \sa QScriptValue, QScriptContext, QScriptEngineAgent + +*/ + +/*! + \enum QScriptEngine::ValueOwnership + + This enum specifies the ownership when wrapping a C++ value, e.g. by using newQObject(). + + \value QtOwnership The standard Qt ownership rules apply, i.e. the associated object will never be explicitly deleted by the script engine. This is the default. (QObject ownership is explained in \l{Object Trees and Object Ownership}.) + \value ScriptOwnership The value is owned by the script environment. The associated data will be deleted when appropriate (i.e. after the garbage collector has discovered that there are no more live references to the value). + \value AutoOwnership If the associated object has a parent, the Qt ownership rules apply (QtOwnership); otherwise, the object is owned by the script environment (ScriptOwnership). +*/ + +/*! + \enum QScriptEngine::QObjectWrapOption + + These flags specify options when wrapping a QObject pointer with newQObject(). + + \value ExcludeChildObjects The script object will not expose child objects as properties. + \value ExcludeSuperClassMethods The script object will not expose signals and slots inherited from the superclass. + \value ExcludeSuperClassProperties The script object will not expose properties inherited from the superclass. + \value ExcludeSuperClassContents Shorthand form for ExcludeSuperClassMethods | ExcludeSuperClassProperties + \value ExcludeDeleteLater The script object will not expose the QObject::deleteLater() slot. + \value AutoCreateDynamicProperties Properties that don't already exist in the QObject will be created as dynamic properties of that object, rather than as properties of the script object. + \value PreferExistingWrapperObject If a wrapper object with the requested configuration already exists, return that object. + \value SkipMethodsInEnumeration Don't include methods (signals and slots) when enumerating the object's properties. +*/ + +class QScriptSyntaxCheckResultPrivate +{ +public: + QScriptSyntaxCheckResultPrivate() { ref = 0; } + ~QScriptSyntaxCheckResultPrivate() {} + + QScriptSyntaxCheckResult::State state; + int errorColumnNumber; + int errorLineNumber; + QString errorMessage; + QBasicAtomicInt ref; +}; + +class QScriptTypeInfo +{ +public: + QScriptTypeInfo() : signature(0, '\0'), marshal(0), demarshal(0) + { } + + QByteArray signature; + QScriptEngine::MarshalFunction marshal; + QScriptEngine::DemarshalFunction demarshal; + JSC::JSValue prototype; +}; + +namespace QScript +{ + +struct GlobalClientData : public JSC::JSGlobalData::ClientData +{ + GlobalClientData(QScriptEnginePrivate *e) + : engine(e) {} + virtual ~GlobalClientData() {} + virtual void mark() { engine->mark(); } + + QScriptEnginePrivate *engine; +}; + +class TimeoutCheckerProxy : public JSC::TimeoutChecker +{ +public: + TimeoutCheckerProxy(const JSC::TimeoutChecker& originalChecker) + : JSC::TimeoutChecker(originalChecker) + , m_shouldProcessEvents(false) + , m_shouldAbortEvaluation(false) + {} + + void setShouldProcessEvents(bool shouldProcess) { m_shouldProcessEvents = shouldProcess; } + void setShouldAbort(bool shouldAbort) { m_shouldAbortEvaluation = shouldAbort; } + bool shouldAbort() { return m_shouldAbortEvaluation; } + + virtual bool didTimeOut(JSC::ExecState* exec) + { + if (JSC::TimeoutChecker::didTimeOut(exec)) + return true; + + if (m_shouldProcessEvents) + QCoreApplication::processEvents(); + + return m_shouldAbortEvaluation; + } + +private: + bool m_shouldProcessEvents; + bool m_shouldAbortEvaluation; +}; + +static int toDigit(char c) +{ + if ((c >= '0') && (c <= '9')) + return c - '0'; + else if ((c >= 'a') && (c <= 'z')) + return 10 + c - 'a'; + else if ((c >= 'A') && (c <= 'Z')) + return 10 + c - 'A'; + return -1; +} + +qsreal integerFromString(const char *buf, int size, int radix) +{ + if (size == 0) + return qSNaN(); + + qsreal sign = 1.0; + int i = 0; + if (buf[0] == '+') { + ++i; + } else if (buf[0] == '-') { + sign = -1.0; + ++i; + } + + if (((size-i) >= 2) && (buf[i] == '0')) { + if (((buf[i+1] == 'x') || (buf[i+1] == 'X')) + && (radix < 34)) { + if ((radix != 0) && (radix != 16)) + return 0; + radix = 16; + i += 2; + } else { + if (radix == 0) { + radix = 8; + ++i; + } + } + } else if (radix == 0) { + radix = 10; + } + + int j = i; + for ( ; i < size; ++i) { + int d = toDigit(buf[i]); + if ((d == -1) || (d >= radix)) + break; + } + qsreal result; + if (j == i) { + if (!qstrcmp(buf, "Infinity")) + result = qInf(); + else + result = qSNaN(); + } else { + result = 0; + qsreal multiplier = 1; + for (--i ; i >= j; --i, multiplier *= radix) + result += toDigit(buf[i]) * multiplier; + } + result *= sign; + return result; +} + +qsreal integerFromString(const QString &str, int radix) +{ + QByteArray ba = str.trimmed().toUtf8(); + 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()) + return false; + JSC::CallData callData; + return (JSC::asObject(value)->getCallData(callData) != JSC::CallTypeNone); +} + +static JSC::JSValue JSC_HOST_CALL functionConnect(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&); +static JSC::JSValue JSC_HOST_CALL functionDisconnect(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&); + +JSC::JSValue JSC_HOST_CALL functionDisconnect(JSC::ExecState *exec, JSC::JSObject */*callee*/, JSC::JSValue thisObject, const JSC::ArgList &args) +{ +#ifndef QT_NO_QOBJECT + if (args.size() == 0) { + return JSC::throwError(exec, JSC::GeneralError, "Function.prototype.disconnect: no arguments given"); + } + + if (!JSC::asObject(thisObject)->inherits(&QScript::QtFunction::info)) { + return JSC::throwError(exec, JSC::TypeError, "Function.prototype.disconnect: this object is not a signal"); + } + + QScript::QtFunction *qtSignal = static_cast<QScript::QtFunction*>(JSC::asObject(thisObject)); + + const QMetaObject *meta = qtSignal->metaObject(); + if (!meta) { + return JSC::throwError(exec, JSC::TypeError, "Function.prototype.discconnect: cannot disconnect from deleted QObject"); + } + + QMetaMethod sig = meta->method(qtSignal->initialIndex()); + if (sig.methodType() != QMetaMethod::Signal) { + QString message = QString::fromLatin1("Function.prototype.disconnect: %0::%1 is not a signal") + .arg(QLatin1String(qtSignal->metaObject()->className())) + .arg(QLatin1String(sig.signature())); + return JSC::throwError(exec, JSC::TypeError, message); + } + + QScriptEnginePrivate *engine = scriptEngineFromExec(exec); + + JSC::JSValue receiver; + JSC::JSValue slot; + JSC::JSValue arg0 = args.at(0); + if (args.size() < 2) { + slot = arg0; + } else { + receiver = arg0; + JSC::JSValue arg1 = args.at(1); + if (isFunction(arg1)) + slot = arg1; + else { + // ### don't go via QScriptValue + QScriptValue tmp = engine->scriptValueFromJSCValue(arg0); + QString propertyName(arg1.toString(exec)); + slot = engine->scriptValueToJSCValue(tmp.property(propertyName, QScriptValue::ResolvePrototype)); + } + } + + if (!isFunction(slot)) { + return JSC::throwError(exec, JSC::TypeError, "Function.prototype.disconnect: target is not a function"); + } + + bool ok = engine->scriptDisconnect(thisObject, receiver, slot); + if (!ok) { + QString message = QString::fromLatin1("Function.prototype.disconnect: failed to disconnect from %0::%1") + .arg(QLatin1String(qtSignal->metaObject()->className())) + .arg(QLatin1String(sig.signature())); + return JSC::throwError(exec, JSC::GeneralError, message); + } + return JSC::jsUndefined(); +#else + Q_UNUSED(eng); + return context->throwError(QScriptContext::TypeError, + QLatin1String("Function.prototype.disconnect")); +#endif // QT_NO_QOBJECT +} + +JSC::JSValue JSC_HOST_CALL functionConnect(JSC::ExecState *exec, JSC::JSObject */*callee*/, JSC::JSValue thisObject, const JSC::ArgList &args) +{ +#ifndef QT_NO_QOBJECT + if (args.size() == 0) { + return JSC::throwError(exec, JSC::GeneralError,"Function.prototype.connect: no arguments given"); + } + + if (!JSC::asObject(thisObject)->inherits(&QScript::QtFunction::info)) { + return JSC::throwError(exec, JSC::TypeError, "Function.prototype.connect: this object is not a signal"); + } + + QScript::QtFunction *qtSignal = static_cast<QScript::QtFunction*>(JSC::asObject(thisObject)); + + const QMetaObject *meta = qtSignal->metaObject(); + if (!meta) { + return JSC::throwError(exec, JSC::TypeError, "Function.prototype.connect: cannot connect to deleted QObject"); + } + + QMetaMethod sig = meta->method(qtSignal->initialIndex()); + if (sig.methodType() != QMetaMethod::Signal) { + QString message = QString::fromLatin1("Function.prototype.connect: %0::%1 is not a signal") + .arg(QLatin1String(qtSignal->metaObject()->className())) + .arg(QLatin1String(sig.signature())); + return JSC::throwError(exec, JSC::TypeError, message); + } + + { + QList<int> overloads = qtSignal->overloadedIndexes(); + if (!overloads.isEmpty()) { + overloads.append(qtSignal->initialIndex()); + QByteArray signature = sig.signature(); + QString message = QString::fromLatin1("Function.prototype.connect: ambiguous connect to %0::%1(); candidates are\n") + .arg(QLatin1String(qtSignal->metaObject()->className())) + .arg(QLatin1String(signature.left(signature.indexOf('(')))); + for (int i = 0; i < overloads.size(); ++i) { + QMetaMethod mtd = meta->method(overloads.at(i)); + message.append(QString::fromLatin1(" %0\n").arg(QString::fromLatin1(mtd.signature()))); + } + message.append(QString::fromLatin1("Use e.g. object['%0'].connect() to connect to a particular overload") + .arg(QLatin1String(signature))); + return JSC::throwError(exec, JSC::GeneralError, message); + } + } + + QScriptEnginePrivate *engine = scriptEngineFromExec(exec); + + JSC::JSValue receiver; + JSC::JSValue slot; + JSC::JSValue arg0 = args.at(0); + if (args.size() < 2) { + slot = arg0; + } else { + receiver = arg0; + JSC::JSValue arg1 = args.at(1); + if (isFunction(arg1)) + slot = arg1; + else { + // ### don't go via QScriptValue + QScriptValue tmp = engine->scriptValueFromJSCValue(arg0); + QString propertyName = arg1.toString(exec); + slot = engine->scriptValueToJSCValue(tmp.property(propertyName, QScriptValue::ResolvePrototype)); + } + } + + if (!isFunction(slot)) { + return JSC::throwError(exec, JSC::TypeError, "Function.prototype.connect: target is not a function"); + } + + bool ok = engine->scriptConnect(thisObject, receiver, slot, Qt::AutoConnection); + if (!ok) { + QString message = QString::fromLatin1("Function.prototype.connect: failed to connect to %0::%1") + .arg(QLatin1String(qtSignal->metaObject()->className())) + .arg(QLatin1String(sig.signature())); + return JSC::throwError(exec, JSC::GeneralError, message); + } + return JSC::jsUndefined(); +#else + Q_UNUSED(eng); + Q_UNUSED(classInfo); + return context->throwError(QScriptContext::TypeError, + QLatin1String("Function.prototype.connect")); +#endif // QT_NO_QOBJECT +} + +static JSC::JSValue JSC_HOST_CALL functionPrint(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&); +static JSC::JSValue JSC_HOST_CALL functionGC(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&); +static JSC::JSValue JSC_HOST_CALL functionVersion(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&); + +JSC::JSValue JSC_HOST_CALL functionPrint(JSC::ExecState* exec, JSC::JSObject*, JSC::JSValue, const JSC::ArgList& args) +{ + QString result; + for (unsigned i = 0; i < args.size(); ++i) { + if (i != 0) + result.append(QLatin1Char(' ')); + QString s(args.at(i).toString(exec)); + if (exec->hadException()) + break; + result.append(s); + } + if (exec->hadException()) + return exec->exception(); + qDebug(qPrintable(result)); + return JSC::jsUndefined(); +} + +JSC::JSValue JSC_HOST_CALL functionGC(JSC::ExecState* exec, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&) +{ + QScriptEnginePrivate *engine = scriptEngineFromExec(exec); + engine->collectGarbage(); + return JSC::jsUndefined(); +} + +JSC::JSValue JSC_HOST_CALL functionVersion(JSC::ExecState *exec, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&) +{ + return JSC::JSValue(exec, 1); +} + +static JSC::JSValue JSC_HOST_CALL functionQsTranslate(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&); +static JSC::JSValue JSC_HOST_CALL functionQsTranslateNoOp(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&); +static JSC::JSValue JSC_HOST_CALL functionQsTr(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&); +static JSC::JSValue JSC_HOST_CALL functionQsTrNoOp(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&); + +JSC::JSValue JSC_HOST_CALL functionQsTranslate(JSC::ExecState *exec, JSC::JSObject*, JSC::JSValue, const JSC::ArgList &args) +{ + if (args.size() < 2) + return JSC::throwError(exec, JSC::GeneralError, "qsTranslate() requires at least two arguments"); + if (!args.at(0).isString()) + return JSC::throwError(exec, JSC::GeneralError, "qsTranslate(): first argument (context) must be a string"); + if (!args.at(1).isString()) + return JSC::throwError(exec, JSC::GeneralError, "qsTranslate(): second argument (text) must be a string"); + if ((args.size() > 2) && !args.at(2).isString()) + return JSC::throwError(exec, JSC::GeneralError, "qsTranslate(): third argument (comment) must be a string"); + if ((args.size() > 3) && !args.at(3).isString()) + return JSC::throwError(exec, JSC::GeneralError, "qsTranslate(): fourth argument (encoding) must be a string"); + if ((args.size() > 4) && !args.at(4).isNumber()) + return JSC::throwError(exec, JSC::GeneralError, "qsTranslate(): fifth argument (n) must be a number"); +#ifndef QT_NO_QOBJECT + QString context(args.at(0).toString(exec)); +#endif + QString text(args.at(1).toString(exec)); +#ifndef QT_NO_QOBJECT + QString comment; + if (args.size() > 2) + comment = args.at(2).toString(exec); + QCoreApplication::Encoding encoding = QCoreApplication::CodecForTr; + if (args.size() > 3) { + QString encStr(args.at(3).toString(exec)); + if (encStr == QLatin1String("CodecForTr")) + encoding = QCoreApplication::CodecForTr; + else if (encStr == QLatin1String("UnicodeUTF8")) + encoding = QCoreApplication::UnicodeUTF8; + else + return JSC::throwError(exec, JSC::GeneralError, QString::fromLatin1("qsTranslate(): invalid encoding '%s'").arg(encStr)); + } + int n = -1; + if (args.size() > 4) + n = args.at(4).toInt32(exec); +#endif + QString result; +#ifndef QT_NO_QOBJECT + result = QCoreApplication::translate(context.toLatin1().constData(), + text.toLatin1().constData(), + comment.toLatin1().constData(), + encoding, n); +#else + result = text; +#endif + return JSC::jsString(exec, result); +} + +JSC::JSValue JSC_HOST_CALL functionQsTranslateNoOp(JSC::ExecState *, JSC::JSObject*, JSC::JSValue, const JSC::ArgList &args) +{ + if (args.size() < 2) + return JSC::jsUndefined(); + return args.at(1); +} + +JSC::JSValue JSC_HOST_CALL functionQsTr(JSC::ExecState *exec, JSC::JSObject*, JSC::JSValue, const JSC::ArgList &args) +{ + if (args.size() < 1) + return JSC::throwError(exec, JSC::GeneralError, "qsTr() requires at least one argument"); + if (!args.at(0).isString()) + return JSC::throwError(exec, JSC::GeneralError, "qsTr(): first argument (text) must be a string"); + if ((args.size() > 1) && !args.at(1).isString()) + return JSC::throwError(exec, JSC::GeneralError, "qsTr(): second argument (comment) must be a string"); + if ((args.size() > 2) && !args.at(2).isNumber()) + return JSC::throwError(exec, JSC::GeneralError, "qsTranslate(): third argument (n) must be a number"); +#ifndef QT_NO_QOBJECT + QString context; +// ### implement context resolution +// if (ctx->parentContext()) +// context = QFileInfo(ctx->parentContext()->fileName()).baseName(); +#endif + QString text(args.at(0).toString(exec)); +#ifndef QT_NO_QOBJECT + QString comment; + if (args.size() > 1) + comment = args.at(1).toString(exec); + int n = -1; + if (args.size() > 2) + n = args.at(2).toInt32(exec); +#endif + QString result; +#ifndef QT_NO_QOBJECT + result = QCoreApplication::translate(context.toLatin1().constData(), + text.toLatin1().constData(), + comment.toLatin1().constData(), + QCoreApplication::CodecForTr, n); +#else + result = text; +#endif + return JSC::jsString(exec, result); +} + +JSC::JSValue JSC_HOST_CALL functionQsTrNoOp(JSC::ExecState *, JSC::JSObject*, JSC::JSValue, const JSC::ArgList &args) +{ + if (args.size() < 1) + return JSC::jsUndefined(); + return args.at(0); +} + +static JSC::JSValue JSC_HOST_CALL stringProtoFuncArg(JSC::ExecState*, JSC::JSObject*, JSC::JSValue, const JSC::ArgList&); + +JSC::JSValue JSC_HOST_CALL stringProtoFuncArg(JSC::ExecState *exec, JSC::JSObject*, JSC::JSValue thisObject, const JSC::ArgList &args) +{ + QString value(thisObject.toString(exec)); + JSC::JSValue arg = (args.size() != 0) ? args.at(0) : JSC::jsUndefined(); + QString result; + if (arg.isString()) + result = value.arg(arg.toString(exec)); + else if (arg.isNumber()) + result = value.arg(arg.toNumber(exec)); + return JSC::jsString(exec, result); +} + + +#if !defined(QT_NO_QOBJECT) && !defined(QT_NO_LIBRARY) +static QScriptValue __setupPackage__(QScriptContext *ctx, QScriptEngine *eng) +{ + QString path = ctx->argument(0).toString(); + QStringList components = path.split(QLatin1Char('.')); + QScriptValue o = eng->globalObject(); + for (int i = 0; i < components.count(); ++i) { + QString name = components.at(i); + QScriptValue oo = o.property(name); + if (!oo.isValid()) { + oo = eng->newObject(); + o.setProperty(name, oo); + } + o = oo; + } + return o; +} +#endif + +} // namespace QScript + +QScriptEnginePrivate::QScriptEnginePrivate() + : registeredScriptValues(0), inEval(false) +{ + qMetaTypeId<QScriptValue>(); + + JSC::initializeThreading(); // ### hmmm + + globalData = JSC::JSGlobalData::create().releaseRef(); + globalData->clientData = new QScript::GlobalClientData(this); + JSC::JSGlobalObject *globalObject = new (globalData)QScript::GlobalObject(); + + JSC::ExecState* exec = globalObject->globalExec(); + + scriptObjectStructure = QScriptObject::createStructure(globalObject->objectPrototype()); + + qobjectPrototype = new (exec) QScript::QObjectPrototype(exec, QScript::QObjectPrototype::createStructure(globalObject->objectPrototype()), globalObject->prototypeFunctionStructure()); + qobjectWrapperObjectStructure = QScriptObject::createStructure(qobjectPrototype); + + qmetaobjectPrototype = new (exec) QScript::QMetaObjectPrototype(exec, QScript::QMetaObjectPrototype::createStructure(globalObject->objectPrototype()), globalObject->prototypeFunctionStructure()); + qmetaobjectWrapperObjectStructure = QScript::QMetaObjectWrapperObject::createStructure(qmetaobjectPrototype); + + variantPrototype = new (exec) QScript::QVariantPrototype(exec, QScript::QVariantPrototype::createStructure(globalObject->objectPrototype()), globalObject->prototypeFunctionStructure()); + variantWrapperObjectStructure = QScriptObject::createStructure(variantPrototype); + + globalObject->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, globalObject->prototypeFunctionStructure(), 1, JSC::Identifier(exec, "print"), QScript::functionPrint)); + globalObject->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, globalObject->prototypeFunctionStructure(), 0, JSC::Identifier(exec, "gc"), QScript::functionGC)); + globalObject->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, globalObject->prototypeFunctionStructure(), 0, JSC::Identifier(exec, "version"), QScript::functionVersion)); + + // ### rather than extending Function.prototype, consider creating a QtSignal.prototype + globalObject->functionPrototype()->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, globalObject->prototypeFunctionStructure(), 1, JSC::Identifier(exec, "disconnect"), QScript::functionDisconnect)); + globalObject->functionPrototype()->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, globalObject->prototypeFunctionStructure(), 1, JSC::Identifier(exec, "connect"), QScript::functionConnect)); + + JSC::TimeoutChecker* originalChecker = globalData->timeoutChecker; + globalData->timeoutChecker = new QScript::TimeoutCheckerProxy(*originalChecker); + delete originalChecker; + + currentFrame = exec; + + originalGlobalObjectProxy = 0; + activeAgent = 0; + agentLineNumber = -1; + processEventsInterval = -1; +} + +QScriptEnginePrivate::~QScriptEnginePrivate() +{ + while (!ownedAgents.isEmpty()) + delete ownedAgents.takeFirst(); + detachAllRegisteredScriptValues(); + qDeleteAll(m_qobjectData); + qDeleteAll(m_typeInfos); + JSC::JSLock lock(false); + globalData->heap.destroy(); + globalData->deref(); +} + +QScriptValue QScriptEnginePrivate::scriptValueFromJSCValue(JSC::JSValue value) +{ + if (!value) + return QScriptValue(); + + QScriptValuePrivate *p_value = new QScriptValuePrivate(); + p_value->engine = this; + p_value->initFrom(value); + return QScriptValuePrivate::toPublic(p_value); +} + +JSC::JSValue QScriptEnginePrivate::scriptValueToJSCValue(const QScriptValue &value) +{ + QScriptValuePrivate *vv = QScriptValuePrivate::get(value); + if (!vv) + return JSC::JSValue(); + if (vv->type != QScriptValuePrivate::JSC) { + Q_ASSERT(!vv->engine || vv->engine == this); + vv->engine = this; + if (vv->type == QScriptValuePrivate::Number) { + vv->initFrom(JSC::jsNumber(currentFrame, vv->numberValue)); + } else { //QScriptValuePrivate::String + vv->initFrom(JSC::jsString(currentFrame, vv->stringValue)); + } + } + return vv->jscValue; +} + +QScriptValue QScriptEnginePrivate::scriptValueFromVariant(const QVariant &v) +{ + Q_Q(QScriptEngine); + QScriptValue result = q->create(v.userType(), v.data()); + Q_ASSERT(result.isValid()); + return result; +} + +QVariant QScriptEnginePrivate::scriptValueToVariant(const QScriptValue &value, int targetType) +{ + QVariant v(targetType, (void *)0); + if (QScriptEnginePrivate::convert(value, targetType, v.data(), this)) + return v; + if (uint(targetType) == QVariant::LastType) + return value.toVariant(); + if (value.isVariant()) { + v = value.toVariant(); + if (v.canConvert(QVariant::Type(targetType))) { + v.convert(QVariant::Type(targetType)); + return v; + } + QByteArray typeName = v.typeName(); + if (typeName.endsWith('*') + && (QMetaType::type(typeName.left(typeName.size()-1)) == targetType)) { + return QVariant(targetType, *reinterpret_cast<void* *>(v.data())); + } + } + + return QVariant(); +} + +JSC::JSValue QScriptEnginePrivate::jscValueFromVariant(const QVariant &v) +{ + // ### it's inefficient to convert to QScriptValue and then to JSValue + QScriptValue vv = scriptValueFromVariant(v); + QScriptValuePrivate *p = QScriptValuePrivate::get(vv); + switch (p->type) { + case QScriptValuePrivate::JSC: + 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) +{ + // ### 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()); + for (int i = 0; i < lst.size(); ++i) + arr.setProperty(i, QScriptValue(q, lst.at(i))); + return arr; +} + +QStringList QScriptEnginePrivate::stringListFromArray(const QScriptValue &arr) +{ + QStringList lst; + uint len = arr.property(QLatin1String("length")).toUInt32(); + for (uint i = 0; i < len; ++i) + lst.append(arr.property(i).toString()); + return lst; +} + +QScriptValue QScriptEnginePrivate::arrayFromVariantList(const QVariantList &lst) +{ + Q_Q(QScriptEngine); + QScriptValue arr = q->newArray(lst.size()); + for (int i = 0; i < lst.size(); ++i) + arr.setProperty(i, scriptValueFromVariant(lst.at(i))); + return arr; +} + +QVariantList QScriptEnginePrivate::variantListFromArray(const QScriptValue &arr) +{ + QVariantList lst; + uint len = arr.property(QLatin1String("length")).toUInt32(); + for (uint i = 0; i < len; ++i) + lst.append(arr.property(i).toVariant()); + return lst; +} + +QScriptValue QScriptEnginePrivate::objectFromVariantMap(const QVariantMap &vmap) +{ + Q_Q(QScriptEngine); + QScriptValue obj = q->newObject(); + QVariantMap::const_iterator it; + for (it = vmap.constBegin(); it != vmap.constEnd(); ++it) + obj.setProperty(it.key(), scriptValueFromVariant(it.value())); + return obj; +} + +QVariantMap QScriptEnginePrivate::variantMapFromObject(const QScriptValue &obj) +{ + QVariantMap vmap; + QScriptValueIterator it(obj); + while (it.hasNext()) { + it.next(); + vmap.insert(it.name(), it.value().toVariant()); + } + return vmap; +} + +JSC::JSValue QScriptEnginePrivate::defaultPrototype(int metaTypeId) const +{ + QScriptTypeInfo *info = m_typeInfos.value(metaTypeId); + if (!info) + return JSC::JSValue(); + return info->prototype; +} + +void QScriptEnginePrivate::setDefaultPrototype(int metaTypeId, JSC::JSValue prototype) +{ + QScriptTypeInfo *info = m_typeInfos.value(metaTypeId); + if (!info) { + info = new QScriptTypeInfo(); + m_typeInfos.insert(metaTypeId, info); + } + info->prototype = prototype; +} + +QScriptContext *QScriptEnginePrivate::contextForFrame(JSC::ExecState *frame) +{ + 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; +} + +JSC::JSObject *QScriptEnginePrivate::customGlobalObject() const +{ + QScript::GlobalObject *glob = static_cast<QScript::GlobalObject*>(originalGlobalObject()); + return glob->customGlobalObject; +} + +JSC::JSObject *QScriptEnginePrivate::getOriginalGlobalObjectProxy() +{ + if (!originalGlobalObjectProxy) { + JSC::ExecState* exec = currentFrame; + originalGlobalObjectProxy = new (exec)QScript::OriginalGlobalObjectProxy(scriptObjectStructure, originalGlobalObject()); + } + return originalGlobalObjectProxy; +} + +JSC::JSObject *QScriptEnginePrivate::globalObject() const +{ + QScript::GlobalObject *glob = static_cast<QScript::GlobalObject*>(originalGlobalObject()); + if (glob->customGlobalObject) + return glob->customGlobalObject; + return glob; +} + +void QScriptEnginePrivate::setGlobalObject(JSC::JSObject *object) +{ + if (object == globalObject()) + return; + QScript::GlobalObject *glob = static_cast<QScript::GlobalObject*>(originalGlobalObject()); + if (object == originalGlobalObjectProxy) + glob->customGlobalObject = 0; + else { + Q_ASSERT(object != originalGlobalObject()); + glob->customGlobalObject = object; + } +} + +JSC::ExecState *QScriptEnginePrivate::globalExec() const +{ + return originalGlobalObject()->globalExec(); +} + +/*! + \internal + + If the given \a value is the original global object, returns the custom + global object or a proxy to the original global object; otherwise returns \a + value. +*/ +JSC::JSValue QScriptEnginePrivate::toUsableValue(JSC::JSValue value) +{ + if (!value || !value.isObject() || !JSC::asObject(value)->isGlobalObject()) + return value; + Q_ASSERT(JSC::asObject(value) == originalGlobalObject()); + if (customGlobalObject()) + return customGlobalObject(); + if (!originalGlobalObjectProxy) + originalGlobalObjectProxy = new (currentFrame)QScript::OriginalGlobalObjectProxy(scriptObjectStructure, originalGlobalObject()); + return originalGlobalObjectProxy; +} +/*! + \internal + Return the 'this' value for a given context + The result may be null for the global context +*/ +JSC::JSValue QScriptEnginePrivate::thisForContext(JSC::ExecState *frame) +{ + if (frame->codeBlock() != 0) { + return frame->thisValue(); + } else { + JSC::Register* thisRegister = frame->registers() - JSC::RegisterFile::CallFrameHeaderSize - frame->argumentCount(); + return thisRegister->jsValue(); + } +} + +/*! \internal + For native context, we use the ReturnValueRegister entry in the stackframe header to store flags. + We can do that because this header is not used as the native function return their value thought C++ + + when setting flags, NativeContext should always be set + + contextFlags returns 0 for non native context + */ +uint QScriptEnginePrivate::contextFlags(JSC::ExecState *exec) +{ + if (exec->codeBlock()) + return 0; //js function doesn't have flags + + return exec->returnValueRegister(); +} + +void QScriptEnginePrivate::setContextFlags(JSC::ExecState *exec, uint flags) +{ + Q_ASSERT(!exec->codeBlock()); + quintptr flag_ptr = flags; + exec->registers()[JSC::RegisterFile::ReturnValueRegister] = JSC::JSValue(reinterpret_cast<JSC::JSObject*>(flag_ptr)); +} + + +void QScriptEnginePrivate::mark() +{ + if (!originalGlobalObject()->marked()) + originalGlobalObject()->mark(); + if (!globalObject()->marked()) + globalObject()->mark(); + if (originalGlobalObjectProxy && !originalGlobalObjectProxy->marked()) + originalGlobalObjectProxy->mark(); + + if (qobjectPrototype && !qobjectPrototype->marked()) + qobjectPrototype->mark(); + if (qmetaobjectPrototype && !qmetaobjectPrototype->marked()) + qmetaobjectPrototype->mark(); + if (variantPrototype && !variantPrototype->marked()) + variantPrototype->mark(); + + { + QScriptValuePrivate *it; + for (it = registeredScriptValues; it != 0; it = it->next) { + if (it->isJSC() && !it->jscValue.marked()) + it->jscValue.mark(); + } + } + +#ifndef QT_NO_QOBJECT + { + QHash<QObject*, QScript::QObjectData*>::const_iterator it; + for (it = m_qobjectData.constBegin(); it != m_qobjectData.constEnd(); ++it) { + QScript::QObjectData *qdata = it.value(); + qdata->mark(); + } + } +#endif + + { + QHash<int, QScriptTypeInfo*>::const_iterator it; + for (it = m_typeInfos.constBegin(); it != m_typeInfos.constEnd(); ++it) { + if ((*it)->prototype && !(*it)->prototype.marked()) + (*it)->prototype.mark(); + } + } +} + +bool QScriptEnginePrivate::isCollecting() const +{ + return globalData->heap.isBusy(); +} + +void QScriptEnginePrivate::collectGarbage() +{ + JSC::JSLock lock(false); + globalData->heap.collect(); +} + +QScript::TimeoutCheckerProxy *QScriptEnginePrivate::timeoutChecker() const +{ + return static_cast<QScript::TimeoutCheckerProxy*>(globalData->timeoutChecker); +} + +void QScriptEnginePrivate::agentDeleted(QScriptEngineAgent *agent) +{ + ownedAgents.removeOne(agent); + if (activeAgent == agent) { + QScriptEngineAgentPrivate::get(agent)->detach(); + activeAgent = 0; + } +} + +#ifndef QT_NO_QOBJECT + +JSC::JSValue QScriptEnginePrivate::newQObject( + QObject *object, QScriptEngine::ValueOwnership ownership, + const QScriptEngine::QObjectWrapOptions &options) +{ + if (!object) + return JSC::jsNull(); + JSC::ExecState* exec = currentFrame; + QScript::QObjectData *data = qobjectData(object); + bool preferExisting = (options & QScriptEngine::PreferExistingWrapperObject) != 0; + QScriptEngine::QObjectWrapOptions opt = options & ~QScriptEngine::PreferExistingWrapperObject; + QScriptObject *result = 0; + if (preferExisting) + result = data->findWrapper(ownership, opt); + if (!result) { + result = new (exec) QScriptObject(qobjectWrapperObjectStructure); + if (preferExisting) + data->registerWrapper(result, ownership, opt); + } + Q_ASSERT(result != 0); + result->setDelegate(new QScript::QObjectDelegate(object, ownership, options)); + /*if (setDefaultPrototype)*/ { + const QMetaObject *meta = object->metaObject(); + while (meta) { + QByteArray typeString = meta->className(); + typeString.append('*'); + int typeId = QMetaType::type(typeString); + if (typeId != 0) { + JSC::JSValue proto = defaultPrototype(typeId); + if (proto) { + result->setPrototype(proto); + break; + } + } + meta = meta->superClass(); + } + } + return result; +} + +JSC::JSValue QScriptEnginePrivate::newQMetaObject( + const QMetaObject *metaObject, JSC::JSValue ctor) +{ + if (!metaObject) + return JSC::jsNull(); + JSC::ExecState* exec = currentFrame; + QScript::QMetaObjectWrapperObject *result = new (exec) QScript::QMetaObjectWrapperObject(exec, metaObject, ctor, qmetaobjectWrapperObjectStructure); + return result; +} + +bool QScriptEnginePrivate::convertToNativeQObject(const QScriptValue &value, + const QByteArray &targetType, + void **result) +{ + if (!targetType.endsWith('*')) + return false; + if (QObject *qobject = value.toQObject()) { + int start = targetType.startsWith("const ") ? 6 : 0; + QByteArray className = targetType.mid(start, targetType.size()-start-1); + if (void *instance = qobject->qt_metacast(className)) { + *result = instance; + return true; + } + } + return false; +} + +QScript::QObjectData *QScriptEnginePrivate::qobjectData(QObject *object) +{ + QHash<QObject*, QScript::QObjectData*>::const_iterator it; + it = m_qobjectData.constFind(object); + if (it != m_qobjectData.constEnd()) + return it.value(); + + QScript::QObjectData *data = new QScript::QObjectData(this); + m_qobjectData.insert(object, data); + QObject::connect(object, SIGNAL(destroyed(QObject*)), + q_func(), SLOT(_q_objectDestroyed(QObject *))); + return data; +} + +void QScriptEnginePrivate::_q_objectDestroyed(QObject *object) +{ + QHash<QObject*, QScript::QObjectData*>::iterator it; + it = m_qobjectData.find(object); + Q_ASSERT(it != m_qobjectData.end()); + QScript::QObjectData *data = it.value(); + m_qobjectData.erase(it); + delete data; +} + +void QScriptEnginePrivate::disposeQObject(QObject *object) +{ + // TODO +/* if (isCollecting()) { + // wait until we're done with GC before deleting it + int index = m_qobjectsToBeDeleted.indexOf(object); + if (index == -1) + m_qobjectsToBeDeleted.append(object); + } else*/ { + delete object; + } +} + +void QScriptEnginePrivate::emitSignalHandlerException() +{ + Q_Q(QScriptEngine); + emit q->signalHandlerException(q->uncaughtException()); +} + +bool QScriptEnginePrivate::scriptConnect(QObject *sender, const char *signal, + JSC::JSValue receiver, JSC::JSValue function, + Qt::ConnectionType type) +{ + Q_ASSERT(sender); + Q_ASSERT(signal); + const QMetaObject *meta = sender->metaObject(); + int index = meta->indexOfSignal(QMetaObject::normalizedSignature(signal+1)); + if (index == -1) + return false; + return scriptConnect(sender, index, receiver, function, /*wrapper=*/JSC::JSValue(), type); +} + +bool QScriptEnginePrivate::scriptDisconnect(QObject *sender, const char *signal, + JSC::JSValue receiver, JSC::JSValue function) +{ + Q_ASSERT(sender); + Q_ASSERT(signal); + const QMetaObject *meta = sender->metaObject(); + int index = meta->indexOfSignal(QMetaObject::normalizedSignature(signal+1)); + if (index == -1) + return false; + return scriptDisconnect(sender, index, receiver, function); +} + +bool QScriptEnginePrivate::scriptConnect(QObject *sender, int signalIndex, + JSC::JSValue receiver, JSC::JSValue function, + JSC::JSValue senderWrapper, + Qt::ConnectionType type) +{ + QScript::QObjectData *data = qobjectData(sender); + return data->addSignalHandler(sender, signalIndex, receiver, function, senderWrapper, type); +} + +bool QScriptEnginePrivate::scriptDisconnect(QObject *sender, int signalIndex, + JSC::JSValue receiver, JSC::JSValue function) +{ + QScript::QObjectData *data = qobjectData(sender); + if (!data) + return false; + return data->removeSignalHandler(sender, signalIndex, receiver, function); +} + +bool QScriptEnginePrivate::scriptConnect(JSC::JSValue signal, JSC::JSValue receiver, + JSC::JSValue function, Qt::ConnectionType type) +{ + QScript::QtFunction *fun = static_cast<QScript::QtFunction*>(JSC::asObject(signal)); + int index = fun->mostGeneralMethod(); + return scriptConnect(fun->qobject(), index, receiver, function, fun->wrapperObject(), type); +} + +bool QScriptEnginePrivate::scriptDisconnect(JSC::JSValue signal, JSC::JSValue receiver, + JSC::JSValue function) +{ + QScript::QtFunction *fun = static_cast<QScript::QtFunction*>(JSC::asObject(signal)); + int index = fun->mostGeneralMethod(); + return scriptDisconnect(fun->qobject(), index, receiver, function); +} + +#endif + +void QScriptEnginePrivate::registerScriptValue(QScriptValuePrivate *value) +{ + value->prev = 0; + value->next = registeredScriptValues; + if (registeredScriptValues) + registeredScriptValues->prev = value; + registeredScriptValues = value; +} + +void QScriptEnginePrivate::unregisterScriptValue(QScriptValuePrivate *value) +{ + if (value->prev) + value->prev->next = value->next; + if (value->next) + value->next->prev = value->prev; + if (value == registeredScriptValues) + registeredScriptValues = value->next; + value->prev = 0; + value->next = 0; +} + +void QScriptEnginePrivate::detachAllRegisteredScriptValues() +{ + QScriptValuePrivate *it; + QScriptValuePrivate *next; + for (it = registeredScriptValues; it != 0; it = next) { + it->detachFromEngine(); + next = it->next; + it->prev = 0; + it->next = 0; + } + registeredScriptValues = 0; +} + +#ifdef QT_NO_QOBJECT + +QScriptEngine::QScriptEngine() + : d_ptr(new QScriptEnginePrivate) +{ + d_ptr->q_ptr = this; +} + +/*! \internal +*/ +QScriptEngine::QScriptEngine(QScriptEnginePrivate &dd) + : d_ptr(&dd) +{ + d_ptr->q_ptr = this; +} +#else + +/*! + Constructs a QScriptEngine object. + + The globalObject() is initialized to have properties as described in + \l{ECMA-262}, Section 15.1. +*/ +QScriptEngine::QScriptEngine() + : QObject(*new QScriptEnginePrivate, 0) +{ +} + +/*! + Constructs a QScriptEngine object with the given \a parent. + + The globalObject() is initialized to have properties as described in + \l{ECMA-262}, Section 15.1. +*/ + +QScriptEngine::QScriptEngine(QObject *parent) + : QObject(*new QScriptEnginePrivate, parent) +{ +} + +/*! \internal +*/ +QScriptEngine::QScriptEngine(QScriptEnginePrivate &dd, QObject *parent) + : QObject(dd, parent) +{ +} +#endif + +/*! + Destroys this QScriptEngine. +*/ +QScriptEngine::~QScriptEngine() +{ +#ifdef QT_NO_QOBJECT + delete d_ptr; + d_ptr = 0; +#endif +} + +/*! + Returns this engine's Global Object. + + By default, the Global Object contains the built-in objects that are + part of \l{ECMA-262}, such as Math, Date and String. Additionally, + you can set properties of the Global Object to make your own + extensions available to all script code. Non-local variables in + script code will be created as properties of the Global Object, as + well as local variables in global code. +*/ +QScriptValue QScriptEngine::globalObject() const +{ + Q_D(const QScriptEngine); + JSC::JSObject *result = d->globalObject(); + return const_cast<QScriptEnginePrivate*>(d)->scriptValueFromJSCValue(result); +} + +/*! + \since 4.5 + + Sets this engine's Global Object to be the given \a object. + If \a object is not a valid script object, this function does + nothing. + + When setting a custom global object, you may want to use + QScriptValueIterator to copy the properties of the standard Global + Object; alternatively, you can set the internal prototype of your + custom object to be the original Global Object. +*/ +void QScriptEngine::setGlobalObject(const QScriptValue &object) +{ + Q_D(QScriptEngine); + if (!object.isObject()) + return; + JSC::JSObject *jscObject = JSC::asObject(d->scriptValueToJSCValue(object)); + d->setGlobalObject(jscObject); +} + +/*! + Returns a QScriptValue of the primitive type Null. + + \sa undefinedValue() +*/ +QScriptValue QScriptEngine::nullValue() +{ + Q_D(QScriptEngine); + return d->scriptValueFromJSCValue(JSC::jsNull()); +} + +/*! + Returns a QScriptValue of the primitive type Undefined. + + \sa nullValue() +*/ +QScriptValue QScriptEngine::undefinedValue() +{ + Q_D(QScriptEngine); + return d->scriptValueFromJSCValue(JSC::jsUndefined()); +} + +/*! + Creates a constructor function from \a fun, with the given \a length. + The \c{prototype} property of the resulting function is set to be the + given \a prototype. The \c{constructor} property of \a prototype is + set to be the resulting function. + + When a function is called as a constructor (e.g. \c{new Foo()}), the + `this' object associated with the function call is the new object + that the function is expected to initialize; the prototype of this + default constructed object will be the function's public + \c{prototype} property. If you always want the function to behave as + a constructor (e.g. \c{Foo()} should also create a new object), or + if you need to create your own object rather than using the default + `this' object, you should make sure that the prototype of your + object is set correctly; either by setting it manually, or, when + wrapping a custom type, by having registered the defaultPrototype() + of that type. Example: + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 9 + + To wrap a custom type and provide a constructor for it, you'd typically + do something like this: + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 10 +*/ +QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, + const QScriptValue &prototype, + int length) +{ + Q_D(QScriptEngine); + JSC::ExecState* exec = d->currentFrame; + JSC::JSValue function = new (exec)QScript::FunctionWrapper(exec, length, JSC::Identifier(exec, ""), fun); + QScriptValue result = d->scriptValueFromJSCValue(function); + result.setProperty(QLatin1String("prototype"), prototype, QScriptValue::Undeletable); + const_cast<QScriptValue&>(prototype) + .setProperty(QLatin1String("constructor"), result, + QScriptValue::Undeletable | QScriptValue::SkipInEnumeration); + return result; +} + +#ifndef QT_NO_REGEXP +/*! + Creates a QtScript object of class RegExp with the given + \a regexp. + + \sa QScriptValue::toRegExp() +*/ +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 + extern QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax); + 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); +} + +#endif // QT_NO_REGEXP + +/*! + Creates a QtScript object holding the given variant \a value. + + If a default prototype has been registered with the meta type id of + \a value, then the prototype of the created object will be that + prototype; otherwise, the prototype will be the Object prototype + object. + + \sa setDefaultPrototype(), QScriptValue::toVariant() +*/ +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; +} + +/*! + \since 4.4 + \overload + + Initializes the given Qt Script \a object to hold the given variant + \a value, and returns the \a object. + + This function enables you to "promote" a plain Qt Script object + (created by the newObject() function) to a variant, or to replace + the variant contained inside an object previously created by the + newVariant() function. + + The prototype() of the \a object will remain unchanged. + + If \a object is not an object, this function behaves like the normal + newVariant(), i.e. it creates a new script object and returns it. + + This function is useful when you want to provide a script + constructor for a C++ type. If your constructor is invoked in a + \c{new} expression (QScriptContext::isCalledAsConstructor() returns + true), you can pass QScriptContext::thisObject() (the default + constructed script object) to this function to initialize the new + object. +*/ +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->isObject(&QScriptObject::info)) { + qWarning("QScriptEngine::newVariant(): changing class of non-QScriptObject not supported"); + return QScriptValue(); + } + QScriptObject *jscScriptObject = static_cast<QScriptObject*>(jscObject); + if (!object.isVariant()) { + delete jscScriptObject->delegate(); + jscScriptObject->setDelegate(new QScript::QVariantDelegate(value)); + } else { + QScriptValuePrivate::get(object)->setVariantValue(value); + } + return object; +} + +#ifndef QT_NO_QOBJECT +/*! + Creates a QtScript object that wraps the given QObject \a + object, using the given \a ownership. The given \a options control + various aspects of the interaction with the resulting script object. + + Signals and slots, properties and children of \a object are + available as properties of the created QScriptValue. For more + information, see the \l{QtScript} documentation. + + If \a object is a null pointer, this function returns nullValue(). + + If a default prototype has been registered for the \a object's class + (or its superclass, recursively), the prototype of the new script + object will be set to be that default prototype. + + If the given \a object is deleted outside of QtScript's control, any + attempt to access the deleted QObject's members through the QtScript + wrapper object (either by script code or C++) will result in a + script exception. + + \sa QScriptValue::toQObject() +*/ +QScriptValue QScriptEngine::newQObject(QObject *object, ValueOwnership ownership, + const QObjectWrapOptions &options) +{ + Q_D(QScriptEngine); + JSC::JSValue jscQObject = d->newQObject(object, ownership, options); + return d->scriptValueFromJSCValue(jscQObject); +} + +/*! + \since 4.4 + \overload + + Initializes the given \a scriptObject to hold the given \a qtObject, + and returns the \a scriptObject. + + This function enables you to "promote" a plain Qt Script object + (created by the newObject() function) to a QObject proxy, or to + replace the QObject contained inside an object previously created by + the newQObject() function. + + The prototype() of the \a scriptObject will remain unchanged. + + If \a scriptObject is not an object, this function behaves like the + normal newQObject(), i.e. it creates a new script object and returns + it. + + This function is useful when you want to provide a script + constructor for a QObject-based class. If your constructor is + invoked in a \c{new} expression + (QScriptContext::isCalledAsConstructor() returns true), you can pass + QScriptContext::thisObject() (the default constructed script object) + to this function to initialize the new object. +*/ +QScriptValue QScriptEngine::newQObject(const QScriptValue &scriptObject, + QObject *qtObject, + ValueOwnership ownership, + const QObjectWrapOptions &options) +{ + if (!scriptObject.isObject()) + return newQObject(qtObject, ownership, options); + JSC::JSObject *jscObject = JSC::asObject(QScriptValuePrivate::get(scriptObject)->jscValue); + if (!jscObject->isObject(&QScriptObject::info)) { + qWarning("QScriptEngine::newQObject(): changing class of non-QScriptObject not supported"); + return QScriptValue(); + } + QScriptObject *jscScriptObject = static_cast<QScriptObject*>(jscObject); + if (!scriptObject.isQObject()) { + delete jscScriptObject->delegate(); + jscScriptObject->setDelegate(new QScript::QObjectDelegate(qtObject, ownership, options)); + } else { + QScript::QObjectDelegate *delegate = static_cast<QScript::QObjectDelegate*>(jscScriptObject->delegate()); + delegate->setValue(qtObject); + delegate->setOwnership(ownership); + delegate->setOptions(options); + } + return scriptObject; +} + +#endif // QT_NO_QOBJECT + +/*! + Creates a QtScript object of class Object. + + The prototype of the created object will be the Object + prototype object. + + \sa newArray(), QScriptValue::setProperty() +*/ +QScriptValue QScriptEngine::newObject() +{ + Q_D(QScriptEngine); + JSC::ExecState* exec = d->currentFrame; + JSC::JSObject *result = new (exec)QScriptObject(d->scriptObjectStructure); + return d->scriptValueFromJSCValue(result); +} + +/*! + \since 4.4 + \overload + + Creates a QtScript Object of the given class, \a scriptClass. + + The prototype of the created object will be the Object + prototype object. + + \a data, if specified, is set as the internal data of the + new object (using QScriptValue::setData()). + + \sa QScriptValue::scriptClass() +*/ +QScriptValue QScriptEngine::newObject(QScriptClass *scriptClass, + const QScriptValue &data) +{ + Q_D(QScriptEngine); + JSC::ExecState* exec = d->currentFrame; + QScriptObject *result = new (exec) QScriptObject(d->scriptObjectStructure); + result->setDelegate(new QScript::ClassObjectDelegate(scriptClass)); + QScriptValue scriptObject = d->scriptValueFromJSCValue(result); + scriptObject.setData(data); + QScriptValue proto = scriptClass->prototype(); + if (proto.isValid()) + scriptObject.setPrototype(proto); + return scriptObject; +} + +/*! + \internal +*/ +QScriptValue QScriptEngine::newActivationObject() +{ + qWarning("QScriptEngine::newActivationObject() not implemented"); + // ### JSActivation or JSVariableObject? + return QScriptValue(); +} + +/*! + Creates a QScriptValue that wraps a native (C++) function. \a fun + must be a C++ function with signature QScriptEngine::FunctionSignature. \a + length is the number of arguments that \a fun expects; this becomes + the \c{length} property of the created QScriptValue. + + Note that \a length only gives an indication of the number of + arguments that the function expects; an actual invocation of a + function can include any number of arguments. You can check the + \l{QScriptContext::argumentCount()}{argumentCount()} of the + QScriptContext associated with the invocation to determine the + actual number of arguments passed. + + A \c{prototype} property is automatically created for the resulting + function object, to provide for the possibility that the function + will be used as a constructor. + + By combining newFunction() and the property flags + QScriptValue::PropertyGetter and QScriptValue::PropertySetter, you + can create script object properties that behave like normal + properties in script code, but are in fact accessed through + functions (analogous to how properties work in \l{Qt's Property + System}). Example: + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 11 + + When the property \c{foo} of the script object is subsequently + accessed in script code, \c{getSetFoo()} will be invoked to handle + the access. In this particular case, we chose to store the "real" + value of \c{foo} as a property of the accessor function itself; you + are of course free to do whatever you like in this function. + + In the above example, a single native function was used to handle + both reads and writes to the property; the argument count is used to + determine if we are handling a read or write. You can also use two + separate functions; just specify the relevant flag + (QScriptValue::PropertyGetter or QScriptValue::PropertySetter) when + setting the property, e.g.: + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 12 + + \sa QScriptValue::call() +*/ +QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, int length) +{ + Q_D(QScriptEngine); + JSC::ExecState* exec = d->currentFrame; + JSC::JSValue function = new (exec)QScript::FunctionWrapper(exec, length, JSC::Identifier(exec, ""), fun); + QScriptValue result = d->scriptValueFromJSCValue(function); + QScriptValue proto = newObject(); + result.setProperty(QLatin1String("prototype"), proto, QScriptValue::Undeletable); + proto.setProperty(QLatin1String("constructor"), result, + QScriptValue::Undeletable | QScriptValue::SkipInEnumeration); + return result; +} + +/*! + \internal + \since 4.4 +*/ +QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionWithArgSignature fun, void *arg) +{ + Q_D(QScriptEngine); + JSC::ExecState* exec = d->currentFrame; + JSC::JSValue function = new (exec)QScript::FunctionWithArgWrapper(exec, /*length=*/0, JSC::Identifier(exec, ""), fun, arg); + QScriptValue result = d->scriptValueFromJSCValue(function); + QScriptValue proto = newObject(); + result.setProperty(QLatin1String("prototype"), proto, QScriptValue::Undeletable); + proto.setProperty(QLatin1String("constructor"), result, + QScriptValue::Undeletable | QScriptValue::SkipInEnumeration); + return result; +} + +/*! + Creates a QtScript object of class Array with the given \a length. + + \sa newObject() +*/ +QScriptValue QScriptEngine::newArray(uint length) +{ + Q_D(QScriptEngine); + JSC::ExecState* exec = d->currentFrame; + JSC::JSArray* result = JSC::constructEmptyArray(exec, length); + return d->scriptValueFromJSCValue(result); +} + +/*! + Creates a QtScript object of class RegExp with the given + \a pattern and \a flags. + + The legal flags are 'g' (global), 'i' (ignore case), and 'm' + (multiline). +*/ +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); +} + +/*! + Creates a QtScript object of class Date with the given + \a value (the number of milliseconds since 01 January 1970, + UTC). +*/ +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); +} + +/*! + Creates a QtScript object of class Date from the given \a value. + + \sa QScriptValue::toDateTime() +*/ +QScriptValue QScriptEngine::newDate(const QDateTime &value) +{ + return newDate(QScript::FromDateTime(value)); +} + +#ifndef QT_NO_QOBJECT +/*! + Creates a QtScript object that represents a QObject class, using the + the given \a metaObject and constructor \a ctor. + + Enums of \a metaObject (declared with Q_ENUMS) are available as + properties of the created QScriptValue. When the class is called as + a function, \a ctor will be called to create a new instance of the + class. + + Example: + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 27 + + \sa newQObject(), scriptValueFromQMetaObject() +*/ +QScriptValue QScriptEngine::newQMetaObject( + const QMetaObject *metaObject, const QScriptValue &ctor) +{ + Q_D(QScriptEngine); + JSC::JSValue jscCtor = d->scriptValueToJSCValue(ctor); + JSC::JSValue jscQMetaObject = d->newQMetaObject(metaObject, jscCtor); + return d->scriptValueFromJSCValue(jscQMetaObject); +} + +/*! + \fn QScriptValue QScriptEngine::scriptValueFromQMetaObject() + + Creates a QScriptValue that represents the Qt class \c{T}. + + This function is used in combination with one of the + Q_SCRIPT_DECLARE_QMETAOBJECT() macro. Example: + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 13 + + \warning This function is not available with MSVC 6. Use + qScriptValueFromQMetaObject() instead if you need to support that version + of the compiler. + + \sa QScriptEngine::newQMetaObject() +*/ + +/*! + \fn QScriptValue qScriptValueFromQMetaObject(QScriptEngine *engine) + \since 4.3 + \relates QScriptEngine + + Uses \a engine to create a QScriptValue that represents the Qt class + \c{T}. + + This function is equivalent to + QScriptEngine::scriptValueFromQMetaObject(). It is provided as a + work-around for MSVC 6, which doesn't support member template + functions. + + \sa QScriptEngine::newQMetaObject() +*/ +#endif // QT_NO_QOBJECT + +/*! + \obsolete + + Returns true if \a program can be evaluated; i.e. the code is + sufficient to determine whether it appears to be a syntactically + correct program, or contains a syntax error. + + This function returns false if \a program is incomplete; i.e. the + input is syntactically correct up to the point where the input is + terminated. + + Note that this function only does a static check of \a program; + e.g. it does not check whether references to variables are + valid, and so on. + + A typical usage of canEvaluate() is to implement an interactive + interpreter for QtScript. The user is repeatedly queried for + individual lines of code; the lines are concatened internally, and + only when canEvaluate() returns true for the resulting program is it + passed to evaluate(). + + The following are some examples to illustrate the behavior of + canEvaluate(). (Note that all example inputs are assumed to have an + explicit newline as their last character, since otherwise the + QtScript parser would automatically insert a semi-colon character at + the end of the input, and this could cause canEvaluate() to produce + different results.) + + Given the input + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 14 + canEvaluate() will return true, since the program appears to be complete. + + Given the input + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 15 + canEvaluate() will return false, since the if-statement is not complete, + but is syntactically correct so far. + + Given the input + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 16 + canEvaluate() will return true, but evaluate() will throw a + SyntaxError given the same input. + + Given the input + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 17 + canEvaluate() will return true, even though the code is clearly not + syntactically valid QtScript code. evaluate() will throw a + SyntaxError when this code is evaluated. + + Given the input + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 18 + canEvaluate() will return true, but evaluate() will throw a + ReferenceError if \c{foo} is not defined in the script + environment. + + \sa evaluate(), checkSyntax() +*/ +bool QScriptEngine::canEvaluate(const QString &program) const +{ + return QScriptEnginePrivate::canEvaluate(program); +} + + +bool QScriptEnginePrivate::canEvaluate(const QString &program) +{ + QScript::SyntaxChecker checker; + QScript::SyntaxChecker::Result result = checker.checkSyntax(program); + return (result.state != QScript::SyntaxChecker::Intermediate); +} + +/*! + \since 4.5 + + Checks the syntax of the given \a program. Returns a + QScriptSyntaxCheckResult object that contains the result of the check. +*/ +QScriptSyntaxCheckResult QScriptEngine::checkSyntax(const QString &program) +{ + return QScriptEnginePrivate::checkSyntax(program); +} + +QScriptSyntaxCheckResult QScriptEnginePrivate::checkSyntax(const QString &program) +{ + QScript::SyntaxChecker checker; + QScript::SyntaxChecker::Result result = checker.checkSyntax(program); + QScriptSyntaxCheckResultPrivate *p = new QScriptSyntaxCheckResultPrivate(); + switch (result.state) { + case QScript::SyntaxChecker::Error: + p->state = QScriptSyntaxCheckResult::Error; + break; + case QScript::SyntaxChecker::Intermediate: + p->state = QScriptSyntaxCheckResult::Intermediate; + break; + case QScript::SyntaxChecker::Valid: + p->state = QScriptSyntaxCheckResult::Valid; + break; + } + p->errorLineNumber = result.errorLineNumber; + p->errorColumnNumber = result.errorColumnNumber; + p->errorMessage = result.errorMessage; + return QScriptSyntaxCheckResult(p); +} + + + +/*! + Evaluates \a program, using \a lineNumber as the base line number, + and returns the result of the evaluation. + + The script code will be evaluated in the current context. + + The evaluation of \a program can cause an exception in the + engine; in this case the return value will be the exception + that was thrown (typically an \c{Error} object). You can call + hasUncaughtException() to determine if an exception occurred in + the last call to evaluate(). + + \a lineNumber is used to specify a starting line number for \a + program; line number information reported by the engine that pertain + to this evaluation (e.g. uncaughtExceptionLineNumber()) will be + based on this argument. For example, if \a program consists of two + lines of code, and the statement on the second line causes a script + exception, uncaughtExceptionLineNumber() would return the given \a + lineNumber plus one. When no starting line number is specified, line + numbers will be 1-based. + + \a fileName is used for error reporting. For example in error objects + the file name is accessible through the "fileName" property if it's + provided with this function. + + \sa canEvaluate(), hasUncaughtException(), isEvaluating(), abortEvaluation() +*/ +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::UString jscProgram = program; + JSC::UString jscFileName = fileName; + JSC::ExecState* exec = d->currentFrame; + JSC::SourceCode source = JSC::makeSource(jscProgram, jscFileName, lineNumber); + + intptr_t sourceId = source.provider()->asID(); + JSC::Debugger* debugger = d->originalGlobalObject()->debugger(); + exec->globalData().scriptpool->startEvaluating(source); + if (debugger) + debugger->evaluateStart(sourceId); + + exec->clearException(); + JSC::DynamicGlobalObjectScope dynamicGlobalObjectScope(exec, exec->scopeChain()->globalObject()); + + int errorLine; + JSC::UString errorMessage; + WTF::RefPtr<JSC::EvalNode> evalNode = exec->globalData().parser->parse<JSC::EvalNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errorLine, &errorMessage); + if (!evalNode) { + JSC::JSValue exceptionValue = JSC::Error::create(exec, JSC::SyntaxError, errorMessage, errorLine, source.provider()->asID(), 0); + exec->setException(exceptionValue); + + if (debugger) { + debugger->exceptionThrow(JSC::DebuggerCallFrame(exec, exceptionValue), sourceId, false); + debugger->evaluateStop(exceptionValue, sourceId); + } + exec->globalData().scriptpool->stopEvaluating(source); + + return d->scriptValueFromJSCValue(exceptionValue); + } + + JSC::JSValue thisValue = d->thisForContext(exec); + JSC::JSObject* thisObject = (!thisValue || thisValue.isUndefinedOrNull()) ? exec->dynamicGlobalObject() : thisValue.toObject(exec); + JSC::JSValue exceptionValue; + d->timeoutChecker()->setShouldAbort(false); + JSC::JSValue result = exec->interpreter()->execute(evalNode.get(), 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); + exec->globalData().scriptpool->stopEvaluating(source); + + return d->abortResult; + } + + if (exceptionValue) { + exec->setException(exceptionValue); + + if (debugger) + debugger->evaluateStop(exceptionValue, sourceId); + exec->globalData().scriptpool->stopEvaluating(source); + + return d->scriptValueFromJSCValue(exceptionValue); + } + + if (debugger) + debugger->evaluateStop(result, sourceId); + exec->globalData().scriptpool->stopEvaluating(source); + + Q_ASSERT(!exec->hadException()); + return d->scriptValueFromJSCValue(result); +} + + +/*! + Returns the current context. + + The current context is typically accessed to retrieve the arguments + and `this' object in native functions; for convenience, it is + available as the first argument in QScriptEngine::FunctionSignature. +*/ +QScriptContext *QScriptEngine::currentContext() const +{ + Q_D(const QScriptEngine); + return const_cast<QScriptEnginePrivate*>(d)->contextForFrame(d->currentFrame); +} + +/*! + Enters a new execution context and returns the associated + QScriptContext object. + + Once you are done with the context, you should call popContext() to + restore the old context. + + By default, the `this' object of the new context is the Global Object. + The context's \l{QScriptContext::callee()}{callee}() will be invalid. + + This function is useful when you want to evaluate script code + as if it were the body of a function. You can use the context's + \l{QScriptContext::activationObject()}{activationObject}() to initialize + local variables that will be available to scripts. Example: + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 19 + + In the above example, the new variable "tmp" defined in the script + will be local to the context; in other words, the script doesn't + have any effect on the global environment. + + Returns 0 in case of stack overflow + + \sa popContext() +*/ +QScriptContext *QScriptEngine::pushContext() +{ + Q_D(QScriptEngine); + + JSC::CallFrame* newFrame = d->pushContext(d->currentFrame, d->currentFrame->globalData().dynamicGlobalObject, + JSC::ArgList(), /*callee = */0); + + if (agent()) + agent()->contextPush(); + + return d->contextForFrame(newFrame); +} + +/*! \internal + push a context for a native function. + JSC native function doesn't have different stackframe or context. so we need to create one. + + use popContext right after to go back to the previous context the context if no stack overflow has hapenned + + exec is the current top frame. + + return the new top frame. (might be the same as exec if a new stackframe was not needed) or 0 if stack overflow +*/ +JSC::CallFrame *QScriptEnginePrivate::pushContext(JSC::CallFrame *exec, JSC::JSValue _thisObject, + const JSC::ArgList& args, JSC::JSObject *callee, bool calledAsConstructor) +{ + JSC::JSValue thisObject = _thisObject; + if (calledAsConstructor) { + //JSC doesn't create default created object for native functions. so we do it + JSC::JSValue prototype = callee->get(exec, exec->propertyNames().prototype); + JSC::Structure *structure = prototype.isObject() ? JSC::asObject(prototype)->inheritorID() + : originalGlobalObject()->emptyObjectStructure(); + thisObject = new (exec) QScriptObject(structure); + } + + int flags = NativeContext; + if (calledAsConstructor) + flags |= CalledAsConstructorContext; + + JSC::CallFrame *newCallFrame = exec; + if (callee == 0 || !(exec->callee() == callee && exec->returnPC() != 0)) { + //We need to check if the Interpreter might have already created a frame for function called from JS. + JSC::Interpreter *interp = exec->interpreter(); + JSC::Register *oldEnd = interp->registerFile().end(); + int argc = args.size() + 1; //add "this" + JSC::Register *newEnd = oldEnd + argc + JSC::RegisterFile::CallFrameHeaderSize; + if (!interp->registerFile().grow(newEnd)) + return 0; //### Stack overflow + newCallFrame = JSC::CallFrame::create(oldEnd); + newCallFrame[0] = thisObject; + int dst = 0; + JSC::ArgList::const_iterator it; + for (it = args.begin(); it != args.end(); ++it) + newCallFrame[++dst] = *it; + newCallFrame += argc + JSC::RegisterFile::CallFrameHeaderSize; + newCallFrame->init(0, /*vPC=*/0, exec->scopeChain(), exec, flags, argc, callee); + } else { + setContextFlags(newCallFrame, flags); + if (calledAsConstructor) { + //update the new created this + JSC::Register* thisRegister = newCallFrame->registers() - JSC::RegisterFile::CallFrameHeaderSize - newCallFrame->argumentCount(); + *thisRegister = thisObject; + } + } + currentFrame = newCallFrame; + return newCallFrame; +} + + +/*! + Pops the current execution context and restores the previous one. + This function must be used in conjunction with pushContext(). + + \sa pushContext() +*/ +void QScriptEngine::popContext() +{ + if (agent()) + agent()->contextPop(); + Q_D(QScriptEngine); + if (d->currentFrame->returnPC() != 0 || d->currentFrame->codeBlock() != 0 + || !currentContext()->parentContext()) { + qWarning("QScriptEngine::popContext() doesn't match with pushContext()"); + return; + } + + d->popContext(); +} + +/*! \internal + counter part of QScriptEnginePrivate::pushContext + */ +void QScriptEnginePrivate::popContext() +{ + bool hasScope = contextFlags(currentFrame) & HasScopeContext; + if (currentFrame->returnPC() == 0) { //normal case + JSC::RegisterFile ®isterFile = currentFrame->interpreter()->registerFile(); + JSC::Register *const newEnd = currentFrame->registers() - JSC::RegisterFile::CallFrameHeaderSize - currentFrame->argumentCount(); + if (hasScope) + currentFrame->scopeChain()->pop()->deref(); + currentFrame = currentFrame->callerFrame(); + registerFile.shrink(newEnd); + } else if(hasScope) { //the stack frame was created by the Interpreter, we don't need to rewind it. + currentFrame->setScopeChain(currentFrame->scopeChain()->pop()); + currentFrame->scopeChain()->deref(); + } +} + +/*! + Returns true if the last script evaluation resulted in an uncaught + exception; otherwise returns false. + + The exception state is cleared when evaluate() is called. + + \sa uncaughtException(), uncaughtExceptionLineNumber(), + uncaughtExceptionBacktrace() +*/ +bool QScriptEngine::hasUncaughtException() const +{ + Q_D(const QScriptEngine); + JSC::ExecState* exec = d->globalExec(); + return exec->hadException(); +} + +/*! + Returns the current uncaught exception, or an invalid QScriptValue + if there is no uncaught exception. + + The exception value is typically an \c{Error} object; in that case, + you can call toString() on the return value to obtain an error + message. + + \sa hasUncaughtException(), uncaughtExceptionLineNumber(), + uncaughtExceptionBacktrace() +*/ +QScriptValue QScriptEngine::uncaughtException() const +{ + Q_D(const QScriptEngine); + JSC::ExecState* exec = d->globalExec(); + return const_cast<QScriptEnginePrivate*>(d)->scriptValueFromJSCValue(exec->exception()); +} + +/*! + Returns the line number where the last uncaught exception occurred. + + Line numbers are 1-based, unless a different base was specified as + the second argument to evaluate(). + + \sa hasUncaughtException(), uncaughtExceptionBacktrace() +*/ +int QScriptEngine::uncaughtExceptionLineNumber() const +{ + if (!hasUncaughtException()) + return -1; + return uncaughtException().property(QLatin1String("lineNumber")).toInt32(); +} + +/*! + Returns a human-readable backtrace of the last uncaught exception. + + Each line is of the form \c{<function-name>(<arguments>)@<file-name>:<line-number>}. + + \sa uncaughtException() +*/ +QStringList QScriptEngine::uncaughtExceptionBacktrace() const +{ + if (!hasUncaughtException()) + return QStringList(); +// ### currently no way to get a full backtrace from JSC without installing a +// debugger that reimplements exception() and store the backtrace there. + QScriptValue value = uncaughtException(); + if (!value.isError()) + return QStringList(); + QStringList result; + result.append(QString::fromLatin1("<anonymous>()@%0:%1") + .arg(value.property(QLatin1String("fileName")).toString()) + .arg(value.property(QLatin1String("lineNumber")).toInt32())); + return result; +} + +/*! + \since 4.4 + + Clears any uncaught exceptions in this engine. + + \sa hasUncaughtException() +*/ +void QScriptEngine::clearExceptions() +{ + Q_D(QScriptEngine); + JSC::ExecState* exec = d->currentFrame; + exec->clearException(); +} + +/*! + Returns the default prototype associated with the given \a metaTypeId, + or an invalid QScriptValue if no default prototype has been set. + + \sa setDefaultPrototype() +*/ +QScriptValue QScriptEngine::defaultPrototype(int metaTypeId) const +{ + Q_D(const QScriptEngine); + return const_cast<QScriptEnginePrivate*>(d)->scriptValueFromJSCValue(d->defaultPrototype(metaTypeId)); +} + +/*! + Sets the default prototype of the C++ type identified by the given + \a metaTypeId to \a prototype. + + The default prototype provides a script interface for values of + type \a metaTypeId when a value of that type is accessed from script + code. Whenever the script engine (implicitly or explicitly) creates + a QScriptValue from a value of type \a metaTypeId, the default + prototype will be set as the QScriptValue's prototype. + + The \a prototype object itself may be constructed using one of two + principal techniques; the simplest is to subclass QScriptable, which + enables you to define the scripting API of the type through QObject + properties and slots. Another possibility is to create a script + object by calling newObject(), and populate the object with the + desired properties (e.g. native functions wrapped with + newFunction()). + + \sa defaultPrototype(), qScriptRegisterMetaType(), QScriptable, {Default Prototypes Example} +*/ +void QScriptEngine::setDefaultPrototype(int metaTypeId, const QScriptValue &prototype) +{ + Q_D(QScriptEngine); + d->setDefaultPrototype(metaTypeId, d->scriptValueToJSCValue(prototype)); +} + +/*! + \typedef QScriptEngine::FunctionSignature + \relates QScriptEngine + + The function signature \c{QScriptValue f(QScriptContext *, QScriptEngine *)}. + + A function with such a signature can be passed to + QScriptEngine::newFunction() to wrap the function. +*/ + +/*! + \typedef QScriptEngine::FunctionWithArgSignature + \relates QScriptEngine + + The function signature \c{QScriptValue f(QScriptContext *, QScriptEngine *, void *)}. + + A function with such a signature can be passed to + QScriptEngine::newFunction() to wrap the function. +*/ + +/*! + \typedef QScriptEngine::MarshalFunction + \internal +*/ + +/*! + \typedef QScriptEngine::DemarshalFunction + \internal +*/ + +/*! + \internal +*/ +QScriptValue QScriptEngine::create(int type, const void *ptr) +{ + Q_D(QScriptEngine); + return d->create(type, ptr); +} + +QScriptValue QScriptEnginePrivate::create(int type, const void *ptr) +{ + Q_ASSERT(ptr != 0); + QScriptValue result; + QScriptTypeInfo *info = m_typeInfos.value(type); + if (info && info->marshal) { + result = info->marshal(q_func(), ptr); + } else { + // check if it's one of the types we know + switch (QMetaType::Type(type)) { + case QMetaType::Void: + result = QScriptValue(QScriptValue::UndefinedValue); + break; + case QMetaType::Bool: + result = QScriptValue(*reinterpret_cast<const bool*>(ptr)); + break; + case QMetaType::Int: + result = QScriptValue(*reinterpret_cast<const int*>(ptr)); + break; + case QMetaType::UInt: + result = QScriptValue(*reinterpret_cast<const uint*>(ptr)); + break; + case QMetaType::LongLong: + result = QScriptValue(qsreal(*reinterpret_cast<const qlonglong*>(ptr))); + break; + 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))); +#elif defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET) + result = QScriptValue(qsreal((qlonglong)*reinterpret_cast<const qulonglong*>(ptr))); +#else + result = QScriptValue(qsreal(*reinterpret_cast<const qulonglong*>(ptr))); +#endif + break; + case QMetaType::Double: + result = QScriptValue(*reinterpret_cast<const double*>(ptr)); + break; + case QMetaType::QString: + result = QScriptValue(q_func(), *reinterpret_cast<const QString*>(ptr)); + break; + case QMetaType::Float: + result = QScriptValue(*reinterpret_cast<const float*>(ptr)); + break; + case QMetaType::Short: + result = QScriptValue(*reinterpret_cast<const short*>(ptr)); + break; + case QMetaType::UShort: + result = QScriptValue(*reinterpret_cast<const unsigned short*>(ptr)); + break; + case QMetaType::Char: + result = QScriptValue(*reinterpret_cast<const char*>(ptr)); + break; + case QMetaType::UChar: + result = QScriptValue(*reinterpret_cast<const unsigned char*>(ptr)); + break; + case QMetaType::QChar: + result = QScriptValue((*reinterpret_cast<const QChar*>(ptr)).unicode()); + break; + case QMetaType::QStringList: + result = arrayFromStringList(*reinterpret_cast<const QStringList *>(ptr)); + break; + case QMetaType::QVariantList: + result = arrayFromVariantList(*reinterpret_cast<const QVariantList *>(ptr)); + break; + case QMetaType::QVariantMap: + result = objectFromVariantMap(*reinterpret_cast<const QVariantMap *>(ptr)); + break; + case QMetaType::QDateTime: + result = q_func()->newDate(*reinterpret_cast<const QDateTime *>(ptr)); + break; + case QMetaType::QDate: + result = q_func()->newDate(QDateTime(*reinterpret_cast<const QDate *>(ptr))); + break; +#ifndef QT_NO_REGEXP + case QMetaType::QRegExp: + result = q_func()->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)); + break; +#endif + default: + if (type == qMetaTypeId<QScriptValue>()) { + result = *reinterpret_cast<const QScriptValue*>(ptr); + if (!result.isValid()) + result = QScriptValue(QScriptValue::UndefinedValue); + } + +#ifndef QT_NO_QOBJECT + // lazy registration of some common list types + else if (type == qMetaTypeId<QObjectList>()) { + qScriptRegisterSequenceMetaType<QObjectList>(q_func()); + return create(type, ptr); + } +#endif + else if (type == qMetaTypeId<QList<int> >()) { + qScriptRegisterSequenceMetaType<QList<int> >(q_func()); + return create(type, ptr); + } + + else { + QByteArray typeName = QMetaType::typeName(type); + if (typeName == "QVariant") + result = scriptValueFromVariant(*reinterpret_cast<const QVariant*>(ptr)); + if (typeName.endsWith('*') && !*reinterpret_cast<void* const *>(ptr)) + result = QScriptValue(QScriptValue::NullValue); + else + result = q_func()->newVariant(QVariant(type, ptr)); + } + } + } + if (result.isObject() && info && info->prototype + && JSC::JSValue::strictEqual(scriptValueToJSCValue(result.prototype()), originalGlobalObject()->objectPrototype())) { + result.setPrototype(scriptValueFromJSCValue(info->prototype)); + } + return result; +} + +bool QScriptEnginePrivate::convert(const QScriptValue &value, + int type, void *ptr, + QScriptEnginePrivate *eng) +{ + if (!eng && value.engine()) + eng = QScriptEnginePrivate::get(value.engine()); + if (eng) { + QScriptTypeInfo *info = eng->m_typeInfos.value(type); + if (info && info->demarshal) { + info->demarshal(value, ptr); + return true; + } + } + + // check if it's one of the types we know + switch (QMetaType::Type(type)) { + case QMetaType::Bool: + *reinterpret_cast<bool*>(ptr) = value.toBoolean(); + return true; + case QMetaType::Int: + *reinterpret_cast<int*>(ptr) = value.toInt32(); + return true; + case QMetaType::UInt: + *reinterpret_cast<uint*>(ptr) = value.toUInt32(); + return true; + case QMetaType::LongLong: + *reinterpret_cast<qlonglong*>(ptr) = qlonglong(value.toInteger()); + return true; + case QMetaType::ULongLong: + *reinterpret_cast<qulonglong*>(ptr) = qulonglong(value.toInteger()); + return true; + case QMetaType::Double: + *reinterpret_cast<double*>(ptr) = value.toNumber(); + return true; + case QMetaType::QString: + if (value.isUndefined() || value.isNull()) + *reinterpret_cast<QString*>(ptr) = QString(); + else + *reinterpret_cast<QString*>(ptr) = value.toString(); + return true; + case QMetaType::Float: + *reinterpret_cast<float*>(ptr) = value.toNumber(); + return true; + case QMetaType::Short: + *reinterpret_cast<short*>(ptr) = short(value.toInt32()); + return true; + case QMetaType::UShort: + *reinterpret_cast<unsigned short*>(ptr) = value.toUInt16(); + return true; + case QMetaType::Char: + *reinterpret_cast<char*>(ptr) = char(value.toInt32()); + return true; + case QMetaType::UChar: + *reinterpret_cast<unsigned char*>(ptr) = (unsigned char)(value.toInt32()); + return true; + case QMetaType::QChar: + if (value.isString()) { + QString str = value.toString(); + *reinterpret_cast<QChar*>(ptr) = str.isEmpty() ? QChar() : str.at(0); + } else { + *reinterpret_cast<QChar*>(ptr) = QChar(value.toUInt16()); + } + return true; + case QMetaType::QDateTime: + if (value.isDate()) { + *reinterpret_cast<QDateTime *>(ptr) = value.toDateTime(); + return true; + } break; + case QMetaType::QDate: + if (value.isDate()) { + *reinterpret_cast<QDate *>(ptr) = value.toDateTime().date(); + return true; + } break; +#ifndef QT_NO_REGEXP + case QMetaType::QRegExp: + if (value.isRegExp()) { + *reinterpret_cast<QRegExp *>(ptr) = value.toRegExp(); + return true; + } break; +#endif +#ifndef QT_NO_QOBJECT + case QMetaType::QObjectStar: + if (value.isQObject() || value.isNull()) { + *reinterpret_cast<QObject* *>(ptr) = value.toQObject(); + return true; + } break; + case QMetaType::QWidgetStar: + if (value.isQObject() || value.isNull()) { + QObject *qo = value.toQObject(); + if (!qo || qo->isWidgetType()) { + *reinterpret_cast<QWidget* *>(ptr) = reinterpret_cast<QWidget*>(qo); + return true; + } + } break; +#endif + case QMetaType::QStringList: + if (value.isArray()) { + *reinterpret_cast<QStringList *>(ptr) = stringListFromArray(value); + return true; + } break; + case QMetaType::QVariantList: + if (value.isArray()) { + *reinterpret_cast<QVariantList *>(ptr) = variantListFromArray(value); + return true; + } break; + case QMetaType::QVariantMap: + if (value.isObject()) { + *reinterpret_cast<QVariantMap *>(ptr) = variantMapFromObject(value); + return true; + } break; + default: + ; + } + + QByteArray name = QMetaType::typeName(type); +#ifndef QT_NO_QOBJECT + if (convertToNativeQObject(value, name, reinterpret_cast<void* *>(ptr))) + return true; +#endif + if (value.isVariant() && name.endsWith('*')) { + int valueType = QMetaType::type(name.left(name.size()-1)); + QVariant &var = QScriptValuePrivate::get(value)->variantValue(); + if (valueType == var.userType()) { + *reinterpret_cast<void* *>(ptr) = var.data(); + return true; + } else { + // look in the prototype chain + QScriptValue proto = value.prototype(); + while (proto.isObject()) { + bool canCast = false; + if (proto.isVariant()) { + canCast = (type == proto.toVariant().userType()) + || (valueType && (valueType == proto.toVariant().userType())); + } +#ifndef QT_NO_QOBJECT + else if (proto.isQObject()) { + QByteArray className = name.left(name.size()-1); + if (QObject *qobject = proto.toQObject()) + canCast = qobject->qt_metacast(className) != 0; + } +#endif + if (canCast) { + QByteArray varTypeName = QMetaType::typeName(var.userType()); + if (varTypeName.endsWith('*')) + *reinterpret_cast<void* *>(ptr) = *reinterpret_cast<void* *>(var.data()); + else + *reinterpret_cast<void* *>(ptr) = var.data(); + return true; + } + proto = proto.prototype(); + } + } + } else if (value.isNull() && name.endsWith('*')) { + *reinterpret_cast<void* *>(ptr) = 0; + return true; + } else if (type == qMetaTypeId<QScriptValue>()) { + if (!eng) + return false; + *reinterpret_cast<QScriptValue*>(ptr) = value; + return true; + } else if (name == "QVariant") { + *reinterpret_cast<QVariant*>(ptr) = value.toVariant(); + return true; + } + + // lazy registration of some common list types +#ifndef QT_NO_QOBJECT + else if (type == qMetaTypeId<QObjectList>()) { + if (!eng) + return false; + qScriptRegisterSequenceMetaType<QObjectList>(eng->q_func()); + return convert(value, type, ptr, eng); + } +#endif + else if (type == qMetaTypeId<QList<int> >()) { + if (!eng) + return false; + qScriptRegisterSequenceMetaType<QList<int> >(eng->q_func()); + return convert(value, type, ptr, eng); + } + +#if 0 + if (!name.isEmpty()) { + qWarning("QScriptEngine::convert: unable to convert value to type `%s'", + name.constData()); + } +#endif + return false; +} + +bool QScriptEnginePrivate::hasDemarshalFunction(int type) const +{ + QScriptTypeInfo *info = m_typeInfos.value(type); + return info && (info->demarshal != 0); +} + +/*! + \internal +*/ +bool QScriptEngine::convert(const QScriptValue &value, int type, void *ptr) +{ + Q_D(QScriptEngine); + return QScriptEnginePrivate::convert(value, type, ptr, d); +} + +/*! + \internal +*/ +bool QScriptEngine::convertV2(const QScriptValue &value, int type, void *ptr) +{ + return QScriptEnginePrivate::convert(value, type, ptr, /*engine=*/0); +} + +/*! + \internal +*/ +void QScriptEngine::registerCustomType(int type, MarshalFunction mf, + DemarshalFunction df, + const QScriptValue &prototype) +{ + Q_D(QScriptEngine); + QScriptTypeInfo *info = d->m_typeInfos.value(type); + if (!info) { + info = new QScriptTypeInfo(); + d->m_typeInfos.insert(type, info); + } + info->marshal = mf; + info->demarshal = df; + info->prototype = d->scriptValueToJSCValue(prototype); +} + +/*! + \since 4.5 + + Installs translator functions on the given \a object, or on the Global + Object if no object is specified. + + The relation between Qt Script translator functions and C++ translator + functions is described in the following table: + + \table + \header \o Script Function \o Corresponding C++ Function + \row \o qsTr() \o QObject::tr() + \row \o QT_TR_NOOP() \o QT_TR_NOOP() + \row \o qsTranslate() \o QCoreApplication::translate() + \row \o QT_TRANSLATE_NOOP() \o QT_TRANSLATE_NOOP() + \endtable + + \sa {Internationalization with Qt} +*/ +void QScriptEngine::installTranslatorFunctions(const QScriptValue &object) +{ + Q_D(QScriptEngine); + JSC::ExecState* exec = d->currentFrame; + JSC::JSValue jscObject = d->scriptValueToJSCValue(object); + JSC::JSGlobalObject *glob = d->originalGlobalObject(); + if (!jscObject || !jscObject.isObject()) + jscObject = glob; +// unsigned attribs = JSC::DontEnum; + JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 5, JSC::Identifier(exec, "qsTranslate"), QScript::functionQsTranslate)); + JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 2, JSC::Identifier(exec, "QT_TRANSLATE_NOOP"), QScript::functionQsTranslateNoOp)); + JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 3, JSC::Identifier(exec, "qsTr"), QScript::functionQsTr)); + JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 1, JSC::Identifier(exec, "QT_TR_NOOP"), QScript::functionQsTrNoOp)); + + glob->stringPrototype()->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 1, JSC::Identifier(exec, "arg"), QScript::stringProtoFuncArg)); +} + +/*! + Imports the given \a extension into this QScriptEngine. Returns + undefinedValue() if the extension was successfully imported. You + can call hasUncaughtException() to check if an error occurred; in + that case, the return value is the value that was thrown by the + exception (usually an \c{Error} object). + + QScriptEngine ensures that a particular extension is only imported + once; subsequent calls to importExtension() with the same extension + name will do nothing and return undefinedValue(). + + \sa availableExtensions(), QScriptExtensionPlugin, {Creating QtScript Extensions} +*/ +QScriptValue QScriptEngine::importExtension(const QString &extension) +{ +#if defined(QT_NO_QOBJECT) || defined(QT_NO_LIBRARY) || defined(QT_NO_SETTINGS) + Q_UNUSED(extension); +#else + Q_D(QScriptEngine); + if (d->importedExtensions.contains(extension)) + return undefinedValue(); // already imported + + QScriptContext *context = currentContext(); + QCoreApplication *app = QCoreApplication::instance(); + if (!app) + return context->throwError(QLatin1String("No application object")); + + QObjectList staticPlugins = QPluginLoader::staticInstances(); + QStringList libraryPaths = app->libraryPaths(); + QString dot = QLatin1String("."); + QStringList pathComponents = extension.split(dot); + QString initDotJs = QLatin1String("__init__.js"); + + QString ext; + for (int i = 0; i < pathComponents.count(); ++i) { + if (!ext.isEmpty()) + ext.append(dot); + ext.append(pathComponents.at(i)); + if (d->importedExtensions.contains(ext)) + continue; // already imported + + if (d->extensionsBeingImported.contains(ext)) { + return context->throwError(QString::fromLatin1("recursive import of %0") + .arg(extension)); + } + d->extensionsBeingImported.insert(ext); + + QScriptExtensionInterface *iface = 0; + QString initjsContents; + QString initjsFileName; + + // look for the extension in static plugins + for (int j = 0; j < staticPlugins.size(); ++j) { + iface = qobject_cast<QScriptExtensionInterface*>(staticPlugins.at(j)); + if (!iface) + continue; + if (iface->keys().contains(ext)) + break; // use this one + else + iface = 0; // keep looking + } + + { + // look for __init__.js resource + QString path = QString::fromLatin1(":/qtscriptextension"); + for (int j = 0; j <= i; ++j) { + path.append(QLatin1Char('/')); + path.append(pathComponents.at(j)); + } + path.append(QLatin1Char('/')); + path.append(initDotJs); + QFile file(path); + if (file.open(QIODevice::ReadOnly)) { + QTextStream ts(&file); + initjsContents = ts.readAll(); + initjsFileName = path; + file.close(); + } + } + + if (!iface && initjsContents.isEmpty()) { + // look for the extension in library paths + for (int j = 0; j < libraryPaths.count(); ++j) { + QString libPath = libraryPaths.at(j) + QDir::separator() + QLatin1String("script"); + QDir dir(libPath); + if (!dir.exists(dot)) + continue; + + // look for C++ plugin + QFileInfoList files = dir.entryInfoList(QDir::Files); + for (int k = 0; k < files.count(); ++k) { + QFileInfo entry = files.at(k); + QString filePath = entry.canonicalFilePath(); + QPluginLoader loader(filePath); + iface = qobject_cast<QScriptExtensionInterface*>(loader.instance()); + if (iface) { + if (iface->keys().contains(ext)) + break; // use this one + else + iface = 0; // keep looking + } + } + + // look for __init__.js in the corresponding dir + QDir dirdir(libPath); + bool dirExists = dirdir.exists(); + for (int k = 0; dirExists && (k <= i); ++k) + dirExists = dirdir.cd(pathComponents.at(k)); + if (dirExists && dirdir.exists(initDotJs)) { + QFile file(dirdir.canonicalPath() + + QDir::separator() + initDotJs); + if (file.open(QIODevice::ReadOnly)) { + QTextStream ts(&file); + initjsContents = ts.readAll(); + initjsFileName = file.fileName(); + file.close(); + } + } + + if (iface || !initjsContents.isEmpty()) + break; + } + } + + if (!iface && initjsContents.isEmpty()) { + d->extensionsBeingImported.remove(ext); + return context->throwError( + QString::fromLatin1("Unable to import %0: no such extension") + .arg(extension)); + } + + // initialize the extension in a new context + QScriptContext *ctx = pushContext(); + ctx->setThisObject(globalObject()); + ctx->activationObject().setProperty(QLatin1String("__extension__"), ext, + QScriptValue::ReadOnly | QScriptValue::Undeletable); + ctx->activationObject().setProperty(QLatin1String("__setupPackage__"), + newFunction(QScript::__setupPackage__)); + ctx->activationObject().setProperty(QLatin1String("__postInit__"), QScriptValue(QScriptValue::UndefinedValue)); + + // the script is evaluated first + if (!initjsContents.isEmpty()) { + QScriptValue ret = evaluate(initjsContents, initjsFileName); + if (hasUncaughtException()) { + popContext(); + d->extensionsBeingImported.remove(ext); + return ret; + } + } + + // next, the C++ plugin is called + if (iface) { + iface->initialize(ext, this); + if (hasUncaughtException()) { + QScriptValue ret = uncaughtException(); // ctx_p->returnValue(); + popContext(); + d->extensionsBeingImported.remove(ext); + return ret; + } + } + + // if the __postInit__ function has been set, we call it + QScriptValue postInit = ctx->activationObject().property(QLatin1String("__postInit__")); + if (postInit.isFunction()) { + postInit.call(globalObject()); + if (hasUncaughtException()) { + QScriptValue ret = uncaughtException(); // ctx_p->returnValue(); + popContext(); + d->extensionsBeingImported.remove(ext); + return ret; + } + } + + popContext(); + + d->importedExtensions.insert(ext); + d->extensionsBeingImported.remove(ext); + } // for (i) +#endif // QT_NO_QOBJECT + return undefinedValue(); +} + +/*! + \since 4.4 + + Returns a list naming the available extensions that can be + imported using the importExtension() function. This list includes + extensions that have been imported. + + \sa importExtension(), importedExtensions() +*/ +QStringList QScriptEngine::availableExtensions() const +{ +#if defined(QT_NO_QOBJECT) || defined(QT_NO_LIBRARY) || defined(QT_NO_SETTINGS) + return QStringList(); +#else + QCoreApplication *app = QCoreApplication::instance(); + if (!app) + return QStringList(); + + QSet<QString> result; + + QObjectList staticPlugins = QPluginLoader::staticInstances(); + for (int i = 0; i < staticPlugins.size(); ++i) { + QScriptExtensionInterface *iface; + iface = qobject_cast<QScriptExtensionInterface*>(staticPlugins.at(i)); + if (iface) { + QStringList keys = iface->keys(); + for (int j = 0; j < keys.count(); ++j) + result << keys.at(j); + } + } + + QStringList libraryPaths = app->libraryPaths(); + for (int i = 0; i < libraryPaths.count(); ++i) { + QString libPath = libraryPaths.at(i) + QDir::separator() + QLatin1String("script"); + QDir dir(libPath); + if (!dir.exists()) + continue; + + // look for C++ plugins + QFileInfoList files = dir.entryInfoList(QDir::Files); + for (int j = 0; j < files.count(); ++j) { + QFileInfo entry = files.at(j); + QString filePath = entry.canonicalFilePath(); + QPluginLoader loader(filePath); + QScriptExtensionInterface *iface; + iface = qobject_cast<QScriptExtensionInterface*>(loader.instance()); + if (iface) { + QStringList keys = iface->keys(); + for (int k = 0; k < keys.count(); ++k) + result << keys.at(k); + } + } + + // look for scripts + QString initDotJs = QLatin1String("__init__.js"); + QList<QFileInfo> stack; + stack << dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); + while (!stack.isEmpty()) { + QFileInfo entry = stack.takeLast(); + QDir dd(entry.canonicalFilePath()); + if (dd.exists(initDotJs)) { + QString rpath = dir.relativeFilePath(dd.canonicalPath()); + QStringList components = rpath.split(QLatin1Char('/')); + result << components.join(QLatin1String(".")); + stack << dd.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); + } + } + } + + QStringList lst = result.toList(); + qSort(lst); + return lst; +#endif +} + +/*! + \since 4.4 + + Returns a list naming the extensions that have been imported + using the importExtension() function. + + \sa availableExtensions() +*/ +QStringList QScriptEngine::importedExtensions() const +{ + Q_D(const QScriptEngine); + QStringList lst = d->importedExtensions.toList(); + qSort(lst); + return lst; +} + +/*! \fn QScriptValue QScriptEngine::toScriptValue(const T &value) + + Creates a QScriptValue with the given \a value. + + Note that the template type \c{T} must be known to QMetaType. + + See \l{Conversion Between QtScript and C++ Types} for a + description of the built-in type conversion provided by + QtScript. By default, the types that are not specially handled by + QtScript are represented as QVariants (e.g. the \a value is passed + to newVariant()); you can change this behavior by installing your + own type conversion functions with qScriptRegisterMetaType(). + + \warning This function is not available with MSVC 6. Use + qScriptValueFromValue() instead if you need to support that + version of the compiler. + + \sa fromScriptValue(), qScriptRegisterMetaType() +*/ + +/*! \fn T QScriptEngine::fromScriptValue(const QScriptValue &value) + + Returns the given \a value converted to the template type \c{T}. + + Note that \c{T} must be known to QMetaType. + + See \l{Conversion Between QtScript and C++ Types} for a + description of the built-in type conversion provided by + QtScript. + + \warning This function is not available with MSVC 6. Use + qScriptValueToValue() or qscriptvalue_cast() instead if you need + to support that version of the compiler. + + \sa toScriptValue(), qScriptRegisterMetaType() +*/ + +/*! + \fn QScriptValue qScriptValueFromValue(QScriptEngine *engine, const T &value) + \since 4.3 + \relates QScriptEngine + + Creates a QScriptValue using the given \a engine with the given \a + value of template type \c{T}. + + This function is equivalent to QScriptEngine::toScriptValue(). + It is provided as a work-around for MSVC 6, which doesn't support + member template functions. + + \sa qScriptValueToValue() +*/ + +/*! + \fn T qScriptValueToValue(const QScriptValue &value) + \since 4.3 + \relates QScriptEngine + + Returns the given \a value converted to the template type \c{T}. + + This function is equivalent to QScriptEngine::fromScriptValue(). + It is provided as a work-around for MSVC 6, which doesn't + support member template functions. + + \sa qScriptValueFromValue() +*/ + +/*! + \fn QScriptValue qScriptValueFromSequence(QScriptEngine *engine, const Container &container) + \since 4.3 + \relates QScriptEngine + + Creates an array in the form of a QScriptValue using the given \a engine + with the given \a container of template type \c{Container}. + + The \c Container type must provide a \c const_iterator class to enable the + contents of the container to be copied into the array. + + Additionally, the type of each element in the sequence should be suitable + for conversion to a QScriptValue. + See \l{QtScript Module#Conversion Between QtScript and C++ Types} + {Conversion Between QtScript and C++ Types} for more information about the + restrictions on types that can be used with QScriptValue. + + \sa qScriptValueFromValue() +*/ + +/*! + \fn void qScriptValueToSequence(const QScriptValue &value, Container &container) + \since 4.3 + \relates QScriptEngine + + Copies the elements in the sequence specified by \a value to the given + \a container of template type \c{Container}. + + The \a value used is typically an array, but any container can be copied + as long as it provides a \c length property describing how many elements + it contains. + + Additionally, the type of each element in the sequence must be suitable + for conversion to a C++ type from a QScriptValue. + See \l{QtScript Module#Conversion Between QtScript and C++ Types} + {Conversion Between QtScript and C++ Types} for more information about the + restrictions on types that can be used with QScriptValue. + + \sa qscriptvalue_cast() +*/ + +/*! + \fn T qscriptvalue_cast(const QScriptValue &value) + \since 4.3 + \relates QScriptValue + + Returns the given \a value converted to the template type \c{T}. + + \sa qScriptRegisterMetaType(), QScriptEngine::toScriptValue() +*/ + +/*! \fn int qScriptRegisterMetaType( + QScriptEngine *engine, + QScriptValue (*toScriptValue)(QScriptEngine *, const T &t), + void (*fromScriptValue)(const QScriptValue &, T &t), + const QScriptValue &prototype = QScriptValue()) + \relates QScriptEngine + + Registers the type \c{T} in the given \a engine. \a toScriptValue must + be a function that will convert from a value of type \c{T} to a + QScriptValue, and \a fromScriptValue a function that does the + opposite. \a prototype, if valid, is the prototype that's set on + QScriptValues returned by \a toScriptValue. + + Returns the internal ID used by QMetaType. + + You only need to call this function if you want to provide custom + conversion of values of type \c{T}, i.e. if the default + QVariant-based representation and conversion is not + appropriate. (Note that custom QObject-derived types also fall in + this category; e.g. for a QObject-derived class called MyObject, + you probably want to define conversion functions for MyObject* + that utilize QScriptEngine::newQObject() and + QScriptValue::toQObject().) + + If you only want to define a common script interface for values of + type \c{T}, and don't care how those values are represented + (i.e. storing them in QVariants is fine), use + \l{QScriptEngine::setDefaultPrototype()}{setDefaultPrototype}() + instead; this will minimize conversion costs. + + You need to declare the custom type first with + Q_DECLARE_METATYPE(). + + After a type has been registered, you can convert from a + QScriptValue to that type using + \l{QScriptEngine::fromScriptValue()}{fromScriptValue}(), and + create a QScriptValue from a value of that type using + \l{QScriptEngine::toScriptValue()}{toScriptValue}(). The engine + will take care of calling the proper conversion function when + calling C++ slots, and when getting or setting a C++ property; + i.e. the custom type may be used seamlessly on both the C++ side + and the script side. + + The following is an example of how to use this function. We will + specify custom conversion of our type \c{MyStruct}. Here's the C++ + type: + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 20 + + We must declare it so that the type will be known to QMetaType: + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 21 + + Next, the \c{MyStruct} conversion functions. We represent the + \c{MyStruct} value as a script object and just copy the properties: + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 22 + + Now we can register \c{MyStruct} with the engine: + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 23 + + Working with \c{MyStruct} values is now easy: + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 24 + + If you want to be able to construct values of your custom type + from script code, you have to register a constructor function for + the type. For example: + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 25 + + \sa qScriptRegisterSequenceMetaType(), qRegisterMetaType() +*/ + +/*! + \macro Q_SCRIPT_DECLARE_QMETAOBJECT(QMetaObject, ArgType) + \since 4.3 + \relates QScriptEngine + + Declares the given \a QMetaObject. Used in combination with + QScriptEngine::scriptValueFromQMetaObject() to make enums and + instantiation of \a QMetaObject available to script code. The + constructor generated by this macro takes a single argument of + type \a ArgType; typically the argument is the parent type of the + new instance, in which case \a ArgType is \c{QWidget*} or + \c{QObject*}. Objects created by the constructor will have + QScriptEngine::AutoOwnership ownership. +*/ + +/*! \fn int qScriptRegisterSequenceMetaType( + QScriptEngine *engine, + const QScriptValue &prototype = QScriptValue()) + \relates QScriptEngine + + Registers the sequence type \c{T} in the given \a engine. This + function provides conversion functions that convert between \c{T} + and Qt Script \c{Array} objects. \c{T} must provide a + const_iterator class and begin(), end() and push_back() + functions. If \a prototype is valid, it will be set as the + prototype of \c{Array} objects due to conversion from \c{T}; + otherwise, the standard \c{Array} prototype will be used. + + Returns the internal ID used by QMetaType. + + You need to declare the container type first with + Q_DECLARE_METATYPE(). If the element type isn't a standard Qt/C++ + type, it must be declared using Q_DECLARE_METATYPE() as well. + Example: + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 26 + + \sa qScriptRegisterMetaType() +*/ + +/*! + Runs the garbage collector. + + The garbage collector will attempt to reclaim memory by locating and + disposing of objects that are no longer reachable in the script + environment. + + Normally you don't need to call this function; the garbage collector + will automatically be invoked when the QScriptEngine decides that + it's wise to do so (i.e. when a certain number of new objects have + been created). However, you can call this function to explicitly + request that garbage collection should be performed as soon as + possible. +*/ +void QScriptEngine::collectGarbage() +{ + Q_D(QScriptEngine); + d->collectGarbage(); +} + +/*! + + Sets the interval between calls to QCoreApplication::processEvents + to \a interval milliseconds. + + While the interpreter is running, all event processing is by default + blocked. This means for instance that the gui will not be updated + and timers will not be fired. To allow event processing during + interpreter execution one can specify the processing interval to be + a positive value, indicating the number of milliseconds between each + time QCoreApplication::processEvents() is called. + + The default value is -1, which disables event processing during + interpreter execution. + + You can use QCoreApplication::postEvent() to post an event that + performs custom processing at the next interval. For example, you + could keep track of the total running time of the script and call + abortEvaluation() when you detect that the script has been running + for a long time without completing. + + \sa processEventsInterval() +*/ +void QScriptEngine::setProcessEventsInterval(int interval) +{ + Q_D(QScriptEngine); + d->processEventsInterval = interval; + + if (interval > 0) + d->globalData->timeoutChecker->setCheckInterval(interval); + + d->timeoutChecker()->setShouldProcessEvents(interval > 0); +} + +/*! + + Returns the interval in milliseconds between calls to + QCoreApplication::processEvents() while the interpreter is running. + + \sa setProcessEventsInterval() +*/ +int QScriptEngine::processEventsInterval() const +{ + Q_D(const QScriptEngine); + return d->processEventsInterval; +} + +/*! + \since 4.4 + + Returns true if this engine is currently evaluating a script, + otherwise returns false. + + \sa evaluate(), abortEvaluation() +*/ +bool QScriptEngine::isEvaluating() const +{ + Q_D(const QScriptEngine); + return (d->currentFrame != d->globalExec()) || d->inEval; +} + +/*! + \since 4.4 + + Aborts any script evaluation currently taking place in this engine. + The given \a result is passed back as the result of the evaluation + (i.e. it is returned from the call to evaluate() being aborted). + + If the engine isn't evaluating a script (i.e. isEvaluating() returns + false), this function does nothing. + + Call this function if you need to abort a running script for some + reason, e.g. when you have detected that the script has been + running for several seconds without completing. + + \sa evaluate(), isEvaluating(), setProcessEventsInterval() +*/ +void QScriptEngine::abortEvaluation(const QScriptValue &result) +{ + Q_D(QScriptEngine); + + d->timeoutChecker()->setShouldAbort(true); + d->abortResult = result; +} + +#ifndef QT_NO_QOBJECT + +/*! + \since 4.4 + \relates QScriptEngine + + Creates a connection from the \a signal in the \a sender to the + given \a function. If \a receiver is an object, it will act as the + `this' object when the signal handler function is invoked. Returns + true if the connection succeeds; otherwise returns false. + + \sa qScriptDisconnect(), QScriptEngine::signalHandlerException() +*/ +bool qScriptConnect(QObject *sender, const char *signal, + const QScriptValue &receiver, const QScriptValue &function) +{ + if (!sender || !signal) + return false; + if (!function.isFunction()) + return false; + if (receiver.isObject() && (receiver.engine() != function.engine())) + return false; + QScriptEnginePrivate *engine = QScriptEnginePrivate::get(function.engine()); + JSC::JSValue jscReceiver = engine->scriptValueToJSCValue(receiver); + JSC::JSValue jscFunction = engine->scriptValueToJSCValue(function); + return engine->scriptConnect(sender, signal, jscReceiver, jscFunction, + Qt::AutoConnection); +} + +/*! + \since 4.4 + \relates QScriptEngine + + Disconnects the \a signal in the \a sender from the given (\a + receiver, \a function) pair. Returns true if the connection is + successfully broken; otherwise returns false. + + \sa qScriptConnect() +*/ +bool qScriptDisconnect(QObject *sender, const char *signal, + const QScriptValue &receiver, const QScriptValue &function) +{ + if (!sender || !signal) + return false; + if (!function.isFunction()) + return false; + if (receiver.isObject() && (receiver.engine() != function.engine())) + return false; + QScriptEnginePrivate *engine = QScriptEnginePrivate::get(function.engine()); + JSC::JSValue jscReceiver = engine->scriptValueToJSCValue(receiver); + JSC::JSValue jscFunction = engine->scriptValueToJSCValue(function); + return engine->scriptDisconnect(sender, signal, jscReceiver, jscFunction); +} + +/*! + \since 4.4 + \fn void QScriptEngine::signalHandlerException(const QScriptValue &exception) + + This signal is emitted when a script function connected to a signal causes + an \a exception. + + \sa qScriptConnect() +*/ + +QT_BEGIN_INCLUDE_NAMESPACE +#include "moc_qscriptengine.cpp" +QT_END_INCLUDE_NAMESPACE + +#endif // QT_NO_QOBJECT + +/*! + \since 4.4 + + Installs the given \a agent on this engine. The agent will be + notified of various events pertaining to script execution. This is + useful when you want to find out exactly what the engine is doing, + e.g. when evaluate() is called. The agent interface is the basis of + tools like debuggers and profilers. + + The engine maintains ownership of the \a agent. + + Calling this function will replace the existing agent, if any. + + \sa agent() +*/ +void QScriptEngine::setAgent(QScriptEngineAgent *agent) +{ + Q_D(QScriptEngine); + if (agent && (agent->engine() != this)) { + qWarning("QScriptEngine::setAgent(): " + "cannot set agent belonging to different engine"); + return; + } + if (d->activeAgent) + QScriptEngineAgentPrivate::get(d->activeAgent)->detach(); + d->activeAgent = agent; + if (agent) { + int index = d->ownedAgents.indexOf(agent); + if (index == -1) + d->ownedAgents.append(agent); + QScriptEngineAgentPrivate::get(agent)->attach(); + } +} + +/*! + \since 4.4 + + Returns the agent currently installed on this engine, or 0 if no + agent is installed. + + \sa setAgent() +*/ +QScriptEngineAgent *QScriptEngine::agent() const +{ + Q_D(const QScriptEngine); + return d->activeAgent; +} + +/*! + \since 4.4 + + Returns a handle that represents the given string, \a str. + + QScriptString can be used to quickly look up properties, and + compare property names, of script objects. + + \sa QScriptValue::property() +*/ +QScriptString QScriptEngine::toStringHandle(const QString &str) +{ + Q_D(QScriptEngine); + QScriptString ss; + QScriptStringPrivate::init(ss, this, JSC::Identifier(d->currentFrame, str)); + return ss; +} + +/*! + \since 4.5 + + Converts the given \a value to an object, if such a conversion is + possible; otherwise returns an invalid QScriptValue. The conversion + is performed according to the following table: + + \table + \header \o Input Type \o Result + \row \o Undefined \o An invalid QScriptValue. + \row \o Null \o An invalid QScriptValue. + \row \o Boolean \o A new Boolean object whose internal value is set to the value of the boolean. + \row \o Number \o A new Number object whose internal value is set to the value of the number. + \row \o String \o A new String object whose internal value is set to the value of the string. + \row \o Object \o The result is the object itself (no conversion). + \endtable + + \sa newObject() +*/ +QScriptValue QScriptEngine::toObject(const QScriptValue &value) +{ + Q_D(QScriptEngine); + JSC::JSValue jscValue = d->scriptValueToJSCValue(value); + if (!jscValue || jscValue.isUndefined() || jscValue.isNull()) + return QScriptValue(); + JSC::ExecState* exec = d->currentFrame; + JSC::JSValue result = jscValue.toObject(exec); + return d->scriptValueFromJSCValue(result); +} + +/*! + \internal + + Returns the object with the given \a id, or an invalid + QScriptValue if there is no object with that id. + + \sa QScriptValue::objectId() +*/ +QScriptValue QScriptEngine::objectById(qint64 id) const +{ + Q_D(const QScriptEngine); + // Assumes that the cell was not been garbage collected + return const_cast<QScriptEnginePrivate*>(d)->scriptValueFromJSCValue((JSC::JSCell*)id); +} + +/*! + \since 4.5 + \class QScriptSyntaxCheckResult + + \brief The QScriptSyntaxCheckResult class provides the result of a script syntax check. + + \ingroup script + \mainclass + + QScriptSyntaxCheckResult is returned by QScriptEngine::checkSyntax() to + provide information about the syntactical (in)correctness of a script. +*/ + +/*! + \enum QScriptSyntaxCheckResult::State + + This enum specifies the state of a syntax check. + + \value Error The program contains a syntax error. + \value Intermediate The program is incomplete. + \value Valid The program is a syntactically correct Qt Script program. +*/ + +/*! + Constructs a new QScriptSyntaxCheckResult from the \a other result. +*/ +QScriptSyntaxCheckResult::QScriptSyntaxCheckResult(const QScriptSyntaxCheckResult &other) + : d_ptr(other.d_ptr) +{ + if (d_ptr) + d_ptr->ref.ref(); +} + +/*! + \internal +*/ +QScriptSyntaxCheckResult::QScriptSyntaxCheckResult(QScriptSyntaxCheckResultPrivate *d) + : d_ptr(d) +{ + if (d_ptr) + d_ptr->ref.ref(); +} + +/*! + \internal +*/ +QScriptSyntaxCheckResult::QScriptSyntaxCheckResult() + : d_ptr(0) +{ +} + +/*! + Destroys this QScriptSyntaxCheckResult. +*/ +QScriptSyntaxCheckResult::~QScriptSyntaxCheckResult() +{ + if (d_ptr && !d_ptr->ref.deref()) { + delete d_ptr; + d_ptr = 0; + } +} + +/*! + Returns the state of this QScriptSyntaxCheckResult. +*/ +QScriptSyntaxCheckResult::State QScriptSyntaxCheckResult::state() const +{ + Q_D(const QScriptSyntaxCheckResult); + if (!d) + return Valid; + return d->state; +} + +/*! + Returns the error line number of this QScriptSyntaxCheckResult, or -1 if + there is no error. + + \sa state(), errorMessage() +*/ +int QScriptSyntaxCheckResult::errorLineNumber() const +{ + Q_D(const QScriptSyntaxCheckResult); + if (!d) + return -1; + return d->errorLineNumber; +} + +/*! + Returns the error column number of this QScriptSyntaxCheckResult, or -1 if + there is no error. + + \sa state(), errorLineNumber() +*/ +int QScriptSyntaxCheckResult::errorColumnNumber() const +{ + Q_D(const QScriptSyntaxCheckResult); + if (!d) + return -1; + return d->errorColumnNumber; +} + +/*! + Returns the error message of this QScriptSyntaxCheckResult, or an empty + string if there is no error. + + \sa state(), errorLineNumber() +*/ +QString QScriptSyntaxCheckResult::errorMessage() const +{ + Q_D(const QScriptSyntaxCheckResult); + if (!d) + return QString(); + return d->errorMessage; +} + +/*! + Assigns the \a other result to this QScriptSyntaxCheckResult, and returns a + reference to this QScriptSyntaxCheckResult. +*/ +QScriptSyntaxCheckResult &QScriptSyntaxCheckResult::operator=(const QScriptSyntaxCheckResult &other) +{ + if (d_ptr == other.d_ptr) + return *this; + if (d_ptr && !d_ptr->ref.deref()) { + delete d_ptr; + d_ptr = 0; + } + d_ptr = other.d_ptr; + if (d_ptr) + d_ptr->ref.ref(); + return *this; +} + +QT_END_NAMESPACE diff --git a/src/script/qscriptengine.h b/src/script/api/qscriptengine.h index 02ebea7..689c05a 100644 --- a/src/script/qscriptengine.h +++ b/src/script/api/qscriptengine.h @@ -44,8 +44,6 @@ #include <QtCore/qmetatype.h> -#ifndef QT_NO_SCRIPT - #include <QtCore/qvariant.h> #ifndef QT_NO_QOBJECT @@ -117,6 +115,7 @@ private: QScriptSyntaxCheckResultPrivate *d_ptr; Q_DECLARE_PRIVATE(QScriptSyntaxCheckResult) + friend class QScriptEngine; friend class QScriptEnginePrivate; }; @@ -363,7 +362,7 @@ inline bool qscriptvalue_cast_helper(const QScriptValue &value, int type, void * template<typename T> T qscriptvalue_cast(const QScriptValue &value -#if !defined qdoc && defined Q_CC_MSVC && _MSC_VER < 1300 +#ifndef Q_QDOC , T * = 0 #endif ) @@ -379,13 +378,11 @@ T qscriptvalue_cast(const QScriptValue &value return T(); } -#if !defined Q_CC_MSVC || _MSC_VER >= 1300 template <> -inline QVariant qscriptvalue_cast<QVariant>(const QScriptValue &value) +inline QVariant qscriptvalue_cast<QVariant>(const QScriptValue &value, QVariant *) { return value.toVariant(); } -#endif template <typename T> inline T qScriptValueToValue(const QScriptValue &value) @@ -477,5 +474,4 @@ QT_END_NAMESPACE QT_END_HEADER -#endif // QT_NO_SCRIPT #endif // QSCRIPTENGINE_H diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h new file mode 100644 index 0000000..5979b9b --- /dev/null +++ b/src/script/api/qscriptengine_p.h @@ -0,0 +1,259 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTENGINE_P_H +#define QSCRIPTENGINE_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 "private/qobject_p.h" + +#include <QtCore/qhash.h> +#include <QtCore/qset.h> + +#include "RefPtr.h" +#include "Structure.h" +#include "JSGlobalObject.h" +#include "JSValue.h" + +QT_BEGIN_NAMESPACE + +namespace JSC +{ + class ExecState; + typedef ExecState CallFrame; + class JSCell; + class JSGlobalObject; + class UString; +} + + +class QString; +class QStringList; +class QScriptContext; +class QScriptValue; +class QScriptValuePrivate; +class QScriptTypeInfo; +class QScriptEngineAgent; +class QScriptEnginePrivate; +class QScriptSyntaxCheckResult; +class QScriptEngine; + +namespace QScript +{ + class QObjectPrototype; + class QMetaObjectPrototype; + class QVariantPrototype; +#ifndef QT_NO_QOBJECT + class QObjectData; +#endif + class TimeoutCheckerProxy; + + //some conversion helper functions + QScriptEnginePrivate *scriptEngineFromExec(const JSC::ExecState *exec); + bool isFunction(JSC::JSValue value); +} + +class QScriptEnginePrivate +#ifndef QT_NO_QOBJECT + : public QObjectPrivate +#endif +{ + Q_DECLARE_PUBLIC(QScriptEngine) +public: + QScriptEnginePrivate(); + virtual ~QScriptEnginePrivate(); + + static QScriptEnginePrivate *get(QScriptEngine *q) { return q ? q->d_func() : 0; } + static QScriptEngine *get(QScriptEnginePrivate *d) { return d ? d->q_func() : 0; } + + static bool convert(const QScriptValue &value, + int type, void *ptr, + QScriptEnginePrivate *eng); + QScriptValue create(int type, const void *ptr); + bool hasDemarshalFunction(int type) const; + + QScriptValue scriptValueFromJSCValue(JSC::JSValue value); + 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); + + QScriptValue arrayFromStringList(const QStringList &lst); + static QStringList stringListFromArray(const QScriptValue &arr); + + QScriptValue arrayFromVariantList(const QVariantList &lst); + static QVariantList variantListFromArray(const QScriptValue &arr); + + QScriptValue objectFromVariantMap(const QVariantMap &vmap); + static QVariantMap variantMapFromObject(const QScriptValue &obj); + + 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); + + JSC::JSGlobalObject *originalGlobalObject() const; + JSC::JSObject *getOriginalGlobalObjectProxy(); + JSC::JSObject *customGlobalObject() const; + JSC::JSObject *globalObject() const; + void setGlobalObject(JSC::JSObject *object); + JSC::ExecState *globalExec() const; + JSC::JSValue toUsableValue(JSC::JSValue value); + static JSC::JSValue thisForContext(JSC::ExecState *frame); + + JSC::CallFrame *pushContext(JSC::CallFrame *exec, JSC::JSValue thisObject, const JSC::ArgList& args, + JSC::JSObject *callee, bool calledAsConstructor = false); + void popContext(); + + void mark(); + bool isCollecting() const; + void collectGarbage(); + + //flags that we set on the return value register for native function. (ie when codeBlock is 0) + enum ContextFlags { + NativeContext = 1, + CalledAsConstructorContext = 2, + HasScopeContext = 4 + }; + static uint contextFlags(JSC::ExecState *); + static void setContextFlags(JSC::ExecState *, uint); + + QScript::TimeoutCheckerProxy *timeoutChecker() const; + + void agentDeleted(QScriptEngineAgent *agent); + +#ifndef QT_NO_QOBJECT + JSC::JSValue newQObject(QObject *object, + QScriptEngine::ValueOwnership ownership = QScriptEngine::QtOwnership, + const QScriptEngine:: QObjectWrapOptions &options = 0); + 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); + + QScript::QObjectData *qobjectData(QObject *object); + void disposeQObject(QObject *object); + void emitSignalHandlerException(); + + bool scriptConnect(QObject *sender, const char *signal, + JSC::JSValue receiver, JSC::JSValue function, + Qt::ConnectionType type); + bool scriptDisconnect(QObject *sender, const char *signal, + JSC::JSValue receiver, JSC::JSValue function); + + bool scriptConnect(QObject *sender, int index, + JSC::JSValue receiver, JSC::JSValue function, + JSC::JSValue senderWrapper, + Qt::ConnectionType type); + bool scriptDisconnect(QObject *sender, int index, + JSC::JSValue receiver, JSC::JSValue function); + + bool scriptConnect(JSC::JSValue signal, JSC::JSValue receiver, + JSC::JSValue function, Qt::ConnectionType type); + bool scriptDisconnect(JSC::JSValue signal, JSC::JSValue receiver, + JSC::JSValue function); + + void registerScriptValue(QScriptValuePrivate *value); + void unregisterScriptValue(QScriptValuePrivate *value); + void detachAllRegisteredScriptValues(); + + // private slots + void _q_objectDestroyed(QObject *); +#endif + + JSC::JSGlobalData *globalData; + JSC::JSObject *originalGlobalObjectProxy; + JSC::ExecState *currentFrame; + + WTF::RefPtr<JSC::Structure> scriptObjectStructure; + + QScript::QObjectPrototype *qobjectPrototype; + WTF::RefPtr<JSC::Structure> qobjectWrapperObjectStructure; + + QScript::QMetaObjectPrototype *qmetaobjectPrototype; + WTF::RefPtr<JSC::Structure> qmetaobjectWrapperObjectStructure; + + QScript::QVariantPrototype *variantPrototype; + WTF::RefPtr<JSC::Structure> variantWrapperObjectStructure; + + QList<QScriptEngineAgent*> ownedAgents; + QScriptEngineAgent *activeAgent; + int agentLineNumber; + QScriptValuePrivate *registeredScriptValues; + QHash<int, QScriptTypeInfo*> m_typeInfos; + int processEventsInterval; + QScriptValue abortResult; + bool inEval; + + QSet<QString> importedExtensions; + QSet<QString> extensionsBeingImported; + +#ifndef QT_NO_QOBJECT + QHash<QObject*, QScript::QObjectData*> m_qobjectData; +#endif + +#ifdef QT_NO_QOBJECT + QScriptEngine *q_ptr; +#endif +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/script/qscriptengineagent.cpp b/src/script/api/qscriptengineagent.cpp index b4793ab..6417ed8 100644 --- a/src/script/qscriptengineagent.cpp +++ b/src/script/api/qscriptengineagent.cpp @@ -39,17 +39,14 @@ ** ****************************************************************************/ +#include "config.h" #include "qscriptengineagent.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptvalue.h" #include "qscriptengineagent_p.h" +#include "qscriptengine.h" #include "qscriptengine_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" -#include "qscriptvalueimpl_p.h" + +#include "CodeBlock.h" +#include "Instruction.h" QT_BEGIN_NAMESPACE @@ -132,17 +129,77 @@ QT_BEGIN_NAMESPACE \sa extension() */ -QScriptEngineAgentPrivate::QScriptEngineAgentPrivate() - : engine(0), q_ptr(0) + +void QScriptEngineAgentPrivate::attach() +{ + if (engine->originalGlobalObject()->debugger()) + engine->originalGlobalObject()->setDebugger(0); + JSC::Debugger::attach(engine->originalGlobalObject()); +} + +void QScriptEngineAgentPrivate::detach() +{ + JSC::Debugger::detach(engine->originalGlobalObject()); +} + +void QScriptEngineAgentPrivate::exceptionThrow(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, bool hasHandler) { + JSC::CallFrame *oldFrame = engine->currentFrame; + engine->currentFrame = frame.callFrame(); + QScriptValue value(engine->scriptValueFromJSCValue(frame.exception())); + q_ptr->exceptionThrow(sourceID, value, hasHandler); + engine->currentFrame = oldFrame; +}; + +void QScriptEngineAgentPrivate::exceptionCatch(const JSC::DebuggerCallFrame& frame, intptr_t sourceID) +{ + JSC::CallFrame *oldFrame = engine->currentFrame; + engine->currentFrame = frame.callFrame(); + QScriptValue value(engine->scriptValueFromJSCValue(frame.exception())); + q_ptr->exceptionCatch(sourceID, value); + engine->currentFrame = oldFrame; +} + +void QScriptEngineAgentPrivate::atStatement(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno, int column) +{ + JSC::CallFrame *oldFrame = engine->currentFrame; + int oldAgentLineNumber = engine->agentLineNumber; + engine->currentFrame = frame.callFrame(); + engine->agentLineNumber = lineno; + q_ptr->positionChange(sourceID, lineno, column); + engine->currentFrame = oldFrame; + engine->agentLineNumber = oldAgentLineNumber; +} + +void QScriptEngineAgentPrivate::functionExit(const JSC::JSValue& returnValue, intptr_t sourceID) +{ + QScriptValue result = engine->scriptValueFromJSCValue(returnValue); + q_ptr->functionExit(sourceID, result); + q_ptr->contextPop(); } -QScriptEngineAgentPrivate::~QScriptEngineAgentPrivate() +void QScriptEngineAgentPrivate::evaluateStop(const JSC::JSValue& returnValue, intptr_t sourceID) { - QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(engine); - eng_p->agentDeleted(q_ptr); + QScriptValue result = engine->scriptValueFromJSCValue(returnValue); + q_ptr->functionExit(sourceID, result); } +void QScriptEngineAgentPrivate::didReachBreakpoint(const JSC::DebuggerCallFrame& frame, + intptr_t sourceID, int lineno, int column) +{ + if (q_ptr->supportsExtension(QScriptEngineAgent::DebuggerInvocationRequest)) { + JSC::CallFrame *oldFrame = engine->currentFrame; + int oldAgentLineNumber = engine->agentLineNumber; + engine->currentFrame = frame.callFrame(); + engine->agentLineNumber = lineno; + QList<QVariant> args; + args << qint64(sourceID) << lineno << column; + q_ptr->extension(QScriptEngineAgent::DebuggerInvocationRequest, args); + engine->currentFrame = oldFrame; + engine->agentLineNumber = oldAgentLineNumber; + } +}; + /*! Constructs a QScriptEngineAgent object for the given \a engine. @@ -152,10 +209,10 @@ QScriptEngineAgentPrivate::~QScriptEngineAgentPrivate() agent. */ QScriptEngineAgent::QScriptEngineAgent(QScriptEngine *engine) - : d_ptr(new QScriptEngineAgentPrivate) + : d_ptr(new QScriptEngineAgentPrivate()) { d_ptr->q_ptr = this; - d_ptr->engine = engine; + d_ptr->engine = QScriptEnginePrivate::get(engine); } /*! @@ -165,7 +222,7 @@ QScriptEngineAgent::QScriptEngineAgent(QScriptEngineAgentPrivate &dd, QScriptEng : d_ptr(&dd) { d_ptr->q_ptr = this; - d_ptr->engine = engine; + d_ptr->engine = QScriptEnginePrivate::get(engine); } /*! @@ -173,6 +230,7 @@ QScriptEngineAgent::QScriptEngineAgent(QScriptEngineAgentPrivate &dd, QScriptEng */ QScriptEngineAgent::~QScriptEngineAgent() { + d_ptr->engine->agentDeleted(this); delete d_ptr; d_ptr = 0; } @@ -436,9 +494,7 @@ QVariant QScriptEngineAgent::extension(Extension extension, QScriptEngine *QScriptEngineAgent::engine() const { Q_D(const QScriptEngineAgent); - return d->engine; + return QScriptEnginePrivate::get(d->engine); } QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptengineagent.h b/src/script/api/qscriptengineagent.h index 00c245b..60c1ed6 100644 --- a/src/script/qscriptengineagent.h +++ b/src/script/api/qscriptengineagent.h @@ -44,8 +44,6 @@ #include <QtCore/qobjectdefs.h> -#ifndef QT_NO_SCRIPT - #include <QtCore/qvariant.h> QT_BEGIN_HEADER @@ -107,6 +105,4 @@ QT_END_NAMESPACE QT_END_HEADER -#endif // QT_NO_SCRIPT - #endif diff --git a/src/script/api/qscriptengineagent_p.h b/src/script/api/qscriptengineagent_p.h new file mode 100644 index 0000000..64befc1 --- /dev/null +++ b/src/script/api/qscriptengineagent_p.h @@ -0,0 +1,147 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTENGINEAGENT_P_H +#define QSCRIPTENGINEAGENT_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> +#include "Debugger.h" +#include "qscriptengineagent.h" + +#include "CallFrame.h" +#include "SourceCode.h" +#include "UString.h" +#include "DebuggerCallFrame.h" + +QT_BEGIN_NAMESPACE + +class QScriptEnginePrivate; + +class QScriptEngineAgent; +class Q_SCRIPT_EXPORT QScriptEngineAgentPrivate : public JSC::Debugger +{ + Q_DECLARE_PUBLIC(QScriptEngineAgent) +public: + static QScriptEngineAgent* get(QScriptEngineAgentPrivate* p) {return p->q_func();} + static QScriptEngineAgentPrivate* get(QScriptEngineAgent* p) {return p->d_func();} + + QScriptEngineAgentPrivate(){} + virtual ~QScriptEngineAgentPrivate(){}; + + void attach(); + void detach(); + + //scripts + virtual void sourceParsed(JSC::ExecState*, const JSC::SourceCode&, int /*errorLine*/, const JSC::UString& /*errorMsg*/) {}; + virtual void scriptUnload(qint64 id) + { + q_ptr->scriptUnload(id); + }; + virtual void scriptLoad(qint64 id, const JSC::UString &program, + const JSC::UString &fileName, int baseLineNumber) + { + q_ptr->scriptLoad(id,program, fileName, baseLineNumber); + }; + + //exceptions + virtual void exception(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno) + { + Q_UNUSED(frame); + Q_UNUSED(sourceID); + Q_UNUSED(lineno); + }; + virtual void exceptionThrow(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, bool hasHandler); + virtual void exceptionCatch(const JSC::DebuggerCallFrame& frame, intptr_t sourceID); + + //statements + virtual void atStatement(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno, int column); + virtual void callEvent(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno) + { + Q_UNUSED(lineno); + q_ptr->contextPush(); + q_ptr->functionEntry(sourceID); + }; + virtual void returnEvent(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno) + { + Q_UNUSED(frame); + Q_UNUSED(sourceID); + Q_UNUSED(lineno); + } + virtual void willExecuteProgram(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno) + { + Q_UNUSED(frame); + Q_UNUSED(sourceID); + Q_UNUSED(lineno); + }; + virtual void didExecuteProgram(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno) + { + Q_UNUSED(frame); + Q_UNUSED(sourceID); + Q_UNUSED(lineno); + }; + virtual void functionExit(const JSC::JSValue& returnValue, intptr_t sourceID); + //others + virtual void didReachBreakpoint(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno, int column); + + virtual void evaluateStart(intptr_t sourceID) + { + q_ptr->functionEntry(sourceID); + } + virtual void evaluateStop(const JSC::JSValue& returnValue, intptr_t sourceID); + + QScriptEnginePrivate *engine; + QScriptEngineAgent *q_ptr; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/script/qscriptextensioninterface.h b/src/script/api/qscriptextensioninterface.h index 2e2c66e..e91fec5 100644 --- a/src/script/qscriptextensioninterface.h +++ b/src/script/api/qscriptextensioninterface.h @@ -44,8 +44,6 @@ #include <QtCore/qfactoryinterface.h> -#ifndef QT_NO_SCRIPT - #include <QtCore/qobject.h> QT_BEGIN_HEADER @@ -69,5 +67,4 @@ QT_END_NAMESPACE QT_END_HEADER -#endif // QT_NO_SCRIPT #endif // QSCRIPTEXTENSIONINTERFACE_H diff --git a/src/script/qscriptextensionplugin.cpp b/src/script/api/qscriptextensionplugin.cpp index 454cceb..38459f4 100644 --- a/src/script/qscriptextensionplugin.cpp +++ b/src/script/api/qscriptextensionplugin.cpp @@ -41,8 +41,6 @@ #include "qscriptextensionplugin.h" -#ifndef QT_NO_SCRIPT - #include "qscriptvalue.h" #include "qscriptengine.h" @@ -143,5 +141,3 @@ QScriptValue QScriptExtensionPlugin::setupPackage( } QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptextensionplugin.h b/src/script/api/qscriptextensionplugin.h index 21818d7..94e53f0 100644 --- a/src/script/qscriptextensionplugin.h +++ b/src/script/api/qscriptextensionplugin.h @@ -44,8 +44,6 @@ #include <QtCore/qplugin.h> -#ifndef QT_NO_SCRIPT - #include <QtScript/qscriptextensioninterface.h> QT_BEGIN_HEADER @@ -75,5 +73,4 @@ QT_END_NAMESPACE QT_END_HEADER -#endif // QT_NO_SCRIPT #endif // QSCRIPTEXTENSIONPLUGIN_H diff --git a/src/script/qscriptstring.cpp b/src/script/api/qscriptstring.cpp index 7d8d4e9..bcafa44 100644 --- a/src/script/qscriptstring.cpp +++ b/src/script/api/qscriptstring.cpp @@ -39,21 +39,14 @@ ** ****************************************************************************/ +#include "config.h" #include "qscriptstring.h" -#ifndef QT_NO_SCRIPT - #include "qscriptstring_p.h" -#include "qscriptnameid_p.h" -#include "qscriptvalue_p.h" -#include "qscriptengine_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" QT_BEGIN_NAMESPACE + /*! \since 4.4 \class QScriptString @@ -81,7 +74,6 @@ QT_BEGIN_NAMESPACE \internal */ QScriptStringPrivate::QScriptStringPrivate() - : nameId(0), engine(0), q_ptr(0) { ref = 0; } @@ -89,26 +81,19 @@ QScriptStringPrivate::QScriptStringPrivate() /*! \internal */ -QScriptStringPrivate *QScriptStringPrivate::create() -{ - return new QScriptStringPrivate(); -} - -/*! - \internal -*/ -QScriptStringPrivate *QScriptStringPrivate::get(const QScriptString &q) +QScriptStringPrivate::~QScriptStringPrivate() { - return const_cast<QScriptStringPrivate*>(q.d_func()); } /*! \internal */ -void QScriptStringPrivate::init(QScriptString &q, QScriptStringPrivate *d) +void QScriptStringPrivate::init(QScriptString &q, QScriptEngine *engine, const JSC::Identifier &value) { - Q_ASSERT(q.d_ptr == 0); - q.d_ptr = d; + Q_ASSERT(!q.isValid()); + q.d_ptr = new QScriptStringPrivate(); + q.d_ptr->identifier = value; + q.d_ptr->engine = engine; q.d_ptr->ref.ref(); } @@ -136,12 +121,7 @@ QScriptString::QScriptString(const QScriptString &other) QScriptString::~QScriptString() { if (d_ptr && !d_ptr->ref.deref()) { - if (isValid()) { - d_ptr->engine->uninternString(d_ptr); - } else { - // the engine has already been deleted - delete d_ptr; - } + delete d_ptr; d_ptr = 0; } } @@ -154,12 +134,7 @@ QScriptString &QScriptString::operator=(const QScriptString &other) if (d_ptr == other.d_ptr) return *this; if (d_ptr && !d_ptr->ref.deref()) { - if (isValid()) { - d_ptr->engine->uninternString(d_ptr); - } else { - // the engine has already been deleted - delete d_ptr; - } + delete d_ptr; } d_ptr = other.d_ptr; if (d_ptr) @@ -174,7 +149,7 @@ QScriptString &QScriptString::operator=(const QScriptString &other) bool QScriptString::isValid() const { Q_D(const QScriptString); - return (d && d->nameId); + return (d && d->engine); } /*! @@ -184,7 +159,15 @@ bool QScriptString::isValid() const bool QScriptString::operator==(const QScriptString &other) const { Q_D(const QScriptString); - return (d == other.d_func()); + if (d == other.d_func()) + return true; + if (!d || !other.d_func()) + return false; + if (d->engine != other.d_func()->engine) + return false; + if (!d->engine) + return true; + return d->identifier == other.d_func()->identifier; } /*! @@ -193,8 +176,7 @@ bool QScriptString::operator==(const QScriptString &other) const */ bool QScriptString::operator!=(const QScriptString &other) const { - Q_D(const QScriptString); - return (d != other.d_func()); + return !operator==(other); } /*! @@ -206,9 +188,9 @@ bool QScriptString::operator!=(const QScriptString &other) const QString QScriptString::toString() const { Q_D(const QScriptString); - if (!d || !d->nameId) + if (!d || !d->engine) return QString(); - return d->nameId->s; + return d->identifier.ustring(); } /*! @@ -223,5 +205,3 @@ QScriptString::operator QString() const } QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptstring.h b/src/script/api/qscriptstring.h index d0f05cb..e42c3e3 100644 --- a/src/script/qscriptstring.h +++ b/src/script/api/qscriptstring.h @@ -44,8 +44,6 @@ #include <QtCore/qstring.h> -#ifndef QT_NO_SCRIPT - QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -74,7 +72,7 @@ public: private: QScriptStringPrivate *d_ptr; - + friend class QScriptValue; Q_DECLARE_PRIVATE(QScriptString) }; @@ -82,5 +80,4 @@ QT_END_NAMESPACE QT_END_HEADER -#endif // QT_NO_SCRIPT #endif // QSCRIPTSTRING_H diff --git a/src/script/qscriptstring_p.h b/src/script/api/qscriptstring_p.h index 09e4a0c..74094bf 100644 --- a/src/script/qscriptstring_p.h +++ b/src/script/api/qscriptstring_p.h @@ -42,12 +42,6 @@ #ifndef QSCRIPTSTRING_P_H #define QSCRIPTSTRING_P_H -#include <QtCore/qatomic.h> - -#ifndef QT_NO_SCRIPT - -QT_BEGIN_NAMESPACE - // // W A R N I N G // ------------- @@ -59,28 +53,36 @@ QT_BEGIN_NAMESPACE // We mean it. // -class QScriptNameIdImpl; -class QScriptEnginePrivate; -class QScriptString; +#include <QtCore/qobjectdefs.h> + +#include <QtCore/qstring.h> +#include <QtCore/qpointer.h> +#include "qscriptengine.h" + +#include "Identifier.h" + +QT_BEGIN_NAMESPACE + +class QScriptString; +class QScriptEngine; class QScriptStringPrivate { - Q_DECLARE_PUBLIC(QScriptString) public: QScriptStringPrivate(); + ~QScriptStringPrivate(); - static QScriptStringPrivate *create(); - static QScriptStringPrivate *get(const QScriptString &q); - static void init(QScriptString &q, QScriptStringPrivate *d); + static void init(QScriptString &q, QScriptEngine *engine, const JSC::Identifier &value); QBasicAtomicInt ref; - QScriptNameIdImpl *nameId; - QScriptEnginePrivate *engine; - QScriptString *q_ptr; +#ifndef QT_NO_QOBJECT + QPointer<QScriptEngine> engine; +#else + void *engine; +#endif + JSC::Identifier identifier; }; QT_END_NAMESPACE -#endif // QT_NO_SCRIPT - #endif diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp new file mode 100644 index 0000000..7b28e37 --- /dev/null +++ b/src/script/api/qscriptvalue.cpp @@ -0,0 +1,2501 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "config.h" +#include "qscriptvalue.h" + +#include "qscriptvalue_p.h" +#include "qscriptengine.h" +#include "qscriptengine_p.h" +#include "qscriptstring_p.h" + +#include "JSArray.h" +#include "JSGlobalObject.h" +#include "JSImmediate.h" +#include "JSObject.h" +#include "JSValue.h" +#include "JSFunction.h" +#include "DateInstance.h" +#include "ErrorInstance.h" +#include "RegExpObject.h" +#include "Identifier.h" +#include "Operations.h" +#include "Arguments.h" + +#include <QtCore/qdatetime.h> +#include <QtCore/qregexp.h> +#include <QtCore/qvariant.h> +#include <QtCore/qnumeric.h> + +#include "utils/qscriptdate_p.h" +#include "bridge/qscriptobject_p.h" +#include "bridge/qscriptclassobject_p.h" +#include "bridge/qscriptvariant_p.h" +#include "bridge/qscriptqobject_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \since 4.3 + \class QScriptValue + + \brief The QScriptValue class acts as a container for the Qt Script data types. + + \ingroup script + \mainclass + + QScriptValue supports the types defined in the \l{ECMA-262} + standard: The primitive types, which are Undefined, Null, Boolean, + Number, and String; and the Object type. Additionally, Qt Script + has built-in support for QVariant, QObject and QMetaObject. + + For the object-based types (including Date and RegExp), use the + newT() functions in QScriptEngine (e.g. QScriptEngine::newObject()) + to create a QScriptValue of the desired type. For the primitive types, + use one of the QScriptValue constructor overloads. + + The methods named isT() (e.g. isBool(), isUndefined()) can be + used to test if a value is of a certain type. The methods named + toT() (e.g. toBool(), toString()) can be used to convert a + QScriptValue to another type. You can also use the generic + qscriptvalue_cast() function. + + Object values have zero or more properties which are themselves + QScriptValues. Use setProperty() to set a property of an object, and + call property() to retrieve the value of a property. + + \snippet doc/src/snippets/code/src_script_qscriptvalue.cpp 0 + + Each property can have a set of attributes; these are specified as + the third (optional) argument to setProperty(). The attributes of a + property can be queried by calling the propertyFlags() function. The + following code snippet creates a property that cannot be modified by + script code: + + \snippet doc/src/snippets/code/src_script_qscriptvalue.cpp 1 + + If you want to iterate over the properties of a script object, use + the QScriptValueIterator class. + + Object values have an internal \c{prototype} property, which can be + accessed with prototype() and setPrototype(). Properties added to a + prototype are shared by all objects having that prototype; this is + referred to as prototype-based inheritance. In practice, it means + that (by default) the property() function will automatically attempt + to look up look the property in the prototype() (and in the + prototype of the prototype(), and so on), if the object itself does + not have the requested property. Note that this prototype-based + lookup is not performed by setProperty(); setProperty() will always + create the property in the script object itself. For more + information, see the \l{QtScript} documentation. + + Function objects (objects for which isFunction() returns true) can + be invoked by calling call(). Constructor functions can be used to + construct new objects by calling construct(). + + Use equals(), strictlyEquals() and lessThan() to compare a QScriptValue + to another. + + Object values can have custom data associated with them; see the + setData() and data() functions. By default, this data is not + accessible to scripts; it can be used to store any data you want to + associate with the script object. Typically this is used by custom + class objects (see QScriptClass) to store a C++ type that contains + the "native" object data. + + Note that a QScriptValue for which isObject() is true only carries a + reference to an actual object; copying the QScriptValue will only + copy the object reference, not the object itself. If you want to + clone an object (i.e. copy an object's properties to another + object), you can do so with the help of a \c{for-in} statement in + script code, or QScriptValueIterator in C++. + + \sa QScriptEngine, QScriptValueIterator +*/ + +/*! + \enum QScriptValue::SpecialValue + + This enum is used to specify a single-valued type. + + \value UndefinedValue An undefined value. + + \value NullValue A null value. +*/ + +/*! + \enum QScriptValue::PropertyFlag + + This enum describes the attributes of a property. + + \value ReadOnly The property is read-only. Attempts by Qt Script code to write to the property will be ignored. + + \value Undeletable Attempts by Qt Script code to \c{delete} the property will be ignored. + + \value SkipInEnumeration The property is not to be enumerated by a \c{for-in} enumeration. + + \value PropertyGetter The property is defined by a function which will be called to get the property value. + + \value PropertySetter The property is defined by a function which will be called to set the property value. + + \value QObjectMember This flag is used to indicate that an existing property is a QObject member (a property or method). + + \value KeepExistingFlags This value is used to indicate to setProperty() that the property's flags should be left unchanged. If the property doesn't exist, the default flags (0) will be used. + + \value UserRange Flags in this range are not used by Qt Script, and can be used for custom purposes. +*/ + +/*! + \enum QScriptValue::ResolveFlag + + This enum specifies how to look up a property of an object. + + \value ResolveLocal Only check the object's own properties. + + \value ResolvePrototype Check the object's own properties first, then search the prototype chain. This is the default. + + \omitvalue ResolveScope Check the object's own properties first, then search the scope chain. + + \omitvalue ResolveFull Check the object's own properties first, then search the prototype chain, and finally search the scope chain. +*/ + +// ### move + +#include <QtCore/qnumeric.h> +#include <math.h> + +namespace QScript +{ + +static const qsreal D32 = 4294967296.0; + +qint32 ToInt32(qsreal n) +{ + if (qIsNaN(n) || qIsInf(n) || (n == 0)) + return 0; + + double 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; + + double 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; + + double 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 + +QScriptValuePrivate::QScriptValuePrivate() : engine(0), prev(0), next(0) +{ + ref = 0; +} + +QScriptValuePrivate::~QScriptValuePrivate() +{ +} + +void QScriptValuePrivate::initFrom(JSC::JSValue value) +{ + if (value.isCell()) { + Q_ASSERT(engine != 0); + value = engine->toUsableValue(value); + JSC::JSCell *cell = JSC::asCell(value); + Q_ASSERT(cell != engine->originalGlobalObject()); + } + type = JSC; + jscValue = value; + if (engine) + engine->registerScriptValue(this); +} + +void QScriptValuePrivate::initFrom(double value) +{ + type = Number; + numberValue = value; + if (engine) + engine->registerScriptValue(this); +} + +void QScriptValuePrivate::initFrom(const QString &value) +{ + type = String; + stringValue = value; + if (engine) + engine->registerScriptValue(this); +} + +bool QScriptValuePrivate::isJSC() const +{ + return (type == JSC); +} + +QScriptValue QScriptValuePrivate::property(const QString &name, int resolveMode) const +{ + JSC::ExecState *exec = engine->currentFrame; + return property(JSC::Identifier(exec, name), resolveMode); +} + +QScriptValue QScriptValuePrivate::property(const JSC::Identifier &id, int resolveMode) const +{ + Q_ASSERT(isJSC()); + JSC::ExecState *exec = engine->currentFrame; + JSC::JSObject *object = jscValue.getObject(); + 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)) { + 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)); + } + } + return engine->scriptValueFromJSCValue(result); +} + +QScriptValue QScriptValuePrivate::property(quint32 index, int resolveMode) const +{ + Q_ASSERT(isJSC()); + JSC::ExecState *exec = engine->currentFrame; + JSC::JSObject *object = jscValue.getObject(); + 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); + } + return engine->scriptValueFromJSCValue(result); +} + +QVariant &QScriptValuePrivate::variantValue() const +{ + Q_ASSERT(jscValue.isObject(&QScriptObject::info)); + QScriptObjectDelegate *delegate = static_cast<QScriptObject*>(JSC::asObject(jscValue))->delegate(); + Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant)); + return static_cast<QScript::QVariantDelegate*>(delegate)->value(); +} + +void QScriptValuePrivate::setVariantValue(const QVariant &value) +{ + Q_ASSERT(jscValue.isObject(&QScriptObject::info)); + QScriptObjectDelegate *delegate = static_cast<QScriptObject*>(JSC::asObject(jscValue))->delegate(); + Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant)); + static_cast<QScript::QVariantDelegate*>(delegate)->setValue(value); +} + +void QScriptValuePrivate::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()) + jscValue = JSC::JSValue(); + engine = 0; +} + +/*! + Constructs an invalid QScriptValue. +*/ +QScriptValue::QScriptValue() + : d_ptr(0) +{ +} + +/*! + Destroys this QScriptValue. +*/ +QScriptValue::~QScriptValue() +{ + if (d_ptr && !d_ptr->ref.deref()) { + if (d_ptr->engine) + d_ptr->engine->unregisterScriptValue(d_ptr); + delete d_ptr; + } +} + +/*! + Constructs a new QScriptValue that is a copy of \a other. + + Note that if \a other is an object (i.e., isObject() would return + true), then only a reference to the underlying object is copied into + the new script value (i.e., the object itself is not copied). +*/ +QScriptValue::QScriptValue(const QScriptValue &other) + : d_ptr(other.d_ptr) +{ + if (d_ptr) + d_ptr->ref.ref(); +} + +/*! + \obsolete + + Constructs a new QScriptValue with the special \a value and + registers it with the script \a engine. +*/ +QScriptValue::QScriptValue(QScriptEngine *engine, QScriptValue::SpecialValue value) + : d_ptr(new QScriptValuePrivate) +{ + d_ptr->engine = QScriptEnginePrivate::get(engine); + switch (value) { + case NullValue: + d_ptr->initFrom(JSC::jsNull()); + break; + case UndefinedValue: + d_ptr->initFrom(JSC::jsUndefined()); + break; + } + d_ptr->ref.ref(); +} + +/*! + \obsolete + + \fn QScriptValue::QScriptValue(QScriptEngine *engine, bool value) + + Constructs a new QScriptValue with the boolean \a value and + registers it with the script \a engine. +*/ +QScriptValue::QScriptValue(QScriptEngine *engine, bool val) + : d_ptr(new QScriptValuePrivate) +{ + d_ptr->engine = QScriptEnginePrivate::get(engine); + d_ptr->initFrom(JSC::jsBoolean(val)); + d_ptr->ref.ref(); +} + +/*! + \fn QScriptValue::QScriptValue(QScriptEngine *engine, int value) + \obsolete + + Constructs a new QScriptValue with the integer \a value and + registers it with the script \a engine. +*/ +QScriptValue::QScriptValue(QScriptEngine *engine, int val) + : d_ptr(new QScriptValuePrivate) +{ + d_ptr->engine = QScriptEnginePrivate::get(engine); + if (engine) { + JSC::ExecState *exec = d_ptr->engine->currentFrame; + d_ptr->initFrom(JSC::jsNumber(exec, val)); + } else { + JSC::JSValue immediate = JSC::JSImmediate::from(val); + if (immediate) + d_ptr->initFrom(immediate); + else + d_ptr->initFrom(val); + } + d_ptr->ref.ref(); +} + +/*! + \fn QScriptValue::QScriptValue(QScriptEngine *engine, uint value) + \obsolete + + Constructs a new QScriptValue with the unsigned integer \a value and + registers it with the script \a engine. + */ +QScriptValue::QScriptValue(QScriptEngine *engine, uint val) + : d_ptr(new QScriptValuePrivate) +{ + d_ptr->engine = QScriptEnginePrivate::get(engine); + if (engine) { + JSC::ExecState *exec = d_ptr->engine->currentFrame; + d_ptr->initFrom(JSC::jsNumber(exec, val)); + } else { + JSC::JSValue immediate = JSC::JSImmediate::from(val); + if (immediate) + d_ptr->initFrom(immediate); + else + d_ptr->initFrom(val); + } + d_ptr->ref.ref(); +} + +/*! + \fn QScriptValue::QScriptValue(QScriptEngine *engine, qsreal value) + \obsolete + + Constructs a new QScriptValue with the qsreal \a value and + registers it with the script \a engine. +*/ +QScriptValue::QScriptValue(QScriptEngine *engine, qsreal val) + : d_ptr(new QScriptValuePrivate) +{ + d_ptr->engine = QScriptEnginePrivate::get(engine); + if (engine) { + JSC::ExecState *exec = d_ptr->engine->currentFrame; + d_ptr->initFrom(JSC::jsNumber(exec, val)); + } else { + JSC::JSValue immediate = JSC::JSImmediate::from(val); + if (immediate) + d_ptr->initFrom(immediate); + else + d_ptr->initFrom(val); + } + d_ptr->ref.ref(); +} + +/*! + \fn QScriptValue::QScriptValue(QScriptEngine *engine, const QString &value) + \obsolete + + Constructs a new QScriptValue with the string \a value and + registers it with the script \a engine. +*/ +QScriptValue::QScriptValue(QScriptEngine *engine, const QString &val) + : d_ptr(new QScriptValuePrivate) +{ + d_ptr->engine = QScriptEnginePrivate::get(engine); + if (engine) { + JSC::ExecState *exec = d_ptr->engine->currentFrame; + d_ptr->initFrom(JSC::jsString(exec, val)); + } else { + d_ptr->initFrom(val); + } + d_ptr->ref.ref(); +} + +/*! + \fn QScriptValue::QScriptValue(QScriptEngine *engine, const char *value) + \obsolete + + Constructs a new QScriptValue with the string \a value and + registers it with the script \a engine. +*/ + +#ifndef QT_NO_CAST_FROM_ASCII +QScriptValue::QScriptValue(QScriptEngine *engine, const char *val) + : d_ptr(new QScriptValuePrivate) +{ + d_ptr->engine = QScriptEnginePrivate::get(engine); + if (engine) { + JSC::ExecState *exec = d_ptr->engine->currentFrame; + d_ptr->initFrom(JSC::jsString(exec, val)); + } else { + d_ptr->initFrom(QString::fromAscii(val)); + } + d_ptr->ref.ref(); +} +#endif + +/*! + \since 4.5 + + Constructs a new QScriptValue with a special \a value. +*/ +QScriptValue::QScriptValue(SpecialValue value) + : d_ptr(new QScriptValuePrivate) +{ + d_ptr->engine = 0; + switch (value) { + case NullValue: + d_ptr->initFrom(JSC::jsNull()); + break; + case UndefinedValue: + d_ptr->initFrom(JSC::jsUndefined()); + break; + } + d_ptr->ref.ref(); +} + +/*! + \since 4.5 + + Constructs a new QScriptValue with a boolean \a value. +*/ +QScriptValue::QScriptValue(bool value) + : d_ptr(new QScriptValuePrivate) +{ + d_ptr->engine = 0; + d_ptr->initFrom(JSC::jsBoolean(value)); + d_ptr->ref.ref(); +} + +/*! + \since 4.5 + + Constructs a new QScriptValue with a number \a value. +*/ +QScriptValue::QScriptValue(int value) + : d_ptr(new QScriptValuePrivate) +{ + d_ptr->engine = 0; + JSC::JSValue immediate = JSC::JSImmediate::from(value); + if (immediate) + d_ptr->initFrom(immediate); + else + d_ptr->initFrom(value); + d_ptr->ref.ref(); +} + +/*! + \since 4.5 + + Constructs a new QScriptValue with a number \a value. +*/ +QScriptValue::QScriptValue(uint value) + : d_ptr(new QScriptValuePrivate) +{ + d_ptr->engine = 0; + JSC::JSValue immediate = JSC::JSImmediate::from(value); + if (immediate) + d_ptr->initFrom(immediate); + else + d_ptr->initFrom(value); + d_ptr->ref.ref(); +} + +/*! + \since 4.5 + + Constructs a new QScriptValue with a number \a value. +*/ +QScriptValue::QScriptValue(qsreal value) + : d_ptr(new QScriptValuePrivate) +{ + d_ptr->engine = 0; + JSC::JSValue immediate = JSC::JSImmediate::from(value); + if (immediate) + d_ptr->initFrom(immediate); + else + d_ptr->initFrom(value); + d_ptr->ref.ref(); +} + +/*! + \since 4.5 + + Constructs a new QScriptValue with a string \a value. +*/ +QScriptValue::QScriptValue(const QString &value) + : d_ptr(new QScriptValuePrivate) +{ + d_ptr->engine = 0; + d_ptr->initFrom(value); + d_ptr->ref.ref(); +} + +/*! + \since 4.5 + + Constructs a new QScriptValue with a string \a value. +*/ +QScriptValue::QScriptValue(const QLatin1String &value) + : d_ptr(new QScriptValuePrivate) +{ + d_ptr->engine = 0; + d_ptr->initFrom(value); + d_ptr->ref.ref(); +} + +/*! + \since 4.5 + + Constructs a new QScriptValue with a string \a value. +*/ + +#ifndef QT_NO_CAST_FROM_ASCII +QScriptValue::QScriptValue(const char *value) + : d_ptr(new QScriptValuePrivate) +{ + d_ptr->engine = 0; + d_ptr->initFrom(QString::fromAscii(value)); + d_ptr->ref.ref(); +} +#endif + +/*! + Assigns the \a other value to this QScriptValue. + + Note that if \a other is an object (isObject() returns true), + only a reference to the underlying object will be assigned; + the object itself will not be copied. +*/ +QScriptValue &QScriptValue::operator=(const QScriptValue &other) +{ + if (d_ptr == other.d_ptr) + return *this; + if (d_ptr && !d_ptr->ref.deref()) { + if (d_ptr->engine) + d_ptr->engine->unregisterScriptValue(d_ptr); + delete d_ptr; + } + d_ptr = other.d_ptr; + if (d_ptr) + d_ptr->ref.ref(); + return *this; +} + +/*! + Returns true if this QScriptValue is an object of the Error class; + otherwise returns false. + + \sa QScriptContext::throwError() +*/ +bool QScriptValue::isError() const +{ + Q_D(const QScriptValue); + if (!d || !d->isJSC() || !d->jscValue.isObject()) + return false; + return d->jscValue.isObject(&JSC::ErrorInstance::info); +} + +/*! + Returns true if this QScriptValue is an object of the Array class; + otherwise returns false. + + \sa QScriptEngine::newArray() +*/ +bool QScriptValue::isArray() const +{ + Q_D(const QScriptValue); + if (!d || !d->isJSC() || !d->jscValue.isObject()) + return false; + return d->jscValue.isObject(&JSC::JSArray::info); +} + +/*! + Returns true if this QScriptValue is an object of the Date class; + otherwise returns false. + + \sa QScriptEngine::newDate() +*/ +bool QScriptValue::isDate() const +{ + Q_D(const QScriptValue); + if (!d || !d->isJSC() || !d->jscValue.isObject()) + return false; + return d->jscValue.isObject(&JSC::DateInstance::info); +} + +/*! + Returns true if this QScriptValue is an object of the RegExp class; + otherwise returns false. + + \sa QScriptEngine::newRegExp() +*/ +bool QScriptValue::isRegExp() const +{ + Q_D(const QScriptValue); + if (!d || !d->isJSC() || !d->jscValue.isObject()) + return false; + return d->jscValue.isObject(&JSC::RegExpObject::info); +} + +/*! + If this QScriptValue is an object, returns the internal prototype + (\c{__proto__} property) of this object; otherwise returns an + invalid QScriptValue. + + \sa setPrototype(), isObject() +*/ +QScriptValue QScriptValue::prototype() const +{ + Q_D(const QScriptValue); + if (!d || !d->isJSC() || !d->jscValue.isObject()) + return QScriptValue(); + return d->engine->scriptValueFromJSCValue(JSC::asObject(d->jscValue)->prototype()); +} + +/*! + If this QScriptValue is an object, sets the internal prototype + (\c{__proto__} property) of this object to be \a prototype; + otherwise does nothing. + + The internal prototype should not be confused with the public + property with name "prototype"; the public prototype is usually + only set on functions that act as constructors. + + \sa prototype(), isObject() +*/ +void QScriptValue::setPrototype(const QScriptValue &prototype) +{ + Q_D(QScriptValue); + if (!d || !d->isJSC() || !d->jscValue.isObject()) + return; + if (prototype.isValid() && prototype.engine() + && (prototype.engine() != engine())) { + qWarning("QScriptValue::setPrototype() failed: " + "cannot set a prototype created in " + "a different engine"); + return; + } + JSC::JSValue other = d->engine->scriptValueToJSCValue(prototype); + + // check for cycle + JSC::JSValue nextPrototypeValue = other; + while (nextPrototypeValue && nextPrototypeValue.isObject()) { + JSC::JSObject *nextPrototype = JSC::asObject(nextPrototypeValue); + if (nextPrototype == JSC::asObject(d->jscValue)) { + qWarning("QScriptValue::setPrototype() failed: cyclic prototype value"); + return; + } + nextPrototypeValue = nextPrototype->prototype(); + } + JSC::asObject(d->jscValue)->setPrototype(other); +} + +/*! + \internal +*/ +QScriptValue QScriptValue::scope() const +{ + Q_D(const QScriptValue); + if (!d || !d->isJSC() || !d->jscValue.isObject()) + return QScriptValue(); + // ### make hidden property + return d->property(QLatin1String("__qt_scope__"), QScriptValue::ResolveLocal); +} + +/*! + \internal +*/ +void QScriptValue::setScope(const QScriptValue &scope) +{ + Q_D(QScriptValue); + if (!d || !d->isJSC() || !d->jscValue.isObject()) + return; + if (scope.isValid() && scope.engine() + && (scope.engine() != engine())) { + qWarning("QScriptValue::setScope() failed: " + "cannot set a scope object created in " + "a different engine"); + return; + } + JSC::JSValue other = d->engine->scriptValueToJSCValue(scope); + JSC::ExecState *exec = d->engine->currentFrame; + JSC::Identifier id = JSC::Identifier(exec, "__qt_scope__"); + if (!scope.isValid()) { + JSC::asObject(d->jscValue)->removeDirect(id); + } else { + // ### make hidden property + JSC::asObject(d->jscValue)->putDirect(id, other); + } +} + +/*! + Returns true if this QScriptValue is an instance of + \a other; otherwise returns false. + + This QScriptValue is considered to be an instance of \a other if + \a other is a function and the value of the \c{prototype} + property of \a other is in the prototype chain of this + QScriptValue. +*/ +bool QScriptValue::instanceOf(const QScriptValue &other) const +{ + Q_D(const QScriptValue); + if (!d || !d->isJSC() || !d->jscValue.isObject() || !other.isObject()) + return false; + if (other.engine() != engine()) { + qWarning("QScriptValue::instanceof: " + "cannot perform operation on a value created in " + "a different engine"); + return false; + } + JSC::JSValue jscProto = d->engine->scriptValueToJSCValue(other.property(QLatin1String("prototype"))); + if (!jscProto) + jscProto = JSC::jsUndefined(); + JSC::ExecState *exec = d->engine->currentFrame; + JSC::JSValue jscOther = d->engine->scriptValueToJSCValue(other); + return JSC::asObject(jscOther)->hasInstance(exec, d->jscValue, jscProto); +} + +// ### move + +namespace QScript +{ + +enum Type { + Undefined, + Null, + Boolean, + String, + Number, + Object +}; + +static Type type(const QScriptValue &v) +{ + if (v.isUndefined()) + return Undefined; + else if (v.isNull()) + return Null; + else if (v.isBoolean()) + return Boolean; + else if (v.isString()) + return String; + else if (v.isNumber()) + return Number; + Q_ASSERT(v.isObject()); + return Object; +} + +QScriptValue ToPrimitive(const QScriptValue &object, JSC::PreferredPrimitiveType hint = JSC::NoPreference) +{ + Q_ASSERT(object.isObject()); + QScriptValuePrivate *pp = QScriptValuePrivate::get(object); + Q_ASSERT(pp->engine != 0); + JSC::ExecState *exec = pp->engine->currentFrame; + JSC::JSValue savedException; + QScriptValuePrivate::saveException(exec, &savedException); + JSC::JSValue result = JSC::asObject(pp->jscValue)->toPrimitive(exec, hint); + QScriptValuePrivate::restoreException(exec, savedException); + return pp->engine->scriptValueFromJSCValue(result); +} + +static bool IsNumerical(const QScriptValue &value) +{ + return value.isNumber() || value.isBool(); +} + +static bool LessThan(QScriptValue lhs, QScriptValue rhs) +{ + if (type(lhs) == type(rhs)) { + switch (type(lhs)) { + case Undefined: + case Null: + return false; + + case Number: +#if defined Q_CC_MSVC && !defined Q_CC_MSVC_NET + if (qIsNaN(lhs.toNumber()) || qIsNaN(rhs.toNumber())) + return false; +#endif + return lhs.toNumber() < rhs.toNumber(); + + case Boolean: + return lhs.toBool() < rhs.toBool(); + + case String: + return lhs.toString() < rhs.toString(); + + case Object: + break; + } // switch + } + + if (lhs.isObject()) + lhs = ToPrimitive(lhs, JSC::PreferNumber); + + if (rhs.isObject()) + rhs = ToPrimitive(rhs, JSC::PreferNumber); + + if (lhs.isString() && rhs.isString()) + return lhs.toString() < rhs.toString(); + + qsreal n1 = lhs.toNumber(); + qsreal n2 = rhs.toNumber(); +#if defined Q_CC_MSVC && !defined Q_CC_MSVC_NET + if (qIsNaN(n1) || qIsNaN(n2)) + return false; +#endif + return n1 < n2; +} + +static bool Equals(QScriptValue lhs, QScriptValue rhs) +{ + if (type(lhs) == type(rhs)) { + switch (type(lhs)) { + case QScript::Undefined: + case QScript::Null: + return true; + + case QScript::Number: + return lhs.toNumber() == rhs.toNumber(); + + case QScript::Boolean: + return lhs.toBool() == rhs.toBool(); + + case QScript::String: + return lhs.toString() == rhs.toString(); + + case QScript::Object: + if (lhs.isVariant()) + return lhs.strictlyEquals(rhs) || (lhs.toVariant() == rhs.toVariant()); +#ifndef QT_NO_QOBJECT + else if (lhs.isQObject()) + return (lhs.strictlyEquals(rhs)) || (lhs.toQObject() == rhs.toQObject()); +#endif + else + return lhs.strictlyEquals(rhs); + } + } + + if (lhs.isNull() && rhs.isUndefined()) + return true; + + else if (lhs.isUndefined() && rhs.isNull()) + return true; + + else if (IsNumerical(lhs) && rhs.isString()) + return lhs.toNumber() == rhs.toNumber(); + + else if (lhs.isString() && IsNumerical(rhs)) + return lhs.toNumber() == rhs.toNumber(); + + else if (lhs.isBool()) + return Equals(lhs.toNumber(), rhs); + + else if (rhs.isBool()) + return Equals(lhs, rhs.toNumber()); + + else if (lhs.isObject() && !rhs.isNull()) { + lhs = ToPrimitive(lhs); + + if (lhs.isValid() && !lhs.isObject()) + return Equals(lhs, rhs); + } + + else if (rhs.isObject() && ! lhs.isNull()) { + rhs = ToPrimitive(rhs); + if (rhs.isValid() && !rhs.isObject()) + return Equals(lhs, rhs); + } + + return false; +} + +} // namespace QScript + +/*! + Returns true if this QScriptValue is less than \a other, otherwise + returns false. The comparison follows the behavior described in + \l{ECMA-262} section 11.8.5, "The Abstract Relational Comparison + Algorithm". + + Note that if this QScriptValue or the \a other value are objects, + calling this function has side effects on the script engine, since + the engine will call the object's valueOf() function (and possibly + toString()) in an attempt to convert the object to a primitive value + (possibly resulting in an uncaught script exception). + + \sa equals() +*/ +bool QScriptValue::lessThan(const QScriptValue &other) const +{ + // 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())) { + qWarning("QScriptValue::lessThan: " + "cannot compare to a value created in " + "a different engine"); + return false; + } + return QScript::LessThan(*this, other); +} + +/*! + Returns true if this QScriptValue is equal to \a other, otherwise + returns false. The comparison follows the behavior described in + \l{ECMA-262} section 11.9.3, "The Abstract Equality Comparison + Algorithm". + + This function can return true even if the type of this QScriptValue + is different from the type of the \a other value; i.e. the + comparison is not strict. For example, comparing the number 9 to + the string "9" returns true; comparing an undefined value to a null + value returns true; comparing a \c{Number} object whose primitive + value is 6 to a \c{String} object whose primitive value is "6" + returns true; and comparing the number 1 to the boolean value + \c{true} returns true. If you want to perform a comparison + without such implicit value conversion, use strictlyEquals(). + + Note that if this QScriptValue or the \a other value are objects, + calling this function has side effects on the script engine, since + the engine will call the object's valueOf() function (and possibly + toString()) in an attempt to convert the object to a primitive value + (possibly resulting in an uncaught script exception). + + \sa strictlyEquals(), lessThan() +*/ +bool QScriptValue::equals(const QScriptValue &other) const +{ + Q_D(const QScriptValue); + if (!d || !other.d_ptr) + return (d == other.d_ptr); + if (other.engine() && engine() && (other.engine() != engine())) { + qWarning("QScriptValue::equals: " + "cannot compare to a value created in " + "a different engine"); + return false; + } + if (d->isJSC() && other.d_ptr->isJSC()) { + QScriptEnginePrivate *eng_p = d->engine; + if (!eng_p) + eng_p = other.d_ptr->engine; + if (eng_p) { + JSC::ExecState *exec = eng_p->currentFrame; + JSC::JSValue savedException; + QScriptValuePrivate::saveException(exec, &savedException); + bool result = JSC::JSValue::equal(exec, d->jscValue, other.d_ptr->jscValue); + QScriptValuePrivate::restoreException(exec, savedException); + // special QtScript rules + if (!result && isQObject() && other.isQObject()) + result = (toQObject() == other.toQObject()); + else if (!result && isVariant() && other.isVariant()) + result = (toVariant() == other.toVariant()); + return result; + } + } + return QScript::Equals(*this, other); +} + +/*! + Returns true if this QScriptValue is equal to \a other using strict + comparison (no conversion), otherwise returns false. The comparison + follows the behavior described in \l{ECMA-262} section 11.9.6, "The + Strict Equality Comparison Algorithm". + + If the type of this QScriptValue is different from the type of the + \a other value, this function returns false. If the types are equal, + the result depends on the type, as shown in the following table: + + \table + \header \o Type \o Result + \row \o Undefined \o true + \row \o Null \o true + \row \o Boolean \o true if both values are true, false otherwise + \row \o Number \o false if either value is NaN (Not-a-Number); true if values are equal, false otherwise + \row \o String \o true if both values are exactly the same sequence of characters, false otherwise + \row \o Object \o true if both values refer to the same object, false otherwise + \endtable + + \sa equals() +*/ +bool QScriptValue::strictlyEquals(const QScriptValue &other) const +{ + Q_D(const QScriptValue); + if (!d || !other.d_ptr) + return (d == other.d_ptr); + if (other.engine() && engine() && (other.engine() != engine())) { + qWarning("QScriptValue::strictlyEquals: " + "cannot compare to a value created in " + "a different engine"); + return false; + } + if (d->type != other.d_ptr->type) + return false; + switch (d->type) { + case QScriptValuePrivate::JSC: + return JSC::JSValue::strictEqual(d->jscValue, other.d_ptr->jscValue); + case QScriptValuePrivate::Number: + return (d->numberValue == other.d_ptr->numberValue); + case QScriptValuePrivate::String: + return (d->stringValue == other.d_ptr->stringValue); + } + return false; +} + +/*! + Returns the string value of this QScriptValue, as defined in + \l{ECMA-262} section 9.8, "ToString". + + Note that if this QScriptValue is an object, calling this function + has side effects on the script engine, since the engine will call + the object's toString() function (and possibly valueOf()) in an + attempt to convert the object to a primitive value (possibly + resulting in an uncaught script exception). + + \sa isString() +*/ +QString QScriptValue::toString() const +{ + Q_D(const QScriptValue); + if (!d) + return QString(); + switch (d->type) { + case QScriptValuePrivate::JSC: { + JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; + JSC::JSValue savedException; + QScriptValuePrivate::saveException(exec, &savedException); + JSC::UString str = d->jscValue.toString(exec); + if (exec && exec->hadException() && !str.size()) { + JSC::JSValue savedException2; + QScriptValuePrivate::saveException(exec, &savedException2); + str = savedException2.toString(exec); + QScriptValuePrivate::restoreException(exec, savedException2); + } + if (savedException) + QScriptValuePrivate::restoreException(exec, savedException); + return str; + } + case QScriptValuePrivate::Number: + return JSC::UString::from(d->numberValue); + case QScriptValuePrivate::String: + return d->stringValue; + } + return QString(); +} + +/*! + Returns the number value of this QScriptValue, as defined in + \l{ECMA-262} section 9.3, "ToNumber". + + Note that if this QScriptValue is an object, calling this function + has side effects on the script engine, since the engine will call + the object's valueOf() function (and possibly toString()) in an + attempt to convert the object to a primitive value (possibly + resulting in an uncaught script exception). + + \sa isNumber(), toInteger(), toInt32(), toUInt32(), toUInt16() +*/ +qsreal QScriptValue::toNumber() const +{ + Q_D(const QScriptValue); + if (!d) + return 0; + switch (d->type) { + case QScriptValuePrivate::JSC: { + JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; + JSC::JSValue savedException; + QScriptValuePrivate::saveException(exec, &savedException); + qsreal result = d->jscValue.toNumber(exec); + QScriptValuePrivate::restoreException(exec, savedException); + return result; + } + case QScriptValuePrivate::Number: + return d->numberValue; + case QScriptValuePrivate::String: + return ((JSC::UString)d->stringValue).toDouble(); + } + return 0; +} + +/*! + \obsolete + + Use toBool() instead. +*/ +bool QScriptValue::toBoolean() const +{ + Q_D(const QScriptValue); + if (!d) + return false; + switch (d->type) { + case QScriptValuePrivate::JSC: { + JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; + JSC::JSValue savedException; + QScriptValuePrivate::saveException(exec, &savedException); + bool result = d->jscValue.toBoolean(exec); + QScriptValuePrivate::restoreException(exec, savedException); + return result; + } + case QScriptValuePrivate::Number: + return (d->numberValue != 0) && !qIsNaN(d->numberValue); + case QScriptValuePrivate::String: + return (!d->stringValue.isEmpty()); + } + return false; +} + +/*! + \since 4.5 + + Returns the boolean value of this QScriptValue, using the conversion + rules described in \l{ECMA-262} section 9.2, "ToBoolean". + + Note that if this QScriptValue is an object, calling this function + has side effects on the script engine, since the engine will call + the object's valueOf() function (and possibly toString()) in an + attempt to convert the object to a primitive value (possibly + resulting in an uncaught script exception). + + \sa isBool() +*/ +bool QScriptValue::toBool() const +{ + Q_D(const QScriptValue); + if (!d) + return false; + switch (d->type) { + case QScriptValuePrivate::JSC: { + JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; + JSC::JSValue savedException; + QScriptValuePrivate::saveException(exec, &savedException); + bool result = d->jscValue.toBoolean(exec); + QScriptValuePrivate::restoreException(exec, savedException); + return result; + } + case QScriptValuePrivate::Number: + return (d->numberValue != 0) && !qIsNaN(d->numberValue); + case QScriptValuePrivate::String: + return (!d->stringValue.isEmpty()); + } + return false; +} + +/*! + Returns the signed 32-bit integer value of this QScriptValue, using + the conversion rules described in \l{ECMA-262} section 9.5, "ToInt32". + + Note that if this QScriptValue is an object, calling this function + has side effects on the script engine, since the engine will call + the object's valueOf() function (and possibly toString()) in an + attempt to convert the object to a primitive value (possibly + resulting in an uncaught script exception). + + \sa toNumber(), toUInt32() +*/ +qint32 QScriptValue::toInt32() const +{ + Q_D(const QScriptValue); + if (!d) + return 0; + switch (d->type) { + case QScriptValuePrivate::JSC: { + JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; + JSC::JSValue savedException; + QScriptValuePrivate::saveException(exec, &savedException); + qint32 result = d->jscValue.toInt32(exec); + QScriptValuePrivate::restoreException(exec, savedException); + return result; + } + case QScriptValuePrivate::Number: + return QScript::ToInt32(d->numberValue); + case QScriptValuePrivate::String: + return QScript::ToInt32(((JSC::UString)d->stringValue).toDouble()); + } + return 0; +} + +/*! + Returns the unsigned 32-bit integer value of this QScriptValue, using + the conversion rules described in \l{ECMA-262} section 9.6, "ToUint32". + + Note that if this QScriptValue is an object, calling this function + has side effects on the script engine, since the engine will call + the object's valueOf() function (and possibly toString()) in an + attempt to convert the object to a primitive value (possibly + resulting in an uncaught script exception). + + \sa toNumber(), toInt32() +*/ +quint32 QScriptValue::toUInt32() const +{ + Q_D(const QScriptValue); + if (!d) + return 0; + switch (d->type) { + case QScriptValuePrivate::JSC: { + JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; + JSC::JSValue savedException; + QScriptValuePrivate::saveException(exec, &savedException); + quint32 result = d->jscValue.toUInt32(exec); + QScriptValuePrivate::restoreException(exec, savedException); + return result; + } + case QScriptValuePrivate::Number: + return QScript::ToUint32(d->numberValue); + case QScriptValuePrivate::String: + return QScript::ToUint32(((JSC::UString)d->stringValue).toDouble()); + } + return 0; +} + +/*! + Returns the unsigned 16-bit integer value of this QScriptValue, using + the conversion rules described in \l{ECMA-262} section 9.7, "ToUint16". + + Note that if this QScriptValue is an object, calling this function + has side effects on the script engine, since the engine will call + the object's valueOf() function (and possibly toString()) in an + attempt to convert the object to a primitive value (possibly + resulting in an uncaught script exception). + + \sa toNumber() +*/ +quint16 QScriptValue::toUInt16() const +{ + Q_D(const QScriptValue); + if (!d) + return 0; + switch (d->type) { + case QScriptValuePrivate::JSC: { + // ### no equivalent function in JSC + return QScript::ToUint16(toNumber()); + } + case QScriptValuePrivate::Number: + return QScript::ToUint16(d->numberValue); + case QScriptValuePrivate::String: + return QScript::ToUint16(((JSC::UString)d->stringValue).toDouble()); + } + return 0; +} + +/*! + Returns the integer value of this QScriptValue, using the conversion + rules described in \l{ECMA-262} section 9.4, "ToInteger". + + Note that if this QScriptValue is an object, calling this function + has side effects on the script engine, since the engine will call + the object's valueOf() function (and possibly toString()) in an + attempt to convert the object to a primitive value (possibly + resulting in an uncaught script exception). + + \sa toNumber() +*/ +qsreal QScriptValue::toInteger() const +{ + Q_D(const QScriptValue); + if (!d) + return 0; + switch (d->type) { + case QScriptValuePrivate::JSC: { + JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; + JSC::JSValue savedException; + QScriptValuePrivate::saveException(exec, &savedException); + qsreal result = d->jscValue.toInteger(exec); + QScriptValuePrivate::restoreException(exec, savedException); + return result; + } + case QScriptValuePrivate::Number: + return QScript::ToInteger(d->numberValue); + case QScriptValuePrivate::String: + return QScript::ToInteger(((JSC::UString)d->stringValue).toDouble()); + } + return 0; +} + +/*! + Returns the QVariant value of this QScriptValue, if it can be + converted to a QVariant; otherwise returns an invalid QVariant. + The conversion is performed according to the following table: + + \table + \header \o Input Type \o Result + \row \o Undefined \o An invalid QVariant. + \row \o Null \o An invalid QVariant. + \row \o Boolean \o A QVariant containing the value of the boolean. + \row \o Number \o A QVariant containing the value of the number. + \row \o String \o A QVariant containing the value of the string. + \row \o QVariant Object \o The result is the QVariant value of the object (no conversion). + \row \o QObject Object \o A QVariant containing a pointer to the QObject. + \row \o Date Object \o A QVariant containing the date value (toDateTime()). + \row \o RegExp Object \o A QVariant containing the regular expression value (toRegExp()). + \row \o Array Object \o The array is converted to a QVariantList. + \row \o Object \o If the value is primitive, then the result is converted to a QVariant according to the above rules; otherwise, an invalid QVariant is returned. + \endtable + + \sa isVariant() +*/ +QVariant QScriptValue::toVariant() const +{ + Q_D(const QScriptValue); + if (!d) + return QVariant(); + switch (d->type) { + case QScriptValuePrivate::JSC: + 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); + // try to convert to primitive + JSC::ExecState *exec = d->engine->currentFrame; + JSC::JSValue savedException; + QScriptValuePrivate::saveException(exec, &savedException); + JSC::JSValue prim = d->jscValue.toPrimitive(exec); + QScriptValuePrivate::restoreException(exec, savedException); + if (!prim.isObject()) + return d->engine->scriptValueFromJSCValue(prim).toVariant(); + } else if (isNumber()) { + return QVariant(toNumber()); + } else if (isString()) { + return QVariant(toString()); + } else if (isBool()) { + return QVariant(toBool()); + } + return QVariant(); + case QScriptValuePrivate::Number: + return QVariant(d->numberValue); + case QScriptValuePrivate::String: + return QVariant(d->stringValue); + } + return QVariant(); +} + +/*! + \obsolete + + This function is obsolete; use QScriptEngine::toObject() instead. +*/ +QScriptValue QScriptValue::toObject() const +{ + Q_D(const QScriptValue); + if (!d || !d->engine) + return QScriptValue(); + return engine()->toObject(*this); +} + +/*! + Returns a QDateTime representation of this value, in local time. + If this QScriptValue is not a date, or the value of the date is NaN + (Not-a-Number), an invalid QDateTime is returned. + + \sa isDate() +*/ +QDateTime QScriptValue::toDateTime() const +{ + Q_D(const QScriptValue); + if (!isDate()) + return QDateTime(); + qsreal t = static_cast<JSC::DateInstance*>(JSC::asObject(d->jscValue))->internalNumber(); + return QScript::ToDateTime(t, Qt::LocalTime); +} + +#ifndef QT_NO_REGEXP +/*! + Returns the QRegExp representation of this value. + If this QScriptValue is not a regular expression, an empty + QRegExp is returned. + + \sa isRegExp() +*/ +QRegExp QScriptValue::toRegExp() const +{ + Q_D(const QScriptValue); + if (!isRegExp()) + return QRegExp(); + QString pattern = d->property(QLatin1String("source"), QScriptValue::ResolvePrototype).toString(); + Qt::CaseSensitivity kase = Qt::CaseSensitive; + if (d->property(QLatin1String("ignoreCase"), QScriptValue::ResolvePrototype).toBool()) + kase = Qt::CaseInsensitive; + return QRegExp(pattern, kase, QRegExp::RegExp2); +} +#endif // QT_NO_REGEXP + +/*! + If this QScriptValue is a QObject, returns the QObject pointer + that the QScriptValue represents; otherwise, returns 0. + + If the QObject that this QScriptValue wraps has been deleted, + this function returns 0 (i.e. it is possible for toQObject() + to return 0 even when isQObject() returns true). + + \sa isQObject() +*/ +QObject *QScriptValue::toQObject() const +{ + Q_D(const QScriptValue); + if (isQObject()) { + QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(d->jscValue)); + return static_cast<QScript::QObjectDelegate*>(object->delegate())->value(); + } else if (isVariant()) { + QVariant var = toVariant(); + int type = var.userType(); + if ((type == QMetaType::QObjectStar) || (type == QMetaType::QWidgetStar)) + return *reinterpret_cast<QObject* const *>(var.constData()); + } + return 0; +} + +/*! + If this QScriptValue is a QMetaObject, returns the QMetaObject pointer + that the QScriptValue represents; otherwise, returns 0. + + \sa isQMetaObject() +*/ +const QMetaObject *QScriptValue::toQMetaObject() const +{ + Q_D(const QScriptValue); + if (isQMetaObject()) + return static_cast<QScript::QMetaObjectWrapperObject*>(JSC::asObject(d->jscValue))->value(); + return 0; +} + +/*! + Sets the value of this QScriptValue's property with the given \a name to + the given \a value. + + If this QScriptValue is not an object, this function does nothing. + + If this QScriptValue does not already have a property with name \a name, + a new property is created; the given \a flags then specify how this + property may be accessed by script code. + + If \a value is invalid, the property is removed. + + If the property is implemented using a setter function (i.e. has the + PropertySetter flag set), calling setProperty() has side-effects on + the script engine, since the setter function will be called with the + given \a value as argument (possibly resulting in an uncaught script + exception). + + Note that you cannot specify custom getter or setter functions for + built-in properties, such as the \c{length} property of Array objects + or meta properties of QObject objects. + + \sa property() +*/ + +void QScriptValue::setProperty(const QString &name, const QScriptValue &value, + const PropertyFlags &flags) +{ + Q_D(QScriptValue); + if (!d || !d->isJSC() || !d->jscValue.isObject()) + return; + setProperty(engine()->toStringHandle(name), value, flags); +} + +/*! + Returns the value of this QScriptValue's property with the given \a name, + using the given \a mode to resolve the property. + + If no such property exists, an invalid QScriptValue is returned. + + If the property is implemented using a getter function (i.e. has the + PropertyGetter flag set), calling property() has side-effects on the + script engine, since the getter function will be called (possibly + resulting in an uncaught script exception). If an exception + occurred, property() returns the value that was thrown (typically + an \c{Error} object). + + \sa setProperty(), propertyFlags(), QScriptValueIterator +*/ +QScriptValue QScriptValue::property(const QString &name, + const ResolveFlags &mode) const +{ + Q_D(const QScriptValue); + if (!d || !d->isJSC() || !d->jscValue.isObject()) + return QScriptValue(); + return d->property(name, mode); +} + +/*! + \overload + + Returns the property at the given \a arrayIndex, using the given \a + mode to resolve the property. + + This function is provided for convenience and performance when + working with array objects. + + If this QScriptValue is not an Array object, this function behaves + as if property() was called with the string representation of \a + arrayIndex. +*/ +QScriptValue QScriptValue::property(quint32 arrayIndex, + const ResolveFlags &mode) const +{ + Q_D(const QScriptValue); + if (!d || !d->isJSC() || !d->jscValue.isObject()) + return QScriptValue(); + return d->property(arrayIndex, mode); +} + +/*! + \overload + + Sets the property at the given \a arrayIndex to the given \a value. + + This function is provided for convenience and performance when + working with array objects. + + If this QScriptValue is not an Array object, this function behaves + as if setProperty() was called with the string representation of \a + arrayIndex. +*/ +void QScriptValue::setProperty(quint32 arrayIndex, const QScriptValue &value, + const PropertyFlags &flags) +{ + Q_D(const QScriptValue); + if (!d || !d->isJSC() || !d->jscValue.isObject()) + return; + if (value.engine() && (value.engine() != engine())) { + qWarning("QScriptValue::setProperty() failed: " + "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)) { + Q_ASSERT_X(false, Q_FUNC_INFO, "property getters and setters not implemented"); + } 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); + } + } + } +} + +/*! + \since 4.4 + + Returns the value of this QScriptValue's property with the given \a name, + using the given \a mode to resolve the property. + + This overload of property() is useful when you need to look up the + same property repeatedly, since the lookup can be performed faster + when the name is represented as an interned string. + + \sa QScriptEngine::toStringHandle(), setProperty() +*/ +QScriptValue QScriptValue::property(const QScriptString &name, + const ResolveFlags &mode) const +{ + Q_D(const QScriptValue); + if (!d || !d->isJSC() || !d->jscValue.isObject() || !name.isValid()) + return QScriptValue(); + return d->property(name.d_ptr->identifier, mode); +} + +/*! + \since 4.4 + + Sets the value of this QScriptValue's property with the given \a + name to the given \a value. The given \a flags specify how this + property may be accessed by script code. + + This overload of setProperty() is useful when you need to set the + same property repeatedly, since the operation can be performed + faster when the name is represented as an interned string. + + \sa QScriptEngine::toStringHandle() +*/ +void QScriptValue::setProperty(const QScriptString &name, + const QScriptValue &value, + const PropertyFlags &flags) +{ + Q_D(QScriptValue); + if (!d || !d->isJSC() || !d->jscValue.isObject() || !name.isValid()) + return; + QScriptEngine *valueEngine = value.engine(); + if (valueEngine && (QScriptEnginePrivate::get(valueEngine) != d->engine)) { + qWarning("QScriptValue::setProperty(%s) failed: " + "cannot set value created in a different engine", + qPrintable(name.toString())); + return; + } + JSC::ExecState *exec = d->engine->currentFrame; + JSC::JSValue jscValue = d->engine->scriptValueToJSCValue(value); + JSC::Identifier id = name.d_ptr->identifier; + JSC::JSObject *thisObject = JSC::asObject(d->jscValue); + JSC::JSValue setter = thisObject->lookupSetter(exec, id); + JSC::JSValue getter = thisObject->lookupGetter(exec, id); + if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) { + if (!jscValue) { + // 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 (jscValue.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(jscValue)); + if (flags & QScriptValue::PropertySetter) + thisObject->defineSetter(exec, id, JSC::asObject(jscValue)); + } + } 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(name.toString())); + return; + } + if (!jscValue) { + // ### 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, jscValue, attribs); + } else { + JSC::PutPropertySlot slot; + thisObject->put(exec, id, jscValue, slot); + } + } +} + +/*! + Returns the flags of the property with the given \a name, using the + given \a mode to resolve the property. + + \sa property() +*/ +QScriptValue::PropertyFlags QScriptValue::propertyFlags(const QString &name, + const ResolveFlags &mode) const +{ + if (!isObject()) + return 0; + return propertyFlags(engine()->toStringHandle(name), mode); + +} + +/*! + \since 4.4 + + Returns the flags of the property with the given \a name, using the + given \a mode to resolve the property. + + \sa property() +*/ +QScriptValue::PropertyFlags QScriptValue::propertyFlags(const QScriptString &name, + const ResolveFlags &mode) const +{ + Q_D(const QScriptValue); + if (!isObject()) + return 0; + JSC::ExecState *exec = d->engine->currentFrame; + JSC::JSObject *object = JSC::asObject(d->jscValue); + JSC::Identifier id = name.d_ptr->identifier; + unsigned attribs = 0; + if (!object->getPropertyAttributes(exec, id, attribs)) { + if ((mode & QScriptValue::ResolvePrototype) && object->prototype()) + return d->engine->scriptValueFromJSCValue(object->prototype()).propertyFlags(name, 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; +} + +/*! + Calls this QScriptValue as a function, using \a thisObject as + the `this' object in the function call, and passing \a args + as arguments to the function. Returns the value returned from + the function. + + If this QScriptValue is not a function, call() does nothing + and returns an invalid QScriptValue. + + Note that if \a thisObject is not an object, the global object + (see \l{QScriptEngine::globalObject()}) will be used as the + `this' object. + + Calling call() can cause an exception to occur in the script engine; + in that case, call() returns the value that was thrown (typically an + \c{Error} object). You can call + QScriptEngine::hasUncaughtException() to determine if an exception + occurred. + + \snippet doc/src/snippets/code/src_script_qscriptvalue.cpp 2 + + \sa construct() +*/ +QScriptValue QScriptValue::call(const QScriptValue &thisObject, + const QScriptValueList &args) +{ + Q_D(const QScriptValue); + if (!isFunction()) + return QScriptValue(); + + if (thisObject.engine() && (thisObject.engine() != engine())) { + qWarning("QScriptValue::call() failed: " + "cannot call function with thisObject created in " + "a different engine"); + return QScriptValue(); + } + engine()->currentContext()->activationObject(); //force the creation of a context for native function; + + JSC::ExecState *exec = d->engine->currentFrame; + + JSC::JSValue jscThisObject = d->engine->scriptValueToJSCValue(thisObject); + if (!jscThisObject || !jscThisObject.isObject()) + jscThisObject = d->engine->globalObject(); + + QVector<JSC::JSValue> argsVector; + argsVector.resize(args.size()); + for (int i = 0; i < args.size(); ++i) { + const QScriptValue &arg = args.at(i); + if (!arg.isValid()) { + argsVector[i] = JSC::jsUndefined(); + } else if (arg.engine() && (arg.engine() != engine())) { + qWarning("QScriptValue::call() failed: " + "cannot call function with argument created in " + "a different engine"); + return QScriptValue(); + } else { + argsVector[i] = d->engine->scriptValueToJSCValue(arg); + } + } + JSC::ArgList jscArgs(argsVector.data(), argsVector.size()); + + JSC::JSValue callee = d->jscValue; + JSC::CallData callData; + JSC::CallType callType = callee.getCallData(callData); + JSC::JSValue savedException; + QScriptValuePrivate::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); + } + return d->engine->scriptValueFromJSCValue(result); +} + +/*! + Calls this QScriptValue as a function, using \a thisObject as + the `this' object in the function call, and passing \a arguments + as arguments to the function. Returns the value returned from + the function. + + If this QScriptValue is not a function, call() does nothing + and returns an invalid QScriptValue. + + \a arguments can be an arguments object, an array, null or + undefined; any other type will cause a TypeError to be thrown. + + Note that if \a thisObject is not an object, the global object + (see \l{QScriptEngine::globalObject()}) will be used as the + `this' object. + + One common usage of this function is to forward native function + calls to another function: + + \snippet doc/src/snippets/code/src_script_qscriptvalue.cpp 3 + + \sa construct(), QScriptContext::argumentsObject() +*/ +QScriptValue QScriptValue::call(const QScriptValue &thisObject, + const QScriptValue &arguments) +{ + Q_D(QScriptValue); + if (!isFunction()) + return QScriptValue(); + + if (thisObject.engine() && (thisObject.engine() != engine())) { + qWarning("QScriptValue::call() failed: " + "cannot call function with thisObject created in " + "a different engine"); + return QScriptValue(); + } + engine()->currentContext()->activationObject(); //force the creation of a context for native function; + + JSC::ExecState *exec = d->engine->currentFrame; + + JSC::JSValue jscThisObject = d->engine->scriptValueToJSCValue(thisObject); + if (!jscThisObject || !jscThisObject.isObject()) + jscThisObject = d->engine->globalObject(); + + JSC::JSValue array = d->engine->scriptValueToJSCValue(arguments); + // copied from runtime/FunctionPrototype.cpp, functionProtoFuncApply() + JSC::MarkedArgumentBuffer applyArgs; + if (!array.isUndefinedOrNull()) { + if (!array.isObject()) { + return d->engine->scriptValueFromJSCValue(JSC::throwError(exec, JSC::TypeError)); + } + if (JSC::asObject(array)->classInfo() == &JSC::Arguments::info) + JSC::asArguments(array)->fillArgList(exec, applyArgs); + else if (JSC::isJSArray(&exec->globalData(), array)) + JSC::asArray(array)->fillArgList(exec, applyArgs); + else if (JSC::asObject(array)->inherits(&JSC::JSArray::info)) { + unsigned length = JSC::asArray(array)->get(exec, exec->propertyNames().length).toUInt32(exec); + for (unsigned i = 0; i < length; ++i) + applyArgs.append(JSC::asArray(array)->get(exec, i)); + } else { + Q_ASSERT_X(false, Q_FUNC_INFO, "implement me"); +// return JSC::throwError(exec, JSC::TypeError); + } + } + + JSC::JSValue callee = d->jscValue; + JSC::CallData callData; + JSC::CallType callType = callee.getCallData(callData); + JSC::JSValue savedException; + QScriptValuePrivate::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); + } + return d->engine->scriptValueFromJSCValue(result); +} + +/*! + Creates a new \c{Object} and calls this QScriptValue as a + constructor, using the created object as the `this' object and + passing \a args as arguments. If the return value from the + constructor call is an object, then that object is returned; + otherwise the default constructed object is returned. + + If this QScriptValue is not a function, construct() does nothing + and returns an invalid QScriptValue. + + Calling construct() can cause an exception to occur in the script + engine; in that case, construct() returns the value that was thrown + (typically an \c{Error} object). You can call + QScriptEngine::hasUncaughtException() to determine if an exception + occurred. + + \sa call(), QScriptEngine::newObject() +*/ +QScriptValue QScriptValue::construct(const QScriptValueList &args) +{ + Q_D(const QScriptValue); + if (!isFunction()) + return QScriptValue(); + engine()->currentContext()->activationObject(); //force the creation of a context for native function; + JSC::ExecState *exec = d->engine->currentFrame; + + QVector<JSC::JSValue> argsVector; + argsVector.resize(args.size()); + for (int i = 0; i < args.size(); ++i) { + if (!args.at(i).isValid()) + argsVector[i] = JSC::jsUndefined(); + else + argsVector[i] = d->engine->scriptValueToJSCValue(args.at(i)); + } + + JSC::ArgList jscArgs(argsVector.data(), argsVector.size()); + + JSC::JSValue callee = d->jscValue; + JSC::ConstructData constructData; + JSC::ConstructType constructType = callee.getConstructData(constructData); + JSC::JSValue savedException; + QScriptValuePrivate::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); + } + return d->engine->scriptValueFromJSCValue(result); +} + +/*! + Creates a new \c{Object} and calls this QScriptValue as a + constructor, using the created object as the `this' object and + passing \a arguments as arguments. If the return value from the + constructor call is an object, then that object is returned; + otherwise the default constructed object is returned. + + If this QScriptValue is not a function, construct() does nothing + and returns an invalid QScriptValue. + + \a arguments can be an arguments object, an array, null or + undefined. Any other type will cause a TypeError to be thrown. + + \sa call(), QScriptEngine::newObject(), QScriptContext::argumentsObject() +*/ +QScriptValue QScriptValue::construct(const QScriptValue &arguments) +{ + Q_D(QScriptValue); + if (!isFunction()) + return QScriptValue(); + engine()->currentContext()->activationObject(); //force the creation of a context for native function; + JSC::ExecState *exec = d->engine->currentFrame; + + JSC::JSValue array = d->engine->scriptValueToJSCValue(arguments); + // copied from runtime/FunctionPrototype.cpp, functionProtoFuncApply() + JSC::MarkedArgumentBuffer applyArgs; + if (!array.isUndefinedOrNull()) { + if (!array.isObject()) { + return d->engine->scriptValueFromJSCValue(JSC::throwError(exec, JSC::TypeError, "Arguments must be an array")); + } + if (JSC::asObject(array)->classInfo() == &JSC::Arguments::info) + JSC::asArguments(array)->fillArgList(exec, applyArgs); + else if (JSC::isJSArray(&exec->globalData(), array)) + JSC::asArray(array)->fillArgList(exec, applyArgs); + else if (JSC::asObject(array)->inherits(&JSC::JSArray::info)) { + unsigned length = JSC::asArray(array)->get(exec, exec->propertyNames().length).toUInt32(exec); + for (unsigned i = 0; i < length; ++i) + applyArgs.append(JSC::asArray(array)->get(exec, i)); + } else { + return d->engine->scriptValueFromJSCValue(JSC::throwError(exec, JSC::TypeError, "Arguments must be an array")); + } + } + + JSC::JSValue callee = d->jscValue; + JSC::ConstructData constructData; + JSC::ConstructType constructType = callee.getConstructData(constructData); + JSC::JSValue savedException; + QScriptValuePrivate::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); + } + return d->engine->scriptValueFromJSCValue(result); +} + +/*! + Returns the QScriptEngine that created this QScriptValue, + or 0 if this QScriptValue is invalid or the value is not + associated with a particular engine. +*/ +QScriptEngine *QScriptValue::engine() const +{ + Q_D(const QScriptValue); + if (!d) + return 0; + return QScriptEnginePrivate::get(d->engine); +} + +/*! + \obsolete + + Use isBool() instead. +*/ +bool QScriptValue::isBoolean() const +{ + Q_D(const QScriptValue); + return d && d->isJSC() && d->jscValue.isBoolean(); +} + +/*! + \since 4.5 + + Returns true if this QScriptValue is of the primitive type Boolean; + otherwise returns false. + + \sa toBool() +*/ +bool QScriptValue::isBool() const +{ + Q_D(const QScriptValue); + return d && d->isJSC() && d->jscValue.isBoolean(); +} + +/*! + Returns true if this QScriptValue is of the primitive type Number; + otherwise returns false. + + \sa toNumber() +*/ +bool QScriptValue::isNumber() const +{ + Q_D(const QScriptValue); + if (!d) + return false; + switch (d->type) { + case QScriptValuePrivate::JSC: + return d->jscValue.isNumber(); + case QScriptValuePrivate::Number: + return true; + case QScriptValuePrivate::String: + return false; + } + return false; +} + +/*! + Returns true if this QScriptValue is of the primitive type String; + otherwise returns false. + + \sa toString() +*/ +bool QScriptValue::isString() const +{ + Q_D(const QScriptValue); + if (!d) + return false; + switch (d->type) { + case QScriptValuePrivate::JSC: + return d->jscValue.isString(); + case QScriptValuePrivate::Number: + return false; + case QScriptValuePrivate::String: + return true; + } + return false; +} + +/*! + Returns true if this QScriptValue is a function; otherwise returns + false. + + \sa call() +*/ +bool QScriptValue::isFunction() const +{ + Q_D(const QScriptValue); + if (!d || !d->isJSC()) + return false; + return QScript::isFunction(d->jscValue); +} + +/*! + Returns true if this QScriptValue is of the primitive type Null; + otherwise returns false. + + \sa QScriptEngine::nullValue() +*/ +bool QScriptValue::isNull() const +{ + Q_D(const QScriptValue); + return d && d->isJSC() && d->jscValue.isNull(); +} + +/*! + Returns true if this QScriptValue is of the primitive type Undefined; + otherwise returns false. + + \sa QScriptEngine::undefinedValue() +*/ +bool QScriptValue::isUndefined() const +{ + Q_D(const QScriptValue); + return d && d->isJSC() && d->jscValue.isUndefined(); +} + +/*! + Returns true if this QScriptValue is of the Object type; otherwise + returns false. + + Note that function values, variant values, and QObject values are + objects, so this function returns true for such values. + + \sa toObject(), QScriptEngine::newObject() +*/ +bool QScriptValue::isObject() const +{ + Q_D(const QScriptValue); + return d && d->isJSC() && d->jscValue.isObject(); +} + +/*! + Returns true if this QScriptValue is a variant value; + otherwise returns false. + + \sa toVariant(), QScriptEngine::newVariant() +*/ +bool QScriptValue::isVariant() const +{ + Q_D(const QScriptValue); + if (!d || !d->isJSC() || !d->jscValue.isObject(&QScriptObject::info)) + return false; + QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(d->jscValue)); + QScriptObjectDelegate *delegate = object->delegate(); + return (delegate && (delegate->type() == QScriptObjectDelegate::Variant)); +} + +/*! + Returns true if this QScriptValue is a QObject; otherwise returns + false. + + Note: This function returns true even if the QObject that this + QScriptValue wraps has been deleted. + + \sa toQObject(), QScriptEngine::newQObject() +*/ +bool QScriptValue::isQObject() const +{ + Q_D(const QScriptValue); + if (!d || !d->isJSC() || !d->jscValue.isObject(&QScriptObject::info)) + return false; + QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(d->jscValue)); + QScriptObjectDelegate *delegate = object->delegate(); + return (delegate && (delegate->type() == QScriptObjectDelegate::QtObject)); +} + +/*! + Returns true if this QScriptValue is a QMetaObject; otherwise returns + false. + + \sa toQMetaObject(), QScriptEngine::newQMetaObject() +*/ +bool QScriptValue::isQMetaObject() const +{ + Q_D(const QScriptValue); + if (!d || !d->isJSC() || !d->jscValue.isObject()) + return false; + return JSC::asObject(d->jscValue)->isObject(&QScript::QMetaObjectWrapperObject::info); + return false; +} + +/*! + Returns true if this QScriptValue is valid; otherwise returns + false. +*/ +bool QScriptValue::isValid() const +{ + Q_D(const QScriptValue); + return d && (!d->isJSC() || !!d->jscValue); +} + +/*! + \since 4.4 + + Returns the internal data of this QScriptValue object. QtScript uses + this property to store the primitive value of Date, String, Number + and Boolean objects. For other types of object, custom data may be + stored using setData(). +*/ +QScriptValue QScriptValue::data() const +{ + Q_D(const QScriptValue); + if (!d || !d->isJSC() || !d->jscValue.isObject()) + return QScriptValue(); + if (d->jscValue.isObject(&QScriptObject::info)) { + QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(d->jscValue)); + return d->engine->scriptValueFromJSCValue(scriptObject->data()); + } else { + // ### make hidden property + return d->property(QLatin1String("__qt_data__"), QScriptValue::ResolveLocal); + } +} + +/*! + \since 4.4 + + Sets the internal \a data of this QScriptValue object. You can use + this function to set object-specific data that won't be directly + accessible to scripts, but may be retrieved in C++ using the data() + function. +*/ +void QScriptValue::setData(const QScriptValue &data) +{ + Q_D(QScriptValue); + if (!d || !d->isJSC() || !d->jscValue.isObject()) + return; + JSC::JSValue other = d->engine->scriptValueToJSCValue(data); + if (d->jscValue.isObject(&QScriptObject::info)) { + QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(d->jscValue)); + scriptObject->setData(other); + } else { + JSC::ExecState *exec = d->engine->currentFrame; + JSC::Identifier id = JSC::Identifier(exec, "__qt_data__"); + if (!data.isValid()) { + JSC::asObject(d->jscValue)->removeDirect(id); + } else { + // ### make hidden property + JSC::asObject(d->jscValue)->putDirect(id, other); + } + } +} + +/*! + \since 4.4 + + Returns the custom script class that this script object is an + instance of, or 0 if the object is not of a custom class. + + \sa setScriptClass() +*/ +QScriptClass *QScriptValue::scriptClass() const +{ + Q_D(const QScriptValue); + if (!d || !d->isJSC() || !d->jscValue.isObject(&QScriptObject::info)) + return 0; + QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(d->jscValue)); + QScriptObjectDelegate *delegate = scriptObject->delegate(); + if (!delegate || (delegate->type() != QScriptObjectDelegate::ClassObject)) + return 0; + return static_cast<QScript::ClassObjectDelegate*>(delegate)->scriptClass(); +} + +/*! + \since 4.4 + + Sets the custom script class of this script object to \a scriptClass. + This can be used to "promote" a plain script object (e.g. created + by the "new" operator in a script, or by QScriptEngine::newObject() in C++) + to an object of a custom type. + + If \a scriptClass is 0, the object will be demoted to a plain + script object. + + \sa scriptClass(), setData() +*/ +void QScriptValue::setScriptClass(QScriptClass *scriptClass) +{ + Q_D(QScriptValue); + if (!d || !d->isJSC() || !d->jscValue.isObject(&QScriptObject::info)) + return; + QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(d->jscValue)); + QScriptObjectDelegate *delegate = scriptObject->delegate(); + if (!delegate || (delegate->type() != QScriptObjectDelegate::ClassObject)) { + delete delegate; + delegate = new QScript::ClassObjectDelegate(scriptClass); + scriptObject->setDelegate(delegate); + } + static_cast<QScript::ClassObjectDelegate*>(delegate)->setScriptClass(scriptClass); +} + +/*! + \internal + + Returns the ID of this object, or -1 if this QScriptValue is not an + object. + + \sa QScriptEngine::objectById() +*/ +qint64 QScriptValue::objectId() const +{ + return d_ptr?d_ptr->objectId():-1; +} +QT_END_NAMESPACE diff --git a/src/script/qscriptvalue.h b/src/script/api/qscriptvalue.h index 5a5cf8b..be59508 100644 --- a/src/script/qscriptvalue.h +++ b/src/script/api/qscriptvalue.h @@ -44,8 +44,6 @@ #include <QtCore/qstring.h> -#ifndef QT_NO_SCRIPT - #include <QtCore/qlist.h> QT_BEGIN_HEADER @@ -233,6 +231,4 @@ QT_END_NAMESPACE QT_END_HEADER -#endif // QT_NO_SCRIPT - #endif diff --git a/src/script/qscriptvaluefwd_p.h b/src/script/api/qscriptvalue_p.h index 216f87e..e05259e 100644 --- a/src/script/qscriptvaluefwd_p.h +++ b/src/script/api/qscriptvalue_p.h @@ -34,21 +34,13 @@ ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. +** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ -#ifndef QSCRIPTVALUEFWD_P_H -#define QSCRIPTVALUEFWD_P_H - -#include <QtCore/qatomic.h> - -#ifndef QT_NO_SCRIPT - -#include "qscriptvalueimplfwd_p.h" - -QT_BEGIN_NAMESPACE +#ifndef QSCRIPTVALUE_P_H +#define QSCRIPTVALUE_P_H // // W A R N I N G @@ -61,29 +53,83 @@ QT_BEGIN_NAMESPACE // We mean it. // -class QScriptValuePrivate -{ -public: - inline QScriptValuePrivate(); - inline ~QScriptValuePrivate(); +#include <QtCore/qobjectdefs.h> - static inline QScriptValuePrivate *create(); - - static inline QScriptValuePrivate *get(const QScriptValue &value); +QT_BEGIN_NAMESPACE - static inline QScriptValueImpl valueOf(const QScriptValue &value); +#include "wtf/Platform.h" +#include "JSValue.h" - static inline void init(QScriptValue &value, QScriptValuePrivate *p); +class QString; +class QScriptEnginePrivate; - inline void invalidate(); +class QScriptValue; +class QScriptValuePrivate +{ + Q_DISABLE_COPY(QScriptValuePrivate); +public: + enum Type { + JSC, + Number, + String + }; + + QScriptValuePrivate(); + ~QScriptValuePrivate(); + + void initFrom(JSC::JSValue value); + void initFrom(double value); + void initFrom(const QString &value); + + bool isJSC() const; + + QVariant &variantValue() const; + void setVariantValue(const QVariant &value); + + static QScriptValuePrivate *get(const QScriptValue &q) + { + return q.d_ptr; + } + + static QScriptValue toPublic(QScriptValuePrivate *d) + { + QScriptValue tmp; + tmp.d_ptr = d; + d->ref.ref(); + return tmp; + } + + QScriptValue property(const JSC::Identifier &id, int resolveMode) const; + QScriptValue property(quint32 index, int resolveMode) const; + QScriptValue property(const QString &, int resolveMode) const; + + void detachFromEngine(); + + qint64 objectId() + { + if ( (type == JSC) && (engine) ) + return (qint64)jscValue.asCell(); + else + return -1; + } + + static void saveException(JSC::ExecState*, JSC::JSValue*); + static void restoreException(JSC::ExecState*, JSC::JSValue); + + QScriptEnginePrivate *engine; + Type type; + JSC::JSValue jscValue; + double numberValue; + QString stringValue; + + // linked list of engine's script values + QScriptValuePrivate *prev; + QScriptValuePrivate *next; - QScriptEngine *engine; - QScriptValueImpl value; QBasicAtomicInt ref; }; -QT_END_NAMESPACE -#endif // QT_NO_SCRIPT +QT_END_NAMESPACE #endif diff --git a/src/script/qscriptvalueiterator.cpp b/src/script/api/qscriptvalueiterator.cpp index 885f9c9..195a23b 100644 --- a/src/script/qscriptvalueiterator.cpp +++ b/src/script/api/qscriptvalueiterator.cpp @@ -39,17 +39,20 @@ ** ****************************************************************************/ +#include "config.h" #include "qscriptvalueiterator.h" -#ifndef QT_NO_SCRIPT - -#include "qscriptvalueiterator_p.h" -#include "qscriptvalueiteratorimpl_p.h" +#include "qscriptstring.h" +#include "qscriptengine.h" #include "qscriptengine_p.h" -#include "qscriptcontext_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" +#include "qscriptvalue_p.h" +#include "qlinkedlist.h" + + +#include "JSObject.h" +#include "PropertyNameArray.h" +#include "JSArray.h" +#include "JSFunction.h" QT_BEGIN_NAMESPACE @@ -93,21 +96,36 @@ QT_BEGIN_NAMESPACE \sa QScriptValue::property() */ -/*! - \internal -*/ -QScriptValueIteratorPrivate::QScriptValueIteratorPrivate() - : q_ptr(0), it(0) +class QScriptValueIteratorPrivate { -} +public: + QScriptValueIteratorPrivate() + : initialized(false) + {} + void ensureInitialized() + { + if (initialized) + return; + QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(object.engine()); + JSC::ExecState *exec = eng_p->globalExec(); + JSC::PropertyNameArray propertyNamesArray(exec); + propertyNamesArray.setShouldCache(false); + JSC::asObject(QScriptValuePrivate::get(object)->jscValue)->getPropertyNames(exec, propertyNamesArray, JSC::Structure::NonEnumerable); + + JSC::PropertyNameArray::const_iterator propertyNamesIt = propertyNamesArray.begin(); + for(; propertyNamesIt != propertyNamesArray.end(); ++propertyNamesIt) { + propertyNames.append(propertyNamesIt->ustring()); + } + it = propertyNames.begin(); + initialized = true; + } -/*! - \internal -*/ -QScriptValueIteratorPrivate::~QScriptValueIteratorPrivate() -{ - delete it; -} + QScriptValue object; + QLinkedList<JSC::UString> propertyNames; + QLinkedList<JSC::UString>::iterator it; + QLinkedList<JSC::UString>::iterator current; + bool initialized; +}; /*! Constructs an iterator for traversing \a object. The iterator is @@ -116,12 +134,11 @@ QScriptValueIteratorPrivate::~QScriptValueIteratorPrivate() */ QScriptValueIterator::QScriptValueIterator(const QScriptValue &object) { - QScriptValueImpl val = QScriptValuePrivate::valueOf(object); - if (!val.isObject()) { + if (!object.isObject()) { d_ptr = 0; } else { d_ptr = new QScriptValueIteratorPrivate(); - d_ptr->it = new QScriptValueIteratorImpl(val); + d_ptr->object = object; } } @@ -146,7 +163,11 @@ QScriptValueIterator::~QScriptValueIterator() bool QScriptValueIterator::hasNext() const { Q_D(const QScriptValueIterator); - return (d && d->it->hasNext()); + if (!d) + return false; + + const_cast<QScriptValueIteratorPrivate*>(d)->ensureInitialized(); + return d->it != d->propertyNames.end(); } /*! @@ -160,8 +181,12 @@ bool QScriptValueIterator::hasNext() const void QScriptValueIterator::next() { Q_D(QScriptValueIterator); - if (d) - d->it->next(); + if (!d) + return; + d->ensureInitialized(); + + d->current = d->it; + ++(d->it); } /*! @@ -174,7 +199,11 @@ void QScriptValueIterator::next() bool QScriptValueIterator::hasPrevious() const { Q_D(const QScriptValueIterator); - return (d && d->it->hasPrevious()); + if (!d) + return false; + + const_cast<QScriptValueIteratorPrivate*>(d)->ensureInitialized(); + return d->it != d->propertyNames.begin(); } /*! @@ -188,8 +217,11 @@ bool QScriptValueIterator::hasPrevious() const void QScriptValueIterator::previous() { Q_D(QScriptValueIterator); - if (d) - d->it->previous(); + if (!d) + return; + d->ensureInitialized(); + --(d->it); + d->current = d->it; } /*! @@ -201,8 +233,10 @@ void QScriptValueIterator::previous() void QScriptValueIterator::toFront() { Q_D(QScriptValueIterator); - if (d) - d->it->toFront(); + if (!d) + return; + d->ensureInitialized(); + d->it = d->propertyNames.begin(); } /*! @@ -214,8 +248,10 @@ void QScriptValueIterator::toFront() void QScriptValueIterator::toBack() { Q_D(QScriptValueIterator); - if (d) - d->it->toBack(); + if (!d) + return; + d->ensureInitialized(); + d->it = d->propertyNames.end(); } /*! @@ -227,9 +263,9 @@ void QScriptValueIterator::toBack() QString QScriptValueIterator::name() const { Q_D(const QScriptValueIterator); - if (!d) + if (!d || !d->initialized) return QString(); - return d->it->name(); + return *d->current; } /*! @@ -241,10 +277,9 @@ QString QScriptValueIterator::name() const QScriptString QScriptValueIterator::scriptName() const { Q_D(const QScriptValueIterator); - if (!d) + if (!d || !d->initialized) return QScriptString(); - QScriptEnginePrivate *eng = d->it->object().engine(); - return eng->internedString(d->it->nameId()); + return d->object.engine()->toStringHandle(name()); } /*! @@ -256,10 +291,9 @@ QScriptString QScriptValueIterator::scriptName() const QScriptValue QScriptValueIterator::value() const { Q_D(const QScriptValueIterator); - if (!d) + if (!d || !d->initialized) return QScriptValue(); - QScriptEnginePrivate *eng = d->it->object().engine(); - return eng->toPublic(d->it->value()); + return d->object.property(name()); } /*! @@ -270,11 +304,10 @@ QScriptValue QScriptValueIterator::value() const */ void QScriptValueIterator::setValue(const QScriptValue &value) { - Q_D(const QScriptValueIterator); - if (d) { - QScriptEnginePrivate *eng = d->it->object().engine(); - d->it->setValue(eng->toImpl(value)); - } + Q_D(QScriptValueIterator); + if (!d || !d->initialized) + return; + d->object.setProperty(name(), value); } /*! @@ -286,9 +319,9 @@ void QScriptValueIterator::setValue(const QScriptValue &value) QScriptValue::PropertyFlags QScriptValueIterator::flags() const { Q_D(const QScriptValueIterator); - if (!d) + if (!d || !d->initialized) return 0; - return QScriptValue::PropertyFlags(d->it->flags() & ~QScript::Member::InternalRange); + return d->object.propertyFlags(name()); } /*! @@ -299,9 +332,11 @@ QScriptValue::PropertyFlags QScriptValueIterator::flags() const */ void QScriptValueIterator::remove() { - Q_D(const QScriptValueIterator); - if (d) - d->it->remove(); + Q_D(QScriptValueIterator); + if (!d || !d->initialized) + return; + d->object.setProperty(name(), QScriptValue()); + d->propertyNames.erase(d->current); } /*! @@ -315,14 +350,11 @@ QScriptValueIterator& QScriptValueIterator::operator=(QScriptValue &object) delete d_ptr; d_ptr = 0; } - QScriptValueImpl val = QScriptValuePrivate::valueOf(object); - if (val.isObject()) { + if (object.isObject()) { d_ptr = new QScriptValueIteratorPrivate(); - d_ptr->it = new QScriptValueIteratorImpl(val); + d_ptr->object = object; } return *this; } QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptvalueiterator.h b/src/script/api/qscriptvalueiterator.h index 6aaf4cd..ce79fe0 100644 --- a/src/script/qscriptvalueiterator.h +++ b/src/script/api/qscriptvalueiterator.h @@ -44,8 +44,6 @@ #include <QtScript/qscriptvalue.h> -#ifndef QT_NO_SCRIPT - QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -94,6 +92,4 @@ QT_END_NAMESPACE QT_END_HEADER -#endif // QT_NO_SCRIPT - #endif // QSCRIPTVALUEITERATOR_H diff --git a/src/script/bridge/bridge.pri b/src/script/bridge/bridge.pri new file mode 100644 index 0000000..666a07e --- /dev/null +++ b/src/script/bridge/bridge.pri @@ -0,0 +1,17 @@ +SOURCES += \ + $$PWD/qscriptfunction.cpp \ + $$PWD/qscriptobject.cpp \ + $$PWD/qscriptclassobject.cpp \ + $$PWD/qscriptvariant.cpp \ + $$PWD/qscriptqobject.cpp \ + $$PWD/qscriptglobalobject.cpp \ + $$PWD/qscriptactivationobject.cpp + +HEADERS += \ + $$PWD/qscriptfunction_p.h \ + $$PWD/qscriptobject_p.h \ + $$PWD/qscriptclassobject_p.h \ + $$PWD/qscriptvariant_p.h \ + $$PWD/qscriptqobject_p.h \ + $$PWD/qscriptglobalobject_p.h \ + $$PWD/qscriptactivationobject_p.h diff --git a/src/script/bridge/qscriptactivationobject.cpp b/src/script/bridge/qscriptactivationobject.cpp new file mode 100644 index 0000000..a8a2181 --- /dev/null +++ b/src/script/bridge/qscriptactivationobject.cpp @@ -0,0 +1,172 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "config.h" +#include "qscriptactivationobject_p.h" + +#include "JSVariableObject.h" + +namespace JSC +{ + ASSERT_CLASS_FITS_IN_CELL(QScript::QScriptActivationObject); +} + +QT_BEGIN_NAMESPACE + +/*! +\class QScriptActivationObject +\internal + + Represent a scope for native function call. +*/ + +namespace QScript +{ + +const JSC::ClassInfo QScriptActivationObject::info = { "QScriptActivationObject", 0, 0, 0 }; + +QScriptActivationObject::QScriptActivationObject(JSC::ExecState *callFrame, JSC::JSObject *delegate) + : JSC::JSVariableObject(callFrame->globalData().activationStructure, + new QScriptActivationObjectData(callFrame->registers(), delegate)) +{ +} + +QScriptActivationObject::~QScriptActivationObject() +{ + delete d; +} + +bool QScriptActivationObject::getOwnPropertySlot(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::PropertySlot& slot) +{ + if (d_ptr()->delegate != 0) + return d_ptr()->delegate->getOwnPropertySlot(exec, propertyName, slot); + return JSC::JSVariableObject::getOwnPropertySlot(exec, propertyName, slot); +} + +bool QScriptActivationObject::getPropertyAttributes(JSC::ExecState* exec, const JSC::Identifier& propertyName, unsigned& attributes) const +{ + if (d_ptr()->delegate != 0) + return d_ptr()->delegate->getPropertyAttributes(exec, propertyName, attributes); + return JSC::JSVariableObject::getPropertyAttributes(exec, propertyName, attributes); +} + +void QScriptActivationObject::getPropertyNames(JSC::ExecState* exec, JSC::PropertyNameArray& propertyNames, unsigned listedAttributes) +{ + if (d_ptr()->delegate != 0) { + d_ptr()->delegate->getPropertyNames(exec, propertyNames, listedAttributes); + return; + } + return JSC::JSVariableObject::getPropertyNames(exec, propertyNames, listedAttributes); +} + +void QScriptActivationObject::putWithAttributes(JSC::ExecState *exec, const JSC::Identifier &propertyName, JSC::JSValue value, unsigned attributes) +{ + if (d_ptr()->delegate != 0) { + d_ptr()->delegate->putWithAttributes(exec, propertyName, value, attributes); + return; + } + + if (symbolTablePutWithAttributes(propertyName, value, attributes)) + return; + + JSC::PutPropertySlot slot; + JSObject::putWithAttributes(exec, propertyName, value, attributes, true, slot); +} + +void QScriptActivationObject::put(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSValue value, JSC::PutPropertySlot& slot) +{ + if (d_ptr()->delegate != 0) { + d_ptr()->delegate->put(exec, propertyName, value, slot); + return; + } + JSC::JSVariableObject::put(exec, propertyName, value, slot); +} + +void QScriptActivationObject::put(JSC::ExecState* exec, unsigned propertyName, JSC::JSValue value) +{ + if (d_ptr()->delegate != 0) { + d_ptr()->delegate->put(exec, propertyName, value); + return; + } + JSC::JSVariableObject::put(exec, propertyName, value); +} + +bool QScriptActivationObject::deleteProperty(JSC::ExecState* exec, const JSC::Identifier& propertyName, bool checkDontDelete) +{ + if (d_ptr()->delegate != 0) + return d_ptr()->delegate->deleteProperty(exec, propertyName, checkDontDelete); + return JSC::JSVariableObject::deleteProperty(exec, propertyName, checkDontDelete); +} + +void QScriptActivationObject::defineGetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction) +{ + if (d_ptr()->delegate != 0) + d_ptr()->delegate->defineGetter(exec, propertyName, getterFunction); + else + JSC::JSVariableObject::defineGetter(exec, propertyName, getterFunction); +} + +void QScriptActivationObject::defineSetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction) +{ + if (d_ptr()->delegate != 0) + d_ptr()->delegate->defineSetter(exec, propertyName, setterFunction); + else + JSC::JSVariableObject::defineSetter(exec, propertyName, setterFunction); +} + +JSC::JSValue QScriptActivationObject::lookupGetter(JSC::ExecState* exec, const JSC::Identifier& propertyName) +{ + if (d_ptr()->delegate != 0) + return d_ptr()->delegate->lookupGetter(exec, propertyName); + return JSC::JSVariableObject::lookupGetter(exec, propertyName); +} + +JSC::JSValue QScriptActivationObject::lookupSetter(JSC::ExecState* exec, const JSC::Identifier& propertyName) +{ + if (d_ptr()->delegate != 0) + return d_ptr()->delegate->lookupSetter(exec, propertyName); + return JSC::JSVariableObject::lookupSetter(exec, propertyName); +} + +} // namespace QScript + +QT_END_NAMESPACE + diff --git a/src/script/bridge/qscriptactivationobject_p.h b/src/script/bridge/qscriptactivationobject_p.h new file mode 100644 index 0000000..cb28341 --- /dev/null +++ b/src/script/bridge/qscriptactivationobject_p.h @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTACTIVATIONOBJECT_P_H +#define QSCRIPTACTIVATIONOBJECT_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> + +#include "JSVariableObject.h" + +QT_BEGIN_NAMESPACE + +namespace QScript +{ + +class QScriptActivationObject : public JSC::JSVariableObject { +public: + QScriptActivationObject(JSC::ExecState *callFrame, JSC::JSObject *delegate = 0); + virtual ~QScriptActivationObject(); + virtual bool isDynamicScope() const { return true; } + + virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&); + virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier&, unsigned&) const; + virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, unsigned listedAttributes = JSC::Structure::Prototype); + + virtual void putWithAttributes(JSC::ExecState *exec, const JSC::Identifier &propertyName, JSC::JSValue value, unsigned attributes); + virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue value, JSC::PutPropertySlot&); + virtual void put(JSC::ExecState*, unsigned propertyName, JSC::JSValue value); + + virtual bool deleteProperty(JSC::ExecState*, const JSC::Identifier& propertyName, bool checkDontDelete = true); + + virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction); + virtual void defineSetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction); + virtual JSC::JSValue lookupGetter(JSC::ExecState*, const JSC::Identifier& propertyName); + virtual JSC::JSValue lookupSetter(JSC::ExecState*, const JSC::Identifier& propertyName); + + virtual const JSC::ClassInfo* classInfo() const { return &info; } + static const JSC::ClassInfo info; + + struct QScriptActivationObjectData : public JSVariableObjectData { + QScriptActivationObjectData(JSC::Register* registers, JSC::JSObject *dlg) + : JSVariableObjectData(&symbolTable, registers), + delegate(dlg) + { } + JSC::SymbolTable symbolTable; + JSC::JSObject *delegate; + }; + + JSC::JSObject *delegate() const + { return d_ptr()->delegate; } + void setDelegate(JSC::JSObject *delegate) + { d_ptr()->delegate = delegate; } + + QScriptActivationObjectData *d_ptr() const { return static_cast<QScriptActivationObjectData *>(d); } +}; + +} // namespace QScript + +QT_END_NAMESPACE + +#endif diff --git a/src/script/bridge/qscriptclassobject.cpp b/src/script/bridge/qscriptclassobject.cpp new file mode 100644 index 0000000..f6c6792 --- /dev/null +++ b/src/script/bridge/qscriptclassobject.cpp @@ -0,0 +1,273 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "config.h" +#include "qscriptclassobject_p.h" + +#include "../api/qscriptengine.h" +#include "../api/qscriptengine_p.h" +#include "../api/qscriptcontext.h" +#include "../api/qscriptcontext_p.h" +#include "../api/qscriptclass.h" +#include "../api/qscriptclasspropertyiterator.h" + +#include "Error.h" +#include "PropertyNameArray.h" + +Q_DECLARE_METATYPE(QScriptContext*) +Q_DECLARE_METATYPE(QScriptValue) +Q_DECLARE_METATYPE(QScriptValueList) + +QT_BEGIN_NAMESPACE + +namespace QScript +{ + +ClassObjectDelegate::ClassObjectDelegate(QScriptClass *scriptClass) + : m_scriptClass(scriptClass) +{ +} + +ClassObjectDelegate::~ClassObjectDelegate() +{ +} + +QScriptClass *ClassObjectDelegate::scriptClass() const +{ + return m_scriptClass; +} + +void ClassObjectDelegate::setScriptClass(QScriptClass *scriptClass) +{ + m_scriptClass = scriptClass; +} + +QScriptObjectDelegate::Type ClassObjectDelegate::type() const +{ + return ClassObject; +} + +bool ClassObjectDelegate::getOwnPropertySlot(QScriptObject* object, + JSC::ExecState *exec, + const JSC::Identifier &propertyName, + JSC::PropertySlot &slot) +{ + // for compatibility with the old back-end, normal JS properties + // are queried first. + if (QScriptObjectDelegate::getOwnPropertySlot(object, exec, propertyName, slot)) + return true; + + QScriptEnginePrivate *engine = scriptEngineFromExec(exec); + QScriptValue scriptObject = engine->scriptValueFromJSCValue(object); + QString name(propertyName.ustring()); + QScriptString scriptName = QScriptEnginePrivate::get(engine)->toStringHandle(name); + uint id = 0; + QScriptClass::QueryFlags flags = m_scriptClass->queryProperty( + scriptObject, scriptName, QScriptClass::HandlesReadAccess, &id); + if (flags & QScriptClass::HandlesReadAccess) { + QScriptValue value = m_scriptClass->property(scriptObject, scriptName, id); + slot.setValue(engine->scriptValueToJSCValue(value)); + return true; + } + return false; +} + +void ClassObjectDelegate::put(QScriptObject* object, JSC::ExecState *exec, + const JSC::Identifier &propertyName, + JSC::JSValue value, JSC::PutPropertySlot &slot) +{ + QScriptEnginePrivate *engine = scriptEngineFromExec(exec); + QScriptValue scriptObject = engine->scriptValueFromJSCValue(object); + QString name(propertyName.ustring()); + QScriptString scriptName = QScriptEnginePrivate::get(engine)->toStringHandle(name); + uint id = 0; + QScriptClass::QueryFlags flags = m_scriptClass->queryProperty( + scriptObject, scriptName, QScriptClass::HandlesWriteAccess, &id); + if (flags & QScriptClass::HandlesWriteAccess) { + m_scriptClass->setProperty(scriptObject, scriptName, id, engine->scriptValueFromJSCValue(value)); + return; + } + QScriptObjectDelegate::put(object, exec, propertyName, value, slot); +} + +bool ClassObjectDelegate::deleteProperty(QScriptObject* object, JSC::ExecState *exec, + const JSC::Identifier &propertyName, + bool checkDontDelete) +{ + // ### avoid duplication of put() + QScriptEnginePrivate *engine = scriptEngineFromExec(exec); + QScriptValue scriptObject = engine->scriptValueFromJSCValue(object); + QString name(propertyName.ustring()); + QScriptString scriptName = QScriptEnginePrivate::get(engine)->toStringHandle(name); + uint id = 0; + QScriptClass::QueryFlags flags = m_scriptClass->queryProperty( + scriptObject, scriptName, QScriptClass::HandlesWriteAccess, &id); + if (flags & QScriptClass::HandlesWriteAccess) { + if (m_scriptClass->propertyFlags(scriptObject, scriptName, id) & QScriptValue::Undeletable) + return false; + m_scriptClass->setProperty(scriptObject, scriptName, id, QScriptValue()); + return true; + } + return QScriptObjectDelegate::deleteProperty(object, exec, propertyName, checkDontDelete); +} + +bool ClassObjectDelegate::getPropertyAttributes(const QScriptObject* object, JSC::ExecState *exec, + const JSC::Identifier &propertyName, + unsigned &attribs) const +{ + QScriptEnginePrivate *engine = scriptEngineFromExec(exec); + QScriptValue scriptObject = engine->scriptValueFromJSCValue(object); + QString name(propertyName.ustring()); + QScriptString scriptName = QScriptEnginePrivate::get(engine)->toStringHandle(name); + uint id = 0; + QScriptClass::QueryFlags flags = m_scriptClass->queryProperty( + scriptObject, scriptName, QScriptClass::HandlesReadAccess, &id); + if (flags & QScriptClass::HandlesReadAccess) { + QScriptValue::PropertyFlags flags = m_scriptClass->propertyFlags(scriptObject, scriptName, id); + attribs = 0; + if (flags & QScriptValue::ReadOnly) + attribs |= JSC::ReadOnly; + if (flags & QScriptValue::SkipInEnumeration) + attribs |= JSC::DontEnum; + if (flags & QScriptValue::Undeletable) + attribs |= JSC::DontDelete; + if (flags & QScriptValue::PropertyGetter) + attribs |= JSC::Getter; + if (flags & QScriptValue::PropertySetter) + attribs |= JSC::Setter; + attribs |= flags & QScriptValue::UserRange; + return true; + } + return QScriptObjectDelegate::getPropertyAttributes(object, exec, propertyName, attribs); +} + +void ClassObjectDelegate::getPropertyNames(QScriptObject* object, JSC::ExecState *exec, + JSC::PropertyNameArray &propertyNames, + unsigned listedAttributes) +{ + QScriptEnginePrivate *engine = scriptEngineFromExec(exec); + QScriptValue scriptObject = engine->scriptValueFromJSCValue(object); + QScriptClassPropertyIterator *it = m_scriptClass->newIterator(scriptObject); + if (it != 0) { + while (it->hasNext()) { + it->next(); + QString name = it->name().toString(); + propertyNames.add(JSC::Identifier(exec, name)); + } + delete it; + } + QScriptObjectDelegate::getPropertyNames(object, exec, propertyNames, listedAttributes); +} + +JSC::CallType ClassObjectDelegate::getCallData(QScriptObject*, JSC::CallData &callData) +{ + if (!m_scriptClass->supportsExtension(QScriptClass::Callable)) + return JSC::CallTypeNone; + callData.native.function = call; + return JSC::CallTypeHost; +} + +JSC::JSValue JSC_HOST_CALL ClassObjectDelegate::call(JSC::ExecState *exec, JSC::JSObject *callee, + JSC::JSValue thisValue, const JSC::ArgList &args) +{ + if (!callee->isObject(&QScriptObject::info)) + return JSC::throwError(exec, JSC::TypeError, "callee is not a ClassObject object"); + QScriptObject *obj = static_cast<QScriptObject*>(callee); + QScriptObjectDelegate *delegate = obj->delegate(); + if (!delegate || (delegate->type() != QScriptObjectDelegate::ClassObject)) + return JSC::throwError(exec, JSC::TypeError, "callee is not a ClassObject object"); + + QScriptClass *scriptClass = static_cast<ClassObjectDelegate*>(delegate)->scriptClass(); + QScriptEnginePrivate *eng_p = scriptEngineFromExec(exec); + + JSC::ExecState *oldFrame = eng_p->currentFrame; + eng_p->pushContext(exec, thisValue, args, callee); + QScriptContext *ctx = eng_p->contextForFrame(eng_p->currentFrame); + QScriptValue scriptObject = eng_p->scriptValueFromJSCValue(obj); + QVariant result = scriptClass->extension(QScriptClass::Callable, qVariantFromValue(ctx)); + eng_p->popContext(); + eng_p->currentFrame = oldFrame; + return eng_p->jscValueFromVariant(result); +} + +JSC::ConstructType ClassObjectDelegate::getConstructData(QScriptObject*, JSC::ConstructData &constructData) +{ + if (!m_scriptClass->supportsExtension(QScriptClass::Callable)) + return JSC::ConstructTypeNone; + constructData.native.function = construct; + return JSC::ConstructTypeHost; +} + +JSC::JSObject* ClassObjectDelegate::construct(JSC::ExecState *exec, JSC::JSObject *callee, + const JSC::ArgList &args) +{ + Q_ASSERT(callee->isObject(&QScriptObject::info)); + QScriptObject *obj = static_cast<QScriptObject*>(callee); + QScriptObjectDelegate *delegate = obj->delegate(); + QScriptClass *scriptClass = static_cast<ClassObjectDelegate*>(delegate)->scriptClass(); + + QScriptEnginePrivate *eng_p = scriptEngineFromExec(exec); + //JSC::ExecState *oldFrame = eng_p->currentFrame; + eng_p->pushContext(exec, JSC::JSValue(), args, callee, true); + QScriptContext *ctx = eng_p->contextForFrame(eng_p->currentFrame); + + QScriptValue defaultObject = ctx->thisObject(); + QScriptValue result = qvariant_cast<QScriptValue>(scriptClass->extension(QScriptClass::Callable, qVariantFromValue(ctx))); + if (!result.isObject()) + result = defaultObject; + return JSC::asObject(eng_p->scriptValueToJSCValue(result)); +} + +bool ClassObjectDelegate::hasInstance(QScriptObject* object, JSC::ExecState *exec, + JSC::JSValue value, JSC::JSValue proto) +{ + if (!scriptClass()->supportsExtension(QScriptClass::HasInstance)) + return QScriptObjectDelegate::hasInstance(object, exec, value, proto); + QScriptValueList args; + QScriptEnginePrivate *eng_p = scriptEngineFromExec(exec); + args << eng_p->scriptValueFromJSCValue(object) << eng_p->scriptValueFromJSCValue(value); + QVariant result = scriptClass()->extension(QScriptClass::HasInstance, qVariantFromValue(args)); + return result.toBool(); +} + +} // namespace QScript + +QT_END_NAMESPACE diff --git a/src/script/qscriptclass_p.h b/src/script/bridge/qscriptclassobject_p.h index d5d8500..38a8585 100644 --- a/src/script/qscriptclass_p.h +++ b/src/script/bridge/qscriptclassobject_p.h @@ -39,14 +39,8 @@ ** ****************************************************************************/ -#ifndef QSCRIPTCLASS_P_H -#define QSCRIPTCLASS_P_H - -#include <QtCore/qobjectdefs.h> - -#ifndef QT_NO_SCRIPT - -QT_BEGIN_NAMESPACE +#ifndef QSCRIPTCLASSOBJECT_P_H +#define QSCRIPTCLASSOBJECT_P_H // // W A R N I N G @@ -59,33 +53,59 @@ QT_BEGIN_NAMESPACE // We mean it. // -class QScriptEngine; -class QScriptClassInfo; -class QScriptFunction; +#include <QtCore/qobjectdefs.h> + +#include "qscriptobject_p.h" + +QT_BEGIN_NAMESPACE class QScriptClass; -class QScriptClassPrivate + +namespace QScript +{ + +class ClassObjectDelegate : public QScriptObjectDelegate { - Q_DECLARE_PUBLIC(QScriptClass) public: - QScriptClassPrivate(QScriptClass*); - virtual ~QScriptClassPrivate(); + ClassObjectDelegate(QScriptClass *scriptClass); + ~ClassObjectDelegate(); - static QScriptClassPrivate *get(QScriptClass *klass); + QScriptClass *scriptClass() const; + void setScriptClass(QScriptClass *scriptClass); - QScriptClassInfo *classInfo(); - static QScriptClass *classFromInfo(QScriptClassInfo *info); + virtual Type type() const; - QScriptFunction *newFunction(); + virtual bool getOwnPropertySlot(QScriptObject*, JSC::ExecState*, + const JSC::Identifier& propertyName, + JSC::PropertySlot&); + virtual void put(QScriptObject*, JSC::ExecState* exec, + const JSC::Identifier& propertyName, + JSC::JSValue, JSC::PutPropertySlot&); + virtual bool deleteProperty(QScriptObject*, JSC::ExecState*, + const JSC::Identifier& propertyName, + bool checkDontDelete = true); + virtual bool getPropertyAttributes(const QScriptObject*, JSC::ExecState*, + const JSC::Identifier&, + unsigned&) const; + virtual void getPropertyNames(QScriptObject*, JSC::ExecState*, + JSC::PropertyNameArray&, unsigned listedAttributes = JSC::Structure::Prototype); - QScriptEngine *engine; - QScriptClassInfo *m_classInfo; + virtual JSC::CallType getCallData(QScriptObject*, JSC::CallData&); + static JSC::JSValue JSC_HOST_CALL call(JSC::ExecState*, JSC::JSObject*, + JSC::JSValue, const JSC::ArgList&); + virtual JSC::ConstructType getConstructData(QScriptObject*, JSC::ConstructData&); + static JSC::JSObject* construct(JSC::ExecState*, JSC::JSObject*, + const JSC::ArgList&); - QScriptClass *q_ptr; + virtual bool hasInstance(QScriptObject*, JSC::ExecState*, + JSC::JSValue value, JSC::JSValue proto); + +private: + QScriptClass *m_scriptClass; }; -QT_END_NAMESPACE +} // namespace QScript -#endif // QT_NO_SCRIPT +QT_END_NAMESPACE #endif diff --git a/src/script/bridge/qscriptfunction.cpp b/src/script/bridge/qscriptfunction.cpp new file mode 100644 index 0000000..27ec203 --- /dev/null +++ b/src/script/bridge/qscriptfunction.cpp @@ -0,0 +1,192 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "config.h" +#include "qscriptfunction_p.h" + +#include "private/qscriptengine_p.h" +#include "qscriptcontext.h" +#include "private/qscriptcontext_p.h" +#include "private/qscriptvalue_p.h" +#include "qscriptactivationobject_p.h" +#include "qscriptobject_p.h" + +#include "JSGlobalObject.h" +#include "DebuggerCallFrame.h" +#include "Debugger.h" + +namespace JSC +{ +ASSERT_CLASS_FITS_IN_CELL(QScript::FunctionWrapper); +ASSERT_CLASS_FITS_IN_CELL(QScript::FunctionWithArgWrapper); +} + +namespace QScript +{ + +const JSC::ClassInfo FunctionWrapper::info = { "QtNativeFunctionWrapper", &PrototypeFunction::info, 0, 0 }; +const JSC::ClassInfo FunctionWithArgWrapper::info = { "QtNativeFunctionWithArgWrapper", &PrototypeFunction::info, 0, 0 }; + +FunctionWrapper::FunctionWrapper(JSC::ExecState *exec, int length, const JSC::Identifier &name, + QScriptEngine::FunctionSignature function) + : JSC::PrototypeFunction(exec, length, name, proxyCall), + data(new Data()) +{ + data->function = function; +} + +FunctionWrapper::~FunctionWrapper() +{ + delete data; +} + +JSC::ConstructType FunctionWrapper::getConstructData(JSC::ConstructData& consData) +{ + consData.native.function = proxyConstruct; + consData.native.function.doNotCallDebuggerFunctionExit(); + return JSC::ConstructTypeHost; +} + +JSC::JSValue FunctionWrapper::proxyCall(JSC::ExecState *exec, JSC::JSObject *callee, + JSC::JSValue thisObject, const JSC::ArgList &args) +{ + FunctionWrapper *self = static_cast<FunctionWrapper*>(callee); + QScriptEnginePrivate *eng_p = QScript::scriptEngineFromExec(exec); + + JSC::ExecState *oldFrame = eng_p->currentFrame; + eng_p->pushContext(exec, thisObject, args, callee); + QScriptContext *ctx = eng_p->contextForFrame(eng_p->currentFrame); + + QScriptValue result = self->data->function(ctx, QScriptEnginePrivate::get(eng_p)); + if (!result.isValid()) + result = QScriptValue(QScriptValue::UndefinedValue); + + eng_p->popContext(); + eng_p->currentFrame = oldFrame; + + return eng_p->scriptValueToJSCValue(result); +} + +JSC::JSObject* FunctionWrapper::proxyConstruct(JSC::ExecState *exec, JSC::JSObject *callee, + const JSC::ArgList &args) +{ + FunctionWrapper *self = static_cast<FunctionWrapper*>(callee); + QScriptEnginePrivate *eng_p = QScript::scriptEngineFromExec(exec); + + JSC::ExecState *oldFrame = eng_p->currentFrame; + eng_p->pushContext(exec, JSC::JSValue(), args, callee, true); + QScriptContext *ctx = eng_p->contextForFrame(eng_p->currentFrame); + + QScriptValue result = self->data->function(ctx, QScriptEnginePrivate::get(eng_p)); + + if (JSC::Debugger* debugger = eng_p->originalGlobalObject()->debugger()) + debugger->functionExit(QScriptValuePrivate::get(result)->jscValue, -1); + + if (!result.isObject()) + result = ctx->thisObject(); + + eng_p->popContext(); + eng_p->currentFrame = oldFrame; + + return JSC::asObject(eng_p->scriptValueToJSCValue(result)); +} + +FunctionWithArgWrapper::FunctionWithArgWrapper(JSC::ExecState *exec, int length, const JSC::Identifier &name, + QScriptEngine::FunctionWithArgSignature function, void *arg) + : JSC::PrototypeFunction(exec, length, name, proxyCall), + data(new Data()) +{ + data->function = function; + data->arg = arg; +} + +FunctionWithArgWrapper::~FunctionWithArgWrapper() +{ + delete data; +} + +JSC::ConstructType FunctionWithArgWrapper::getConstructData(JSC::ConstructData& consData) +{ + consData.native.function = proxyConstruct; + return JSC::ConstructTypeHost; +} + +JSC::JSValue FunctionWithArgWrapper::proxyCall(JSC::ExecState *exec, JSC::JSObject *callee, + JSC::JSValue thisObject, const JSC::ArgList &args) +{ + FunctionWithArgWrapper *self = static_cast<FunctionWithArgWrapper*>(callee); + QScriptEnginePrivate *eng_p = QScript::scriptEngineFromExec(exec); + + JSC::ExecState *oldFrame = eng_p->currentFrame; + eng_p->pushContext(exec, thisObject, args, callee); + QScriptContext *ctx = eng_p->contextForFrame(eng_p->currentFrame); + + QScriptValue result = self->data->function(ctx, QScriptEnginePrivate::get(eng_p), self->data->arg); + + eng_p->popContext(); + eng_p->currentFrame = oldFrame; + + return eng_p->scriptValueToJSCValue(result); +} + +JSC::JSObject* FunctionWithArgWrapper::proxyConstruct(JSC::ExecState *exec, JSC::JSObject *callee, + const JSC::ArgList &args) +{ + FunctionWithArgWrapper *self = static_cast<FunctionWithArgWrapper*>(callee); + QScriptEnginePrivate *eng_p = QScript::scriptEngineFromExec(exec); + + JSC::ExecState *oldFrame = eng_p->currentFrame; + eng_p->pushContext(exec, JSC::JSValue(), args, callee, true); + QScriptContext *ctx = eng_p->contextForFrame(eng_p->currentFrame); + + QScriptValue result = self->data->function(ctx, QScriptEnginePrivate::get(eng_p) , self->data->arg); + if (!result.isObject()) + result = ctx->thisObject(); + + eng_p->popContext(); + eng_p->currentFrame = oldFrame; + + return JSC::asObject(eng_p->scriptValueToJSCValue(result)); +} + +} // namespace QScript + +QT_END_NAMESPACE diff --git a/src/script/qscriptmemorypool_p.h b/src/script/bridge/qscriptfunction_p.h index d657ebb..3763645 100644 --- a/src/script/qscriptmemorypool_p.h +++ b/src/script/bridge/qscriptfunction_p.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef QSCRIPTMEMORYPOOL_P_H -#define QSCRIPTMEMORYPOOL_P_H +#ifndef QSCRIPTFUNCTION_P_H +#define QSCRIPTFUNCTIOn_P_H // // W A R N I N G @@ -54,73 +54,80 @@ // #include <QtCore/qglobal.h> -#include <QtCore/qshareddata.h> -#include <string.h> + +#include "qscriptengine.h" + +#include "PrototypeFunction.h" QT_BEGIN_NAMESPACE -namespace QScript { +namespace QScript +{ + +class FunctionWrapper : public JSC::PrototypeFunction // ### subclass InternalFunction instead +{ +public: + // work around CELL_SIZE limitation + struct Data + { + QScriptEngine::FunctionSignature function; + }; + + FunctionWrapper(JSC::ExecState*, int length, const JSC::Identifier&, + QScriptEngine::FunctionSignature); + ~FunctionWrapper(); + + virtual const JSC::ClassInfo* classInfo() const { return &info; } + static const JSC::ClassInfo info; + + QScriptEngine::FunctionSignature function() const + { return data->function; } + +private: + virtual JSC::ConstructType getConstructData(JSC::ConstructData&); + + static JSC::JSValue JSC_HOST_CALL proxyCall(JSC::ExecState *, JSC::JSObject *, + JSC::JSValue, const JSC::ArgList &); + static JSC::JSObject* proxyConstruct(JSC::ExecState *, JSC::JSObject *, + const JSC::ArgList &); + +private: + Data *data; +}; -class MemoryPool : public QSharedData +class FunctionWithArgWrapper : public JSC::PrototypeFunction { public: - enum { maxBlockCount = -1 }; - enum { defaultBlockSize = 1 << 12 }; - - MemoryPool() { - m_blockIndex = maxBlockCount; - m_currentIndex = 0; - m_storage = 0; - m_currentBlock = 0; - m_currentBlockSize = 0; - } - - virtual ~MemoryPool() { - for (int index = 0; index < m_blockIndex + 1; ++index) - qFree(m_storage[index]); - - qFree(m_storage); - } - - char *allocate(int bytes) { - bytes += (8 - bytes) & 7; // ensure multiple of 8 bytes (maintain alignment) - if (m_currentBlock == 0 || m_currentBlockSize < m_currentIndex + bytes) { - ++m_blockIndex; - m_currentBlockSize = defaultBlockSize << m_blockIndex; - - m_storage = reinterpret_cast<char**>(qRealloc(m_storage, sizeof(char*) * (1 + m_blockIndex))); - m_currentBlock = m_storage[m_blockIndex] = reinterpret_cast<char*>(qMalloc(m_currentBlockSize)); - ::memset(m_currentBlock, 0, m_currentBlockSize); - - m_currentIndex = (8 - quintptr(m_currentBlock)) & 7; // ensure first chunk is 64-bit aligned - Q_ASSERT(m_currentIndex + bytes <= m_currentBlockSize); - } - - char *p = reinterpret_cast<char *> - (m_currentBlock + m_currentIndex); - - m_currentIndex += bytes; - - return p; - } - - int bytesAllocated() const { - int bytes = 0; - for (int index = 0; index < m_blockIndex; ++index) - bytes += (defaultBlockSize << index); - bytes += m_currentIndex; - return bytes; - } + // work around CELL_SIZE limitation + struct Data + { + QScriptEngine::FunctionWithArgSignature function; + void *arg; + }; + + FunctionWithArgWrapper(JSC::ExecState*, int length, const JSC::Identifier&, + QScriptEngine::FunctionWithArgSignature, void *); + ~FunctionWithArgWrapper(); + + virtual const JSC::ClassInfo* classInfo() const { return &info; } + static const JSC::ClassInfo info; + + QScriptEngine::FunctionWithArgSignature function() const + { return data->function; } + + void *arg() const + { return data->arg; } private: - int m_blockIndex; - int m_currentIndex; - char *m_currentBlock; - int m_currentBlockSize; - char **m_storage; + virtual JSC::ConstructType getConstructData(JSC::ConstructData&); + + static JSC::JSValue JSC_HOST_CALL proxyCall(JSC::ExecState *, JSC::JSObject *, + JSC::JSValue , const JSC::ArgList &); + static JSC::JSObject* proxyConstruct(JSC::ExecState *, JSC::JSObject *, + const JSC::ArgList &); private: - Q_DISABLE_COPY(MemoryPool) + Data *data; }; } // namespace QScript diff --git a/src/script/bridge/qscriptglobalobject.cpp b/src/script/bridge/qscriptglobalobject.cpp new file mode 100644 index 0000000..eb8673e --- /dev/null +++ b/src/script/bridge/qscriptglobalobject.cpp @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "config.h" +#include "qscriptglobalobject_p.h" + +#include "../api/qscriptengine.h" +#include "../api/qscriptengine_p.h" + +QT_BEGIN_NAMESPACE + +namespace JSC +{ + +ASSERT_CLASS_FITS_IN_CELL(QScript::GlobalObject); +ASSERT_CLASS_FITS_IN_CELL(QScript::OriginalGlobalObjectProxy); + +} // namespace JSC + +namespace QScript +{ + +GlobalObject::GlobalObject() + : JSC::JSGlobalObject(), customGlobalObject(0) +{ +} + +GlobalObject::~GlobalObject() +{ +} + +void GlobalObject::mark() +{ + Q_ASSERT(!marked()); + JSC::JSGlobalObject::mark(); + if (customGlobalObject && !customGlobalObject->marked()) + customGlobalObject->mark(); +} + +bool GlobalObject::getOwnPropertySlot(JSC::ExecState* exec, + const JSC::Identifier& propertyName, + JSC::PropertySlot& slot) +{ + QScriptEnginePrivate *engine = scriptEngineFromExec(exec); + if (propertyName == exec->propertyNames().arguments && engine->currentFrame->argumentCount() > 0) { + JSC::JSValue args = engine->scriptValueToJSCValue(engine->contextForFrame(engine->currentFrame)->argumentsObject()); + slot.setValue(args); + return true; + } + if (customGlobalObject) + return customGlobalObject->getOwnPropertySlot(exec, propertyName, slot); + return JSC::JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot); +} + +void GlobalObject::put(JSC::ExecState* exec, const JSC::Identifier& propertyName, + JSC::JSValue value, JSC::PutPropertySlot& slot) +{ + if (customGlobalObject) + customGlobalObject->put(exec, propertyName, value, slot); + else + JSC::JSGlobalObject::put(exec, propertyName, value, slot); +} + +bool GlobalObject::deleteProperty(JSC::ExecState* exec, + const JSC::Identifier& propertyName, bool checkDontDelete) +{ + if (customGlobalObject) + return customGlobalObject->deleteProperty(exec, propertyName, checkDontDelete); + return JSC::JSGlobalObject::deleteProperty(exec, propertyName, checkDontDelete); +} + +bool GlobalObject::getPropertyAttributes(JSC::ExecState* exec, const JSC::Identifier& propertyName, + unsigned& attributes) const +{ + if (customGlobalObject) + return customGlobalObject->getPropertyAttributes(exec, propertyName, attributes); + return JSC::JSGlobalObject::getPropertyAttributes(exec, propertyName, attributes); +} + +void GlobalObject::getPropertyNames(JSC::ExecState* exec, JSC::PropertyNameArray& propertyNames, unsigned listedAttributes) +{ + if (customGlobalObject) + customGlobalObject->getPropertyNames(exec, propertyNames, listedAttributes); + else + JSC::JSGlobalObject::getPropertyNames(exec, propertyNames, listedAttributes); +} + +void GlobalObject::defineGetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction) +{ + if (customGlobalObject) + customGlobalObject->defineGetter(exec, propertyName, getterFunction); + else + JSC::JSGlobalObject::defineGetter(exec, propertyName, getterFunction); +} + +void GlobalObject::defineSetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction) +{ + if (customGlobalObject) + customGlobalObject->defineSetter(exec, propertyName, setterFunction); + else + JSC::JSGlobalObject::defineSetter(exec, propertyName, setterFunction); +} + +JSC::JSValue GlobalObject::lookupGetter(JSC::ExecState* exec, const JSC::Identifier& propertyName) +{ + if (customGlobalObject) + return customGlobalObject->lookupGetter(exec, propertyName); + return JSC::JSGlobalObject::lookupGetter(exec, propertyName); +} + +JSC::JSValue GlobalObject::lookupSetter(JSC::ExecState* exec, const JSC::Identifier& propertyName) +{ + if (customGlobalObject) + return customGlobalObject->lookupSetter(exec, propertyName); + return JSC::JSGlobalObject::lookupSetter(exec, propertyName); +} + +} // namespace QScript + +QT_END_NAMESPACE diff --git a/src/script/bridge/qscriptglobalobject_p.h b/src/script/bridge/qscriptglobalobject_p.h new file mode 100644 index 0000000..673f7f6 --- /dev/null +++ b/src/script/bridge/qscriptglobalobject_p.h @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTGLOBALOBJECT_P_H +#define QSCRIPTGLOBALOBJECT_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> + +#include "JSGlobalObject.h" + +QT_BEGIN_NAMESPACE + +namespace QScript +{ + +class GlobalObject : public JSC::JSGlobalObject +{ +public: + GlobalObject(); + virtual ~GlobalObject(); + virtual JSC::UString className() const { return "global"; } + virtual void mark(); + virtual bool getOwnPropertySlot(JSC::ExecState*, + const JSC::Identifier& propertyName, + JSC::PropertySlot&); + virtual void put(JSC::ExecState* exec, const JSC::Identifier& propertyName, + JSC::JSValue, JSC::PutPropertySlot&); + virtual bool deleteProperty(JSC::ExecState*, + const JSC::Identifier& propertyName, + bool checkDontDelete = true); + virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier&, + unsigned&) const; + virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, + unsigned listedAttributes = JSC::Structure::Prototype); + virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction); + virtual void defineSetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction); + virtual JSC::JSValue lookupGetter(JSC::ExecState*, const JSC::Identifier& propertyName); + virtual JSC::JSValue lookupSetter(JSC::ExecState*, const JSC::Identifier& propertyName); + +public: + JSC::JSObject *customGlobalObject; +}; + +class OriginalGlobalObjectProxy : public JSC::JSObject +{ +public: + explicit OriginalGlobalObjectProxy(WTF::PassRefPtr<JSC::Structure> sid, + JSC::JSGlobalObject *object) + : JSC::JSObject(sid), originalGlobalObject(object) + {} + virtual ~OriginalGlobalObjectProxy() + {} + virtual JSC::UString className() const + { return originalGlobalObject->className(); } + virtual void mark() + { + Q_ASSERT(!marked()); + if (!originalGlobalObject->marked()) + originalGlobalObject->JSC::JSGlobalObject::mark(); + JSC::JSObject::mark(); + } + virtual bool getOwnPropertySlot(JSC::ExecState* exec, + const JSC::Identifier& propertyName, + JSC::PropertySlot& slot) + { return originalGlobalObject->JSC::JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot); } + virtual void put(JSC::ExecState* exec, const JSC::Identifier& propertyName, + JSC::JSValue value, JSC::PutPropertySlot& slot) + { originalGlobalObject->JSC::JSGlobalObject::put(exec, propertyName, value, slot); } + virtual bool deleteProperty(JSC::ExecState* exec, + const JSC::Identifier& propertyName, bool checkDontDelete = true) + { return originalGlobalObject->JSC::JSGlobalObject::deleteProperty(exec, propertyName, checkDontDelete); } + virtual bool getPropertyAttributes(JSC::ExecState* exec, const JSC::Identifier& propertyName, + unsigned& attributes) const + { return originalGlobalObject->JSC::JSGlobalObject::getPropertyAttributes(exec, propertyName, attributes); } + virtual void getPropertyNames(JSC::ExecState* exec, JSC::PropertyNameArray& propertyNames, + unsigned listedAttributes = JSC::Structure::Prototype) + { originalGlobalObject->JSC::JSGlobalObject::getPropertyNames(exec, propertyNames, listedAttributes); } + virtual void defineGetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction) + { originalGlobalObject->JSC::JSGlobalObject::defineGetter(exec, propertyName, getterFunction); } + virtual void defineSetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction) + { originalGlobalObject->JSC::JSGlobalObject::defineSetter(exec, propertyName, setterFunction); } + virtual JSC::JSValue lookupGetter(JSC::ExecState* exec, const JSC::Identifier& propertyName) + { return originalGlobalObject->JSC::JSGlobalObject::lookupGetter(exec, propertyName); } + virtual JSC::JSValue lookupSetter(JSC::ExecState* exec, const JSC::Identifier& propertyName) + { return originalGlobalObject->JSC::JSGlobalObject::lookupSetter(exec, propertyName); } +private: + JSC::JSGlobalObject *originalGlobalObject; +}; + +} // namespace QScript + +QT_END_NAMESPACE + +#endif diff --git a/src/script/bridge/qscriptobject.cpp b/src/script/bridge/qscriptobject.cpp new file mode 100644 index 0000000..a550d39 --- /dev/null +++ b/src/script/bridge/qscriptobject.cpp @@ -0,0 +1,255 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "config.h" +#include "qscriptobject_p.h" +#include "private/qobject_p.h" + +QT_BEGIN_NAMESPACE + +namespace JSC +{ +ASSERT_CLASS_FITS_IN_CELL(QScriptObject); +ASSERT_CLASS_FITS_IN_CELL(QScriptObjectPrototype); +} + +// masquerading as JSC::JSObject +const JSC::ClassInfo QScriptObject::info = { "Object", 0, 0, 0 }; + +QScriptObject::Data::~Data() +{ + delete delegate; +} + +QScriptObject::QScriptObject(WTF::PassRefPtr<JSC::Structure> sid) + : JSC::JSObject(sid), d(0) +{ +} + +QScriptObject::~QScriptObject() +{ + delete d; +} + +JSC::JSValue QScriptObject::data() const +{ + if (!d) + return JSC::JSValue(); + return d->data; +} + +void QScriptObject::setData(JSC::JSValue data) +{ + if (!d) + d = new Data(); + d->data = data; +} + +QScriptObjectDelegate *QScriptObject::delegate() const +{ + if (!d) + return 0; + return d->delegate; +} + +void QScriptObject::setDelegate(QScriptObjectDelegate *delegate) +{ + if (!d) + d = new Data(); + d->delegate = delegate; +} + +bool QScriptObject::getOwnPropertySlot(JSC::ExecState* exec, + const JSC::Identifier& propertyName, + JSC::PropertySlot& slot) +{ + if (!d || !d->delegate) + return JSC::JSObject::getOwnPropertySlot(exec, propertyName, slot); + return d->delegate->getOwnPropertySlot(this, exec, propertyName, slot); +} + +void QScriptObject::put(JSC::ExecState* exec, const JSC::Identifier& propertyName, + JSC::JSValue value, JSC::PutPropertySlot& slot) +{ + if (!d || !d->delegate) { + JSC::JSObject::put(exec, propertyName, value, slot); + return; + } + d->delegate->put(this, exec, propertyName, value, slot); +} + +bool QScriptObject::deleteProperty(JSC::ExecState* exec, + const JSC::Identifier& propertyName, + bool checkDontDelete) +{ + if (!d || !d->delegate) + return JSC::JSObject::deleteProperty(exec, propertyName, checkDontDelete); + return d->delegate->deleteProperty(this, exec, propertyName, checkDontDelete); +} + +bool QScriptObject::getPropertyAttributes(JSC::ExecState* exec, const JSC::Identifier& propertyName, + unsigned& attributes) const +{ + if (!d || !d->delegate) + return JSC::JSObject::getPropertyAttributes(exec, propertyName, attributes); + return d->delegate->getPropertyAttributes(this, exec, propertyName, attributes); +} + +void QScriptObject::getPropertyNames(JSC::ExecState* exec, JSC::PropertyNameArray& propertyNames, unsigned listedAttributes) +{ + if (!d || !d->delegate) { + JSC::JSObject::getPropertyNames(exec, propertyNames, listedAttributes); + return; + } + d->delegate->getPropertyNames(this, exec, propertyNames, listedAttributes); +} + +void QScriptObject::mark() +{ + Q_ASSERT(!marked()); + if (!d) + d = new Data(); + if (d->isMarking) + return; + QBoolBlocker markBlocker(d->isMarking, true); + if (d && d->data && !d->data.marked()) + d->data.mark(); + if (!d || !d->delegate) { + JSC::JSObject::mark(); + return; + } + d->delegate->mark(this); +} + +JSC::CallType QScriptObject::getCallData(JSC::CallData &data) +{ + if (!d || !d->delegate) + return JSC::JSObject::getCallData(data); + return d->delegate->getCallData(this, data); +} + +JSC::ConstructType QScriptObject::getConstructData(JSC::ConstructData &data) +{ + if (!d || !d->delegate) + return JSC::JSObject::getConstructData(data); + return d->delegate->getConstructData(this, data); +} + +bool QScriptObject::hasInstance(JSC::ExecState* exec, JSC::JSValue value, JSC::JSValue proto) +{ + if (!d || !d->delegate) + return JSC::JSObject::hasInstance(exec, value, proto); + return d->delegate->hasInstance(this, exec, value, proto); +} + +QScriptObjectPrototype::QScriptObjectPrototype(JSC::ExecState*, WTF::PassRefPtr<JSC::Structure> structure, + JSC::Structure* /*prototypeFunctionStructure*/) + : QScriptObject(structure) +{ +} + +QScriptObjectDelegate::QScriptObjectDelegate() +{ +} + +QScriptObjectDelegate::~QScriptObjectDelegate() +{ +} + +bool QScriptObjectDelegate::getOwnPropertySlot(QScriptObject* object, JSC::ExecState* exec, + const JSC::Identifier& propertyName, + JSC::PropertySlot& slot) +{ + return object->JSC::JSObject::getOwnPropertySlot(exec, propertyName, slot); +} + +void QScriptObjectDelegate::put(QScriptObject* object, JSC::ExecState* exec, + const JSC::Identifier& propertyName, + JSC::JSValue value, JSC::PutPropertySlot& slot) +{ + object->JSC::JSObject::put(exec, propertyName, value, slot); +} + +bool QScriptObjectDelegate::deleteProperty(QScriptObject* object, JSC::ExecState* exec, + const JSC::Identifier& propertyName, + bool checkDontDelete) +{ + return object->JSC::JSObject::deleteProperty(exec, propertyName, checkDontDelete); +} + +bool QScriptObjectDelegate::getPropertyAttributes(const QScriptObject* object, + JSC::ExecState* exec, + const JSC::Identifier& propertyName, + unsigned& attributes) const +{ + return object->JSC::JSObject::getPropertyAttributes(exec, propertyName, attributes); +} + +void QScriptObjectDelegate::getPropertyNames(QScriptObject* object, JSC::ExecState* exec, + JSC::PropertyNameArray& propertyNames, + unsigned listedAttributes) +{ + object->JSC::JSObject::getPropertyNames(exec, propertyNames, listedAttributes); +} + +void QScriptObjectDelegate::mark(QScriptObject* object) +{ + if (!object->marked()) + object->JSC::JSObject::mark(); +} + +JSC::CallType QScriptObjectDelegate::getCallData(QScriptObject* object, JSC::CallData& data) +{ + return object->JSC::JSObject::getCallData(data); +} + +JSC::ConstructType QScriptObjectDelegate::getConstructData(QScriptObject* object, JSC::ConstructData& data) +{ + return object->JSC::JSObject::getConstructData(data); +} + +bool QScriptObjectDelegate::hasInstance(QScriptObject* object, JSC::ExecState* exec, + JSC::JSValue value, JSC::JSValue proto) +{ + return object->JSC::JSObject::hasInstance(exec, value, proto); +} + +QT_END_NAMESPACE diff --git a/src/script/bridge/qscriptobject_p.h b/src/script/bridge/qscriptobject_p.h new file mode 100644 index 0000000..d499c61 --- /dev/null +++ b/src/script/bridge/qscriptobject_p.h @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTOBJECT_P_H +#define QSCRIPTOBJECT_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> + +#include "JSObject.h" + +QT_BEGIN_NAMESPACE + +class QScriptObjectDelegate; + +class QScriptObject : public JSC::JSObject +{ +public: + // work around CELL_SIZE limitation + struct Data + { + JSC::JSValue data; // QScriptValue::data + QScriptObjectDelegate *delegate; + bool isMarking; // recursion guard + + Data() : delegate(0), isMarking(false) {} + ~Data(); + }; + + explicit QScriptObject(WTF::PassRefPtr<JSC::Structure> sid); + virtual ~QScriptObject(); + + virtual bool getOwnPropertySlot(JSC::ExecState*, + const JSC::Identifier& propertyName, + JSC::PropertySlot&); + virtual void put(JSC::ExecState* exec, const JSC::Identifier& propertyName, + JSC::JSValue, JSC::PutPropertySlot&); + virtual bool deleteProperty(JSC::ExecState*, + const JSC::Identifier& propertyName, + bool checkDontDelete = true); + virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier&, + unsigned&) const; + virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, unsigned listedAttributes = JSC::Structure::Prototype); + virtual void mark(); + virtual JSC::CallType getCallData(JSC::CallData&); + virtual JSC::ConstructType getConstructData(JSC::ConstructData&); + virtual bool hasInstance(JSC::ExecState*, JSC::JSValue value, JSC::JSValue proto); + + virtual const JSC::ClassInfo* classInfo() const { return &info; } + static const JSC::ClassInfo info; + + static WTF::PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype) + { + return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, JSC::ImplementsHasInstance)); + } + + JSC::JSValue data() const; + void setData(JSC::JSValue data); + + QScriptObjectDelegate *delegate() const; + void setDelegate(QScriptObjectDelegate *delegate); + +protected: + Data *d; +}; + +class QScriptObjectPrototype : public QScriptObject +{ +public: + QScriptObjectPrototype(JSC::ExecState*, WTF::PassRefPtr<JSC::Structure>, + JSC::Structure* prototypeFunctionStructure); +}; + +class QScriptObjectDelegate +{ +public: + enum Type { + QtObject, + Variant, + ClassObject + }; + + QScriptObjectDelegate(); + virtual ~QScriptObjectDelegate(); + + virtual Type type() const = 0; + + virtual bool getOwnPropertySlot(QScriptObject*, JSC::ExecState*, + const JSC::Identifier& propertyName, + JSC::PropertySlot&); + virtual void put(QScriptObject*, JSC::ExecState* exec, const JSC::Identifier& propertyName, + JSC::JSValue, JSC::PutPropertySlot&); + virtual bool deleteProperty(QScriptObject*, JSC::ExecState*, + const JSC::Identifier& propertyName, + bool checkDontDelete = true); + virtual bool getPropertyAttributes(const QScriptObject*, JSC::ExecState*, + const JSC::Identifier&, unsigned&) const; + virtual void getPropertyNames(QScriptObject*, JSC::ExecState*, JSC::PropertyNameArray&, + unsigned listedAttributes = JSC::Structure::Prototype); + virtual void mark(QScriptObject*); + virtual JSC::CallType getCallData(QScriptObject*, JSC::CallData&); + virtual JSC::ConstructType getConstructData(QScriptObject*, JSC::ConstructData&); + virtual bool hasInstance(QScriptObject*, JSC::ExecState*, + JSC::JSValue value, JSC::JSValue proto); + +private: + Q_DISABLE_COPY(QScriptObjectDelegate) +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/script/bridge/qscriptqobject.cpp b/src/script/bridge/qscriptqobject.cpp new file mode 100644 index 0000000..b7a0e44 --- /dev/null +++ b/src/script/bridge/qscriptqobject.cpp @@ -0,0 +1,2221 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "config.h" +#include "qscriptqobject_p.h" + +#include <QtCore/qmetaobject.h> +#include <QtCore/qvarlengtharray.h> +#include <QtCore/qdebug.h> +#include <QtScript/qscriptable.h> +#include "../api/qscriptengine_p.h" +#include "../api/qscriptable_p.h" +#include "../api/qscriptcontext_p.h" +#include "qscriptfunction_p.h" + +#include "Error.h" +#include "PrototypeFunction.h" +#include "PropertyNameArray.h" +#include "JSFunction.h" +#include "JSString.h" +#include "JSValue.h" +#include "JSArray.h" +#include "RegExpObject.h" +#include "RegExpConstructor.h" + +QT_BEGIN_NAMESPACE + +namespace JSC +{ +ASSERT_CLASS_FITS_IN_CELL(QScript::QObjectPrototype); +ASSERT_CLASS_FITS_IN_CELL(QScript::QMetaObjectWrapperObject); +ASSERT_CLASS_FITS_IN_CELL(QScript::QMetaObjectPrototype); +ASSERT_CLASS_FITS_IN_CELL(QScript::QtFunction); +ASSERT_CLASS_FITS_IN_CELL(QScript::QtPropertyFunction); +} + +namespace QScript +{ + +struct QObjectConnection +{ + int slotIndex; + JSC::JSValue receiver; + JSC::JSValue slot; + JSC::JSValue senderWrapper; + + QObjectConnection(int i, JSC::JSValue r, JSC::JSValue s, + JSC::JSValue sw) + : slotIndex(i), receiver(r), slot(s), senderWrapper(sw) {} + QObjectConnection() : slotIndex(-1) {} + + bool hasTarget(JSC::JSValue r, JSC::JSValue s) const + { + if ((r && r.isObject()) != (receiver && receiver.isObject())) + return false; + if (((r && r.isObject()) && (receiver && receiver.isObject())) + && (r != receiver)) { + return false; + } + return (s == slot); + } + + void mark() + { + if (senderWrapper && !senderWrapper.marked()) { + // see if the sender should be marked or not + Q_ASSERT(senderWrapper.isObject(&QScriptObject::info)); + QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(senderWrapper)); + QScriptObjectDelegate *delegate = scriptObject->delegate(); + Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::QtObject)); + QObjectDelegate *inst = static_cast<QObjectDelegate*>(delegate); + if ((inst->ownership() == QScriptEngine::ScriptOwnership) + || ((inst->ownership() == QScriptEngine::AutoOwnership) + && inst->value() && !inst->value()->parent())) { + senderWrapper = JSC::JSValue(); + } else { + senderWrapper.mark(); + } + } + if (receiver && !receiver.marked()) + receiver.mark(); + if (slot && !slot.marked()) + slot.mark(); + } +}; + +class QObjectNotifyCaller : public QObject +{ +public: + void callConnectNotify(const char *signal) + { connectNotify(signal); } + void callDisconnectNotify(const char *signal) + { disconnectNotify(signal); } +}; + +class QObjectConnectionManager: public QObject +{ +public: + QObjectConnectionManager(QScriptEnginePrivate *engine); + ~QObjectConnectionManager(); + + bool addSignalHandler(QObject *sender, int signalIndex, + JSC::JSValue receiver, + JSC::JSValue slot, + JSC::JSValue senderWrapper, + Qt::ConnectionType type); + bool removeSignalHandler(QObject *sender, int signalIndex, + JSC::JSValue receiver, + JSC::JSValue slot); + + static const QMetaObject staticMetaObject; + virtual const QMetaObject *metaObject() const; + virtual void *qt_metacast(const char *); + virtual int qt_metacall(QMetaObject::Call, int, void **argv); + + void execute(int slotIndex, void **argv); + + void mark(); + +private: + QScriptEnginePrivate *engine; + int slotCounter; + QVector<QVector<QObjectConnection> > connections; +}; + +static bool hasMethodAccess(const QMetaMethod &method, int index, const QScriptEngine::QObjectWrapOptions &opt) +{ + return (method.access() != QMetaMethod::Private) + && ((index != 2) || !(opt & QScriptEngine::ExcludeDeleteLater)); +} + +static bool isEnumerableMetaProperty(const QMetaProperty &prop, + const QMetaObject *mo, int index) +{ + return prop.isScriptable() && prop.isValid() + // the following lookup is to ensure that we have the + // "most derived" occurrence of the property with this name + && (mo->indexOfProperty(prop.name()) == index); +} + +static inline QByteArray methodName(const QMetaMethod &method) +{ + QByteArray signature = method.signature(); + return signature.left(signature.indexOf('(')); +} + +static QVariant variantFromValue(QScriptEnginePrivate *eng, + int targetType, const QScriptValue &value) +{ + QVariant v(targetType, (void *)0); + Q_ASSERT(eng); + if (QScriptEnginePrivate::convert(value, targetType, v.data(), eng)) + return v; + if (uint(targetType) == QVariant::LastType) + return value.toVariant(); + if (value.isVariant()) { + v = value.toVariant(); + if (v.canConvert(QVariant::Type(targetType))) { + v.convert(QVariant::Type(targetType)); + return v; + } + QByteArray typeName = v.typeName(); + if (typeName.endsWith('*') + && (QMetaType::type(typeName.left(typeName.size()-1)) == targetType)) { + return QVariant(targetType, *reinterpret_cast<void* *>(v.data())); + } + } + + return QVariant(); +} + +static const bool GeneratePropertyFunctions = true; + +static unsigned flagsForMetaProperty(const QMetaProperty &prop) +{ + return (JSC::DontDelete + | (!prop.isWritable() ? unsigned(JSC::ReadOnly) : unsigned(0)) + | (GeneratePropertyFunctions + ? unsigned(JSC::Getter | JSC::Setter) + : unsigned(0)) + | QObjectMemberAttribute); +} + +static int indexOfMetaEnum(const QMetaObject *meta, const QByteArray &str) +{ + QByteArray scope; + QByteArray name; + int scopeIdx = str.lastIndexOf("::"); + if (scopeIdx != -1) { + scope = str.left(scopeIdx); + name = str.mid(scopeIdx + 2); + } else { + name = str; + } + for (int i = meta->enumeratorCount() - 1; i >= 0; --i) { + QMetaEnum m = meta->enumerator(i); + if ((m.name() == name) && (scope.isEmpty() || (m.scope() == scope))) + return i; + } + return -1; +} + +static inline QScriptable *scriptableFromQObject(QObject *qobj) +{ + void *ptr = qobj->qt_metacast("QScriptable"); + return reinterpret_cast<QScriptable*>(ptr); +} + +QtFunction::QtFunction(JSC::JSValue object, int initialIndex, bool maybeOverloaded, + JSC::JSGlobalData *data, WTF::PassRefPtr<JSC::Structure> sid, + const JSC::Identifier &ident) + : JSC::InternalFunction(data, sid, ident), + data(new Data(object, initialIndex, maybeOverloaded)) +{ +} + +QtFunction::~QtFunction() +{ + delete data; +} + +JSC::CallType QtFunction::getCallData(JSC::CallData &callData) +{ + callData.native.function = call; + return JSC::CallTypeHost; +} + +void QtFunction::mark() +{ + Q_ASSERT(!marked()); + if (data->object && !data->object.marked()) + data->object.mark(); + JSC::InternalFunction::mark(); +} + +QScriptObject *QtFunction::wrapperObject() const +{ + Q_ASSERT(JSC::asObject(data->object)->inherits(&QScriptObject::info)); + return static_cast<QScriptObject*>(JSC::asObject(data->object)); +} + +QObject *QtFunction::qobject() const +{ + QScriptObject *scriptObject = wrapperObject(); + QScriptObjectDelegate *delegate = scriptObject->delegate(); + Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::QtObject)); + return static_cast<QScript::QObjectDelegate*>(delegate)->value(); +} + +const QMetaObject *QtFunction::metaObject() const +{ + QObject *qobj = qobject(); + if (!qobj) + return 0; + return qobj->metaObject(); +} + +int QtFunction::initialIndex() const +{ + return data->initialIndex; +} + +bool QtFunction::maybeOverloaded() const +{ + return data->maybeOverloaded; +} + +int QtFunction::mostGeneralMethod(QMetaMethod *out) const +{ + const QMetaObject *meta = metaObject(); + if (!meta) + return -1; + int index = initialIndex(); + QMetaMethod method = meta->method(index); + if (maybeOverloaded() && (method.attributes() & QMetaMethod::Cloned)) { + // find the most general method + do { + method = meta->method(--index); + } while (method.attributes() & QMetaMethod::Cloned); + } + if (out) + *out = method; + return index; +} + +QList<int> QScript::QtFunction::overloadedIndexes() const +{ + if (!maybeOverloaded()) + return QList<int>(); + QList<int> result; + QString name = functionName(); + const QMetaObject *meta = metaObject(); + for (int index = mostGeneralMethod() - 1; index >= 0; --index) { + QString otherName = QString::fromLatin1(methodName(meta->method(index))); + if (otherName == name) + result.append(index); + } + return result; +} + +QString QtFunction::functionName() const +{ + const QMetaObject *meta = metaObject(); + if (!meta) + return QString(); + QMetaMethod method = meta->method(initialIndex()); + return QLatin1String(methodName(method)); +} + +class QScriptMetaType +{ +public: + enum Kind { + Invalid, + Variant, + MetaType, + Unresolved, + MetaEnum + }; + + inline QScriptMetaType() + : m_kind(Invalid) { } + + inline Kind kind() const + { return m_kind; } + + int typeId() const; + + inline bool isValid() const + { return (m_kind != Invalid); } + + inline bool isVariant() const + { return (m_kind == Variant); } + + inline bool isMetaType() const + { return (m_kind == MetaType); } + + inline bool isUnresolved() const + { return (m_kind == Unresolved); } + + inline bool isMetaEnum() const + { return (m_kind == MetaEnum); } + + QByteArray name() const; + + inline int enumeratorIndex() const + { Q_ASSERT(isMetaEnum()); return m_typeId; } + + inline bool operator==(const QScriptMetaType &other) const + { + return (m_kind == other.m_kind) && (m_typeId == other.m_typeId); + } + + static inline QScriptMetaType variant() + { return QScriptMetaType(Variant); } + + static inline QScriptMetaType metaType(int typeId, const QByteArray &name) + { return QScriptMetaType(MetaType, typeId, name); } + + static inline QScriptMetaType metaEnum(int enumIndex, const QByteArray &name) + { return QScriptMetaType(MetaEnum, enumIndex, name); } + + static inline QScriptMetaType unresolved(const QByteArray &name) + { return QScriptMetaType(Unresolved, /*typeId=*/0, name); } + +private: + inline QScriptMetaType(Kind kind, int typeId = 0, const QByteArray &name = QByteArray()) + : m_kind(kind), m_typeId(typeId), m_name(name) { } + + Kind m_kind; + int m_typeId; + QByteArray m_name; +}; + +int QScriptMetaType::typeId() const +{ + if (isVariant()) + return QMetaType::type("QVariant"); + return isMetaEnum() ? 2/*int*/ : m_typeId; +} + +QByteArray QScriptMetaType::name() const +{ + if (!m_name.isEmpty()) + return m_name; + else if (m_kind == Variant) + return "QVariant"; + return QMetaType::typeName(typeId()); +} + +class QScriptMetaMethod +{ +public: + inline QScriptMetaMethod() + { } + inline QScriptMetaMethod(const QByteArray &name, const QVector<QScriptMetaType> &types) + : m_name(name), m_types(types), m_firstUnresolvedIndex(-1) + { + QVector<QScriptMetaType>::const_iterator it; + for (it = m_types.constBegin(); it != m_types.constEnd(); ++it) { + if ((*it).kind() == QScriptMetaType::Unresolved) { + m_firstUnresolvedIndex = it - m_types.constBegin(); + break; + } + } + } + inline bool isValid() const + { return !m_types.isEmpty(); } + + QByteArray name() const + { return m_name; } + + inline QScriptMetaType returnType() const + { return m_types.at(0); } + + inline int argumentCount() const + { return m_types.count() - 1; } + + inline QScriptMetaType argumentType(int arg) const + { return m_types.at(arg + 1); } + + inline bool fullyResolved() const + { return m_firstUnresolvedIndex == -1; } + + inline bool hasUnresolvedReturnType() const + { return (m_firstUnresolvedIndex == 0); } + + inline int firstUnresolvedIndex() const + { return m_firstUnresolvedIndex; } + + inline int count() const + { return m_types.count(); } + + inline QScriptMetaType type(int index) const + { return m_types.at(index); } + + inline QVector<QScriptMetaType> types() const + { return m_types; } + +private: + QByteArray m_name; + QVector<QScriptMetaType> m_types; + int m_firstUnresolvedIndex; +}; + +struct QScriptMetaArguments +{ + int matchDistance; + int index; + QScriptMetaMethod method; + QVarLengthArray<QVariant, 9> args; + + inline QScriptMetaArguments(int dist, int idx, const QScriptMetaMethod &mtd, + const QVarLengthArray<QVariant, 9> &as) + : matchDistance(dist), index(idx), method(mtd), args(as) { } + inline QScriptMetaArguments() + : index(-1) { } + + inline bool isValid() const + { return (index != -1); } +}; + +static QMetaMethod metaMethod(const QMetaObject *meta, + QMetaMethod::MethodType type, + int index) +{ + if (type != QMetaMethod::Constructor) + return meta->method(index); + else + return meta->constructor(index); +} + +static JSC::JSValue callQtMethod(JSC::ExecState *exec, QMetaMethod::MethodType callType, + QObject *thisQObject, const JSC::ArgList &scriptArgs, + const QMetaObject *meta, int initialIndex, + bool maybeOverloaded) +{ + QByteArray funName; + QScriptMetaMethod chosenMethod; + int chosenIndex = -1; + QVarLengthArray<QVariant, 9> args; + QVector<QScriptMetaArguments> candidates; + QVector<QScriptMetaArguments> unresolved; + QVector<int> tooFewArgs; + QVector<int> conversionFailed; + int index; + exec->clearException(); + QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(exec); + for (index = initialIndex; index >= 0; --index) { + QMetaMethod method = metaMethod(meta, callType, index); + + if (index == initialIndex) + funName = methodName(method); + else { + if (methodName(method) != funName) + continue; + } + + QVector<QScriptMetaType> types; + // resolve return type + QByteArray returnTypeName = method.typeName(); + int rtype = QMetaType::type(returnTypeName); + if ((rtype == 0) && !returnTypeName.isEmpty()) { + if (returnTypeName == "QVariant") { + types.append(QScriptMetaType::variant()); + } else { + int enumIndex = indexOfMetaEnum(meta, returnTypeName); + if (enumIndex != -1) + types.append(QScriptMetaType::metaEnum(enumIndex, returnTypeName)); + else + types.append(QScriptMetaType::unresolved(returnTypeName)); + } + } else { + if (callType == QMetaMethod::Constructor) + types.append(QScriptMetaType::metaType(QMetaType::QObjectStar, "QObject*")); + else if (returnTypeName == "QVariant") + types.append(QScriptMetaType::variant()); + else + types.append(QScriptMetaType::metaType(rtype, returnTypeName)); + } + + // resolve argument types + QList<QByteArray> parameterTypeNames = method.parameterTypes(); + for (int i = 0; i < parameterTypeNames.count(); ++i) { + QByteArray argTypeName = parameterTypeNames.at(i); + int atype = QMetaType::type(argTypeName); + if (atype == 0) { + if (argTypeName == "QVariant") { + types.append(QScriptMetaType::variant()); + } else { + int enumIndex = indexOfMetaEnum(meta, argTypeName); + if (enumIndex != -1) + types.append(QScriptMetaType::metaEnum(enumIndex, argTypeName)); + else + types.append(QScriptMetaType::unresolved(argTypeName)); + } + } else { + if (argTypeName == "QVariant") + types.append(QScriptMetaType::variant()); + else + types.append(QScriptMetaType::metaType(atype, argTypeName)); + } + } + + QScriptMetaMethod mtd = QScriptMetaMethod(methodName(method), types); + + if (int(scriptArgs.size()) < mtd.argumentCount()) { + tooFewArgs.append(index); + continue; + } + + if (!mtd.fullyResolved()) { + // remember it so we can give an error message later, if necessary + unresolved.append(QScriptMetaArguments(/*matchDistance=*/INT_MAX, index, + mtd, QVarLengthArray<QVariant, 9>())); + if (mtd.hasUnresolvedReturnType()) + continue; + } + + if (args.count() != mtd.count()) + args.resize(mtd.count()); + + QScriptMetaType retType = mtd.returnType(); + args[0] = QVariant(retType.typeId(), (void *)0); // the result + + // try to convert arguments + bool converted = true; + int matchDistance = 0; + for (int i = 0; converted && i < mtd.argumentCount(); ++i) { + QScriptValue actual; + if (i < (int)scriptArgs.size()) + actual = engine->scriptValueFromJSCValue(scriptArgs.at(i)); + else + actual = QScriptValue::QScriptValue(QScriptValue::UndefinedValue); + QScriptMetaType argType = mtd.argumentType(i); + int tid = -1; + QVariant v; + if (argType.isUnresolved()) { + v = QVariant(QMetaType::QObjectStar, (void *)0); + converted = engine->convertToNativeQObject( + actual, argType.name(), reinterpret_cast<void* *>(v.data())); + } else if (argType.isVariant()) { + if (actual.isVariant()) { + v = actual.toVariant(); + } else { + v = actual.toVariant(); + converted = v.isValid() || actual.isUndefined() || actual.isNull(); + } + } else { + tid = argType.typeId(); + v = QVariant(tid, (void *)0); + converted = QScriptEnginePrivate::convert(actual, tid, v.data(), engine); + if (exec->hadException()) + return exec->exception(); + } + + if (!converted) { + if (actual.isVariant()) { + if (tid == -1) + tid = argType.typeId(); + QVariant vv = actual.toVariant(); + if (vv.canConvert(QVariant::Type(tid))) { + v = vv; + converted = v.convert(QVariant::Type(tid)); + if (converted && (vv.userType() != tid)) + matchDistance += 10; + } else { + QByteArray vvTypeName = vv.typeName(); + if (vvTypeName.endsWith('*') + && (vvTypeName.left(vvTypeName.size()-1) == argType.name())) { + v = QVariant(tid, *reinterpret_cast<void* *>(vv.data())); + converted = true; + matchDistance += 10; + } + } + } else if (actual.isNumber() || actual.isString()) { + // see if it's an enum value + QMetaEnum m; + if (argType.isMetaEnum()) { + m = meta->enumerator(argType.enumeratorIndex()); + } else { + int mi = indexOfMetaEnum(meta, argType.name()); + if (mi != -1) + m = meta->enumerator(mi); + } + if (m.isValid()) { + if (actual.isNumber()) { + int ival = actual.toInt32(); + if (m.valueToKey(ival) != 0) { + qVariantSetValue(v, ival); + converted = true; + matchDistance += 10; + } + } else { + QString sval = actual.toString(); + int ival = m.keyToValue(sval.toLatin1()); + if (ival != -1) { + qVariantSetValue(v, ival); + converted = true; + matchDistance += 10; + } + } + } + } + } else { + // determine how well the conversion matched + if (actual.isNumber()) { + switch (tid) { + case QMetaType::Double: + // perfect + break; + case QMetaType::Float: + matchDistance += 1; + break; + case QMetaType::LongLong: + case QMetaType::ULongLong: + matchDistance += 2; + break; + case QMetaType::Long: + case QMetaType::ULong: + matchDistance += 3; + break; + case QMetaType::Int: + case QMetaType::UInt: + matchDistance += 4; + break; + case QMetaType::Short: + case QMetaType::UShort: + matchDistance += 5; + break; + case QMetaType::Char: + case QMetaType::UChar: + matchDistance += 6; + break; + default: + matchDistance += 10; + break; + } + } else if (actual.isString()) { + switch (tid) { + case QMetaType::QString: + // perfect + break; + default: + matchDistance += 10; + break; + } + } else if (actual.isBoolean()) { + switch (tid) { + case QMetaType::Bool: + // perfect + break; + default: + matchDistance += 10; + break; + } + } else if (actual.isDate()) { + switch (tid) { + case QMetaType::QDateTime: + // perfect + break; + case QMetaType::QDate: + matchDistance += 1; + break; + case QMetaType::QTime: + matchDistance += 2; + break; + default: + matchDistance += 10; + break; + } + } else if (actual.isRegExp()) { + switch (tid) { + case QMetaType::QRegExp: + // perfect + break; + default: + matchDistance += 10; + break; + } + } else if (actual.isVariant()) { + if (argType.isVariant() + || (actual.toVariant().userType() == tid)) { + // perfect + } else { + matchDistance += 10; + } + } else if (actual.isArray()) { + switch (tid) { + case QMetaType::QStringList: + case QMetaType::QVariantList: + matchDistance += 5; + break; + default: + matchDistance += 10; + break; + } + } else if (actual.isQObject()) { + switch (tid) { + case QMetaType::QObjectStar: + case QMetaType::QWidgetStar: + // perfect + break; + default: + matchDistance += 10; + break; + } + } else if (actual.isNull()) { + switch (tid) { + case QMetaType::VoidStar: + case QMetaType::QObjectStar: + case QMetaType::QWidgetStar: + // perfect + break; + default: + if (!argType.name().endsWith('*')) + matchDistance += 10; + break; + } + } else { + matchDistance += 10; + } + } + + if (converted) + args[i+1] = v; + } + + if (converted) { + if ((scriptArgs.size() == (size_t)mtd.argumentCount()) + && (matchDistance == 0)) { + // perfect match, use this one + chosenMethod = mtd; + chosenIndex = index; + break; + } else { + bool redundant = false; + if ((callType != QMetaMethod::Constructor) + && (index < meta->methodOffset())) { + // it is possible that a virtual method is redeclared in a subclass, + // in which case we want to ignore the superclass declaration + for (int i = 0; i < candidates.size(); ++i) { + const QScriptMetaArguments &other = candidates.at(i); + if (mtd.types() == other.method.types()) { + redundant = true; + break; + } + } + } + if (!redundant) { + QScriptMetaArguments metaArgs(matchDistance, index, mtd, args); + if (candidates.isEmpty()) { + candidates.append(metaArgs); + } else { + const QScriptMetaArguments &otherArgs = candidates.at(0); + if ((args.count() > otherArgs.args.count()) + || ((args.count() == otherArgs.args.count()) + && (matchDistance <= otherArgs.matchDistance))) { + candidates.prepend(metaArgs); + } else { + candidates.append(metaArgs); + } + } + } + } + } else if (mtd.fullyResolved()) { + conversionFailed.append(index); + } + + if (!maybeOverloaded) + break; + } + + JSC::JSValue result; + if ((chosenIndex == -1) && candidates.isEmpty()) { +// context->calleeMetaIndex = initialIndex; +//#ifndef Q_SCRIPT_NO_EVENT_NOTIFY +// engine->notifyFunctionEntry(context); +//#endif + if (!conversionFailed.isEmpty()) { + QString message = QString::fromLatin1("incompatible type of argument(s) in call to %0(); candidates were\n") + .arg(QLatin1String(funName)); + for (int i = 0; i < conversionFailed.size(); ++i) { + if (i > 0) + message += QLatin1String("\n"); + QMetaMethod mtd = metaMethod(meta, callType, conversionFailed.at(i)); + message += QString::fromLatin1(" %0").arg(QString::fromLatin1(mtd.signature())); + } + result = JSC::throwError(exec, JSC::TypeError, message); + } else if (!unresolved.isEmpty()) { + QScriptMetaArguments argsInstance = unresolved.first(); + int unresolvedIndex = argsInstance.method.firstUnresolvedIndex(); + Q_ASSERT(unresolvedIndex != -1); + QScriptMetaType unresolvedType = argsInstance.method.type(unresolvedIndex); + QString unresolvedTypeName = QString::fromLatin1(unresolvedType.name()); + QString message = QString::fromLatin1("cannot call %0(): ") + .arg(QString::fromLatin1(funName)); + if (unresolvedIndex > 0) { + message.append(QString::fromLatin1("argument %0 has unknown type `%1'"). + arg(unresolvedIndex).arg(unresolvedTypeName)); + } else { + message.append(QString::fromLatin1("unknown return type `%0'") + .arg(unresolvedTypeName)); + } + message.append(QString::fromLatin1(" (register the type with qScriptRegisterMetaType())")); + result = JSC::throwError(exec, JSC::TypeError, message); + } else { + QString message = QString::fromLatin1("too few arguments in call to %0(); candidates are\n") + .arg(QLatin1String(funName)); + for (int i = 0; i < tooFewArgs.size(); ++i) { + if (i > 0) + message += QLatin1String("\n"); + QMetaMethod mtd = metaMethod(meta, callType, tooFewArgs.at(i)); + message += QString::fromLatin1(" %0").arg(QString::fromLatin1(mtd.signature())); + } + result = JSC::throwError(exec, JSC::SyntaxError, message); + } + } else { + if (chosenIndex == -1) { + QScriptMetaArguments metaArgs = candidates.at(0); + if ((candidates.size() > 1) + && (metaArgs.args.count() == candidates.at(1).args.count()) + && (metaArgs.matchDistance == candidates.at(1).matchDistance)) { + // ambiguous call + QString message = QString::fromLatin1("ambiguous call of overloaded function %0(); candidates were\n") + .arg(QLatin1String(funName)); + for (int i = 0; i < candidates.size(); ++i) { + if (i > 0) + message += QLatin1String("\n"); + QMetaMethod mtd = metaMethod(meta, callType, candidates.at(i).index); + message += QString::fromLatin1(" %0").arg(QString::fromLatin1(mtd.signature())); + } + result = JSC::throwError(exec, JSC::TypeError, message); + } else { + chosenMethod = metaArgs.method; + chosenIndex = metaArgs.index; + args = metaArgs.args; + } + } + + if (chosenIndex != -1) { + // call it +// context->calleeMetaIndex = chosenIndex; + + QVarLengthArray<void*, 9> array(args.count()); + void **params = array.data(); + for (int i = 0; i < args.count(); ++i) { + const QVariant &v = args[i]; + switch (chosenMethod.type(i).kind()) { + case QScriptMetaType::Variant: + params[i] = const_cast<QVariant*>(&v); + break; + case QScriptMetaType::MetaType: + case QScriptMetaType::MetaEnum: + case QScriptMetaType::Unresolved: + params[i] = const_cast<void*>(v.constData()); + break; + default: + Q_ASSERT(0); + } + } + + QScriptable *scriptable = 0; + if (thisQObject) + scriptable = scriptableFromQObject(thisQObject); + QScriptEngine *oldEngine = 0; + if (scriptable) { + oldEngine = QScriptablePrivate::get(scriptable)->engine; + QScriptablePrivate::get(scriptable)->engine = QScriptEnginePrivate::get(engine); + } + +// ### fixme +//#ifndef Q_SCRIPT_NO_EVENT_NOTIFY +// engine->notifyFunctionEntry(context); +//#endif + + if (callType == QMetaMethod::Constructor) { + Q_ASSERT(meta != 0); + meta->static_metacall(QMetaObject::CreateInstance, chosenIndex, params); + } else { + QMetaObject::metacall(thisQObject, QMetaObject::InvokeMetaMethod, chosenIndex, params); + } + + if (scriptable) + QScriptablePrivate::get(scriptable)->engine = oldEngine; + + if (exec->hadException()) { + result = exec->exception() ; // propagate + } else { + QScriptMetaType retType = chosenMethod.returnType(); + if (retType.isVariant()) { + result = engine->jscValueFromVariant(*(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); + } + } else { + result = JSC::jsUndefined(); + } + } + } + } + + return result; +} + +JSC::JSValue QtFunction::execute(JSC::ExecState *exec, JSC::JSValue thisValue, + const JSC::ArgList &scriptArgs) +{ + Q_ASSERT(data->object.isObject(&QScriptObject::info)); + QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(data->object)); + QScriptObjectDelegate *delegate = scriptObject->delegate(); + Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::QtObject)); + QObject *qobj = static_cast<QScript::QObjectDelegate*>(delegate)->value(); + Q_ASSERT_X(qobj != 0, "QtFunction::call", "handle the case when QObject has been deleted"); + QScriptEnginePrivate *engine = scriptEngineFromExec(exec); + + const QMetaObject *meta = qobj->metaObject(); + QObject *thisQObject = 0; + thisValue = engine->toUsableValue(thisValue); + if (thisValue.isObject(&QScriptObject::info)) { + delegate = static_cast<QScriptObject*>(JSC::asObject(thisValue))->delegate(); + if (delegate && (delegate->type() == QScriptObjectDelegate::QtObject)) + thisQObject = static_cast<QScript::QObjectDelegate*>(delegate)->value(); + } + if (!thisQObject) + thisQObject = qobj; // ### TypeError + + if (!meta->cast(thisQObject)) { + // invoking a function in the prototype + thisQObject = qobj; + } + + return callQtMethod(exec, QMetaMethod::Method, thisQObject, scriptArgs, + meta, data->initialIndex, data->maybeOverloaded); +} + +const JSC::ClassInfo QtFunction::info = { "QtFunction", &InternalFunction::info, 0, 0 }; + +JSC::JSValue JSC_HOST_CALL QtFunction::call(JSC::ExecState *exec, JSC::JSObject *callee, + JSC::JSValue thisValue, const JSC::ArgList &args) +{ + if (!callee->isObject(&QtFunction::info)) + return throwError(exec, JSC::TypeError, "callee is not a QtFunction object"); + QtFunction *qfun = static_cast<QtFunction*>(callee); + QScriptEnginePrivate *eng_p = scriptEngineFromExec(exec); + JSC::ExecState *previousFrame = eng_p->currentFrame; + eng_p->currentFrame = exec; + eng_p->pushContext(exec, thisValue, args, callee); + JSC::JSValue result = qfun->execute(eng_p->currentFrame, thisValue, args); + eng_p->popContext(); + eng_p->currentFrame = previousFrame; + return result; +} + +const JSC::ClassInfo QtPropertyFunction::info = { "QtPropertyFunction", &InternalFunction::info, 0, 0 }; + +QtPropertyFunction::QtPropertyFunction(const QMetaObject *meta, int index, + JSC::JSGlobalData *data, + WTF::PassRefPtr<JSC::Structure> sid, + const JSC::Identifier &ident) + : JSC::InternalFunction(data, sid, ident), + data(new Data(meta, index)) +{ +} + +QtPropertyFunction::~QtPropertyFunction() +{ + delete data; +} + +JSC::CallType QtPropertyFunction::getCallData(JSC::CallData &callData) +{ + callData.native.function = call; + return JSC::CallTypeHost; +} + +JSC::JSValue JSC_HOST_CALL QtPropertyFunction::call( + JSC::ExecState *exec, JSC::JSObject *callee, + JSC::JSValue thisValue, const JSC::ArgList &args) +{ + if (!callee->isObject(&QtPropertyFunction::info)) + return throwError(exec, JSC::TypeError, "callee is not a QtPropertyFunction object"); + QtPropertyFunction *qfun = static_cast<QtPropertyFunction*>(callee); + QScriptEnginePrivate *eng_p = scriptEngineFromExec(exec); + JSC::ExecState *previousFrame = eng_p->currentFrame; + eng_p->currentFrame = exec; + eng_p->pushContext(exec, thisValue, args, callee); + JSC::JSValue result = qfun->execute(eng_p->currentFrame, thisValue, args); + eng_p->popContext(); + eng_p->currentFrame = previousFrame; + return result; +} + +JSC::JSValue QtPropertyFunction::execute(JSC::ExecState *exec, + JSC::JSValue thisValue, + const JSC::ArgList &args) +{ + 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(); + while ((!qobject || (qobject->metaObject() != data->meta)) + && object.prototype().isObject()) { + object = object.prototype(); + qobject = object.toQObject(); + } + Q_ASSERT_X(qobject, Q_FUNC_INFO, "this-object must be a QObject"); + + QMetaProperty prop = data->meta->property(data->index); + Q_ASSERT(prop.isScriptable()); + if (args.size() == 0) { + // get + if (prop.isValid()) { + QScriptable *scriptable = scriptableFromQObject(qobject); + QScriptEngine *oldEngine = 0; + if (scriptable) { + oldEngine = QScriptablePrivate::get(scriptable)->engine; + QScriptablePrivate::get(scriptable)->engine = QScriptEnginePrivate::get(engine); + } + + QVariant v = prop.read(qobject); + + if (scriptable) + QScriptablePrivate::get(scriptable)->engine = oldEngine; + + result = engine->jscValueFromVariant(v); + } + } else { + // set + JSC::JSValue arg = args.at(0); + QVariant v; + if (prop.isEnumType() && arg.isString() + && !engine->hasDemarshalFunction(prop.userType())) { + // give QMetaProperty::write() a chance to convert from + // 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); + } + + QScriptable *scriptable = scriptableFromQObject(qobject); + QScriptEngine *oldEngine = 0; + if (scriptable) { + oldEngine = QScriptablePrivate::get(scriptable)->engine; + QScriptablePrivate::get(scriptable)->engine = QScriptEnginePrivate::get(engine); + } + + prop.write(qobject, v); + + if (scriptable) + QScriptablePrivate::get(scriptable)->engine = oldEngine; + + result = arg; + } + return result; +} + +const QMetaObject *QtPropertyFunction::metaObject() const +{ + return data->meta; +} + +int QtPropertyFunction::propertyIndex() const +{ + return data->index; +} + + +QObjectDelegate::QObjectDelegate( + QObject *object, QScriptEngine::ValueOwnership ownership, + const QScriptEngine::QObjectWrapOptions &options) + : data(new Data(object, ownership, options)) +{ +} + +QObjectDelegate::~QObjectDelegate() +{ + switch (data->ownership) { + case QScriptEngine::QtOwnership: + break; + case QScriptEngine::ScriptOwnership: + if (data->value) + delete data->value; // ### fixme +// eng->disposeQObject(value); + break; + case QScriptEngine::AutoOwnership: + if (data->value && !data->value->parent()) + delete data->value; // ### fixme +// eng->disposeQObject(value); + break; + } + delete data; +} + +QScriptObjectDelegate::Type QObjectDelegate::type() const +{ + return QtObject; +} + +bool QObjectDelegate::getOwnPropertySlot(QScriptObject *object, JSC::ExecState *exec, + const JSC::Identifier &propertyName, + JSC::PropertySlot &slot) +{ + QByteArray name = QString(propertyName.ustring()).toLatin1(); + QObject *qobject = data->value; + if (!qobject) { + QString message = QString::fromLatin1("cannot access member `%0' of deleted QObject") + .arg(QString::fromLatin1(name)); + slot.setValue(JSC::throwError(exec, JSC::GeneralError, message)); + return true; + } + + const QMetaObject *meta = qobject->metaObject(); + { + QHash<QByteArray, JSC::JSValue>::const_iterator it = data->cachedMembers.constFind(name); + if (it != data->cachedMembers.constEnd()) { + if (GeneratePropertyFunctions && (meta->indexOfProperty(name) != -1)) + slot.setGetterSlot(JSC::asObject(it.value())); + else + slot.setValue(it.value()); + return true; + } + } + + const QScriptEngine::QObjectWrapOptions &opt = data->options; + QScriptEnginePrivate *eng = scriptEngineFromExec(exec); + int index = -1; + if (name.contains('(')) { + QByteArray normalized = QMetaObject::normalizedSignature(name); + if (-1 != (index = meta->indexOfMethod(normalized))) { + QMetaMethod method = meta->method(index); + if (hasMethodAccess(method, index, opt)) { + if (!(opt & QScriptEngine::ExcludeSuperClassMethods) + || (index >= meta->methodOffset())) { + QtFunction *fun = new (exec)QtFunction( + object, index, /*maybeOverloaded=*/false, + &exec->globalData(), eng->originalGlobalObject()->functionStructure(), + propertyName); + slot.setValue(fun); + data->cachedMembers.insert(name, fun); + return true; + } + } + } + } + + index = meta->indexOfProperty(name); + if (index != -1) { + QMetaProperty prop = meta->property(index); + if (prop.isScriptable()) { + if (!(opt & QScriptEngine::ExcludeSuperClassProperties) + || (index >= meta->propertyOffset())) { + if (GeneratePropertyFunctions) { + QtPropertyFunction *fun = new (exec)QtPropertyFunction( + meta, index, &exec->globalData(), + eng->originalGlobalObject()->functionStructure(), + propertyName); + data->cachedMembers.insert(name, fun); + slot.setGetterSlot(fun); + } else { + JSC::JSValue val; + if (!prop.isValid()) + val = JSC::jsUndefined(); + else + val = eng->jscValueFromVariant(prop.read(qobject)); + slot.setValue(val); + } + return true; + } + } + } + + index = qobject->dynamicPropertyNames().indexOf(name); + if (index != -1) { + JSC::JSValue val = eng->jscValueFromVariant(qobject->property(name)); + slot.setValue(val); + return true; + } + + const int offset = (opt & QScriptEngine::ExcludeSuperClassMethods) + ? meta->methodOffset() : 0; + for (index = meta->methodCount() - 1; index >= offset; --index) { + QMetaMethod method = meta->method(index); + if (hasMethodAccess(method, index, opt) + && (methodName(method) == name)) { + QtFunction *fun = new (exec)QtFunction( + object, index, /*maybeOverloaded=*/true, + &exec->globalData(), eng->originalGlobalObject()->functionStructure(), + propertyName); + slot.setValue(fun); + data->cachedMembers.insert(name, fun); + return true; + } + } + + if (!(opt & QScriptEngine::ExcludeChildObjects)) { + QList<QObject*> children = qobject->children(); + for (index = 0; index < children.count(); ++index) { + 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)); + return true; + } + } + } + + return QScriptObjectDelegate::getOwnPropertySlot(object, exec, propertyName, slot); +} + +void QObjectDelegate::put(QScriptObject *object, JSC::ExecState* exec, + const JSC::Identifier& propertyName, + JSC::JSValue value, JSC::PutPropertySlot &slot) +{ + QByteArray name = ((QString)propertyName.ustring()).toLatin1(); + QObject *qobject = data->value; + if (!qobject) { + QString message = QString::fromLatin1("cannot access member `%0' of deleted QObject") + .arg(QString::fromLatin1(name)); + JSC::throwError(exec, JSC::GeneralError, message); + return; + } + + const QScriptEngine::QObjectWrapOptions &opt = data->options; + const QMetaObject *meta = qobject->metaObject(); + QScriptEnginePrivate *eng = scriptEngineFromExec(exec); + int index = -1; + if (name.contains('(')) { + QByteArray normalized = QMetaObject::normalizedSignature(name); + if (-1 != (index = meta->indexOfMethod(normalized))) { + QMetaMethod method = meta->method(index); + if (hasMethodAccess(method, index, opt)) { + if (!(opt & QScriptEngine::ExcludeSuperClassMethods) + || (index >= meta->methodOffset())) { + data->cachedMembers.insert(name, value); + return; + } + } + } + } + + index = meta->indexOfProperty(name); + if (index != -1) { + QMetaProperty prop = meta->property(index); + if (prop.isScriptable()) { + if (!(opt & QScriptEngine::ExcludeSuperClassProperties) + || (index >= meta->propertyOffset())) { + if (GeneratePropertyFunctions) { + // ### ideally JSC would do this for us already, i.e. find out + // that the property is a setter and call the setter. + // Maybe QtPropertyFunction needs to inherit JSC::GetterSetter. + JSC::JSValue fun; + QHash<QByteArray, JSC::JSValue>::const_iterator it; + it = data->cachedMembers.constFind(name); + if (it != data->cachedMembers.constEnd()) { + fun = it.value(); + } else { + fun = new (exec)QtPropertyFunction( + meta, index, &exec->globalData(), + eng->originalGlobalObject()->functionStructure(), + propertyName); + data->cachedMembers.insert(name, fun); + } + JSC::CallData callData; + JSC::CallType callType = fun.getCallData(callData); + JSC::JSValue argv[1] = { value }; + JSC::ArgList args(argv, 1); + (void)JSC::call(exec, fun, callType, callData, object, args); + } else { + QVariant v; + if (prop.isEnumType() && value.isString() + && !eng->hasDemarshalFunction(prop.userType())) { + // give QMetaProperty::write() a chance to convert from + // string to enum value + v = (QString)value.toString(exec); + } else { + v = eng->jscValueToVariant(value, prop.userType()); + } + (void)prop.write(qobject, v); + } + return; + } + } + } + + const int offset = (opt & QScriptEngine::ExcludeSuperClassMethods) + ? meta->methodOffset() : 0; + for (index = meta->methodCount() - 1; index >= offset; --index) { + QMetaMethod method = meta->method(index); + if (hasMethodAccess(method, index, opt) + && (methodName(method) == name)) { + data->cachedMembers.insert(name, value); + return; + } + } + + index = qobject->dynamicPropertyNames().indexOf(name); + if ((index != -1) || (opt & QScriptEngine::AutoCreateDynamicProperties)) { + QVariant v = eng->scriptValueFromJSCValue(value).toVariant(); + (void)qobject->setProperty(name, v); + return; + } + + QScriptObjectDelegate::put(object, exec, propertyName, value, slot); +} + +bool QObjectDelegate::deleteProperty(QScriptObject *object, JSC::ExecState *exec, + const JSC::Identifier& propertyName, + bool checkDontDelete) +{ + QByteArray name = ((QString)propertyName.ustring()).toLatin1(); + QObject *qobject = data->value; + if (!qobject) { + QString message = QString::fromLatin1("cannot access member `%0' of deleted QObject") + .arg(QString::fromLatin1(name)); + JSC::throwError(exec, JSC::GeneralError, message); + return false; + } + + const QMetaObject *meta = qobject->metaObject(); + { + QHash<QByteArray, JSC::JSValue>::iterator it = data->cachedMembers.find(name); + if (it != data->cachedMembers.end()) { + if (GeneratePropertyFunctions && (meta->indexOfProperty(name) != -1)) + return false; + data->cachedMembers.erase(it); + return true; + } + } + + const QScriptEngine::QObjectWrapOptions &opt = data->options; + int index = meta->indexOfProperty(name); + if (index != -1) { + QMetaProperty prop = meta->property(index); + if (prop.isScriptable() && + (!(opt & QScriptEngine::ExcludeSuperClassProperties) + || (index >= meta->propertyOffset()))) { + return false; + } + } + + index = qobject->dynamicPropertyNames().indexOf(name); + if (index != -1) { + (void)qobject->setProperty(name, QVariant()); + return true; + } + + return QScriptObjectDelegate::deleteProperty(object, exec, propertyName, checkDontDelete); +} + +bool QObjectDelegate::getPropertyAttributes(const QScriptObject *object, + JSC::ExecState *exec, + const JSC::Identifier &propertyName, + unsigned &attributes) const +{ + // ### try to avoid duplicating logic from getOwnPropertySlot() + QByteArray name = ((QString)propertyName.ustring()).toLatin1(); + QObject *qobject = data->value; + if (!qobject) + return false; + + const QScriptEngine::QObjectWrapOptions &opt = data->options; + const QMetaObject *meta = qobject->metaObject(); + int index = -1; + if (name.contains('(')) { + QByteArray normalized = QMetaObject::normalizedSignature(name); + if (-1 != (index = meta->indexOfMethod(normalized))) { + QMetaMethod method = meta->method(index); + if (hasMethodAccess(method, index, opt)) { + if (!(opt & QScriptEngine::ExcludeSuperClassMethods) + || (index >= meta->methodOffset())) { + attributes = QObjectMemberAttribute; + if (opt & QScriptEngine::SkipMethodsInEnumeration) + attributes |= JSC::DontEnum; + return true; + } + } + } + } + + index = meta->indexOfProperty(name); + if (index != -1) { + QMetaProperty prop = meta->property(index); + if (prop.isScriptable()) { + if (!(opt & QScriptEngine::ExcludeSuperClassProperties) + || (index >= meta->propertyOffset())) { + attributes = flagsForMetaProperty(prop); + return true; + } + } + } + + index = qobject->dynamicPropertyNames().indexOf(name); + if (index != -1) { + attributes = QObjectMemberAttribute; + return true; + } + + const int offset = (opt & QScriptEngine::ExcludeSuperClassMethods) + ? meta->methodOffset() : 0; + for (index = meta->methodCount() - 1; index >= offset; --index) { + QMetaMethod method = meta->method(index); + if (hasMethodAccess(method, index, opt) + && (methodName(method) == name)) { + attributes = QObjectMemberAttribute; + if (opt & QScriptEngine::SkipMethodsInEnumeration) + attributes |= JSC::DontEnum; + return true; + } + } + + if (!(opt & QScriptEngine::ExcludeChildObjects)) { + QList<QObject*> children = qobject->children(); + for (index = 0; index < children.count(); ++index) { + QObject *child = children.at(index); + if (child->objectName() == (QString)(propertyName.ustring())) { + attributes = JSC::ReadOnly | JSC::DontDelete | JSC::DontEnum; + return true; + } + } + } + + return QScriptObjectDelegate::getPropertyAttributes(object, exec, propertyName, attributes); +} + +void QObjectDelegate::getPropertyNames(QScriptObject *object, JSC::ExecState *exec, + JSC::PropertyNameArray &propertyNames, + unsigned listedAttributes) +{ + QObject *qobject = data->value; + if (!qobject) { + QString message = QString::fromLatin1("cannot get property names of deleted QObject"); + JSC::throwError(exec, JSC::GeneralError, message); + return; + } + + const QScriptEngine::QObjectWrapOptions &opt = data->options; + const QMetaObject *meta = qobject->metaObject(); + { + int i = (opt & QScriptEngine::ExcludeSuperClassProperties) + ? meta->propertyOffset() : 0; + for ( ; i < meta->propertyCount(); ++i) { + QMetaProperty prop = meta->property(i); + if (isEnumerableMetaProperty(prop, meta, i)) { + QString name = QString::fromLatin1(prop.name()); + propertyNames.add(JSC::Identifier(exec, name)); + } + } + } + + { + QList<QByteArray> dpNames = qobject->dynamicPropertyNames(); + for (int i = 0; i < dpNames.size(); ++i) { + QString name = QString::fromLatin1(dpNames.at(i)); + propertyNames.add(JSC::Identifier(exec, name)); + } + } + + if (!(opt & QScriptEngine::SkipMethodsInEnumeration)) { + int i = (opt & QScriptEngine::ExcludeSuperClassMethods) + ? meta->methodOffset() : 0; + for ( ; i < meta->methodCount(); ++i) { + QMetaMethod method = meta->method(i); + if (hasMethodAccess(method, i, opt)) { + QMetaMethod method = meta->method(i); + QString sig = QString::fromLatin1(method.signature()); + propertyNames.add(JSC::Identifier(exec, sig)); + } + } + } + + QScriptObjectDelegate::getPropertyNames(object, exec, propertyNames, listedAttributes); +} + +void QObjectDelegate::mark(QScriptObject *object) +{ + QHash<QByteArray, JSC::JSValue>::const_iterator it; + for (it = data->cachedMembers.constBegin(); it != data->cachedMembers.constEnd(); ++it) { + JSC::JSValue val = it.value(); + if (val && !val.marked()) + val.mark(); + } + + QScriptObjectDelegate::mark(object); +} + +static JSC::JSValue JSC_HOST_CALL qobjectProtoFuncFindChild(JSC::ExecState *exec, JSC::JSObject*, + JSC::JSValue thisValue, const JSC::ArgList &args) +{ + QScriptEnginePrivate *engine = scriptEngineFromExec(exec); + thisValue = engine->toUsableValue(thisValue); + if (!thisValue.isObject(&QScriptObject::info)) + return throwError(exec, JSC::TypeError, "this object is not a QObject"); + QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(thisValue)); + QScriptObjectDelegate *delegate = scriptObject->delegate(); + if (!delegate || (delegate->type() != QScriptObjectDelegate::QtObject)) + return throwError(exec, JSC::TypeError, "this object is not a QObject"); + QObject *obj = static_cast<QObjectDelegate*>(delegate)->value(); + QString name; + if (args.size() != 0) + name = args.at(0).toString(exec); + QObject *child = qFindChild<QObject*>(obj, name); + QScriptEngine::QObjectWrapOptions opt = QScriptEngine::PreferExistingWrapperObject; + return engine->newQObject(child, QScriptEngine::QtOwnership, opt); +} + +static JSC::JSValue JSC_HOST_CALL qobjectProtoFuncFindChildren(JSC::ExecState *exec, JSC::JSObject*, + JSC::JSValue thisValue, const JSC::ArgList &args) +{ + QScriptEnginePrivate *engine = scriptEngineFromExec(exec); + thisValue = engine->toUsableValue(thisValue); + // extract the QObject + if (!thisValue.isObject(&QScriptObject::info)) + return throwError(exec, JSC::TypeError, "this object is not a QObject"); + QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(thisValue)); + QScriptObjectDelegate *delegate = scriptObject->delegate(); + if (!delegate || (delegate->type() != QScriptObjectDelegate::QtObject)) + return throwError(exec, JSC::TypeError, "this object is not a QObject"); + const QObject *const obj = static_cast<QObjectDelegate*>(delegate)->value(); + + // find the children + QList<QObject *> children; + if (args.size() != 0) { + const JSC::JSValue arg = args.at(0); + if (arg.isObject(&JSC::RegExpObject::info)) { + const QObjectList allChildren= obj->children(); + + JSC::RegExpObject *const regexp = JSC::asRegExpObject(arg); + + const int allChildrenCount = allChildren.size(); + for (int i = 0; i < allChildrenCount; ++i) { + QObject *const child = allChildren.at(i); + const JSC::UString childName = child->objectName(); + JSC::RegExpConstructor* regExpConstructor = engine->originalGlobalObject()->regExpConstructor(); + int position; + int length; + regExpConstructor->performMatch(regexp->regExp(), childName, 0, position, length); + if (position >= 0) + children.append(child); + } + } else { + const QString name(args.at(0).toString(exec)); + children = qFindChildren<QObject*>(obj, name); + } + } else { + children = qFindChildren<QObject*>(obj, QString()); + } + // create the result array with the children + const int length = children.size(); + JSC::JSArray *const result = JSC::constructEmptyArray(exec, length); + + QScriptEngine::QObjectWrapOptions opt = QScriptEngine::PreferExistingWrapperObject; + for (int i = 0; i < length; ++i) { + QObject *const child = children.at(i); + result->put(exec, i, engine->newQObject(child, QScriptEngine::QtOwnership, opt)); + } + return JSC::JSValue(result); +} + +static JSC::JSValue JSC_HOST_CALL qobjectProtoFuncToString(JSC::ExecState *exec, JSC::JSObject*, + JSC::JSValue thisValue, const JSC::ArgList&) +{ + QScriptEnginePrivate *engine = scriptEngineFromExec(exec); + thisValue = engine->toUsableValue(thisValue); + if (!thisValue.isObject(&QScriptObject::info)) + return JSC::jsUndefined(); + QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(thisValue)); + QScriptObjectDelegate *delegate = scriptObject->delegate(); + if (!delegate || (delegate->type() != QScriptObjectDelegate::QtObject)) + return JSC::jsUndefined(); + QObject *obj = static_cast<QObjectDelegate*>(delegate)->value(); + const QMetaObject *meta = obj ? obj->metaObject() : &QObject::staticMetaObject; + QString name = obj ? obj->objectName() : QString::fromUtf8("unnamed"); + QString str = QString::fromUtf8("%0(name = \"%1\")") + .arg(QLatin1String(meta->className())).arg(name); + return JSC::jsString(exec, str); +} + +QObjectPrototype::QObjectPrototype(JSC::ExecState* exec, WTF::PassRefPtr<JSC::Structure> structure, + JSC::Structure* prototypeFunctionStructure) + : QScriptObject(structure) +{ + setDelegate(new QObjectDelegate(new QObjectPrototypeObject(), QScriptEngine::AutoOwnership, + QScriptEngine::ExcludeSuperClassMethods + | QScriptEngine::ExcludeSuperClassProperties + | QScriptEngine::ExcludeChildObjects)); + + putDirectFunction(exec, new (exec) JSC::PrototypeFunction(exec, prototypeFunctionStructure, /*length=*/0, exec->propertyNames().toString, qobjectProtoFuncToString), JSC::DontEnum); + putDirectFunction(exec, new (exec) JSC::PrototypeFunction(exec, prototypeFunctionStructure, /*length=*/1, JSC::Identifier(exec, "findChild"), qobjectProtoFuncFindChild), JSC::DontEnum); + putDirectFunction(exec, new (exec) JSC::PrototypeFunction(exec, prototypeFunctionStructure, /*length=*/1, JSC::Identifier(exec, "findChildren"), qobjectProtoFuncFindChildren), JSC::DontEnum); +} + +const JSC::ClassInfo QMetaObjectWrapperObject::info = { "QMetaObject", 0, 0, 0 }; + +QMetaObjectWrapperObject::QMetaObjectWrapperObject( + JSC::ExecState *exec, const QMetaObject *metaObject, JSC::JSValue ctor, + WTF::PassRefPtr<JSC::Structure> sid) + : JSC::JSObject(sid), + data(new Data(metaObject, ctor)) +{ + if (!ctor) + data->prototype = new (exec)JSC::JSObject(exec->lexicalGlobalObject()->emptyObjectStructure()); +} + +QMetaObjectWrapperObject::~QMetaObjectWrapperObject() +{ + delete data; +} + +bool QMetaObjectWrapperObject::getOwnPropertySlot( + JSC::ExecState *exec, const JSC::Identifier& propertyName, + JSC::PropertySlot &slot) +{ + const QMetaObject *meta = data->value; + if (!meta) + return false; + + if (propertyName == exec->propertyNames().prototype) { + if (data->ctor) + slot.setValue(data->ctor.get(exec, propertyName)); + else + slot.setValue(data->prototype); + return true; + } + + QByteArray name = QString(propertyName.ustring()).toLatin1(); + + for (int i = 0; i < meta->enumeratorCount(); ++i) { + QMetaEnum e = meta->enumerator(i); + for (int j = 0; j < e.keyCount(); ++j) { + const char *key = e.key(j); + if (!qstrcmp(key, name.constData())) { + slot.setValue(JSC::JSValue(exec, e.value(j))); + return true; + } + } + } + + return JSC::JSObject::getOwnPropertySlot(exec, propertyName, slot); +} + +void QMetaObjectWrapperObject::put(JSC::ExecState* exec, const JSC::Identifier& propertyName, + JSC::JSValue value, JSC::PutPropertySlot &slot) +{ + if (propertyName == exec->propertyNames().prototype) { + if (data->ctor) + data->ctor.put(exec, propertyName, value, slot); + else + data->prototype = value; + return; + } + const QMetaObject *meta = data->value; + if (meta) { + QByteArray name = QString(propertyName.ustring()).toLatin1(); + for (int i = 0; i < meta->enumeratorCount(); ++i) { + QMetaEnum e = meta->enumerator(i); + for (int j = 0; j < e.keyCount(); ++j) { + if (!qstrcmp(e.key(j), name.constData())) + return; + } + } + } + JSC::JSObject::put(exec, propertyName, value, slot); +} + +bool QMetaObjectWrapperObject::deleteProperty( + JSC::ExecState *exec, const JSC::Identifier& propertyName, + bool checkDontDelete) +{ + if (propertyName == exec->propertyNames().prototype) + return false; + const QMetaObject *meta = data->value; + if (meta) { + QByteArray name = QString(propertyName.ustring()).toLatin1(); + for (int i = 0; i < meta->enumeratorCount(); ++i) { + QMetaEnum e = meta->enumerator(i); + for (int j = 0; j < e.keyCount(); ++j) { + if (!qstrcmp(e.key(j), name.constData())) + return false; + } + } + } + return JSC::JSObject::deleteProperty(exec, propertyName, checkDontDelete); +} + +bool QMetaObjectWrapperObject::getPropertyAttributes(JSC::ExecState *exec, + const JSC::Identifier &propertyName, + unsigned &attributes) const +{ + if (propertyName == exec->propertyNames().prototype) { + attributes = JSC::DontDelete; + return true; + } + const QMetaObject *meta = data->value; + if (meta) { + QByteArray name = QString(propertyName.ustring()).toLatin1(); + for (int i = 0; i < meta->enumeratorCount(); ++i) { + QMetaEnum e = meta->enumerator(i); + for (int j = 0; j < e.keyCount(); ++j) { + if (!qstrcmp(e.key(j), name.constData())) { + attributes = JSC::ReadOnly | JSC::DontDelete; + return true; + } + } + } + } + return JSC::JSObject::getPropertyAttributes(exec, propertyName, attributes); +} + +void QMetaObjectWrapperObject::getPropertyNames(JSC::ExecState *exec, JSC::PropertyNameArray &propertyNames, unsigned listedAttributes) +{ + const QMetaObject *meta = data->value; + if (!meta) + return; + for (int i = 0; i < meta->enumeratorCount(); ++i) { + QMetaEnum e = meta->enumerator(i); + for (int j = 0; j < e.keyCount(); ++j) + propertyNames.add(JSC::Identifier(exec, e.key(j))); + } + JSC::JSObject::getPropertyNames(exec, propertyNames, listedAttributes); +} + +void QMetaObjectWrapperObject::mark() +{ + Q_ASSERT(!marked()); + if (data->ctor && !data->ctor.marked()) + data->ctor.mark(); + if (data->prototype && !data->prototype.marked()) + data->prototype.mark(); + JSC::JSObject::mark(); +} + +JSC::CallType QMetaObjectWrapperObject::getCallData(JSC::CallData& callData) +{ + callData.native.function = call; + return JSC::CallTypeHost; +} + +JSC::ConstructType QMetaObjectWrapperObject::getConstructData(JSC::ConstructData& constructData) +{ + constructData.native.function = construct; + return JSC::ConstructTypeHost; +} + +JSC::JSValue JSC_HOST_CALL QMetaObjectWrapperObject::call( + JSC::ExecState *exec, JSC::JSObject *callee, + JSC::JSValue thisValue, const JSC::ArgList &args) +{ + QScriptEnginePrivate *eng_p = scriptEngineFromExec(exec); + thisValue = eng_p->toUsableValue(thisValue); + if (!callee->isObject(&QMetaObjectWrapperObject::info)) + return throwError(exec, JSC::TypeError, "callee is not a QMetaObject"); + QMetaObjectWrapperObject *self = static_cast<QMetaObjectWrapperObject*>(callee); + JSC::ExecState *previousFrame = eng_p->currentFrame; + eng_p->pushContext(exec, thisValue, args, callee); + JSC::JSValue result = self->execute(eng_p->currentFrame, args); + eng_p->popContext(); + eng_p->currentFrame = previousFrame; + return result; +} + +JSC::JSObject* QMetaObjectWrapperObject::construct(JSC::ExecState *exec, JSC::JSObject *callee, const JSC::ArgList &args) +{ + QMetaObjectWrapperObject *self = static_cast<QMetaObjectWrapperObject*>(callee); + QScriptEnginePrivate *eng_p = scriptEngineFromExec(exec); + JSC::ExecState *previousFrame = eng_p->currentFrame; + eng_p->pushContext(exec, JSC::JSValue(), args, callee, true); + JSC::JSValue result = self->execute(eng_p->currentFrame, args); + eng_p->popContext(); + eng_p->currentFrame = previousFrame; + if (!result || !result.isObject()) + return 0; + return JSC::asObject(result); +} + +JSC::JSValue QMetaObjectWrapperObject::execute(JSC::ExecState *exec, + const JSC::ArgList &args) +{ + if (data->ctor) { + QScriptEnginePrivate *eng_p = QScript::scriptEngineFromExec(exec); + QScriptContext *ctx = eng_p->contextForFrame(exec); + JSC::CallData callData; + JSC::CallType callType = data->ctor.getCallData(callData); + Q_ASSERT_X(callType == JSC::CallTypeHost, Q_FUNC_INFO, "script constructors not supported"); + if (data->ctor.isObject(&FunctionWithArgWrapper::info)) { + FunctionWithArgWrapper *wrapper = static_cast<FunctionWithArgWrapper*>(JSC::asObject(data->ctor)); + QScriptValue result = wrapper->function()(ctx, QScriptEnginePrivate::get(eng_p), wrapper->arg()); + return eng_p->scriptValueToJSCValue(result); + } else { + Q_ASSERT(data->ctor.isObject(&FunctionWrapper::info)); + FunctionWrapper *wrapper = static_cast<FunctionWrapper*>(JSC::asObject(data->ctor)); + QScriptValue result = wrapper->function()(ctx, QScriptEnginePrivate::get(eng_p)); + return eng_p->scriptValueToJSCValue(result); + } + } else { + const QMetaObject *meta = data->value; + if (meta->constructorCount() > 0) { + JSC::JSValue result = callQtMethod(exec, QMetaMethod::Constructor, /*thisQObject=*/0, + args, meta, meta->constructorCount()-1, /*maybeOverloaded=*/true); + if (!exec->hadException()) { + Q_ASSERT(result && result.isObject(&QScriptObject::info)); + QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(result)); + QScript::QObjectDelegate *delegate = static_cast<QScript::QObjectDelegate*>(object->delegate()); + delegate->setOwnership(QScriptEngine::AutoOwnership); + if (data->prototype) + object->setPrototype(data->prototype); + } + return result; + } else { + QString message = QString::fromLatin1("no constructor for %0") + .arg(QLatin1String(meta->className())); + return JSC::throwError(exec, JSC::TypeError, message); + } + } +} + +struct StaticQtMetaObject : public QObject +{ + static const QMetaObject *get() + { return &static_cast<StaticQtMetaObject*> (0)->staticQtMetaObject; } +}; + +static JSC::JSValue JSC_HOST_CALL qmetaobjectProtoFuncClassName( + JSC::ExecState *exec, JSC::JSObject*, JSC::JSValue thisValue, const JSC::ArgList&) +{ + QScriptEnginePrivate *engine = scriptEngineFromExec(exec); + thisValue = engine->toUsableValue(thisValue); + if (!thisValue.isObject(&QMetaObjectWrapperObject::info)) + return throwError(exec, JSC::TypeError, "this object is not a QMetaObject"); + const QMetaObject *meta = static_cast<QMetaObjectWrapperObject*>(JSC::asObject(thisValue))->value(); + return JSC::jsString(exec, meta->className()); +} + +QMetaObjectPrototype::QMetaObjectPrototype( + JSC::ExecState *exec, WTF::PassRefPtr<JSC::Structure> structure, + JSC::Structure* prototypeFunctionStructure) + : QMetaObjectWrapperObject(exec, StaticQtMetaObject::get(), /*ctor=*/JSC::JSValue(), structure) +{ + putDirectFunction(exec, new (exec) JSC::PrototypeFunction(exec, prototypeFunctionStructure, /*length=*/0, JSC::Identifier(exec, "className"), qmetaobjectProtoFuncClassName), JSC::DontEnum); +} + +static const uint qt_meta_data_QObjectConnectionManager[] = { + + // content: + 1, // revision + 0, // classname + 0, 0, // classinfo + 1, 10, // methods + 0, 0, // properties + 0, 0, // enums/sets + + // slots: signature, parameters, type, tag, flags + 35, 34, 34, 34, 0x0a, + + 0 // eod +}; + +static const char qt_meta_stringdata_QObjectConnectionManager[] = { + "QScript::QObjectConnectionManager\0\0execute()\0" +}; + +const QMetaObject QObjectConnectionManager::staticMetaObject = { + { &QObject::staticMetaObject, qt_meta_stringdata_QObjectConnectionManager, + qt_meta_data_QObjectConnectionManager, 0 } +}; + +const QMetaObject *QObjectConnectionManager::metaObject() const +{ + return &staticMetaObject; +} + +void *QObjectConnectionManager::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_QObjectConnectionManager)) + return static_cast<void*>(const_cast<QObjectConnectionManager*>(this)); + return QObject::qt_metacast(_clname); +} + +int QObjectConnectionManager::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QObject::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + execute(_id, _a); + _id -= slotCounter; + } + return _id; +} + +void QObjectConnectionManager::execute(int slotIndex, void **argv) +{ + JSC::JSValue receiver; + JSC::JSValue slot; + JSC::JSValue senderWrapper; + int signalIndex = -1; + for (int i = 0; i < connections.size(); ++i) { + const QVector<QObjectConnection> &cs = connections.at(i); + for (int j = 0; j < cs.size(); ++j) { + const QObjectConnection &c = cs.at(j); + if (c.slotIndex == slotIndex) { + receiver = c.receiver; + slot = c.slot; + senderWrapper = c.senderWrapper; + signalIndex = i; + break; + } + } + } + Q_ASSERT(slot && slot.isObject()); + + if (engine->isCollecting()) { + qWarning("QtScript: can't execute signal handler during GC"); + // we can't do a script function call during GC, + // so we're forced to ignore this signal + return; + } + +#if 0 + QScriptFunction *fun = engine->convertToNativeFunction(slot); + if (fun == 0) { + // the signal handler has been GC'ed. This can only happen when + // a QObject is owned by the engine, the engine is destroyed, and + // there is a script function connected to the destroyed() signal + Q_ASSERT(signalIndex <= 1); // destroyed(QObject*) + return; + } +#endif + + const QMetaObject *meta = sender()->metaObject(); + const QMetaMethod method = meta->method(signalIndex); + + QList<QByteArray> parameterTypes = method.parameterTypes(); + int argc = parameterTypes.count(); + + JSC::ExecState *exec = engine->currentFrame; + QVector<JSC::JSValue> argsVector; + argsVector.resize(argc); + for (int i = 0; i < argc; ++i) { + // ### optimize -- no need to convert via QScriptValue + QScriptValue actual; + void *arg = argv[i + 1]; + QByteArray typeName = parameterTypes.at(i); + int argType = QMetaType::type(parameterTypes.at(i)); + if (!argType) { + if (typeName == "QVariant") { + actual = engine->scriptValueFromVariant(*reinterpret_cast<QVariant*>(arg)); + } 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); + } + } else { + actual = engine->create(argType, arg); + } + argsVector[i] = engine->scriptValueToJSCValue(actual); + } + JSC::ArgList jscArgs(argsVector.data(), argsVector.size()); + + JSC::JSValue senderObject; + if (senderWrapper && senderWrapper.isObject(&QScriptObject::info)) // ### check if it's actually a QObject wrapper + senderObject = senderWrapper; + else { + QScriptEngine::QObjectWrapOptions opt = QScriptEngine::PreferExistingWrapperObject; + senderObject = engine->newQObject(sender(), QScriptEngine::QtOwnership, opt); + } + + JSC::JSValue thisObject; + if (receiver && receiver.isObject()) + thisObject = receiver; + else + thisObject = engine->globalObject(); + + JSC::CallData callData; + JSC::CallType callType = slot.getCallData(callData); + if (exec->hadException()) + exec->clearException(); // ### otherwise JSC asserts + JSC::call(exec, slot, callType, callData, thisObject, jscArgs); + + if (exec->hadException()) { + engine->emitSignalHandlerException(); + } +} + +QObjectConnectionManager::QObjectConnectionManager(QScriptEnginePrivate *eng) + : engine(eng), slotCounter(0) +{ +} + +QObjectConnectionManager::~QObjectConnectionManager() +{ +} + +void QObjectConnectionManager::mark() +{ + for (int i = 0; i < connections.size(); ++i) { + QVector<QObjectConnection> &cs = connections[i]; + for (int j = 0; j < cs.size(); ++j) + cs[j].mark(); + } +} + +bool QObjectConnectionManager::addSignalHandler( + QObject *sender, int signalIndex, JSC::JSValue receiver, + JSC::JSValue function, JSC::JSValue senderWrapper, + Qt::ConnectionType type) +{ + if (connections.size() <= signalIndex) + connections.resize(signalIndex+1); + QVector<QObjectConnection> &cs = connections[signalIndex]; + int absSlotIndex = slotCounter + metaObject()->methodOffset(); + bool ok = QMetaObject::connect(sender, signalIndex, this, absSlotIndex, type); + if (ok) { + cs.append(QObjectConnection(slotCounter++, receiver, function, senderWrapper)); + QMetaMethod signal = sender->metaObject()->method(signalIndex); + QByteArray signalString; + signalString.append('2'); // signal code + signalString.append(signal.signature()); + static_cast<QObjectNotifyCaller*>(sender)->callConnectNotify(signalString); + } + return ok; +} + +bool QObjectConnectionManager::removeSignalHandler( + QObject *sender, int signalIndex, + JSC::JSValue receiver, JSC::JSValue slot) +{ + if (connections.size() <= signalIndex) + return false; + QVector<QObjectConnection> &cs = connections[signalIndex]; + for (int i = 0; i < cs.size(); ++i) { + const QObjectConnection &c = cs.at(i); + if (c.hasTarget(receiver, slot)) { + int absSlotIndex = c.slotIndex + metaObject()->methodOffset(); + bool ok = QMetaObject::disconnect(sender, signalIndex, this, absSlotIndex); + if (ok) { + cs.remove(i); + QMetaMethod signal = sender->metaObject()->method(signalIndex); + QByteArray signalString; + signalString.append('2'); // signal code + signalString.append(signal.signature()); + static_cast<QScript::QObjectNotifyCaller*>(sender)->callDisconnectNotify(signalString); + } + return ok; + } + } + return false; +} + +QObjectData::QObjectData(QScriptEnginePrivate *eng) + : engine(eng), connectionManager(0) +{ +} + +QObjectData::~QObjectData() +{ + if (connectionManager) { + delete connectionManager; + connectionManager = 0; + } +} + +void QObjectData::mark() +{ + if (connectionManager) + connectionManager->mark(); + { + QList<QScript::QObjectWrapperInfo>::iterator it; + for (it = wrappers.begin(); it != wrappers.end(); ) { + const QScript::QObjectWrapperInfo &info = *it; + if (info.object->marked()) { + ++it; + } else { + it = wrappers.erase(it); + } + } + } +} + +bool QObjectData::addSignalHandler(QObject *sender, + int signalIndex, + JSC::JSValue receiver, + JSC::JSValue slot, + JSC::JSValue senderWrapper, + Qt::ConnectionType type) +{ + if (!connectionManager) + connectionManager = new QObjectConnectionManager(engine); + return connectionManager->addSignalHandler( + sender, signalIndex, receiver, slot, senderWrapper, type); +} + +bool QObjectData::removeSignalHandler(QObject *sender, + int signalIndex, + JSC::JSValue receiver, + JSC::JSValue slot) +{ + if (!connectionManager) + return false; + return connectionManager->removeSignalHandler( + sender, signalIndex, receiver, slot); +} + +QScriptObject *QObjectData::findWrapper(QScriptEngine::ValueOwnership ownership, + const QScriptEngine::QObjectWrapOptions &options) const +{ + for (int i = 0; i < wrappers.size(); ++i) { + const QObjectWrapperInfo &info = wrappers.at(i); + if ((info.ownership == ownership) && (info.options == options)) + return info.object; + } + return 0; +} + +void QObjectData::registerWrapper(QScriptObject *wrapper, + QScriptEngine::ValueOwnership ownership, + const QScriptEngine::QObjectWrapOptions &options) +{ + wrappers.append(QObjectWrapperInfo(wrapper, ownership, options)); +} + +} // namespace QScript + +namespace JSC +{ + ASSERT_CLASS_FITS_IN_CELL(QScript::QtFunction); +} + +QT_END_NAMESPACE + +#include "moc_qscriptqobject_p.cpp" + diff --git a/src/script/bridge/qscriptqobject_p.h b/src/script/bridge/qscriptqobject_p.h new file mode 100644 index 0000000..64853ff --- /dev/null +++ b/src/script/bridge/qscriptqobject_p.h @@ -0,0 +1,337 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCRIPTQOBJECT_P_H +#define QSCRIPTQOBJECT_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 "qscriptobject_p.h" + +#include "qscriptengine.h" +#include <QtCore/qpointer.h> + +#include "InternalFunction.h" + +QT_BEGIN_NAMESPACE + +namespace QScript +{ + +enum AttributeExtension { + // ### Make sure there's no conflict with JSC::Attribute + QObjectMemberAttribute = 1 << 12 +}; + +class QObjectDelegate : public QScriptObjectDelegate +{ +public: + struct Data + { + QPointer<QObject> value; + QScriptEngine::ValueOwnership ownership; + QScriptEngine::QObjectWrapOptions options; + + QHash<QByteArray, JSC::JSValue> cachedMembers; + + Data(QObject *o, QScriptEngine::ValueOwnership own, + QScriptEngine::QObjectWrapOptions opt) + : value(o), ownership(own), options(opt) {} + }; + + QObjectDelegate( + QObject *object, QScriptEngine::ValueOwnership ownership, + const QScriptEngine::QObjectWrapOptions &options); + ~QObjectDelegate(); + + virtual Type type() const; + + virtual bool getOwnPropertySlot(QScriptObject*, JSC::ExecState*, + const JSC::Identifier& propertyName, + JSC::PropertySlot&); + virtual void put(QScriptObject*, JSC::ExecState* exec, + const JSC::Identifier& propertyName, + JSC::JSValue, JSC::PutPropertySlot&); + virtual bool deleteProperty(QScriptObject*, JSC::ExecState*, + const JSC::Identifier& propertyName, + bool checkDontDelete = true); + virtual bool getPropertyAttributes(const QScriptObject*, JSC::ExecState*, + const JSC::Identifier&, + unsigned&) const; + virtual void getPropertyNames(QScriptObject*, JSC::ExecState*, JSC::PropertyNameArray&, + unsigned listedAttributes = JSC::Structure::Prototype); + virtual void mark(QScriptObject*); + + inline QObject *value() const { return data->value; } + inline void setValue(QObject* value) { data->value = value; } + + inline QScriptEngine::ValueOwnership ownership() const + { return data->ownership; } + inline void setOwnership(QScriptEngine::ValueOwnership ownership) + { data->ownership = ownership; } + + inline QScriptEngine::QObjectWrapOptions options() const + { return data->options; } + inline void setOptions(QScriptEngine::QObjectWrapOptions options) + { data->options = options; } + +protected: + Data *data; +}; + +class QObjectPrototypeObject : public QObject +{ + Q_OBJECT +public: + QObjectPrototypeObject(QObject *parent = 0) + : QObject(parent) { } + ~QObjectPrototypeObject() { } +}; + +class QObjectPrototype : public QScriptObject +{ +public: + QObjectPrototype(JSC::ExecState*, WTF::PassRefPtr<JSC::Structure>, + JSC::Structure* prototypeFunctionStructure); +}; + +class QObjectConnectionManager; + +struct QObjectWrapperInfo +{ + QObjectWrapperInfo(QScriptObject *obj, + QScriptEngine::ValueOwnership own, + const QScriptEngine::QObjectWrapOptions &opt) + : object(obj), ownership(own), options(opt) {} + + QScriptObject *object; + QScriptEngine::ValueOwnership ownership; + QScriptEngine::QObjectWrapOptions options; +}; + +class QObjectData // : public QObjectUserData +{ +public: + QObjectData(QScriptEnginePrivate *engine); + ~QObjectData(); + + bool addSignalHandler(QObject *sender, + int signalIndex, + JSC::JSValue receiver, + JSC::JSValue slot, + JSC::JSValue senderWrapper, + Qt::ConnectionType type); + bool removeSignalHandler(QObject *sender, + int signalIndex, + JSC::JSValue receiver, + JSC::JSValue slot); + + QScriptObject *findWrapper(QScriptEngine::ValueOwnership ownership, + const QScriptEngine::QObjectWrapOptions &options) const; + void registerWrapper(QScriptObject *wrapper, + QScriptEngine::ValueOwnership ownership, + const QScriptEngine::QObjectWrapOptions &options); + + void mark(); + +private: + QScriptEnginePrivate *engine; + QScript::QObjectConnectionManager *connectionManager; + QList<QScript::QObjectWrapperInfo> wrappers; +}; + +class QtFunction: public JSC::InternalFunction +{ +public: + // work around CELL_SIZE limitation + struct Data + { + JSC::JSValue object; + int initialIndex; + bool maybeOverloaded; + + Data(JSC::JSValue o, int ii, bool mo) + : object(o), initialIndex(ii), maybeOverloaded(mo) {} + }; + + QtFunction(JSC::JSValue object, int initialIndex, bool maybeOverloaded, + JSC::JSGlobalData*, WTF::PassRefPtr<JSC::Structure>, const JSC::Identifier&); + virtual ~QtFunction(); + + virtual JSC::CallType getCallData(JSC::CallData&); + virtual void mark(); + + virtual const JSC::ClassInfo* classInfo() const { return &info; } + static const JSC::ClassInfo info; + + static JSC::JSValue JSC_HOST_CALL call(JSC::ExecState*, JSC::JSObject*, + JSC::JSValue, const JSC::ArgList&); + + JSC::JSValue execute(JSC::ExecState *exec, JSC::JSValue thisValue, + const JSC::ArgList &args); + + QScriptObject *wrapperObject() const; + QObject *qobject() const; + const QMetaObject *metaObject() const; + int initialIndex() const; + bool maybeOverloaded() const; + int mostGeneralMethod(QMetaMethod *out = 0) const; + QList<int> overloadedIndexes() const; + QString functionName() const; + +private: + Data *data; +}; + +class QtPropertyFunction: public JSC::InternalFunction +{ +public: + // work around CELL_SIZE limitation + struct Data + { + const QMetaObject *meta; + int index; + + Data(const QMetaObject *m, int i) + : meta(m), index(i) {} + }; + + QtPropertyFunction(const QMetaObject *meta, int index, + JSC::JSGlobalData*, WTF::PassRefPtr<JSC::Structure>, + const JSC::Identifier&); + virtual ~QtPropertyFunction(); + + virtual JSC::CallType getCallData(JSC::CallData&); + + virtual const JSC::ClassInfo* classInfo() const { return &info; } + static const JSC::ClassInfo info; + + static JSC::JSValue JSC_HOST_CALL call(JSC::ExecState*, JSC::JSObject*, + JSC::JSValue, const JSC::ArgList&); + + JSC::JSValue execute(JSC::ExecState *exec, JSC::JSValue thisValue, + const JSC::ArgList &args); + + const QMetaObject *metaObject() const; + int propertyIndex() const; + +private: + Data *data; +}; + +class QMetaObjectWrapperObject : public JSC::JSObject +{ +public: + // work around CELL_SIZE limitation + struct Data + { + const QMetaObject *value; + JSC::JSValue ctor; + JSC::JSValue prototype; + + Data(const QMetaObject *mo, JSC::JSValue c) + : value(mo), ctor(c) {} + }; + + explicit QMetaObjectWrapperObject( + JSC::ExecState *, const QMetaObject *metaobject, JSC::JSValue ctor, + WTF::PassRefPtr<JSC::Structure> sid); + ~QMetaObjectWrapperObject(); + + virtual bool getOwnPropertySlot(JSC::ExecState*, + const JSC::Identifier& propertyName, + JSC::PropertySlot&); + virtual void put(JSC::ExecState* exec, const JSC::Identifier& propertyName, + JSC::JSValue, JSC::PutPropertySlot&); + virtual bool deleteProperty(JSC::ExecState*, + const JSC::Identifier& propertyName, + bool checkDontDelete = true); + virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier&, + unsigned&) const; + virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, + unsigned listedAttributes = JSC::Structure::Prototype); + virtual void mark(); + + virtual JSC::CallType getCallData(JSC::CallData&); + virtual JSC::ConstructType getConstructData(JSC::ConstructData&); + + virtual const JSC::ClassInfo* classInfo() const { return &info; } + static const JSC::ClassInfo info; + + static JSC::JSValue JSC_HOST_CALL call(JSC::ExecState*, JSC::JSObject*, + JSC::JSValue, const JSC::ArgList&); + static JSC::JSObject* construct(JSC::ExecState *, JSC::JSObject *, const JSC::ArgList &); + + JSC::JSValue execute(JSC::ExecState *exec, const JSC::ArgList &args); + + inline const QMetaObject *value() const { return data->value; } + inline void setValue(const QMetaObject* value) { data->value = value; } + + static WTF::PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype) + { + return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType)); + } + +protected: + Data *data; +}; + +class QMetaObjectPrototype : public QMetaObjectWrapperObject +{ +public: + QMetaObjectPrototype(JSC::ExecState*, WTF::PassRefPtr<JSC::Structure>, + JSC::Structure* prototypeFunctionStructure); +}; + +} // namespace QScript + +QT_END_NAMESPACE + +#endif diff --git a/src/script/bridge/qscriptvariant.cpp b/src/script/bridge/qscriptvariant.cpp new file mode 100644 index 0000000..ee59e4f --- /dev/null +++ b/src/script/bridge/qscriptvariant.cpp @@ -0,0 +1,162 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "config.h" +#include "qscriptvariant_p.h" + +#include "../api/qscriptengine.h" +#include "../api/qscriptengine_p.h" + +#include "Error.h" +#include "PrototypeFunction.h" +#include "JSString.h" + +QT_BEGIN_NAMESPACE + +namespace JSC +{ +ASSERT_CLASS_FITS_IN_CELL(QScript::QVariantPrototype); +} + +namespace QScript +{ + +QVariantDelegate::QVariantDelegate(const QVariant &value) + : m_value(value) +{ +} + +QVariantDelegate::~QVariantDelegate() +{ +} + +QVariant &QVariantDelegate::value() +{ + return m_value; +} + +void QVariantDelegate::setValue(const QVariant &value) +{ + m_value = value; +} + +QScriptObjectDelegate::Type QVariantDelegate::type() const +{ + return Variant; +} + +static JSC::JSValue JSC_HOST_CALL variantProtoFuncValueOf(JSC::ExecState *exec, JSC::JSObject*, + JSC::JSValue thisValue, const JSC::ArgList&) +{ + QScriptEnginePrivate *engine = scriptEngineFromExec(exec); + thisValue = engine->toUsableValue(thisValue); + if (!thisValue.isObject(&QScriptObject::info)) + return throwError(exec, JSC::TypeError); + QScriptObjectDelegate *delegate = static_cast<QScriptObject*>(JSC::asObject(thisValue))->delegate(); + if (!delegate || (delegate->type() != QScriptObjectDelegate::Variant)) + return throwError(exec, JSC::TypeError); + const QVariant &v = static_cast<QVariantDelegate*>(delegate)->value(); + switch (v.type()) { + case QVariant::Invalid: + return JSC::jsUndefined(); + case QVariant::String: + return JSC::jsString(exec, v.toString()); + + case QVariant::Int: + return JSC::jsNumber(exec, v.toInt()); + + case QVariant::Bool: + return JSC::jsBoolean(v.toBool()); + + case QVariant::Double: + return JSC::jsNumber(exec, v.toDouble()); + +// case QVariant::Char: +// return JSC::jsNumber(exec, v.toChar().unicode()); + + case QVariant::UInt: + return JSC::jsNumber(exec, v.toUInt()); + + default: + ; + } + return thisValue; +} + +static JSC::JSValue JSC_HOST_CALL variantProtoFuncToString(JSC::ExecState *exec, JSC::JSObject *callee, + JSC::JSValue thisValue, const JSC::ArgList &args) +{ + QScriptEnginePrivate *engine = scriptEngineFromExec(exec); + thisValue = engine->toUsableValue(thisValue); + if (!thisValue.isObject(&QScriptObject::info)) + return throwError(exec, JSC::TypeError, "This object is not a QVariant"); + QScriptObjectDelegate *delegate = static_cast<QScriptObject*>(JSC::asObject(thisValue))->delegate(); + if (!delegate || (delegate->type() != QScriptObjectDelegate::Variant)) + return throwError(exec, JSC::TypeError, "This object is not a QVariant"); + const QVariant &v = static_cast<QVariantDelegate*>(delegate)->value(); + JSC::UString result; + JSC::JSValue value = variantProtoFuncValueOf(exec, callee, thisValue, args); + if (value.isObject()) { + result = v.toString(); + if (result.isEmpty()) { + result = "QVariant("; + result += v.typeName(); + result += ")"; + } + } else { + result = value.toString(exec); + } + return JSC::jsString(exec, result); +} + +QVariantPrototype::QVariantPrototype(JSC::ExecState* exec, WTF::PassRefPtr<JSC::Structure> structure, + JSC::Structure* prototypeFunctionStructure) + : QScriptObject(structure) +{ + setDelegate(new QVariantDelegate(QVariant())); + + putDirectFunction(exec, new (exec) JSC::PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, variantProtoFuncToString), JSC::DontEnum); + putDirectFunction(exec, new (exec) JSC::PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().valueOf, variantProtoFuncValueOf), JSC::DontEnum); +} + +} // namespace QScript + +QT_END_NAMESPACE diff --git a/src/script/qscriptrepository_p.h b/src/script/bridge/qscriptvariant_p.h index 3c2f63e..4a97ba3 100644 --- a/src/script/qscriptrepository_p.h +++ b/src/script/bridge/qscriptvariant_p.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef QSCRIPTREPOSITORY_P_H -#define QSCRIPTREPOSITORY_P_H +#ifndef QSCRIPTVARIANT_P_H +#define QSCRIPTVARIANT_P_H // // W A R N I N G @@ -53,35 +53,35 @@ // We mean it. // -#include "qscriptbuffer_p.h" +#include <QtCore/qvariant.h> + +#include "qscriptobject_p.h" QT_BEGIN_NAMESPACE -namespace QScript { +namespace QScript +{ -template <typename Tp, typename Factory> -class Repository +class QVariantDelegate : public QScriptObjectDelegate { public: - inline Repository() { cache.reserve(32); } - inline ~Repository() { qDeleteAll(cache); } + QVariantDelegate(const QVariant &value); + ~QVariantDelegate(); - inline Tp *get() - { - if (cache.isEmpty()) - return Factory::create(); + QVariant &value(); + void setValue(const QVariant &value); - return cache.takeLast(); - } - - inline void release(Tp *item) - { cache.append(item); } + Type type() const; private: - Buffer<Tp*> cache; + QVariant m_value; +}; -private: - Q_DISABLE_COPY(Repository) +class QVariantPrototype : public QScriptObject +{ +public: + QVariantPrototype(JSC::ExecState*, WTF::PassRefPtr<JSC::Structure>, + JSC::Structure* prototypeFunctionStructure); }; } // namespace QScript diff --git a/src/script/instruction.table b/src/script/instruction.table deleted file mode 100644 index 389db18..0000000 --- a/src/script/instruction.table +++ /dev/null @@ -1,87 +0,0 @@ -Q_SCRIPT_DEFINE_OPERATOR(Add) -Q_SCRIPT_DEFINE_OPERATOR(Assign) -Q_SCRIPT_DEFINE_OPERATOR(BitAnd) -Q_SCRIPT_DEFINE_OPERATOR(BitOr) -Q_SCRIPT_DEFINE_OPERATOR(BitXor) -Q_SCRIPT_DEFINE_OPERATOR(BitNot) -Q_SCRIPT_DEFINE_OPERATOR(Branch) -Q_SCRIPT_DEFINE_OPERATOR(BranchTrue) -Q_SCRIPT_DEFINE_OPERATOR(BranchFalse) -Q_SCRIPT_DEFINE_OPERATOR(Call) -Q_SCRIPT_DEFINE_OPERATOR(DeclareLocal) -Q_SCRIPT_DEFINE_OPERATOR(Decr) -Q_SCRIPT_DEFINE_OPERATOR(Delete) -Q_SCRIPT_DEFINE_OPERATOR(Div) -Q_SCRIPT_DEFINE_OPERATOR(Duplicate) -Q_SCRIPT_DEFINE_OPERATOR(EnterWith) -Q_SCRIPT_DEFINE_OPERATOR(Equal) -Q_SCRIPT_DEFINE_OPERATOR(Fetch) -Q_SCRIPT_DEFINE_OPERATOR(FetchField) -Q_SCRIPT_DEFINE_OPERATOR(LazyArguments) -Q_SCRIPT_DEFINE_OPERATOR(GreatOrEqual) -Q_SCRIPT_DEFINE_OPERATOR(GreatThan) -Q_SCRIPT_DEFINE_OPERATOR(HasNextElement) -Q_SCRIPT_DEFINE_OPERATOR(In) -Q_SCRIPT_DEFINE_OPERATOR(Incr) -Q_SCRIPT_DEFINE_OPERATOR(InplaceAdd) -Q_SCRIPT_DEFINE_OPERATOR(InplaceAnd) -Q_SCRIPT_DEFINE_OPERATOR(InplaceDiv) -Q_SCRIPT_DEFINE_OPERATOR(InplaceLeftShift) -Q_SCRIPT_DEFINE_OPERATOR(InplaceMod) -Q_SCRIPT_DEFINE_OPERATOR(InplaceMul) -Q_SCRIPT_DEFINE_OPERATOR(InplaceOr) -Q_SCRIPT_DEFINE_OPERATOR(InplaceRightShift) -Q_SCRIPT_DEFINE_OPERATOR(InplaceSub) -Q_SCRIPT_DEFINE_OPERATOR(InplaceURightShift) -Q_SCRIPT_DEFINE_OPERATOR(InstanceOf) -Q_SCRIPT_DEFINE_OPERATOR(LeaveWith) -Q_SCRIPT_DEFINE_OPERATOR(LeftShift) -Q_SCRIPT_DEFINE_OPERATOR(LessOrEqual) -Q_SCRIPT_DEFINE_OPERATOR(LessThan) -Q_SCRIPT_DEFINE_OPERATOR(LoadFalse) -Q_SCRIPT_DEFINE_OPERATOR(LoadString) -Q_SCRIPT_DEFINE_OPERATOR(LoadNumber) -Q_SCRIPT_DEFINE_OPERATOR(LoadThis) -Q_SCRIPT_DEFINE_OPERATOR(LoadActivation) -Q_SCRIPT_DEFINE_OPERATOR(LoadNull) -Q_SCRIPT_DEFINE_OPERATOR(LoadTrue) -Q_SCRIPT_DEFINE_OPERATOR(LoadUndefined) -Q_SCRIPT_DEFINE_OPERATOR(Mod) -Q_SCRIPT_DEFINE_OPERATOR(Mul) -Q_SCRIPT_DEFINE_OPERATOR(New) -Q_SCRIPT_DEFINE_OPERATOR(NewArray) -Q_SCRIPT_DEFINE_OPERATOR(NewClosure) -Q_SCRIPT_DEFINE_OPERATOR(NewEnumeration) -Q_SCRIPT_DEFINE_OPERATOR(NewObject) -Q_SCRIPT_DEFINE_OPERATOR(NewRegExp) -Q_SCRIPT_DEFINE_OPERATOR(NextElement) -Q_SCRIPT_DEFINE_OPERATOR(Nop) -Q_SCRIPT_DEFINE_OPERATOR(Not) -Q_SCRIPT_DEFINE_OPERATOR(NotEqual) -Q_SCRIPT_DEFINE_OPERATOR(Pop) -Q_SCRIPT_DEFINE_OPERATOR(PostDecr) -Q_SCRIPT_DEFINE_OPERATOR(PostIncr) -Q_SCRIPT_DEFINE_OPERATOR(PutField) -Q_SCRIPT_DEFINE_OPERATOR(Receive) -Q_SCRIPT_DEFINE_OPERATOR(Resolve) -Q_SCRIPT_DEFINE_OPERATOR(Ret) -Q_SCRIPT_DEFINE_OPERATOR(RightShift) -Q_SCRIPT_DEFINE_OPERATOR(StrictEqual) -Q_SCRIPT_DEFINE_OPERATOR(StrictNotEqual) -Q_SCRIPT_DEFINE_OPERATOR(Sub) -Q_SCRIPT_DEFINE_OPERATOR(Swap) -Q_SCRIPT_DEFINE_OPERATOR(ToFirstElement) -Q_SCRIPT_DEFINE_OPERATOR(Throw) -Q_SCRIPT_DEFINE_OPERATOR(TypeOf) -Q_SCRIPT_DEFINE_OPERATOR(UnaryMinus) -Q_SCRIPT_DEFINE_OPERATOR(UnaryPlus) -Q_SCRIPT_DEFINE_OPERATOR(URightShift) -Q_SCRIPT_DEFINE_OPERATOR(InplaceXor) -Q_SCRIPT_DEFINE_OPERATOR(Line) -Q_SCRIPT_DEFINE_OPERATOR(Sync) -Q_SCRIPT_DEFINE_OPERATOR(Halt) -Q_SCRIPT_DEFINE_OPERATOR(BeginCatch) -Q_SCRIPT_DEFINE_OPERATOR(EndCatch) -Q_SCRIPT_DEFINE_OPERATOR(MakeReference) -Q_SCRIPT_DEFINE_OPERATOR(NewString) -Q_SCRIPT_DEFINE_OPERATOR(Debugger) diff --git a/src/script/parser/parser.pri b/src/script/parser/parser.pri new file mode 100644 index 0000000..4839ed2 --- /dev/null +++ b/src/script/parser/parser.pri @@ -0,0 +1,19 @@ +SOURCES += \ + $$PWD/qscriptast.cpp \ + $$PWD/qscriptastvisitor.cpp \ + $$PWD/qscriptgrammar.cpp \ + $$PWD/qscriptsyntaxchecker.cpp \ + $$PWD/qscriptlexer.cpp \ + #$$PWD/qscriptparser.cpp + +HEADERS += \ + $$PWD/qscriptastfwd_p.h \ + $$PWD/qscriptast_p.h \ + $$PWD/qscriptastvisitor_p.h \ + $$PWD/qscriptgrammar_p.h \ + $$PWD/qscriptsyntaxchecker_p.h \ + $$PWD/qscriptlexer_p.h \ + #$$PWD/qscriptparser_p.h + +INCLUDEPATH += \ + $$PWD diff --git a/src/script/qscript.g b/src/script/parser/qscript.g index adce274..39900a8 100644 --- a/src/script/qscript.g +++ b/src/script/parser/qscript.g @@ -89,21 +89,6 @@ ** ** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this @@ -125,8 +110,6 @@ #include <QtCore/QtDebug> -#ifndef QT_NO_SCRIPT - #include <string.h> #include "qscriptengine.h" @@ -156,34 +139,6 @@ ** ** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at http://qt.nokia.com/contact. ** $QT_END_LICENSE$ @@ -211,8 +166,6 @@ #include "qscriptgrammar_p.h" -#ifndef QT_NO_SCRIPT - #include "qscriptastfwd_p.h" QT_BEGIN_NAMESPACE @@ -331,9 +284,7 @@ QScriptParser::QScriptParser(): stack_size(0), sym_stack(0), state_stack(0), - location_stack(0), - error_lineno(0), - error_column(0) + location_stack(0) { } @@ -2111,13 +2062,9 @@ PropertyNameAndValueListOpt: PropertyNameAndValueList ; } QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT ./ /: QT_END_NAMESPACE -#endif // QT_NO_SCRIPT - #endif // QSCRIPTPARSER_P_H :/ diff --git a/src/script/qscriptast.cpp b/src/script/parser/qscriptast.cpp index 0866d74..b0cc171 100644 --- a/src/script/qscriptast.cpp +++ b/src/script/parser/qscriptast.cpp @@ -41,8 +41,6 @@ #include "qscriptast_p.h" -#ifndef QT_NO_SCRIPT - #include "qscriptastvisitor_p.h" QT_BEGIN_NAMESPACE @@ -785,5 +783,3 @@ void DebuggerStatement::accept0(Visitor *visitor) } } // namespace QScript::AST QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptast_p.h b/src/script/parser/qscriptast_p.h index b23bd16..d0e534a 100644 --- a/src/script/qscriptast_p.h +++ b/src/script/parser/qscriptast_p.h @@ -55,8 +55,6 @@ #include <QtCore/QString> -#ifndef QT_NO_SCRIPT - #include "qscriptastvisitor_p.h" QT_BEGIN_NAMESPACE @@ -1495,8 +1493,6 @@ public: } } // namespace AST -#endif // QT_NO_SCRIPT - QT_END_NAMESPACE #endif diff --git a/src/script/qscriptastfwd_p.h b/src/script/parser/qscriptastfwd_p.h index 84c1c24..84c1c24 100644 --- a/src/script/qscriptastfwd_p.h +++ b/src/script/parser/qscriptastfwd_p.h diff --git a/src/script/qscriptastvisitor.cpp b/src/script/parser/qscriptastvisitor.cpp index 196c906..196c906 100644 --- a/src/script/qscriptastvisitor.cpp +++ b/src/script/parser/qscriptastvisitor.cpp diff --git a/src/script/qscriptastvisitor_p.h b/src/script/parser/qscriptastvisitor_p.h index c199e5e..c199e5e 100644 --- a/src/script/qscriptastvisitor_p.h +++ b/src/script/parser/qscriptastvisitor_p.h diff --git a/src/script/qscriptgrammar.cpp b/src/script/parser/qscriptgrammar.cpp index ab1aa19..a2971a0 100644 --- a/src/script/qscriptgrammar.cpp +++ b/src/script/parser/qscriptgrammar.cpp @@ -42,8 +42,6 @@ #include "qscriptgrammar_p.h" -#ifndef QT_NO_SCRIPT - QT_BEGIN_NAMESPACE const char *const QScriptGrammar::spell [] = { @@ -971,5 +969,3 @@ const int QScriptGrammar::action_check [] = { -1, -1, -1, -1, -1, -1, -1, -1}; QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptgrammar_p.h b/src/script/parser/qscriptgrammar_p.h index 80f22d5..43e8b67 100644 --- a/src/script/qscriptgrammar_p.h +++ b/src/script/parser/qscriptgrammar_p.h @@ -57,8 +57,6 @@ #include <QtCore/qglobal.h> -#ifndef QT_NO_SCRIPT - QT_BEGIN_NAMESPACE class QScriptGrammar @@ -203,6 +201,4 @@ public: QT_END_NAMESPACE -#endif // QT_NO_SCRIPT - #endif // QSCRIPTGRAMMAR_P_H diff --git a/src/script/qscriptlexer.cpp b/src/script/parser/qscriptlexer.cpp index 058e659..ea7578f 100644 --- a/src/script/qscriptlexer.cpp +++ b/src/script/parser/qscriptlexer.cpp @@ -39,21 +39,9 @@ ** ****************************************************************************/ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "qscriptengine_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" #include "qscriptlexer_p.h" -#include "qscriptgrammar_p.h" +#include "qscriptgrammar_p.h" #include <ctype.h> #include <stdlib.h> #include <stdio.h> @@ -72,6 +60,8 @@ extern double qstrtod(const char *s00, char const **se, bool *ok); } \ while (0) +typedef double qsreal; // ### + namespace QScript { extern qsreal integerFromString(const char *buf, int size, int radix); } @@ -79,25 +69,14 @@ extern qsreal integerFromString(const char *buf, int size, int radix); QScript::Lexer::Lexer(QScriptEnginePrivate *eng) : driver(eng), yylineno(0), - done(false), - size8(128), size16(128), - pos8(0), pos16(0), - terminator(false), - restrKeyword(false), - delimited(false), - stackToken(-1), - state(Start), - pos(0), + size8(128), size16(128), restrKeyword(false), + stackToken(-1), pos(0), code(0), length(0), - yycolumn(0), - startlineno(0), startcolumn(0), bol(true), current(0), next1(0), next2(0), next3(0), err(NoError), - wantRx(false), check_reserved(true), parenthesesState(IgnoreParentheses), - parenthesesCount(0), prohibitAutomaticSemicolon(false) { // allocate space for read buffers @@ -790,9 +769,10 @@ int QScript::Lexer::lex() case Identifier: if ((token = findReservedWord(buffer16, pos16)) < 0) { /* TODO: close leak on parse error. same holds true for String */ - if (driver) - qsyylval.ustr = driver->intern(buffer16, pos16); - else + if (driver) { + Q_ASSERT_X(false, Q_FUNC_INFO, "not implemented"); + qsyylval.ustr = 0; // driver->intern(buffer16, pos16); + } else qsyylval.ustr = 0; return QScriptGrammar::T_IDENTIFIER; } @@ -808,9 +788,10 @@ int QScript::Lexer::lex() } return token; case String: - if (driver) - qsyylval.ustr = driver->intern(buffer16, pos16); - else + if (driver) { + Q_ASSERT_X(false, Q_FUNC_INFO, "not implemented"); + qsyylval.ustr = 0; // driver->intern(buffer16, pos16); + } else qsyylval.ustr = 0; return QScriptGrammar::T_STRING_LITERAL; case Number: @@ -1077,9 +1058,10 @@ bool QScript::Lexer::scanRegExp(RegExpBodyPrefix prefix) lastWasEscape = !lastWasEscape && (current == '\\'); } else { - if (driver) - pattern = driver->intern(buffer16, pos16); - else + if (driver) { + Q_ASSERT_X(false, Q_FUNC_INFO, "not implemented"); + pattern = 0; // driver->intern(buffer16, pos16); + } else pattern = 0; pos16 = 0; shift(1); @@ -1090,7 +1072,16 @@ bool QScript::Lexer::scanRegExp(RegExpBodyPrefix prefix) flags = 0; while (isIdentLetter(current)) { - int flag = QScript::Ecma::RegExp::flagFromChar(current); + // current version was remade from this line: + //int flag = QScript::Ecma::RegExp::flagFromChar(current); + //code was "inlined" because it was only one call to this function + int flag; + switch (current) { + case 'g': flag = 0x01; break; + case 'm': flag = 0x02; break; + case 'i': flag = 0x04; break; + default: flag = 0; + } if (flag == 0) { errmsg = QString::fromLatin1("Invalid regular expression flag '%0'") .arg(QChar(current)); @@ -1118,5 +1109,3 @@ void QScript::Lexer::syncProhibitAutomaticSemicolon() } QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptlexer_p.h b/src/script/parser/qscriptlexer_p.h index 7a8651c..2d7d3b5 100644 --- a/src/script/qscriptlexer_p.h +++ b/src/script/parser/qscriptlexer_p.h @@ -55,8 +55,6 @@ #include <QtCore/QString> -#ifndef QT_NO_SCRIPT - QT_BEGIN_NAMESPACE class QScriptEnginePrivate; @@ -241,6 +239,4 @@ private: QT_END_NAMESPACE -#endif // QT_NO_SCRIPT - #endif diff --git a/src/script/qscriptparser.cpp b/src/script/parser/qscriptparser.cpp index e14aace..b3880af 100644 --- a/src/script/qscriptparser.cpp +++ b/src/script/parser/qscriptparser.cpp @@ -43,19 +43,9 @@ #include <QtCore/QtDebug> -#ifndef QT_NO_SCRIPT - #include <string.h> -#include "qscriptengine.h" -#include "qscriptengine_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" -#include "qscriptlexer_p.h" #include "qscriptast_p.h" -#include "qscriptnodepool_p.h" #define Q_SCRIPT_UPDATE_POSITION(node, startloc, endloc) do { \ node->startLine = startloc.startLine; \ @@ -88,9 +78,7 @@ QScriptParser::QScriptParser(): stack_size(0), sym_stack(0), state_stack(0), - location_stack(0), - error_lineno(0), - error_column(0) + location_stack(0) { } @@ -1168,5 +1156,3 @@ case 266: { } QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptparser_p.h b/src/script/parser/qscriptparser_p.h index 56736f5..cd463aa 100644 --- a/src/script/qscriptparser_p.h +++ b/src/script/parser/qscriptparser_p.h @@ -62,8 +62,6 @@ #include "qscriptgrammar_p.h" -#ifndef QT_NO_SCRIPT - #include "qscriptastfwd_p.h" QT_BEGIN_NAMESPACE @@ -162,6 +160,4 @@ inline void QScriptParser::reallocateStack() QT_END_NAMESPACE -#endif // QT_NO_SCRIPT - #endif // QSCRIPTPARSER_P_H diff --git a/src/script/qscriptsyntaxchecker.cpp b/src/script/parser/qscriptsyntaxchecker.cpp index b7c4905..ee91c52 100644 --- a/src/script/qscriptsyntaxchecker.cpp +++ b/src/script/parser/qscriptsyntaxchecker.cpp @@ -41,8 +41,6 @@ #include "qscriptsyntaxchecker_p.h" -#ifndef QT_NO_SCRIPT - #include "qscriptlexer_p.h" #include "qscriptparser_p.h" @@ -214,5 +212,3 @@ SyntaxChecker::Result SyntaxChecker::checkSyntax(const QString &code) } // namespace QScript QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptsyntaxchecker_p.h b/src/script/parser/qscriptsyntaxchecker_p.h index 853bb76..5609cc2 100644 --- a/src/script/qscriptsyntaxchecker_p.h +++ b/src/script/parser/qscriptsyntaxchecker_p.h @@ -55,8 +55,6 @@ #include <QtCore/qstring.h> -#ifndef QT_NO_SCRIPT - #include "qscriptgrammar_p.h" QT_BEGIN_NAMESPACE @@ -71,7 +69,7 @@ public: enum State { Error, Intermediate, - Valid + Valid, }; struct Result { @@ -113,6 +111,4 @@ inline void SyntaxChecker::reallocateStack() QT_END_NAMESPACE -#endif // QT_NO_SCRIPT - #endif diff --git a/src/script/qscriptarray_p.h b/src/script/qscriptarray_p.h deleted file mode 100644 index cabac9e..0000000 --- a/src/script/qscriptarray_p.h +++ /dev/null @@ -1,428 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTARRAY_P_H -#define QSCRIPTARRAY_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/QMap> - -#ifndef QT_NO_SCRIPT - -#include <QtCore/QVector> - -#include "qscriptvalueimplfwd_p.h" -#include "qscriptenginefwd_p.h" - -QT_BEGIN_NAMESPACE - -namespace QScript { - -class Array -{ -public: - inline Array(QScriptEnginePrivate *engine); - inline Array(const Array &other); - inline ~Array(); - - inline Array &operator = (const Array &other); - - inline bool isEmpty() const; - inline uint size() const; - inline uint count() const; - inline QScriptValueImpl at(uint index) const; - inline void assign(uint index, const QScriptValueImpl &v); - inline void clear(); - inline void mark(int generation); - inline void resize(uint size); - inline void concat(const Array &other); - inline QScriptValueImpl pop(); - inline void sort(const QScriptValueImpl &comparefn); - inline void splice(qsreal start, qsreal deleteCount, - const QVector<QScriptValueImpl> &items, - Array &other); - inline QList<uint> keys() const; - -private: - enum Mode { - VectorMode, - MapMode - }; - - QScriptEnginePrivate *m_engine; - Mode m_mode; - int m_instances; - - union { - QMap<uint, QScriptValueImpl> *to_map; - QVector<QScriptValueImpl> *to_vector; - }; -}; - -class ArrayElementLessThan -{ -public: - inline ArrayElementLessThan(const QScriptValueImpl &comparefn) - : m_comparefn(comparefn) {} - - inline bool operator()(const QScriptValueImpl &v1, const QScriptValueImpl &v2) const - { - if (!v1.isValid() || v1.isUndefined()) - return false; - if (!v2.isValid() || v2.isUndefined()) - return true; - if (!m_comparefn.isUndefined()) { - ArrayElementLessThan *that = const_cast<ArrayElementLessThan*>(this); - QScriptValueImpl result = that->m_comparefn.call(QScriptValueImpl(), - QScriptValueImplList() << v1 << v2); - return result.toNumber() <= 0; - } - return v1.toString() < v2.toString(); - } - -private: - QScriptValueImpl m_comparefn; -}; - -} // namespace QScript - -inline QScript::Array::Array(QScriptEnginePrivate *engine): - m_engine(engine), - m_mode(VectorMode), - m_instances(0) -{ - to_vector = new QVector<QScriptValueImpl>(); -} - -inline QScript::Array::Array(const Array &other): - m_engine(other.m_engine), - m_mode(other.m_mode), - m_instances(other.m_instances) -{ - if (m_mode == VectorMode) - to_vector = new QVector<QScriptValueImpl> (*other.to_vector); - else - to_map = new QMap<uint, QScriptValueImpl> (*other.to_map); -} - -inline QScript::Array::~Array() -{ - if (m_mode == VectorMode) - delete to_vector; - else - delete to_map; -} - -inline QScript::Array &QScript::Array::operator = (const Array &other) -{ - m_engine = other.m_engine; - m_instances = other.m_instances; - if (m_mode != other.m_mode) { - if (m_mode == VectorMode) - delete to_vector; - else - delete to_map; - m_mode = other.m_mode; - - if (m_mode == VectorMode) - to_vector = new QVector<QScriptValueImpl> (*other.to_vector); - else - to_map = new QMap<uint, QScriptValueImpl> (*other.to_map); - } - - if (m_mode == VectorMode) - *to_vector = *other.to_vector; - else - *to_map = *other.to_map; - - return *this; -} - -inline bool QScript::Array::isEmpty() const -{ - if (m_mode == VectorMode) - return to_vector->isEmpty(); - - return to_map->isEmpty(); -} - -inline uint QScript::Array::size() const -{ - if (m_mode == VectorMode) - return to_vector->size(); - - if (to_map->isEmpty()) - return 0; - - return (--to_map->constEnd()).key(); -} - -inline uint QScript::Array::count() const -{ - return size(); -} - -inline QScriptValueImpl QScript::Array::at(uint index) const -{ - if (m_mode == VectorMode) { - if (index < uint(to_vector->size())) - return to_vector->at(index); - return QScriptValueImpl(); - } else { - return to_map->value(index, QScriptValueImpl()); - } -} - -inline void QScript::Array::assign(uint index, const QScriptValueImpl &v) -{ - if (index >= size()) { - resize(index + 1); - if (v.isValid() && m_engine) - m_engine->adjustBytesAllocated(sizeof(QScriptValueImpl) * (size() - index)); - } - - const QScriptValueImpl &oldv = at(index); - if (oldv.isValid() && (oldv.isObject() || oldv.isString())) - --m_instances; - - if (v.isValid() && (v.isObject() || v.isString())) - ++m_instances; - - if (m_mode == VectorMode) { - to_vector->replace(index, v); - } else { - if (!v.isValid()) - to_map->remove(index); - else - to_map->insert(index, v); - } -} - -inline void QScript::Array::clear() -{ - m_instances = 0; - - if (m_mode == VectorMode) - to_vector->clear(); - - else - to_map->clear(); -} - -inline void QScript::Array::mark(int generation) -{ - if (! m_instances) - return; - - if (m_mode == VectorMode) { - for (int i = 0; i < to_vector->size(); ++i) - to_vector->at(i).mark(generation); - } else { - QMap<uint, QScriptValueImpl>::const_iterator it = to_map->constBegin(); - for (; it != to_map->constEnd(); ++it) - it.value().mark(generation); - } -} - -inline void QScript::Array::resize(uint s) -{ - const uint oldSize = size(); - if (oldSize == s) - return; - - const uint N = 10 * 1024; - - if (m_mode == VectorMode) { - if (s < N) { - to_vector->resize (s); - } else { - // switch to MapMode - QMap<uint, QScriptValueImpl> *m = new QMap<uint, QScriptValueImpl>(); - for (uint i = 0; i < oldSize; ++i) { - if (to_vector->at(i).isValid()) - m->insert(i, to_vector->at(i)); - } - m->insert(s, QScriptValueImpl()); - delete to_vector; - to_map = m; - m_mode = MapMode; - } - } - - else { - if (s < N) { - // switch to VectorMode - QVector<QScriptValueImpl> *v = new QVector<QScriptValueImpl> (s); - QMap<uint, QScriptValueImpl>::const_iterator it = to_map->constBegin(); - for ( ; (it != to_map->constEnd()) && (it.key() < s); ++it) - (*v) [it.key()] = it.value(); - delete to_map; - to_vector = v; - m_mode = VectorMode; - } else { - if (!to_map->isEmpty()) { - QMap<uint, QScriptValueImpl>::iterator it = --to_map->end(); - if (oldSize > s) { - // shrink - while ((it != to_map->end()) && (it.key() >= s)) { - it = to_map->erase(it); - --it; - } - } else { - if ((it.key() == oldSize) && !it.value().isValid()) - to_map->erase(it); - } - } - to_map->insert(s, QScriptValueImpl()); - } - } -} - -inline void QScript::Array::concat(const QScript::Array &other) -{ - uint k = size(); - resize (k + other.size()); - for (uint i = 0; i < other.size(); ++i) { - QScriptValueImpl v = other.at(i); - if (! v.isValid()) - continue; - - assign(k + i, v); - } -} - -inline QScriptValueImpl QScript::Array::pop() -{ - if (isEmpty()) - return QScriptValueImpl(); - - QScriptValueImpl v; - - if (m_mode == VectorMode) - v = to_vector->last(); - else - v = *--to_map->end(); - - resize(size() - 1); - - return v; -} - -inline void QScript::Array::sort(const QScriptValueImpl &comparefn) -{ - ArrayElementLessThan lessThan(comparefn); - if (m_mode == VectorMode) { - qSort(to_vector->begin(), to_vector->end(), lessThan); - } else { - QList<uint> keys = to_map->keys(); - QList<QScriptValueImpl> values = to_map->values(); - qStableSort(values.begin(), values.end(), lessThan); - const uint len = keys.size(); - for (uint i = 0; i < len; ++i) - to_map->insert(keys.at(i), values.at(i)); - } -} - -inline void QScript::Array::splice(qsreal start, qsreal deleteCount, - const QVector<QScriptValueImpl> &items, - Array &other) -{ - const qsreal len = size(); - if (start < 0) - start = qMax(len + start, qsreal(0)); - else if (start > len) - start = len; - deleteCount = qMax(qMin(deleteCount, len - start), qsreal(0)); - - const uint st = uint(start); - const uint dc = uint(deleteCount); - other.resize(dc); - - const uint itemsSize = uint(items.size()); - - if (m_mode == VectorMode) { - for (uint i = 0; i < dc; ++i) - other.assign(i, to_vector->at(st + i)); - if (itemsSize > dc) - to_vector->insert(st, itemsSize - dc, QScriptValueImpl()); - else if (itemsSize < dc) - to_vector->remove(st, dc - itemsSize); - for (uint i = 0; i < itemsSize; ++i) - to_vector->replace(st + i, items.at(i)); - } else { - for (uint i = 0; i < dc; ++i) - other.assign(i, to_map->take(st + i)); - uint del = itemsSize - dc; - if (del != 0) { - for (uint i = st; i < uint(len); ++i) { - if (to_map->contains(i)) - to_map->insert(i + del, to_map->take(i)); - } - resize(uint(len) + del); - } - for (uint i = 0; i < itemsSize; ++i) - to_map->insert(st + i, items.at(i)); - } -} - -inline QList<uint> QScript::Array::keys() const -{ - if (m_mode == VectorMode) - return QList<uint>(); - else - return to_map->keys(); -} - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT - -#endif // QSCRIPTARRAY_P_H diff --git a/src/script/qscriptasm.cpp b/src/script/qscriptasm.cpp deleted file mode 100644 index 08a44a7..0000000 --- a/src/script/qscriptasm.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtCore/QTextStream> - -#ifndef QT_NO_SCRIPT - -#include "qscriptasm_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptengine_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" - -QT_BEGIN_NAMESPACE - -const char *QScriptInstruction::opcode[] = { -#define STR(a) #a -#define Q_SCRIPT_DEFINE_OPERATOR(op) STR(i##op) , -#include "instruction.table" -#undef Q_SCRIPT_DEFINE_OPERATOR -#undef STR -}; - -void QScriptInstruction::print(QTextStream &out) const -{ - out << opcode[op]; - - if (! operand[0].isValid()) - return; - - out << '(' << operand[0].toString(); - - if (operand[1].isValid()) - out << ", " << operand[1].toString(); - - out << ')'; -} - -namespace QScript { - -Code::Code(): - optimized(false), - firstInstruction(0), - lastInstruction(0), - astPool(0) -{ -} - -Code::~Code() -{ - delete[] firstInstruction; -} - -void Code::init(const CompilationUnit &compilation, NodePool *pool) -{ - optimized = false; - const QVector<QScriptInstruction> ilist = compilation.instructions(); - firstInstruction = new QScriptInstruction[ilist.count()]; - lastInstruction = firstInstruction + ilist.count(); - qCopy(ilist.begin(), ilist.end(), firstInstruction); - exceptionHandlers = compilation.exceptionHandlers(); - astPool = pool; -} - -} // namespace QScript - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptasm_p.h b/src/script/qscriptasm_p.h deleted file mode 100644 index 6b01d64..0000000 --- a/src/script/qscriptasm_p.h +++ /dev/null @@ -1,183 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTASM_P_H -#define QSCRIPTASM_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/qglobal.h> - -#ifndef QT_NO_SCRIPT - -#include <QtCore/qvector.h> - -#include "qscriptvalueimplfwd_p.h" - -QT_BEGIN_NAMESPACE - -class QTextStream; - -class QScriptInstruction -{ -public: - enum Operator { -#define Q_SCRIPT_DEFINE_OPERATOR(op) OP_##op, -#include "instruction.table" -#undef Q_SCRIPT_DEFINE_OPERATOR - OP_Dummy - }; - -public: - Operator op; - QScriptValueImpl operand[2]; -#if defined(Q_SCRIPT_DIRECT_CODE) - void *code; -#endif - - void print(QTextStream &out) const; - - static const char *opcode[]; -}; - -namespace QScript { - -class NodePool; - -class ExceptionHandlerDescriptor -{ -public: - ExceptionHandlerDescriptor() - : m_startInstruction(0), - m_endInstruction(0), - m_handlerInstruction(0) {} - - ExceptionHandlerDescriptor( - int startInstruction, - int endInstruction, - int handlerInstruction) - : m_startInstruction(startInstruction), - m_endInstruction(endInstruction), - m_handlerInstruction(handlerInstruction) {} - - inline int startInstruction() const { return m_startInstruction; } - inline int endInstruction() const { return m_endInstruction; } - inline int handlerInstruction() const { return m_handlerInstruction; } - -private: - int m_startInstruction; - int m_endInstruction; - int m_handlerInstruction; -}; - -class CompilationUnit -{ -public: - CompilationUnit(): m_valid(true), - m_errorLineNumber(-1) {} - - bool isValid() const { return m_valid; } - - void setError(const QString &message, int lineNumber) - { - m_errorMessage = message; - m_errorLineNumber = lineNumber; - m_valid = false; - } - - QString errorMessage() const - { return m_errorMessage; } - int errorLineNumber() const - { return m_errorLineNumber; } - - QVector<QScriptInstruction> instructions() const - { return m_instructions; } - void setInstructions(const QVector<QScriptInstruction> &instructions) - { m_instructions = instructions; } - - QVector<ExceptionHandlerDescriptor> exceptionHandlers() const - { return m_exceptionHandlers; } - void setExceptionHandlers(const QVector<ExceptionHandlerDescriptor> &exceptionHandlers) - { m_exceptionHandlers = exceptionHandlers; } - -private: - bool m_valid; - QString m_errorMessage; - int m_errorLineNumber; - QVector<QScriptInstruction> m_instructions; - QVector<ExceptionHandlerDescriptor> m_exceptionHandlers; -}; - -class Code -{ -public: - Code(); - ~Code(); - - void init(const CompilationUnit &compilation, NodePool *astPool); - -public: // attributes - bool optimized; - QScriptInstruction *firstInstruction; - QScriptInstruction *lastInstruction; - QVector<ExceptionHandlerDescriptor> exceptionHandlers; - NodePool *astPool; - -private: - Q_DISABLE_COPY(Code) -}; - - -} // namespace QScript - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT -#endif // QSCRIPTASM_P_H diff --git a/src/script/qscriptbuffer_p.h b/src/script/qscriptbuffer_p.h deleted file mode 100644 index 0551451..0000000 --- a/src/script/qscriptbuffer_p.h +++ /dev/null @@ -1,211 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTBUFFER_P_H -#define QSCRIPTBUFFER_P_H - -#include <QtCore/qglobal.h> - -#if defined(Q_OS_VXWORKS) && defined(m_data) -# undef m_data -#endif - - -QT_BEGIN_NAMESPACE - -// -// 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. -// - -namespace QScript -{ - template <typename T> class Buffer - { - public: - typedef T *iterator; - typedef const T *const_iterator; - - Buffer() : m_data(0), m_capacity(0), m_size(0) { } - ~Buffer() { delete [] m_data; } - - inline void reserve(int num); - inline void reset(); - inline void clear(); - inline void append(const T &t); - - inline iterator begin(); - inline iterator end(); - - inline const_iterator begin() const; - inline const_iterator end() const; - - inline int size() const; - inline void resize(int s); - - inline int capacity() const; - inline T *data(); - inline const T *constData() const; - - inline T &last(); - inline T &takeLast(); - - inline T &at(int i) { return (*this)[i]; } - inline const T &at(int i) const { return (*this)[i]; } - - inline T &operator[](int i); - inline const T &operator[](int i) const; - - inline bool isEmpty() const; - - private: - T *m_data; - int m_capacity; - int m_size; - - private: - Q_DISABLE_COPY(Buffer) - }; - -} // namespace QScript - -template <typename T> T *QScript::Buffer<T>::data() { return m_data; } -template <typename T> const T *QScript::Buffer<T>::constData() const { return m_data; } -template <typename T> void QScript::Buffer<T>::reset() { m_size = 0; } -template <typename T> int QScript::Buffer<T>::capacity() const { return m_capacity; } - -template <typename T> int QScript::Buffer<T>::size() const { return m_size; } -template <typename T> void QScript::Buffer<T>::resize(int s) -{ - if (m_capacity < s) - reserve (s << 1); - - m_size = s; -} - -template <typename T> void QScript::Buffer<T>::clear() -{ - delete [] m_data; - m_data = 0; - m_size = 0; - m_capacity = 0; -} - -template <typename T> void QScript::Buffer<T>::reserve(int x) -{ - // its an ever expanding buffer so it never gets smaller.. - if (x < m_capacity) - return; - m_capacity = x; - T *new_data = new T[m_capacity]; - for (int i=0; i<m_size; ++i) - new_data[i] = m_data[i]; - delete [] m_data; - m_data = new_data; -} - -template <typename T> void QScript::Buffer<T>::append(const T &t) -{ - if (m_size == m_capacity) - reserve(m_capacity + 32); - m_data[m_size++] = t; -} - -template <typename T> T &QScript::Buffer<T>::operator[](int i) -{ - Q_ASSERT(i >= 0); - Q_ASSERT(i < m_size); - return m_data[i]; -} - -template <typename T> const T &QScript::Buffer<T>::operator[](int i) const -{ - Q_ASSERT(i >= 0); - Q_ASSERT(i < m_size); - return m_data[i]; -} - -template <typename T> bool QScript::Buffer<T>::isEmpty() const -{ - return m_size == 0; -} - -template <typename T> T &QScript::Buffer<T>::takeLast() -{ - Q_ASSERT(!isEmpty()); - --m_size; - return m_data[m_size]; -} - -template <typename T> T &QScript::Buffer<T>::last() -{ - return m_data[m_size - 1]; -} - -template <typename T> typename QScript::Buffer<T>::iterator QScript::Buffer<T>::begin() -{ - return m_data; -} - -template <typename T> typename QScript::Buffer<T>::iterator QScript::Buffer<T>::end() -{ - return m_data + m_size; -} - -template <typename T> typename QScript::Buffer<T>::const_iterator QScript::Buffer<T>::begin() const -{ - return m_data; -} - -template <typename T> typename QScript::Buffer<T>::const_iterator QScript::Buffer<T>::end() const -{ - return m_data + m_size; -} - -QT_END_NAMESPACE - -#endif diff --git a/src/script/qscriptclassdata.cpp b/src/script/qscriptclassdata.cpp deleted file mode 100644 index 29e03d9..0000000 --- a/src/script/qscriptclassdata.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qscriptclassdata_p.h" - -#ifndef QT_NO_SCRIPT - -QT_BEGIN_NAMESPACE - -QScriptClassData::QScriptClassData() -{ -} - -QScriptClassData::~QScriptClassData() -{ -} - -void QScriptClassData::mark(const QScriptValueImpl &, int) -{ -} - -bool QScriptClassData:: resolve(const QScriptValueImpl &, QScriptNameIdImpl *, - QScript::Member *, QScriptValueImpl *, - QScript::AccessMode) -{ - return false; -} - -bool QScriptClassData::get(const QScriptValueImpl &, const QScript::Member &, - QScriptValueImpl *) -{ - Q_ASSERT_X(false, "QScriptClassData::get()", - "implement if resolveMember is implemented"); - return false; -} - -bool QScriptClassData::put(QScriptValueImpl *, const QScript::Member &, - const QScriptValueImpl &) -{ - Q_ASSERT_X(false, "QScriptClassData::put()", - "implement if resolveMember is implemented"); - return false; -} - -bool QScriptClassData::removeMember(const QScriptValueImpl &, - const QScript::Member &) -{ - return true; -} - -bool QScriptClassData::implementsHasInstance(const QScriptValueImpl &) -{ - return false; -} - -bool QScriptClassData::hasInstance(const QScriptValueImpl &, - const QScriptValueImpl &) -{ - Q_ASSERT_X(false, "QScriptClassData::hasInstance()", - "implement if implementsHasInstance() returns true"); - return false; -} - -QScriptClassDataIterator *QScriptClassData::newIterator(const QScriptValueImpl &) -{ - return 0; -} - -QScriptClassDataIterator::QScriptClassDataIterator() -{ -} - -QScriptClassDataIterator::~QScriptClassDataIterator() -{ -} - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptclassdata_p.h b/src/script/qscriptclassdata_p.h deleted file mode 100644 index 69093ba..0000000 --- a/src/script/qscriptclassdata_p.h +++ /dev/null @@ -1,119 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTCLASSDATA_P_H -#define QSCRIPTCLASSDATA_P_H - -#include "qscriptglobals_p.h" - -#ifndef QT_NO_SCRIPT - -QT_BEGIN_NAMESPACE - -// -// 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. -// - -class QScriptValueImpl; -class QScriptNameIdImpl; -class QScriptClassDataIterator; - -namespace QScript { - class Member; -} - -class QScriptClassData -{ -protected: - QScriptClassData(); - -public: - virtual ~QScriptClassData(); - - virtual void mark(const QScriptValueImpl &object, int generation); - virtual bool resolve(const QScriptValueImpl &object, QScriptNameIdImpl *nameId, - QScript::Member *member, QScriptValueImpl *base, - QScript::AccessMode access); - virtual bool get(const QScriptValueImpl &obj, const QScript::Member &m, - QScriptValueImpl *result); - virtual bool put(QScriptValueImpl *object, const QScript::Member &member, - const QScriptValueImpl &value); - virtual bool removeMember(const QScriptValueImpl &object, - const QScript::Member &member); - virtual bool implementsHasInstance(const QScriptValueImpl &object); - virtual bool hasInstance(const QScriptValueImpl &object, - const QScriptValueImpl &value); - virtual QScriptClassDataIterator *newIterator(const QScriptValueImpl &object); - -private: - Q_DISABLE_COPY(QScriptClassData) -}; - -class QScriptClassDataIterator -{ -protected: - QScriptClassDataIterator(); - -public: - virtual ~QScriptClassDataIterator(); - - virtual bool hasNext() const = 0; - virtual void next(QScript::Member *member) = 0; - - virtual bool hasPrevious() const = 0; - virtual void previous(QScript::Member *member) = 0; - - virtual void toFront() = 0; - virtual void toBack() = 0; -}; - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT - -#endif // QSCRIPTCLASSDATA_P_H diff --git a/src/script/qscriptclassinfo_p.h b/src/script/qscriptclassinfo_p.h deleted file mode 100644 index 6f7b761..0000000 --- a/src/script/qscriptclassinfo_p.h +++ /dev/null @@ -1,126 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTCLASSINFO_P_H -#define QSCRIPTCLASSINFO_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. -// - -#if defined(Q_OS_VXWORKS) && defined(m_type) -# undef m_type -#endif - -#include "qscriptclassdata_p.h" - -#ifndef QT_NO_SCRIPT - -#include <QtCore/qstring.h> - -QT_BEGIN_NAMESPACE - -class QScriptClassInfo -{ -public: - enum Type { - FunctionBased = 0x40000000, - - ObjectType = 1, - FunctionType = 2 | FunctionBased, - ArrayType = 3, - StringType = 4, - BooleanType = 5, - NumberType = 6, - DateType = 7, - RegExpType = 8, - ErrorType = 9, - - VariantType = 10, - QObjectType = 11, - QMetaObjectType = 12 | FunctionBased, - - // Types used by the runtime - ActivationType = 100, - EnumerationType = 101, - - CustomType = 1000, - - TypeMask = 0x0000FFFF - }; - - inline QScriptClassInfo(QScriptEnginePrivate *engine, Type type, const QString &name) - : m_engine(engine), m_type(type), m_name(name), m_data(0) { } - inline ~QScriptClassInfo() { delete m_data; } - - inline QScriptEnginePrivate *engine() const - { return m_engine; } - inline Type type() const - { return m_type; } - inline QString name() const - { return m_name; } - - inline void setData(QScriptClassData *data) - { m_data = data; } - QScriptClassData *data() const - { return m_data; } - -private: - QScriptEnginePrivate *m_engine; - Type m_type; - QString m_name; - QScriptClassData *m_data; - -private: - Q_DISABLE_COPY(QScriptClassInfo) -}; - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT -#endif // QSCRIPTCLASSINFO_P_H diff --git a/src/script/qscriptclasspropertyiterator_p.h b/src/script/qscriptclasspropertyiterator_p.h deleted file mode 100644 index 8fe42aa..0000000 --- a/src/script/qscriptclasspropertyiterator_p.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTCLASSPROPERTYITERATOR_P_H -#define QSCRIPTCLASSPROPERTYITERATOR_P_H - -#include <QtCore/qobjectdefs.h> - -#ifndef QT_NO_SCRIPT - -#include "qscriptvalue.h" - -QT_BEGIN_NAMESPACE - -// -// 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. -// - -class QScriptClassPropertyIterator; -class QScriptClassPropertyIteratorPrivate -{ - Q_DECLARE_PUBLIC(QScriptClassPropertyIterator) -public: - QScriptClassPropertyIteratorPrivate(QScriptClassPropertyIterator*); - virtual ~QScriptClassPropertyIteratorPrivate(); - - QScriptValue object; - - QScriptClassPropertyIterator *q_ptr; -}; - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT - -#endif diff --git a/src/script/qscriptcompiler.cpp b/src/script/qscriptcompiler.cpp deleted file mode 100644 index 9f60db0..0000000 --- a/src/script/qscriptcompiler.cpp +++ /dev/null @@ -1,2111 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qscriptcompiler_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptast_p.h" -#include "qscriptengine_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" - -#include <QtCore/QtDebug> - -QT_BEGIN_NAMESPACE - -namespace QScript { - -class Compare : protected AST::Visitor -{ -public: - bool operator()(AST::ExpressionNode *e1, AST::ExpressionNode *e2) - { - if (!e1 || !e2) - return (e1 == e2); - - if (e1->kind != e2->kind) - return false; - - m_e2 = e2; - m_equal = false; - e1->accept(this); - return m_equal; - } - -protected: - virtual bool visit(AST::ThisExpression *) - { - m_equal = true; - return false; - } - virtual bool visit(AST::NullExpression *) - { - m_equal = true; - return false; - } - virtual bool visit(AST::VoidExpression *) - { - m_equal = true; - return false; - } - virtual bool visit(AST::FalseLiteral *) - { - m_equal = true; - return false; - } - virtual bool visit(AST::TrueLiteral *) - { - m_equal = true; - return false; - } - virtual bool visit(AST::NumericLiteral *e1) - { - AST::NumericLiteral *e2 = static_cast<AST::NumericLiteral*>(m_e2); - m_equal = (e1->value == e2->value); - return false; - } - virtual bool visit(AST::RegExpLiteral *e1) - { - AST::RegExpLiteral *e2 = static_cast<AST::RegExpLiteral*>(m_e2); - m_equal = (e1->pattern == e2->pattern) - && (e1->flags == e2->flags); - return false; - } - virtual bool visit(AST::StringLiteral *e1) - { - AST::StringLiteral *e2 = static_cast<AST::StringLiteral*>(m_e2); - m_equal = (e1->value == e2->value); - return false; - } - virtual bool visit(AST::IdentifierExpression *e1) - { - AST::IdentifierExpression *e2 = static_cast<AST::IdentifierExpression*>(m_e2); - m_equal = (e1->name == e2->name); - return false; - } - virtual bool visit(AST::ArrayMemberExpression *e1) - { - AST::ArrayMemberExpression *e2 = static_cast<AST::ArrayMemberExpression*>(m_e2); - m_equal = operator()(e1->base, e2->base) - && operator()(e1->expression, e2->expression); - return false; - } - virtual bool visit(AST::FieldMemberExpression *e1) - { - AST::FieldMemberExpression *e2 = static_cast<AST::FieldMemberExpression*>(m_e2); - m_equal = (e1->name == e2->name) && operator()(e1->base, e2->base); - return false; - } - virtual bool visit(AST::BinaryExpression *e1) - { - AST::BinaryExpression *e2 = static_cast<AST::BinaryExpression*>(m_e2); - m_equal = (e1->op == e2->op) && operator()(e1->left, e2->left) - && operator()(e1->right, e2->right); - return false; - } - virtual bool visit(AST::ConditionalExpression *e1) - { - AST::ConditionalExpression *e2 = static_cast<AST::ConditionalExpression*>(m_e2); - m_equal = operator()(e1->expression, e2->expression) - && operator()(e1->ok, e2->ok) - && operator()(e1->ko, e2->ko); - return false; - } - virtual bool visit(AST::TypeOfExpression *e1) - { - AST::TypeOfExpression *e2 = static_cast<AST::TypeOfExpression*>(m_e2); - m_equal = operator()(e1->expression, e2->expression); - return false; - } - virtual bool visit(AST::UnaryPlusExpression *e1) - { - AST::UnaryPlusExpression *e2 = static_cast<AST::UnaryPlusExpression*>(m_e2); - m_equal = operator()(e1->expression, e2->expression); - return false; - } - virtual bool visit(AST::UnaryMinusExpression *e1) - { - AST::UnaryMinusExpression *e2 = static_cast<AST::UnaryMinusExpression*>(m_e2); - m_equal = operator()(e1->expression, e2->expression); - return false; - } - virtual bool visit(AST::TildeExpression *e1) - { - AST::TildeExpression *e2 = static_cast<AST::TildeExpression*>(m_e2); - m_equal = operator()(e1->expression, e2->expression); - return false; - } - virtual bool visit(AST::NotExpression *e1) - { - AST::NotExpression *e2 = static_cast<AST::NotExpression*>(m_e2); - m_equal = operator()(e1->expression, e2->expression); - return false; - } - virtual bool visit(AST::Expression *) - { return false; } - virtual bool visit(AST::ArrayLiteral *) - { return false; } - virtual bool visit(AST::ObjectLiteral *) - { return false; } - virtual bool visit(AST::CallExpression *) - { return false; } - virtual bool visit(AST::DeleteExpression *) - { return false; } - virtual bool visit(AST::FunctionExpression *) - { return false; } - virtual bool visit(AST::NewExpression *) - { return false; } - virtual bool visit(AST::NewMemberExpression *) - { return false; } - virtual bool visit(AST::PostDecrementExpression *) - { return false; } - virtual bool visit(AST::PostIncrementExpression *) - { return false; } - virtual bool visit(AST::PreDecrementExpression *) - { return false; } - virtual bool visit(AST::PreIncrementExpression *) - { return false; } - -private: - AST::ExpressionNode *m_e2; - bool m_equal; -}; - -class FetchName: protected AST::Visitor -{ -public: - inline FetchName(QScriptEnginePrivate *e): - eng(e), name(0) {} - - QScriptNameIdImpl *operator() (AST::PropertyName *node) - { - name = 0; - node->accept(this); - return name; - } - -protected: - virtual bool visit(AST::IdentifierPropertyName *node) - { - name = node->id; - return false; - } - - virtual bool visit(AST::StringLiteralPropertyName *node) - { - name = node->id; - return false; - } - - virtual bool visit(AST::NumericLiteralPropertyName *node) - { - name = eng->nameId(QString::number(node->id), /*persistent=*/false); // ### don't use QString::number - name->persistent = true; // ### remove - return false; - } - -private: - QScriptEnginePrivate *eng; - QScriptNameIdImpl *name; -}; - -class EmptySourceElements: protected AST::Visitor -{ -public: - EmptySourceElements(QScriptEngine *d): - driver(d), empty(false) {} - - inline bool operator () (AST::Node *) - { - empty = false; - return empty; - } - -private: - QScriptEngine *driver; - bool empty; -}; - -class DeclareLocals: protected AST::Visitor -{ -public: - DeclareLocals(Compiler *c): - compiler(c), - eng(c->engine()) - { - } - - void operator () (AST::Node *node) - { - if (node) - node->accept(this); - } - -protected: - virtual bool visit(AST::FunctionDeclaration *node) - { - compiler->iDeclareLocal(node->name, /*readOnly=*/false); - return false; - } - - virtual bool visit(AST::FunctionExpression *) - { return false; } - - virtual bool visit(AST::VariableDeclaration *node) - { - compiler->iDeclareLocal(node->name, node->readOnly); - return false; - } - -private: - Compiler *compiler; - QScriptEnginePrivate *eng; -}; - -Compiler::Compiler(QScriptEnginePrivate *eng): - m_eng(eng), - m_generateReferences(0), m_iterationStatement(0), - m_switchStatement(0), m_withStatement(0), - m_generateLeaveWithOnBreak(0), m_generateFastArgumentLookup(0), - m_parseStatements(0), m_pad(0), - m_topLevelCompiler(false), - m_activeLoop(0) -{ -} - -Compiler::~Compiler() -{ -} - -bool Compiler::topLevelCompiler() const -{ - return m_topLevelCompiler; -} - -void Compiler::setTopLevelCompiler(bool b) -{ - m_topLevelCompiler = b; -} - - CompilationUnit Compiler::compile(AST::Node *node, const QList<QScriptNameIdImpl *> &formals) -{ - m_formals = formals; - m_generateReferences = 0; - m_iterationStatement = 0; - m_switchStatement = 0; - m_withStatement = 0; - m_generateLeaveWithOnBreak = 0; - m_generateFastArgumentLookup = 0; - m_parseStatements = 0; - m_pad = 0; - m_instructions.clear(); - m_exceptionHandlers.clear(); - m_generateFastArgumentLookup = false; // ### !formals.isEmpty(); // ### disabled for now.. it's buggy :( - - m_compilationUnit = CompilationUnit(); - - if (node) - node->accept(this); - - // add a terminator - if (topLevelCompiler()) { - iHalt(); - } else if (m_instructions.isEmpty() || m_instructions.last().op != QScriptInstruction::OP_Ret) { - iLoadUndefined(); - iRet(); - } - - m_compilationUnit.setInstructions(m_instructions); - m_compilationUnit.setExceptionHandlers(m_exceptionHandlers); - return m_compilationUnit; -} - -bool Compiler::preVisit(AST::Node *) -{ - return m_compilationUnit.isValid(); -} - -bool Compiler::visit(AST::SourceElements *node) -{ - DeclareLocals declareLocals(this); - declareLocals(node); - - bool was = changeParseStatements(false); - - for (AST::SourceElements *it = node; it != 0; it = it->next) - it->element->accept(this); - - changeParseStatements(true); - - for (AST::SourceElements *it = node; it != 0; it = it->next) - it->element->accept(this); - - changeParseStatements(was); - - return false; -} - -bool Compiler::visit(AST::StatementList *) -{ - return true; -} - -bool Compiler::visit(AST::FunctionSourceElement *) -{ - return m_parseStatements == 0; -} - -bool Compiler::visit(AST::StatementSourceElement *) -{ - return m_parseStatements; -} - -bool Compiler::visit(AST::ThisExpression *) -{ - iLoadThis(); - return false; -} - -bool Compiler::visit(AST::NullExpression *) -{ - iLoadNull(); - return false; -} - -bool Compiler::visit(AST::RegExpLiteral *node) -{ - Q_ASSERT(node->pattern != 0); - - if (node->flags) - iNewRegExp(node->pattern, node->flags); - else - iNewRegExp(node->pattern); - - return false; -} - -bool Compiler::visit(AST::NumericLiteral *node) -{ - iLoadNumber(node->value); - return false; -} - -bool Compiler::visit(AST::StringLiteral *node) -{ - iNewString(node->value); - - return false; -} - -bool Compiler::visit(AST::ObjectLiteral *node) -{ - iNewObject(); - - FetchName fetchName(m_eng); - bool was = generateReferences(false); - for (AST::PropertyNameAndValueList *it = node->properties; it != 0; it = it->next) { - iLine(it->value); - iDuplicate(); - - QScriptNameIdImpl *name = fetchName(it->name); - Q_ASSERT(name != 0); - iLoadString(name); - iMakeReference(); - - it->value->accept(this); - iPutField(); - } - generateReferences(was); - - return false; -} - -bool Compiler::visit(AST::IdentifierExpression *node) -{ - Q_ASSERT(node->name != 0); - - if (node->name == m_eng->idTable()->id_arguments) - iLazyArguments(); - if (m_generateReferences) - iResolve(node->name); - else - iFetch(node->name); - - return false; -} - -bool Compiler::visit(AST::FunctionDeclaration *node) -{ - iLoadActivation(); - iLoadString(node->name); - iMakeReference(); - iNewClosure(node); - iPutField(); - return false; -} - -bool Compiler::visit(AST::FunctionExpression *node) -{ - iNewClosure(node); - if (node->name) { - iDuplicate(); - iLoadActivation(); - iSwap(); - iLoadString(node->name); - iSwap(); - iMakeReference(); - iSwap(); - iPutField(); - } - return false; -} - -bool Compiler::visit(AST::CallExpression *node) -{ - bool was = generateReferences(true); - node->base->accept(this); - generateReferences(false); - - int argc = 0; - for (AST::ArgumentList *it = node->arguments; it != 0; it = it->next) { - it->expression->accept(this); - ++argc; - } - - generateReferences(was); - - iCall(argc); - return false; -} - -bool Compiler::visit(AST::NewExpression *node) -{ - bool was = generateReferences(true); - node->expression->accept(this); - generateReferences(was); - iNew(0); - return false; -} - -bool Compiler::visit(AST::NewMemberExpression *node) -{ - bool was = generateReferences(true); - node->base->accept(this); - generateReferences(false); - - int argc = 0; - for (AST::ArgumentList *it = node->arguments; it != 0; it = it->next) { - it->expression->accept(this); - ++argc; - } - - generateReferences(was); - - iNew(argc); - return false; -} - -bool Compiler::visit(AST::FieldMemberExpression *node) -{ - bool was = generateReferences(false); - node->base->accept(this); - generateReferences(was); - - iLoadString(node->name); - - if (! was) - iFetchField(); - else - iMakeReference(); - - return false; -} - -bool Compiler::visit(AST::ArrayMemberExpression *node) -{ - bool was = generateReferences(false); - node->base->accept(this); - node->expression->accept(this); - generateReferences(was); - - if (! was) - iFetchField(); - else - iMakeReference(); - - return false; -} - -bool Compiler::visit(AST::PostIncrementExpression *node) -{ - bool was = generateReferences(true); - node->base->accept(this); - generateReferences(was); - iPostIncr(); - - return false; -} - -bool Compiler::visit(AST::PostDecrementExpression *node) -{ - bool was = generateReferences(true); - node->base->accept(this); - generateReferences(was); - iPostDecr(); - - return false; -} - -bool Compiler::visit(AST::PreIncrementExpression *node) -{ - bool was = generateReferences(true); - node->expression->accept(this); - generateReferences(was); - iIncr(); - return false; -} - -bool Compiler::visit(AST::PreDecrementExpression *node) -{ - bool was = generateReferences(true); - node->expression->accept(this); - generateReferences(was); - iDecr(); - return false; -} - -void Compiler::endVisit(AST::NotExpression *) -{ - iNot(); -} - -void Compiler::endVisit(AST::TildeExpression *) -{ - iBitNot(); -} - -bool Compiler::visit(AST::ThrowStatement *node) -{ - iLine(node); - return true; -} - -bool Compiler::visit(AST::TryStatement *node) -{ - int start = nextInstructionOffset(); - if (node->statement) - node->statement->accept(this); - int end = nextInstructionOffset(); - if (node->catchExpression) { - iBranch(0); // skip the catch if no exception - ExceptionHandlerDescriptor ehd(start, end, nextInstructionOffset()); - m_exceptionHandlers.append(ehd); - iBeginCatch(node->catchExpression->name); - node->catchExpression->statement->accept(this); - iEndCatch(); - patchInstruction(end, nextInstructionOffset() - end); - } - if (node->finallyExpression) { - if (!node->catchExpression) { - ExceptionHandlerDescriptor ehd(start, end, nextInstructionOffset()); - m_exceptionHandlers.prepend(ehd); - } - node->finallyExpression->statement->accept(this); - } - return false; -} - -void Compiler::endVisit(AST::ThrowStatement *node) -{ - if (! node->expression) - iLoadUndefined(); - - iThrow(); -} - -void Compiler::endVisit(AST::VoidExpression *) -{ - iPop(); - iLoadUndefined(); -} - -bool Compiler::visit(AST::TypeOfExpression *node) -{ - bool was = generateReferences(true); - node->expression->accept(this); - generateReferences(was); - iTypeOf(); - return false; -} - -bool Compiler::visit(AST::DeleteExpression *node) -{ - bool was = generateReferences(true); - node->expression->accept(this); - generateReferences(was); - iDelete(); - return false; -} - -bool Compiler::visit(AST::ReturnStatement *node) -{ - if (topLevelCompiler()) { - m_compilationUnit.setError(QString::fromUtf8("return outside function body"), - node->startLine); - return false; - } - iLine(node); - return true; -} - -void Compiler::endVisit(AST::ReturnStatement *node) -{ - if (! node->expression) - iLoadUndefined(); - - iRet(); -} - -bool Compiler::visit(AST::VariableStatement *node) -{ - AST::VariableDeclarationList *lst = node->declarations; - while (lst) { - if (lst->declaration->expression) { - iLine(node); - break; - } - lst = lst->next; - } - return true; -} - -bool Compiler::visit(AST::VariableDeclaration *node) -{ - if (node->expression != 0) { - iResolve(node->name); - node->expression->accept(this); - iAssign(); - iPop(); - } - - return false; -} - -bool Compiler::visit(AST::ConditionalExpression *node) -{ - node->expression->accept(this); - - int cond = nextInstructionOffset(); - iBranchFalse(0); - - node->ok->accept(this); - - if (! node->ko) { - patchInstruction(cond, nextInstructionOffset() - cond); - } else { - int terminator = nextInstructionOffset(); - iBranch(0); - node->ko->accept(this); - - patchInstruction(cond, terminator + 1 - cond); - patchInstruction(terminator, nextInstructionOffset() - terminator); - } - - return false; -} - -bool Compiler::visit(AST::IfStatement *node) -{ - iLine(node); - node->expression->accept(this); - - int cond = nextInstructionOffset(); - iBranchFalse(0); - - node->ok->accept(this); - - if (! node->ko) { - patchInstruction(cond, nextInstructionOffset() - cond); - } else { - int terminator = nextInstructionOffset(); - iBranch(0); - node->ko->accept(this); - - patchInstruction(cond, terminator + 1 - cond); - patchInstruction(terminator, nextInstructionOffset() - terminator); - } - if (!m_instructions.isEmpty() && m_instructions.last().op == QScriptInstruction::OP_Ret) - iNop(); - - return false; -} - -bool Compiler::visit(AST::Block *node) -{ - if (node->statements && m_loops.contains(node)) { - Loop &loop = m_loops[node]; - - node->statements->accept(this); - - loop.breakLabel.offset = nextInstructionOffset(); - - foreach (int index, loop.breakLabel.uses) { - patchInstruction(index, loop.breakLabel.offset - index); - } - - return false; - } - - return true; -} - -bool Compiler::visit(AST::WhileStatement *node) -{ - Loop *previousLoop = changeActiveLoop(&m_loops[node]); - m_activeLoop->continueLabel.offset = nextInstructionOffset(); - - iLine(node); - int again = nextInstructionOffset(); - node->expression->accept(this); - - int cond = nextInstructionOffset(); - iBranchFalse(0); - - bool was = iterationStatement(true); - bool was2 = generateLeaveOnBreak(false); - node->statement->accept(this); - generateLeaveOnBreak(was2); - iterationStatement(was); - - iBranch(again - nextInstructionOffset()); - patchInstruction(cond, nextInstructionOffset() - cond); - - m_activeLoop->breakLabel.offset = nextInstructionOffset(); - - foreach (int index, m_activeLoop->breakLabel.uses) { - patchInstruction(index, m_activeLoop->breakLabel.offset - index); - } - - foreach (int index, m_activeLoop->continueLabel.uses) { - patchInstruction(index, m_activeLoop->continueLabel.offset - index); - } - - changeActiveLoop(previousLoop); - m_loops.remove(node); - - return false; -} - -bool Compiler::visit(AST::DoWhileStatement *node) -{ - Loop *previousLoop = changeActiveLoop(&m_loops[node]); - int again = nextInstructionOffset(); - iLine(node); - bool was = iterationStatement(true); - node->statement->accept(this); - iterationStatement(was); - - m_activeLoop->continueLabel.offset = nextInstructionOffset(); - - node->expression->accept(this); - - iBranchTrue(again - nextInstructionOffset()); - m_activeLoop->breakLabel.offset = nextInstructionOffset(); - - foreach (int index, m_activeLoop->breakLabel.uses) { - patchInstruction(index, m_activeLoop->breakLabel.offset - index); - } - - foreach (int index, m_activeLoop->continueLabel.uses) { - patchInstruction(index, m_activeLoop->continueLabel.offset - index); - } - - changeActiveLoop(previousLoop); - m_loops.remove(node); - - return false; -} - -bool Compiler::visit(AST::ForEachStatement *node) -{ - Loop *previousLoop = changeActiveLoop(&m_loops[node]); - - iLine(node); - node->expression->accept(this); - iNewEnumeration(); - iDuplicate(); - iToFirstElement(); - - int again = nextInstructionOffset(); - m_activeLoop->continueLabel.offset = again; - iDuplicate(); - iHasNextElement(); - int cond = nextInstructionOffset(); - iBranchFalse(0); - bool was = generateReferences(true); - node->initialiser->accept(this); - generateReferences(was); - iNextElement(); - iAssign(); - iPop(); - was = iterationStatement(true); - node->statement->accept(this); - iterationStatement(was); - iBranch(again - nextInstructionOffset()); - patchInstruction(cond, nextInstructionOffset() - cond); - - m_activeLoop->breakLabel.offset = nextInstructionOffset(); - iPop(); // pop the Enumeration - - foreach (int index, m_activeLoop->breakLabel.uses) { - patchInstruction(index, m_activeLoop->breakLabel.offset - index); - } - - foreach (int index, m_activeLoop->continueLabel.uses) { - patchInstruction(index, m_activeLoop->continueLabel.offset - index); - } - - changeActiveLoop(previousLoop); - m_loops.remove(node); - - return false; -} - -bool Compiler::visit(AST::LocalForEachStatement *node) -{ - Loop *previousLoop = changeActiveLoop(&m_loops[node]); - - iLine(node); - node->declaration->accept(this); - node->expression->accept(this); - iNewEnumeration(); - iDuplicate(); - iToFirstElement(); - - int again = nextInstructionOffset(); - m_activeLoop->continueLabel.offset = again; - iDuplicate(); - iHasNextElement(); - int cond = nextInstructionOffset(); - iBranchFalse(0); - iResolve(node->declaration->name); - iNextElement(); - iAssign(); - iPop(); - bool was = iterationStatement(true); - node->statement->accept(this); - iterationStatement(was); - iBranch(again - nextInstructionOffset()); - patchInstruction(cond, nextInstructionOffset() - cond); - - m_activeLoop->breakLabel.offset = nextInstructionOffset(); - iPop(); // pop the Enumeration - - foreach (int index, m_activeLoop->breakLabel.uses) { - patchInstruction(index, m_activeLoop->breakLabel.offset - index); - } - - foreach (int index, m_activeLoop->continueLabel.uses) { - patchInstruction(index, m_activeLoop->continueLabel.offset - index); - } - - changeActiveLoop(previousLoop); - m_loops.remove(node); - - return false; -} - -void Compiler::visitForInternal(AST::Statement *node, AST::ExpressionNode *condition, AST::Statement *statement, AST::ExpressionNode *expression) -{ - Q_ASSERT(statement != 0); - - int again = nextInstructionOffset(); - if (condition != 0) { -// iLine(condition); - condition->accept(this); - } else { -// iLine(node); - iLoadNumber(1); - } - - int cond = nextInstructionOffset(); - iBranchFalse(0); - - Loop *previousLoop = changeActiveLoop(&m_loops[node]); - - bool was = iterationStatement(true); - statement->accept(this); - iterationStatement(was); - - m_activeLoop->continueLabel.offset = nextInstructionOffset(); - - if (expression != 0) { - expression->accept(this); - iPop(); - } - - iBranch(again - nextInstructionOffset()); - patchInstruction(cond, nextInstructionOffset() - cond); - - m_activeLoop->breakLabel.offset = nextInstructionOffset(); - - foreach (int index, m_activeLoop->breakLabel.uses) { - patchInstruction(index, m_activeLoop->breakLabel.offset - index); - } - - foreach (int index, m_activeLoop->continueLabel.uses) { - patchInstruction(index, m_activeLoop->continueLabel.offset - index); - } - - changeActiveLoop(previousLoop); - m_loops.remove(node); -} - -bool Compiler::visit(AST::ForStatement *node) -{ - iLine(node); - - if (node->initialiser != 0) { - node->initialiser->accept(this); - iPop(); - } - - visitForInternal(node, node->condition, node->statement, node->expression); - return false; -} - -bool Compiler::visit(AST::LocalForStatement *node) -{ - iLine(node); - - if (node->declarations) - node->declarations->accept(this); - - visitForInternal(node, node->condition, node->statement, node->expression); - return false; -} - -bool Compiler::isAssignmentOperator(int op) const -{ - switch (op) { - - case QSOperator::Assign: - case QSOperator::InplaceAnd: - case QSOperator::InplaceSub: - case QSOperator::InplaceDiv: - case QSOperator::InplaceAdd: - case QSOperator::InplaceLeftShift: - case QSOperator::InplaceMod: - case QSOperator::InplaceMul: - case QSOperator::InplaceOr: - case QSOperator::InplaceRightShift: - case QSOperator::InplaceURightShift: - case QSOperator::InplaceXor: - return true; - - default: - break; - - } - - return false; -} - -int Compiler::inplaceAssignmentOperator(int op) const -{ - switch (op) { - case QSOperator::BitAnd: - return QSOperator::InplaceAnd; - case QSOperator::Sub: - return QSOperator::InplaceSub; - case QSOperator::Div: - return QSOperator::InplaceDiv; - case QSOperator::Add: - return QSOperator::InplaceAdd; - case QSOperator::LShift: - return QSOperator::InplaceLeftShift; - case QSOperator::Mod: - return QSOperator::InplaceMod; - case QSOperator::Mul: - return QSOperator::InplaceMul; - case QSOperator::BitOr: - return QSOperator::InplaceOr; - case QSOperator::RShift: - return QSOperator::InplaceRightShift; - case QSOperator::URShift: - return QSOperator::InplaceURightShift; - case QSOperator::BitXor: - return QSOperator::InplaceXor; - - default: - break; - - } - - return(-1); -} - -bool Compiler::visit(AST::Expression *node) -{ - node->left->accept(this); - iPop(); // ### or iSync? - node->right->accept(this); - return false; -} - -bool Compiler::visit(AST::BinaryExpression *node) -{ - if (isAssignmentOperator(node->op)) { - bool was = generateReferences(true); - node->left->accept(this); - generateReferences(was); - } else { - node->left->accept(this); - } - - int address = 0; - if (node->op == QSOperator::Or || node->op == QSOperator::And) { - iDuplicate(); - address = nextInstructionOffset(); - if (node->op == QSOperator::Or) - iBranchTrue(0); - else - iBranchFalse(0); - iPop(); - } - - int op = node->op; - Compare compare; - if ((op == QSOperator::Assign) && node->right->binaryExpressionCast() - && (inplaceAssignmentOperator(node->right->binaryExpressionCast()->op) != -1) - && compare(node->left, node->right->binaryExpressionCast()->left)) { - // node->left is equivalent to node->right->left, so we generate - // x op= y rather than x = x op y - op = inplaceAssignmentOperator(node->right->binaryExpressionCast()->op); - node->right->binaryExpressionCast()->right->accept(this); - } else { - node->right->accept(this); - } - - switch (op) { - - case QSOperator::Assign: - iAssign(); - break; - - case QSOperator::InplaceAnd: - iInplaceAnd(); - break; - - case QSOperator::InplaceSub: - iInplaceSub(); - break; - - case QSOperator::InplaceDiv: - iInplaceDiv(); - break; - - case QSOperator::InplaceAdd: - iInplaceAdd(); - break; - - case QSOperator::InplaceLeftShift: - iInplaceLeftShift(); - break; - - case QSOperator::InplaceMod: - iInplaceMod(); - break; - - case QSOperator::InplaceMul: - iInplaceMul(); - break; - - case QSOperator::InplaceOr: - iInplaceOr(); - break; - - case QSOperator::InplaceRightShift: - iInplaceRightShift(); - break; - - case QSOperator::InplaceURightShift: - iInplaceURightShift(); - break; - - case QSOperator::InplaceXor: - iInplaceXor(); - break; - - case QSOperator::BitAnd: - iBitAnd(); - break; - - case QSOperator::BitOr: - iBitOr(); - break; - - case QSOperator::BitXor: - iBitXor(); - break; - - case QSOperator::LShift: - iLeftShift(); - break; - - case QSOperator::Mod: - iMod(); - break; - - case QSOperator::RShift: - iRightShift(); - break; - - case QSOperator::URShift: - iURightShift(); - break; - - case QSOperator::InstanceOf: - iInstanceOf(); - break; - - case QSOperator::Add: - iAdd(); - break; - - case QSOperator::And: - patchInstruction(address, nextInstructionOffset() - address); - break; - - case QSOperator::Div: - iDiv(); - break; - - case QSOperator::Equal: - iEqual(); - break; - - case QSOperator::Ge: - iGreatOrEqual(); - break; - - case QSOperator::Gt: - iGreatThan(); - break; - - case QSOperator::Le: - iLessOrEqual(); - break; - - case QSOperator::Lt: - iLessThan(); - break; - - case QSOperator::Mul: - iMul(); - break; - - case QSOperator::NotEqual: - iNotEqual(); - break; - - case QSOperator::Or: - patchInstruction(address, nextInstructionOffset() - address); - break; - - case QSOperator::Sub: - iSub(); - break; - - case QSOperator::StrictEqual: - iStrictEqual(); - break; - - case QSOperator::StrictNotEqual: - iStrictNotEqual(); - break; - - case QSOperator::In: - iIn(); - break; - } - - return false; -} - -bool Compiler::visit(AST::TrueLiteral *) -{ - iLoadTrue(); - return false; -} - -bool Compiler::visit(AST::FalseLiteral *) -{ - iLoadFalse(); - return false; -} - -bool Compiler::visit(AST::SwitchStatement *node) -{ - iLine(node); - Loop *previousLoop = changeActiveLoop(&m_loops[node]); - - node->expression->accept(this); - - bool was = switchStatement(true); - - AST::CaseClauses *clauses; - int skipIndex = -1; - int fallthroughIndex = -1; - // ### make a function for this - for (clauses = node->block->clauses; clauses != 0; clauses = clauses->next) { - AST::CaseClause *clause = clauses->clause; - if (skipIndex != -1) - patchInstruction(skipIndex, nextInstructionOffset() - skipIndex); - - iDuplicate(); // expression - clause->expression->accept(this); - iStrictEqual(); - skipIndex = nextInstructionOffset(); - iBranchFalse(0); // next case - - if (fallthroughIndex != -1) // previous case falls through to here - patchInstruction(fallthroughIndex, nextInstructionOffset() - fallthroughIndex); - - int breaksBefore = m_activeLoop->breakLabel.uses.count(); - if (clause->statements) - clause->statements->accept(this); - int breaksAfter = m_activeLoop->breakLabel.uses.count(); - if (breaksAfter == breaksBefore) { // fallthrough - fallthroughIndex = nextInstructionOffset(); - iBranch(0); - } else { // no fallthrough (break) - fallthroughIndex = -1; - } - } - - if (fallthroughIndex != -1) { - patchInstruction(fallthroughIndex, nextInstructionOffset() - fallthroughIndex); - fallthroughIndex = -1; - } - - int defaultIndex = -1; - if (node->block->defaultClause) { - int skipDefaultIndex = -1; - if (!node->block->clauses && node->block->moreClauses) { - skipDefaultIndex = nextInstructionOffset(); - iBranch(0); - } - defaultIndex = nextInstructionOffset(); - int breaksBefore = m_activeLoop->breakLabel.uses.count(); - if (node->block->defaultClause->statements) - node->block->defaultClause->statements->accept(this); - int breaksAfter = m_activeLoop->breakLabel.uses.count(); - if (breaksAfter == breaksBefore) { // fallthrough - fallthroughIndex = nextInstructionOffset(); - iBranch(0); - } else { // no fallthrough (break) - fallthroughIndex = -1; - } - if (skipDefaultIndex != -1) - patchInstruction(skipDefaultIndex, nextInstructionOffset() - skipDefaultIndex); - } - - for (clauses = node->block->moreClauses; clauses != 0; clauses = clauses->next) { - AST::CaseClause *clause = clauses->clause; - if (skipIndex != -1) - patchInstruction(skipIndex, nextInstructionOffset() - skipIndex); - - iDuplicate(); // expression - clause->expression->accept(this); - iStrictEqual(); - skipIndex = nextInstructionOffset(); - iBranchFalse(0); // next case - - if (fallthroughIndex != -1) // previous case falls through to here - patchInstruction(fallthroughIndex, nextInstructionOffset() - fallthroughIndex); - - int breaksBefore = m_activeLoop->breakLabel.uses.count(); - if (clause->statements) - clause->statements->accept(this); - int breaksAfter = m_activeLoop->breakLabel.uses.count(); - if (breaksAfter == breaksBefore) { // fallthrough - fallthroughIndex = nextInstructionOffset(); - iBranch(0); - } else { // no fallthrough (break) - fallthroughIndex = -1; - } - } - - if (skipIndex != -1) { - patchInstruction(skipIndex, nextInstructionOffset() - skipIndex); - if (defaultIndex != -1) - iBranch(defaultIndex - nextInstructionOffset()); // goto default - } - - if (fallthroughIndex != -1) - patchInstruction(fallthroughIndex, nextInstructionOffset() - fallthroughIndex); - - // backpatch the breaks - int term = nextInstructionOffset(); - foreach (int index, m_activeLoop->breakLabel.uses) { - patchInstruction(index, term - index); - } - - iPop(); // expression - - if (previousLoop && !m_activeLoop->continueLabel.uses.isEmpty()) { - // join the continues and add to outer loop - iBranch(3); - foreach (int index, m_activeLoop->continueLabel.uses) { - patchInstruction(index, nextInstructionOffset() - index); - } - iPop(); - iBranch(0); - previousLoop->continueLabel.uses.append(nextInstructionOffset() - 1); - } - - switchStatement(was); - changeActiveLoop(previousLoop); - m_loops.remove(node); - return false; -} - -bool Compiler::visit(AST::LabelledStatement *node) -{ - Loop *loop = findLoop(node->label); - if (loop != 0) { - QString str = m_eng->toString(node->label); - m_compilationUnit.setError(QString::fromUtf8("duplicate label `%1'").arg(str), - node->startLine); - return false; - } - - loop = &m_loops[node->statement]; - loop->name = node->label; - node->statement->accept(this); - if (m_loops.contains(node->statement)) { - loop->breakLabel.offset = nextInstructionOffset(); - foreach (int index, loop->breakLabel.uses) { - patchInstruction(index, loop->breakLabel.offset - index); - } - m_loops.remove(node->statement); - } - return false; -} - -bool Compiler::visit(AST::ExpressionStatement *node) -{ - if (node->expression) - iLine(node->expression); - return true; -} - -void Compiler::endVisit(AST::ExpressionStatement *) -{ - if (topLevelCompiler()) - iSync(); - else - iPop(); -} - -void Compiler::endVisit(AST::UnaryPlusExpression *) -{ - iUnaryPlus(); -} - -void Compiler::endVisit(AST::UnaryMinusExpression *) -{ - iUnaryMinus(); -} - -bool Compiler::visit(AST::ContinueStatement *node) -{ - iLine(node); - return true; -} - -void Compiler::endVisit(AST::ContinueStatement *node) -{ - int offset = nextInstructionOffset(); - iBranch(0); - - Loop *loop = findLoop(node->label); - if (!loop || !m_iterationStatement) { - m_compilationUnit.setError(QString::fromUtf8("label not found"), - node->startLine); - return; - } - - loop->continueLabel.uses.append(offset); -} - -bool Compiler::visit(AST::BreakStatement *node) -{ - iLine(node); - return true; -} - -void Compiler::endVisit(AST::BreakStatement *node) -{ - Loop *loop = findLoop(node->label); - if (! loop) { - m_compilationUnit.setError(QString::fromUtf8("label not found"), - node->startLine); - return; - } - - if (m_generateLeaveWithOnBreak) - iLeaveWith(); - int offset = nextInstructionOffset(); - iBranch(0); - loop->breakLabel.uses.append(offset); -} - -void Compiler::endVisit(AST::EmptyStatement *node) -{ - iLine(node); -} - -bool Compiler::visit(AST::DebuggerStatement *node) -{ - iLine(node); - iDebugger(); - return false; -} - -void Compiler::patchInstruction(int index, int offset) -{ - QScriptInstruction &i = m_instructions[index]; - - switch (i.op) { - case QScriptInstruction::OP_Branch: - case QScriptInstruction::OP_BranchFalse: - case QScriptInstruction::OP_BranchTrue: - m_eng->newInteger(&i.operand[0], offset); - break; - - default: - Q_ASSERT_X(0, "Compiler::patchInstruction()", "expected a branch instruction"); - break; - } -} - -bool Compiler::visit(AST::WithStatement *node) -{ - iLine(node); - node->expression->accept(this); - iEnterWith(); - bool was = withStatement(true); - bool was2 = generateLeaveOnBreak(true); - node->statement->accept(this); - generateLeaveOnBreak(was2); - withStatement(was); - iLeaveWith(); - return false; -} - -bool Compiler::visit(AST::ArrayLiteral *node) -{ - iNewArray(); - - int length = 0; - - for (AST::ElementList *it = node->elements; it != 0; it = it->next) { - for (AST::Elision *eit = it->elision; eit != 0; eit = eit->next) { - iDuplicate(); - iLoadNumber(length); - iMakeReference(); - iLoadUndefined(); - iAssign(); - iPop(); - ++length; - } - - if (it->expression) { - iDuplicate(); - iLoadNumber(length); - iMakeReference(); - it->expression->accept(this); - iAssign(); - iPop(); - ++length; - } - } - - for (AST::Elision *eit = node->elision; eit != 0; eit = eit->next) { - iDuplicate(); - iLoadNumber(length); - iMakeReference(); - iLoadUndefined(); - iAssign(); - iPop(); - ++length; - } - - return false; -} - -void Compiler::iLoadUndefined() -{ - pushInstruction(QScriptInstruction::OP_LoadUndefined); -} - -void Compiler::iLoadThis() -{ - pushInstruction(QScriptInstruction::OP_LoadThis); -} - -void Compiler::iLoadActivation() -{ - pushInstruction(QScriptInstruction::OP_LoadActivation); -} - -void Compiler::iLoadNull() -{ - pushInstruction(QScriptInstruction::OP_LoadNull); -} - -void Compiler::iLoadNumber(double number) -{ - QScriptValueImpl arg0(number); - pushInstruction(QScriptInstruction::OP_LoadNumber, arg0); -} - -void Compiler::iLoadString(QScriptNameIdImpl *id) -{ - QScriptValueImpl arg0; - id->persistent = true; - m_eng->newNameId(&arg0, id); - pushInstruction(QScriptInstruction::OP_LoadString, arg0); -} - -void Compiler::iDuplicate() -{ - pushInstruction(QScriptInstruction::OP_Duplicate); -} - -void Compiler::iSwap() -{ - pushInstruction(QScriptInstruction::OP_Swap); -} - -void Compiler::iResolve(QScriptNameIdImpl *id) -{ - QScriptValueImpl arg0; - id->persistent = true; - m_eng->newNameId(&arg0, id); - pushInstruction(QScriptInstruction::OP_Resolve, arg0); -} - -void Compiler::iPutField() -{ - pushInstruction(QScriptInstruction::OP_PutField); -} - -void Compiler::iCall(int argc) -{ - QScriptValueImpl arg0; - m_eng->newInteger(&arg0, argc); - pushInstruction(QScriptInstruction::OP_Call, arg0); -} - -void Compiler::iNew(int argc) -{ - QScriptValueImpl arg0; - m_eng->newInteger(&arg0, argc); - pushInstruction(QScriptInstruction::OP_New, arg0); -} - -void Compiler::iFetchField() -{ - pushInstruction(QScriptInstruction::OP_FetchField); -} - -void Compiler::iLazyArguments() -{ - pushInstruction(QScriptInstruction::OP_LazyArguments); -} - -void Compiler::iRet() -{ - pushInstruction(QScriptInstruction::OP_Ret); -} - -void Compiler::iDeclareLocal(QScriptNameIdImpl *id, bool readOnly) -{ - QScriptValueImpl arg0; - id->persistent = true; - m_eng->newNameId(&arg0, id); - QScriptValueImpl arg1; - m_eng->newInteger(&arg1, readOnly); - pushInstruction(QScriptInstruction::OP_DeclareLocal, arg0, arg1); -} - -void Compiler::iAssign() -{ - pushInstruction(QScriptInstruction::OP_Assign); -} - -void Compiler::iBitAnd() -{ - pushInstruction(QScriptInstruction::OP_BitAnd); -} - -void Compiler::iBitOr() -{ - pushInstruction(QScriptInstruction::OP_BitOr); -} - -void Compiler::iBitXor() -{ - pushInstruction(QScriptInstruction::OP_BitXor); -} - -void Compiler::iLeftShift() -{ - pushInstruction(QScriptInstruction::OP_LeftShift); -} - -void Compiler::iMod() -{ - pushInstruction(QScriptInstruction::OP_Mod); -} - -void Compiler::iRightShift() -{ - pushInstruction(QScriptInstruction::OP_RightShift); -} - -void Compiler::iURightShift() -{ - pushInstruction(QScriptInstruction::OP_URightShift); -} - -void Compiler::iAdd() -{ - pushInstruction(QScriptInstruction::OP_Add); -} - -void Compiler::iDiv() -{ - pushInstruction(QScriptInstruction::OP_Div); -} - -void Compiler::iEqual() -{ - pushInstruction(QScriptInstruction::OP_Equal); -} - -void Compiler::iGreatOrEqual() -{ - pushInstruction(QScriptInstruction::OP_GreatOrEqual); -} - -void Compiler::iGreatThan() -{ - pushInstruction(QScriptInstruction::OP_GreatThan); -} - -void Compiler::iLessOrEqual() -{ - pushInstruction(QScriptInstruction::OP_LessOrEqual); -} - -void Compiler::iLessThan() -{ - pushInstruction(QScriptInstruction::OP_LessThan); -} - -void Compiler::iMul() -{ - pushInstruction(QScriptInstruction::OP_Mul); -} - -void Compiler::iNotEqual() -{ - pushInstruction(QScriptInstruction::OP_NotEqual); -} - -void Compiler::iSub() -{ - pushInstruction(QScriptInstruction::OP_Sub); -} - -void Compiler::iStrictEqual() -{ - pushInstruction(QScriptInstruction::OP_StrictEqual); -} - -void Compiler::iStrictNotEqual() -{ - pushInstruction(QScriptInstruction::OP_StrictNotEqual); -} - -void Compiler::iBranch(int index) -{ - QScriptValueImpl arg0; - m_eng->newInteger(&arg0, index); - pushInstruction(QScriptInstruction::OP_Branch, arg0); -} - -void Compiler::iBranchFalse(int index) -{ - QScriptValueImpl arg0; - m_eng->newInteger(&arg0, index); - pushInstruction(QScriptInstruction::OP_BranchFalse, arg0); -} - -void Compiler::iBranchTrue(int index) -{ - QScriptValueImpl arg0; - m_eng->newInteger(&arg0, index); - pushInstruction(QScriptInstruction::OP_BranchTrue, arg0); -} - -void Compiler::iNewClosure(AST::FunctionExpression *expr) -{ - QScriptValueImpl arg0; - m_eng->newPointer(&arg0, expr); - - pushInstruction(QScriptInstruction::OP_NewClosure, arg0); -} - -void Compiler::iIncr() -{ - pushInstruction(QScriptInstruction::OP_Incr); -} - -void Compiler::iDecr() -{ - pushInstruction(QScriptInstruction::OP_Decr); -} - -void Compiler::iPop() -{ - pushInstruction(QScriptInstruction::OP_Pop); -} - -void Compiler::iFetch(QScriptNameIdImpl *id) -{ - if (m_generateFastArgumentLookup) { - int index = m_formals.indexOf(id); - - if (index != -1) { - QScriptValueImpl arg0; - m_eng->newInteger(&arg0, index); - pushInstruction(QScriptInstruction::OP_Receive, arg0); - return; - } - } - - QScriptValueImpl arg0; - id->persistent = true; - m_eng->newNameId(&arg0, id); - pushInstruction(QScriptInstruction::OP_Fetch, arg0); -} - -void Compiler::iLoadTrue() -{ - pushInstruction(QScriptInstruction::OP_LoadTrue); -} - -void Compiler::iLoadFalse() -{ - pushInstruction(QScriptInstruction::OP_LoadFalse); -} - -void Compiler::iUnaryMinus() -{ - pushInstruction(QScriptInstruction::OP_UnaryMinus); -} - -void Compiler::iUnaryPlus() -{ - pushInstruction(QScriptInstruction::OP_UnaryPlus); -} - -void Compiler::iPostIncr() -{ - pushInstruction(QScriptInstruction::OP_PostIncr); -} - -void Compiler::iPostDecr() -{ - pushInstruction(QScriptInstruction::OP_PostDecr); -} - -void Compiler::iNewArray() -{ - pushInstruction(QScriptInstruction::OP_NewArray); -} - -void Compiler::iNewObject() -{ - pushInstruction(QScriptInstruction::OP_NewObject); -} - -void Compiler::iTypeOf() -{ - pushInstruction(QScriptInstruction::OP_TypeOf); -} - -void Compiler::iDelete() -{ - pushInstruction(QScriptInstruction::OP_Delete); -} - -void Compiler::iInstanceOf() -{ - pushInstruction(QScriptInstruction::OP_InstanceOf); -} - -void Compiler::iInplaceAnd() -{ - pushInstruction(QScriptInstruction::OP_InplaceAnd); -} - -void Compiler::iInplaceSub() -{ - pushInstruction(QScriptInstruction::OP_InplaceSub); -} - -void Compiler::iInplaceDiv() -{ - pushInstruction(QScriptInstruction::OP_InplaceDiv); -} - -void Compiler::iInplaceAdd() -{ - pushInstruction(QScriptInstruction::OP_InplaceAdd); -} - -void Compiler::iInplaceLeftShift() -{ - pushInstruction(QScriptInstruction::OP_InplaceLeftShift); -} - -void Compiler::iInplaceMod() -{ - pushInstruction(QScriptInstruction::OP_InplaceMod); -} - -void Compiler::iInplaceMul() -{ - pushInstruction(QScriptInstruction::OP_InplaceMul); -} - -void Compiler::iInplaceOr() -{ - pushInstruction(QScriptInstruction::OP_InplaceOr); -} - -void Compiler::iInplaceRightShift() -{ - pushInstruction(QScriptInstruction::OP_InplaceRightShift); -} - -void Compiler::iInplaceURightShift() -{ - pushInstruction(QScriptInstruction::OP_InplaceURightShift); -} - -void Compiler::iInplaceXor() -{ - pushInstruction(QScriptInstruction::OP_InplaceXor); -} - -void Compiler::iThrow() -{ - pushInstruction(QScriptInstruction::OP_Throw); -} - -void Compiler::iLine(AST::Node *node) -{ - if (! node) - return; - - QScriptValueImpl arg0; - m_eng->newInteger(&arg0, node->startLine); - - QScriptValueImpl arg1; - m_eng->newInteger(&arg1, node->startColumn); - - pushInstruction(QScriptInstruction::OP_Line, arg0, arg1); -} - -void Compiler::iBitNot() -{ - pushInstruction(QScriptInstruction::OP_BitNot); -} - -void Compiler::iNot() -{ - pushInstruction(QScriptInstruction::OP_Not); -} - -void Compiler::iNewRegExp(QScriptNameIdImpl *pattern) -{ - QScriptValueImpl arg0; - pattern->persistent = true; - m_eng->newNameId(&arg0, pattern); - pushInstruction(QScriptInstruction::OP_NewRegExp, arg0); -} - -void Compiler::iNewRegExp(QScriptNameIdImpl *pattern, int flags) -{ - QScriptValueImpl arg0; - pattern->persistent = true; - m_eng->newNameId(&arg0, pattern); - - QScriptValueImpl arg1; - m_eng->newInteger(&arg1, flags); - - pushInstruction(QScriptInstruction::OP_NewRegExp, arg0, arg1); -} - -void Compiler::iNewEnumeration() -{ - pushInstruction(QScriptInstruction::OP_NewEnumeration); -} - -void Compiler::iToFirstElement() -{ - pushInstruction(QScriptInstruction::OP_ToFirstElement); -} - -void Compiler::iHasNextElement() -{ - pushInstruction(QScriptInstruction::OP_HasNextElement); -} - -void Compiler::iNextElement() -{ - pushInstruction(QScriptInstruction::OP_NextElement); -} - -void Compiler::iEnterWith() -{ - pushInstruction(QScriptInstruction::OP_EnterWith); -} - -void Compiler::iLeaveWith() -{ - pushInstruction(QScriptInstruction::OP_LeaveWith); -} - -void Compiler::iBeginCatch(QScriptNameIdImpl *id) -{ - QScriptValueImpl arg0; - id->persistent = true; - m_eng->newNameId(&arg0, id); - pushInstruction(QScriptInstruction::OP_BeginCatch, arg0); -} - -void Compiler::iEndCatch() -{ - pushInstruction(QScriptInstruction::OP_EndCatch); -} - -void Compiler::iSync() -{ - pushInstruction(QScriptInstruction::OP_Sync); -} - -void Compiler::iHalt() -{ - pushInstruction(QScriptInstruction::OP_Halt); -} - -void Compiler::iMakeReference() -{ - pushInstruction(QScriptInstruction::OP_MakeReference); -} - -void Compiler::iIn() -{ - pushInstruction(QScriptInstruction::OP_In); -} - -void Compiler::iNop() -{ - pushInstruction(QScriptInstruction::OP_Nop); -} - -void Compiler::iNewString(QScriptNameIdImpl *id) -{ - QScriptValueImpl arg0; - id->persistent = true; - m_eng->newNameId(&arg0, id); - pushInstruction(QScriptInstruction::OP_NewString, arg0); -} - -void Compiler::iDebugger() -{ - pushInstruction(QScriptInstruction::OP_Debugger); -} - -Compiler::Loop *Compiler::findLoop(QScriptNameIdImpl *name) -{ - if (! name) - return m_activeLoop; - - QMap<AST::Statement*, Loop>::iterator it = m_loops.begin(); - - for (; it != m_loops.end(); ++it) { - Loop &loop = *it; - - if (loop.name == name) - return &loop; - } - - return 0; -} - - -} // namespace QScript - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptcompiler_p.h b/src/script/qscriptcompiler_p.h deleted file mode 100644 index 397abf1..0000000 --- a/src/script/qscriptcompiler_p.h +++ /dev/null @@ -1,377 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTCOMPILER_P_H -#define QSCRIPTCOMPILER_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/QMap> - -#ifndef QT_NO_SCRIPT - -#include <QtCore/QVector> - -#include "qscriptastvisitor_p.h" -#include "qscriptasm_p.h" - -QT_BEGIN_NAMESPACE - -class QScriptEnginePrivate; - -namespace QScript { - -class Compiler: protected AST::Visitor -{ -public: - Compiler(QScriptEnginePrivate *eng); - virtual ~Compiler(); - - inline QScriptEnginePrivate *engine() const { return m_eng; } - - bool topLevelCompiler() const; - void setTopLevelCompiler(bool b); - - CompilationUnit compile(AST::Node *node, const QList<QScriptNameIdImpl *> &formals - = QList<QScriptNameIdImpl *>()); - - struct Label { - Label(int o = 0): - offset (o) {} - - int offset; - QVector<int> uses; - }; - -// instruction set - void iAdd(); - void iAssign(); - void iBitAnd(); - void iBitOr(); - void iBitXor(); - void iBitNot(); - void iBranch(int index); - void iBranchTrue(int index); - void iBranchFalse(int index); - void iCall(int argc); - void iDeclareLocal(QScriptNameIdImpl *id, bool readOnly); - void iDecr(); - void iDelete(); - void iDiv(); - void iDuplicate(); - void iEqual(); - void iFetch(QScriptNameIdImpl *id); - void iFetchField(); - void iLazyArguments(); - void iGreatOrEqual(); - void iGreatThan(); - void iIncr(); - void iInplaceAdd(); - void iInplaceAnd(); - void iInplaceDecr(); - void iInplaceDiv(); - void iInplaceLeftShift(); - void iInplaceMod(); - void iInplaceMul(); - void iInplaceOr(); - void iInplaceRightShift(); - void iInplaceSub(); - void iInplaceURightShift(); - void iInstanceOf(); - void iLeftShift(); - void iLessOrEqual(); - void iLessThan(); - void iLoadFalse(); - void iLoadNumber(double number); - void iLoadString(QScriptNameIdImpl *id); - void iNewString(QScriptNameIdImpl *id); - void iLoadThis(); - void iLoadActivation(); - void iLoadNull(); - void iLoadTrue(); - void iLoadUndefined(); - void iMod(); - void iMul(); - void iUnaryPlus(); - void iUnaryMinus(); - void iNew(int argc); - void iNewArray(); - void iNewClosure(AST::FunctionExpression *expr); - void iNewObject(); - void iNewRegExp(QScriptNameIdImpl *pattern); - void iNewRegExp(QScriptNameIdImpl *pattern, int flags); - void iNot(); - void iNotEqual(); - void iPop(); - void iPostDecr(); - void iPostIncr(); - void iPutField(); - void iResolve(QScriptNameIdImpl *id); - void iRet(); - void iRightShift(); - void iSub(); - void iStrictEqual(); - void iStrictNotEqual(); - void iSwap(); - void iThrow(); - void iTypeOf(); - void iURightShift(); - void iInplaceXor(); - void iLine(AST::Node *node); - void iNewEnumeration(); - void iToFirstElement(); - void iHasNextElement(); - void iNextElement(); - void iEnterWith(); - void iLeaveWith(); - void iBeginCatch(QScriptNameIdImpl *id); - void iEndCatch(); - void iSync(); - void iHalt(); - void iMakeReference(); - void iIn(); - void iNop(); - void iDebugger(); - -protected: - virtual bool preVisit(AST::Node *node); - - virtual bool visit(AST::ArrayLiteral *node); - virtual bool visit(AST::ArrayMemberExpression *node); - virtual bool visit(AST::Expression *node); - virtual bool visit(AST::BinaryExpression *node); - virtual bool visit(AST::BreakStatement *node); - virtual bool visit(AST::CallExpression *node); - virtual bool visit(AST::ConditionalExpression *node); - virtual bool visit(AST::ContinueStatement *node); - virtual bool visit(AST::DeleteExpression *node); - virtual bool visit(AST::DoWhileStatement *node); - virtual bool visit(AST::ExpressionStatement *node); - virtual bool visit(AST::FalseLiteral *node); - virtual bool visit(AST::FieldMemberExpression *node); - virtual bool visit(AST::ForEachStatement *node); - virtual bool visit(AST::LocalForEachStatement *node); - virtual bool visit(AST::ForStatement *node); - virtual bool visit(AST::FunctionDeclaration *node); - virtual bool visit(AST::FunctionExpression *node); - virtual bool visit(AST::FunctionSourceElement *node); - virtual bool visit(AST::IdentifierExpression *node); - virtual bool visit(AST::IfStatement *node); - virtual bool visit(AST::LabelledStatement *node); - virtual bool visit(AST::LocalForStatement *node); - virtual bool visit(AST::NewExpression *node); - virtual bool visit(AST::NewMemberExpression *node); - virtual bool visit(AST::NumericLiteral *node); - virtual bool visit(AST::ObjectLiteral *node); - virtual bool visit(AST::PostDecrementExpression *node); - virtual bool visit(AST::PostIncrementExpression *node); - virtual bool visit(AST::PreDecrementExpression *node); - virtual bool visit(AST::PreIncrementExpression *node); - virtual bool visit(AST::RegExpLiteral *node); - virtual bool visit(AST::ReturnStatement *node); - virtual bool visit(AST::SourceElements *node); - virtual bool visit(AST::StatementList *node); - virtual bool visit(AST::StatementSourceElement *node); - virtual bool visit(AST::StringLiteral *node); - virtual bool visit(AST::SwitchStatement *node); - virtual bool visit(AST::ThisExpression *node); - virtual bool visit(AST::NullExpression *node); - virtual bool visit(AST::ThrowStatement *node); - virtual bool visit(AST::TryStatement *node); - virtual bool visit(AST::TrueLiteral *node); - virtual bool visit(AST::VariableStatement *node); - virtual bool visit(AST::VariableDeclaration *node); - virtual bool visit(AST::WhileStatement *node); - virtual bool visit(AST::WithStatement *node); - virtual bool visit(AST::Block *node); - virtual bool visit(AST::TypeOfExpression *node); - virtual bool visit(AST::DebuggerStatement *node); - - virtual void endVisit(AST::BreakStatement *node); - virtual void endVisit(AST::ContinueStatement *node); - virtual void endVisit(AST::ExpressionStatement *node); - virtual void endVisit(AST::NotExpression *node); - virtual void endVisit(AST::ReturnStatement *node); - virtual void endVisit(AST::ThrowStatement *node); - virtual void endVisit(AST::TildeExpression *node); - virtual void endVisit(AST::UnaryPlusExpression *node); - virtual void endVisit(AST::UnaryMinusExpression *node); - virtual void endVisit(AST::VoidExpression *node); - virtual void endVisit(AST::EmptyStatement *node); - - void visitForInternal(AST::Statement *node, AST::ExpressionNode *condition, - AST::Statement *statement, AST::ExpressionNode *expression); - - bool isAssignmentOperator(int op) const; - int inplaceAssignmentOperator(int op) const; - - inline int nextInstructionOffset() const - { return m_instructions.count(); } - - inline void pushInstruction(QScriptInstruction::Operator op) - { - pushInstruction(op, QScriptValueImpl(), QScriptValueImpl()); - } - - inline void pushInstruction(QScriptInstruction::Operator op, - const QScriptValueImpl &arg1) - { - pushInstruction(op, arg1, QScriptValueImpl()); - } - - inline void pushInstruction(QScriptInstruction::Operator op, - const QScriptValueImpl &arg1, - const QScriptValueImpl &arg2) - { - QScriptInstruction i; - i.op = op; - i.operand[0] = arg1; - i.operand[1] = arg2; - m_instructions.append(i); - } - - inline bool generateReferences(bool b) - { - bool was = m_generateReferences; - m_generateReferences = b; - return was; - } - - inline bool generateFastArgumentLookup(bool b) - { - bool was = m_generateFastArgumentLookup; - m_generateFastArgumentLookup= b; - return was; - } - - inline bool iterationStatement(bool b) - { - bool was = m_iterationStatement; - m_iterationStatement = b; - return was; - } - - inline bool switchStatement(bool b) - { - bool was = m_switchStatement; - m_switchStatement = b; - return was; - } - - inline bool changeParseStatements(bool b) - { - bool was = m_parseStatements; - m_parseStatements = b; - return was; - } - - inline bool withStatement(bool b) - { - bool was = m_withStatement; - m_withStatement = b; - return was; - } - - inline bool generateLeaveOnBreak(bool b) - { - bool was = m_generateLeaveWithOnBreak; - m_generateLeaveWithOnBreak = b; - return was; - } - - void patchInstruction(int index, int offset); - -private: - QScriptEnginePrivate *m_eng; - - uint m_generateReferences: 1; - uint m_iterationStatement: 1; - uint m_switchStatement: 1; - uint m_withStatement: 1; - uint m_generateLeaveWithOnBreak: 1; - uint m_generateFastArgumentLookup: 1; - uint m_parseStatements: 1; - uint m_pad: 25; - - bool m_topLevelCompiler; // bit - QVector<QScriptInstruction> m_instructions; - QVector<ExceptionHandlerDescriptor> m_exceptionHandlers; - QList<QScriptNameIdImpl *> m_formals; - - struct Loop { - Loop(QScriptNameIdImpl *n = 0): - name(n) {} - - QScriptNameIdImpl *name; - Label breakLabel; - Label continueLabel; - }; - - inline Loop *changeActiveLoop(Loop *activeLoop) - { - Loop *was = m_activeLoop; - m_activeLoop = activeLoop; - return was; - } - - Loop *findLoop(QScriptNameIdImpl *name = 0); - - Loop *m_activeLoop; - QMap<AST::Statement*, Loop> m_loops; - CompilationUnit m_compilationUnit; -}; - -} // namespace QScript - -#endif // QT_NO_SCRIPT - -QT_END_NAMESPACE - -#endif diff --git a/src/script/qscriptcontext.cpp b/src/script/qscriptcontext.cpp deleted file mode 100644 index aed69d3..0000000 --- a/src/script/qscriptcontext.cpp +++ /dev/null @@ -1,571 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qscriptcontext.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptcontextinfo.h" -#include "qscriptengine_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" - -QT_BEGIN_NAMESPACE - -/*! - \since 4.3 - \class QScriptContext - - \brief The QScriptContext class represents a Qt Script function invocation. - - \ingroup script - - - A QScriptContext provides access to the `this' object and arguments - passed to a script function. You typically want to access this - information when you're writing a native (C++) function (see - QScriptEngine::newFunction()) that will be called from script - code. For example, when the script code - - \snippet doc/src/snippets/code/src_script_qscriptcontext.cpp 0 - - is evaluated, a QScriptContext will be created, and the context will - carry the arguments as QScriptValues; in this particular case, the - arguments will be one QScriptValue containing the number 20.5, a second - QScriptValue containing the string \c{"hello"}, and a third QScriptValue - containing a Qt Script object. - - Use argumentCount() to get the number of arguments passed to the - function, and argument() to get an argument at a certain index. The - argumentsObject() function returns a Qt Script array object - containing all the arguments; you can use the QScriptValueIterator - to iterate over its elements, or pass the array on as arguments to - another script function using QScriptValue::call(). - - Use thisObject() to get the `this' object associated with the function call, - and setThisObject() to set the `this' object. If you are implementing a - native "instance method", you typically fetch the thisObject() and access - one or more of its properties: - - \snippet doc/src/snippets/code/src_script_qscriptcontext.cpp 1 - - Use isCalledAsConstructor() to determine if the function was called - as a constructor (e.g. \c{"new foo()"} (as constructor) or just - \c{"foo()"}). When a function is called as a constructor, the - thisObject() contains the newly constructed object that the function - is expected to initialize. - - Use throwValue() or throwError() to throw an exception. - - Use callee() to obtain the QScriptValue that represents the function being - called. This can for example be used to call the function recursively. - - Use parentContext() to get a pointer to the context that precedes - this context in the activation stack. This is mostly useful for - debugging purposes (e.g. when constructing some form of backtrace). - - The activationObject() function returns the object that is used to - hold the local variables associated with this function call. You can - replace the activation object by calling setActivationObject(). A - typical usage of these functions is when you want script code to be - evaluated in the context of the parent context, e.g. to implement an - include() function: - - \snippet doc/src/snippets/code/src_script_qscriptcontext.cpp 2 - - Use backtrace() to get a human-readable backtrace associated with - this context. This can be useful for debugging purposes when - implementing native functions. The toString() function provides a - string representation of the context. (QScriptContextInfo provides - more detailed debugging-related information about the - QScriptContext.) - - Use engine() to obtain a pointer to the QScriptEngine that this context - resides in. - - \sa QScriptContextInfo, QScriptEngine::newFunction(), QScriptable -*/ - -/*! - \enum QScriptContext::ExecutionState - - This enum specifies the execution state of the context. - - \value NormalState The context is in a normal state. - - \value ExceptionState The context is in an exceptional state. -*/ - -/*! - \enum QScriptContext::Error - - This enum specifies types of error. - - \value ReferenceError A reference error. - - \value SyntaxError A syntax error. - - \value TypeError A type error. - - \value RangeError A range error. - - \value URIError A URI error. - - \value UnknownError An unknown error. -*/ - -/*! - Throws an exception with the given \a value. - Returns the value thrown (the same as the argument). - - \sa throwError(), state() -*/ -QScriptValue QScriptContext::throwValue(const QScriptValue &value) -{ - Q_D(QScriptContext); - d->m_result = d->engine()->toImpl(value); - d->m_state = QScriptContext::ExceptionState; -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - d->engine()->notifyException(d); -#endif - return value; -} - -/*! - Throws an \a error with the given \a text. - Returns the created error object. - - The \a text will be stored in the \c{message} property of the error - object. - - The error object will be initialized to contain information about - the location where the error occurred; specifically, it will have - properties \c{lineNumber}, \c{fileName} and \c{stack}. These - properties are described in \l {QtScript Extensions to ECMAScript}. - - \sa throwValue(), state() -*/ -QScriptValue QScriptContext::throwError(Error error, const QString &text) -{ - Q_D(QScriptContext); - return d->engine()->toPublic(d->throwError(error, text)); -} - -/*! - \overload - - Throws an error with the given \a text. - Returns the created error object. - - \sa throwValue(), state() -*/ -QScriptValue QScriptContext::throwError(const QString &text) -{ - Q_D(QScriptContext); - return d->engine()->toPublic(d->throwError(text)); -} - -/*! - \internal -*/ -QScriptContext::QScriptContext(): - d_ptr(new QScriptContextPrivate()) -{ - d_ptr->q_ptr = this; -} - -/*! - Destroys this QScriptContext. -*/ -QScriptContext::~QScriptContext() -{ - delete d_ptr; - d_ptr = 0; -} - -/*! - Returns the QScriptEngine that this QScriptContext belongs to. -*/ -QScriptEngine *QScriptContext::engine() const -{ - Q_D(const QScriptContext); - return QScriptEnginePrivate::get(d->engine()); -} - -/*! - Returns the function argument at the given \a index. - - If \a index >= argumentCount(), a QScriptValue of - the primitive type Undefined is returned. - - \sa argumentCount() -*/ -QScriptValue QScriptContext::argument(int index) const -{ - Q_D(const QScriptContext); - if (index < 0) - return QScriptValue(); - return d->engine()->toPublic(d->argument(index)); -} - -/*! - Returns the callee. The callee is the function object that this - QScriptContext represents an invocation of. -*/ -QScriptValue QScriptContext::callee() const -{ - Q_D(const QScriptContext); - return d->engine()->toPublic(d->m_callee); -} - -/*! - Returns the arguments object of this QScriptContext. - - The arguments object has properties \c callee (equal to callee()) - and \c length (equal to argumentCount()), and properties \c 0, \c 1, - ..., argumentCount() - 1 that provide access to the argument - values. Initially, property \c P (0 <= \c P < argumentCount()) has - the same value as argument(\c P). In the case when \c P is less - than the number of formal parameters of the function, \c P shares - its value with the corresponding property of the activation object - (activationObject()). This means that changing this property changes - the corresponding property of the activation object and vice versa. - - \sa argument(), activationObject() -*/ -QScriptValue QScriptContext::argumentsObject() const -{ - Q_D(const QScriptContext); - return d->engine()->toPublic(d->argumentsObject()); -} - -/*! - Returns true if the function was called as a constructor - (e.g. \c{"new foo()"}); otherwise returns false. - - When a function is called as constructor, the thisObject() - contains the newly constructed object to be initialized. -*/ -bool QScriptContext::isCalledAsConstructor() const -{ - Q_D(const QScriptContext); - return d->m_calledAsConstructor; -} - -/*! - Returns the parent context of this QScriptContext. -*/ -QScriptContext *QScriptContext::parentContext() const -{ - Q_D(const QScriptContext); - return QScriptContextPrivate::get(d->previous); -} - -/*! - Returns the number of arguments passed to the function - in this invocation. - - Note that the argument count can be different from the - formal number of arguments (the \c{length} property of - callee()). - - \sa argument() -*/ -int QScriptContext::argumentCount() const -{ - Q_D(const QScriptContext); - return d->argc; -} - -/*! - \internal -*/ -QScriptValue QScriptContext::returnValue() const -{ - Q_D(const QScriptContext); - return d->engine()->toPublic(d->m_result); -} - -/*! - \internal -*/ -void QScriptContext::setReturnValue(const QScriptValue &result) -{ - Q_D(QScriptContext); - d->m_result = d->engine()->toImpl(result); -} - -/*! - Returns the activation object of this QScriptContext. The activation - object provides access to the local variables associated with this - context. - - \sa argument(), argumentsObject() -*/ -QScriptValue QScriptContext::activationObject() const -{ - Q_D(const QScriptContext); - return d->engine()->toPublic(d->activationObject()); -} - -/*! - Sets the activation object of this QScriptContext to be the given \a - activation. - - If \a activation is not an object, this function does nothing. -*/ -void QScriptContext::setActivationObject(const QScriptValue &activation) -{ - Q_D(QScriptContext); - if (!activation.isObject()) { - return; - } else if (activation.engine() != engine()) { - qWarning("QScriptContext::setActivationObject() failed: " - "cannot set an object created in " - "a different engine"); - } else { - d->m_activation = d->engine()->toImpl(activation); - } -} - -/*! - Returns the `this' object associated with this QScriptContext. -*/ -QScriptValue QScriptContext::thisObject() const -{ - Q_D(const QScriptContext); - return d->engine()->toPublic(d->m_thisObject); -} - -/*! - Sets the `this' object associated with this QScriptContext to be - \a thisObject. - - If \a thisObject is not an object, this function does nothing. -*/ -void QScriptContext::setThisObject(const QScriptValue &thisObject) -{ - Q_D(QScriptContext); - if (!thisObject.isObject()) { - } else if (thisObject.engine() != engine()) { - qWarning("QScriptContext::setThisObject() failed: " - "cannot set an object created in " - "a different engine"); - } else { - d->m_thisObject = d->engine()->toImpl(thisObject); - } -} - -/*! - Returns the execution state of this QScriptContext. -*/ -QScriptContext::ExecutionState QScriptContext::state() const -{ - Q_D(const QScriptContext); - return d->m_state; -} - -/*! - Returns a human-readable backtrace of this QScriptContext. - - Each line is of the form \c{<function-name>(<arguments>)@<file-name>:<line-number>}. - - To access individual pieces of debugging-related information (for - example, to construct your own backtrace representation), use - QScriptContextInfo. - - \sa QScriptEngine::uncaughtExceptionBacktrace(), QScriptContextInfo, toString() -*/ -QStringList QScriptContext::backtrace() const -{ - Q_D(const QScriptContext); - return d->backtrace(); -} - -static QString safeValueToString(const QScriptValue &value) -{ - if (value.isObject()) - return QLatin1String("[object Object]"); - else - return value.toString(); -} - -/*! - \since 4.4 - - Returns a string representation of this context. - This is useful for debugging. - - \sa backtrace() -*/ -QString QScriptContext::toString() const -{ - QScriptContextInfo info(this); - QString result; - - QString functionName = info.functionName(); - if (functionName.isEmpty()) { - if (parentContext()) { - if (info.functionType() == QScriptContextInfo::ScriptFunction) - result.append(QLatin1String("<anonymous>")); - else - result.append(QLatin1String("<native>")); - } else { - result.append(QLatin1String("<global>")); - } - } else { - result.append(functionName); - } - - QStringList parameterNames = info.functionParameterNames(); - result.append(QLatin1String(" (")); - for (int i = 0; i < argumentCount(); ++i) { - if (i > 0) - result.append(QLatin1String(", ")); - if (i < parameterNames.count()) { - result.append(parameterNames.at(i)); - result.append(QLatin1Char('=')); - } - QScriptValue arg = argument(i); - result.append(safeValueToString(arg)); - } - result.append(QLatin1Char(')')); - - QString fileName = info.fileName(); - int lineNumber = info.lineNumber(); - result.append(QLatin1String(" at ")); - if (!fileName.isEmpty()) { - result.append(fileName); - result.append(QLatin1Char(':')); - } - result.append(QString::number(lineNumber)); - return result; -} - -/*! - \internal - \since 4.5 - - Returns the scope chain of this QScriptContext. -*/ -QScriptValueList QScriptContext::scopeChain() const -{ - Q_D(const QScriptContext); - // make sure arguments properties are initialized - const QScriptContextPrivate *ctx = d; - while (ctx) { - (void)ctx->activationObject(); - ctx = ctx->previous; - } - QScriptValueList result; - QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(engine()); - QScriptValueImpl scope = d->m_scopeChain; - while (scope.isObject()) { - if (scope.classInfo() == eng_p->m_class_with) - result.append(eng_p->toPublic(scope.prototype())); - else - result.append(eng_p->toPublic(scope)); - scope = scope.scope(); - } - return result; -} - -/*! - \internal - \since 4.5 - - Adds the given \a object to the front of this context's scope chain. - - If \a object is not an object, this function does nothing. -*/ -void QScriptContext::pushScope(const QScriptValue &object) -{ - Q_D(QScriptContext); - if (!object.isObject()) { - return; - } else if (object.engine() != engine()) { - qWarning("QScriptContext::pushScope() failed: " - "cannot push an object created in " - "a different engine"); - return; - } - QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(engine()); - if (!d->m_scopeChain.isValid()) { - d->m_scopeChain = eng_p->toImpl(object); - } else { - QScriptValueImpl withObject; - eng_p->newObject(&withObject, eng_p->toImpl(object), eng_p->m_class_with); - withObject.m_object_value->m_scope = d->m_scopeChain; - withObject.setInternalValue(1); // to differentiate from with-statement objects - d->m_scopeChain = withObject; - } -} - -/*! - \internal - \since 4.5 - - Removes the front object from this context's scope chain, and - returns the removed object. - - If the scope chain is already empty, this function returns an - invalid QScriptValue. -*/ -QScriptValue QScriptContext::popScope() -{ - Q_D(QScriptContext); - if (!d->m_scopeChain.isObject()) - return QScriptValue(); - QScriptValueImpl result; - QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(engine()); - if (d->m_scopeChain.classInfo() != eng_p->m_class_with) - result = d->m_scopeChain; - else - result = d->m_scopeChain.prototype(); - d->m_scopeChain = d->m_scopeChain.m_object_value->m_scope; - return eng_p->toPublic(result); -} - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptcontext_p.cpp b/src/script/qscriptcontext_p.cpp deleted file mode 100644 index ba0783b..0000000 --- a/src/script/qscriptcontext_p.cpp +++ /dev/null @@ -1,2598 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtCore/QtDebug> - -#ifndef QT_NO_SCRIPT - -#include "qscriptcontext_p.h" -#include "qscriptengine_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" -#include "qscriptprettypretty_p.h" -#include "qscriptast_p.h" -#include "qscriptnodepool_p.h" -#include "qscriptcompiler_p.h" -#include "qscriptextenumeration_p.h" - -#include <math.h> // floor & friends... - -QT_BEGIN_NAMESPACE - -#define Q_SCRIPT_NO_PRINT_GENERATED_CODE - -#define Q_SCRIPT_NO_JOINED_FUNCTION - -#define CHECK_TEMPSTACK(needed) do { \ - if (stackPtr + needed >= eng->tempStackEnd) { \ - throwError(QLatin1String("out of memory")); \ - HandleException(); \ - } \ -} while (0) - -#ifndef Q_SCRIPT_NO_PRINT_GENERATED_CODE -static QTextStream qout(stderr, QIODevice::WriteOnly); -#endif - -static inline void qscript_uint_to_string_helper(uint i, QString &s) -{ - switch (i) { - case 0: case 1: case 2: case 3: case 4: - case 5: case 6: case 7: case 8: case 9: - s += QLatin1Char('0' + i); - break; - - default: - qscript_uint_to_string_helper(i / 10, s); - s += QLatin1Char('0' + (i % 10)); - } -} - -static inline void qscript_uint_to_string(qsreal i, QString &s) -{ - if ((i < 0) || (i > 0xFFFFFFFF)) - return; // nothing to do - - qsreal x = ::fmod(i, 10); - - if (x != 0.0 && x != 1.0 - && x != 2.0 && x != 3.0 - && x != 4.0 && x != 5.0 - && x != 6.0 && x != 7.0 - && x != 8.0 && x != 9.0) - return; // nothing to do - - qscript_uint_to_string_helper(uint(i), s); -} - -static inline quint32 toArrayIndex(const QScriptValueImpl &v) -{ - if (v.isNumber()) { - quint32 ui = v.toUInt32(); - if (qsreal(ui) == v.m_number_value) - return ui; - } else if (v.isString()) { - QByteArray bytes = v.m_string_value->s.toUtf8(); - char *eptr; - quint32 pos = strtoul(bytes.constData(), &eptr, 10); - if ((eptr == bytes.constData() + bytes.size()) - && (QByteArray::number(pos) == bytes)) { - return pos; - } - } - return 0xFFFFFFFF; -} - -#define CREATE_MEMBER(__obj__, __name__, __member__, __flags__) do { \ - (__obj__).createMember(__name__, __member__, __flags__); \ - eng->adjustBytesAllocated(sizeof(QScript::Member) + sizeof(QScriptValueImpl)); \ -} while (0) - -#define BEGIN_PREFIX_OPERATOR \ - QScriptValue::ResolveFlags mode; \ - mode = QScriptValue::ResolveFlags(stackPtr[0].m_int_value) \ - | QScriptValue::ResolvePrototype; \ - --stackPtr; \ - QScriptValueImpl object = eng->toObject(stackPtr[-1]); \ - if (!object.isObject()) { \ - stackPtr -= 2; \ - throwTypeError(QLatin1String("not an object")); \ - HandleException(); \ - } \ - QScriptNameIdImpl *memberName = 0; \ - if (stackPtr[0].isString() && stackPtr[0].m_string_value->unique) \ - memberName = stackPtr[0].m_string_value; \ - else \ - memberName = eng->nameId(stackPtr[0].toString(), /*persistent=*/false); \ - QScript::Member member; \ - QScriptValueImpl base; \ - QScriptValueImpl value; \ - QScriptValueImpl getter; \ - QScriptValueImpl setter; \ - const bool isMemberAssignment = (object.m_object_value != m_scopeChain.m_object_value); \ - if (object.resolve(memberName, &member, &base, mode, QScript::ReadWrite)) { \ - base.get(member, &value); \ - if (hasUncaughtException()) { \ - stackPtr -= 2; \ - HandleException(); \ - } else if (member.isGetterOrSetter()) { \ - if (member.isGetter()) { \ - getter = value; \ - if (!member.isSetter() && !base.m_object_value->findSetter(&member)) { \ - stackPtr -= 2; \ - throwError(QLatin1String("No setter defined")); \ - HandleException(); \ - } \ - base.get(member, &setter); \ - } else { \ - setter = value; \ - QScript::Member tmp = member; \ - if (!base.m_object_value->findGetter(&member)) { \ - stackPtr -= 2; \ - throwError(QLatin1String("No getter defined")); \ - HandleException(); \ - } \ - base.get(member, &getter); \ - member = tmp; \ - } \ - value = getter.call(object); \ - if (hasUncaughtException()) { \ - stackPtr -= 2; \ - Done(); \ - } \ - } \ - } else if (!isMemberAssignment) { \ - stackPtr -= 2; \ - throwNotDefined(memberName); \ - HandleException(); \ - } else { \ - base = object; \ - CREATE_MEMBER(base, memberName, &member, /*flags=*/0); \ - value = undefined; \ - } - -#define END_PREFIX_OPERATOR \ - if (member.isSetter()) { \ - setter.call(object, QScriptValueImplList() << value); \ - if (hasUncaughtException()) { \ - stackPtr -= 2; \ - Done(); \ - } \ - } else { \ - if (member.isWritable()) { \ - if (isMemberAssignment && (base.m_object_value != object.m_object_value)) { \ - base = object; \ - CREATE_MEMBER(base, memberName, &member, /*flags=*/0); \ - } \ - base.put(member, value); \ - if (hasUncaughtException()) { \ - stackPtr -= 2; \ - HandleException(); \ - } \ - } \ - } \ - *--stackPtr = value; \ - ++iPtr; - -#define BEGIN_INPLACE_OPERATOR \ - if (! stackPtr[-1].isReference()) { \ - stackPtr -= 2; \ - throwSyntaxError(QLatin1String("invalid assignment lvalue")); \ - HandleException(); \ - } \ - QScriptValue::ResolveFlags mode; \ - mode = QScriptValue::ResolveFlags(stackPtr[-1].m_int_value) \ - | QScriptValue::ResolvePrototype; \ - QScriptValueImpl object = eng->toObject(stackPtr[-3]); \ - if (! object.isValid()) { \ - stackPtr -= 4; \ - throwTypeError(QLatin1String("not an object")); \ - HandleException(); \ - } \ - QScriptNameIdImpl *memberName = 0; \ - if (stackPtr[-2].isString() && stackPtr[-2].m_string_value->unique) \ - memberName = stackPtr[-2].m_string_value; \ - else \ - memberName = eng->nameId(stackPtr[-2].toString(), /*persistent=*/false); \ - QScriptValueImpl lhs; \ - QScriptValueImpl base; \ - QScript::Member member; \ - QScriptValueImpl getter; \ - QScriptValueImpl setter; \ - const bool isMemberAssignment = (object.m_object_value != m_scopeChain.m_object_value); \ - if (object.resolve(memberName, &member, &base, mode, QScript::ReadWrite)) { \ - base.get(member, &lhs); \ - if (hasUncaughtException()) { \ - stackPtr -= 4; \ - HandleException(); \ - } else if (member.isGetterOrSetter()) { \ - if (member.isGetter()) { \ - getter = lhs; \ - if (!member.isSetter() && !base.m_object_value->findSetter(&member)) { \ - stackPtr -= 4; \ - throwError(QLatin1String("No setter defined")); \ - HandleException(); \ - } \ - base.get(member, &setter); \ - } else { \ - setter = lhs; \ - QScript::Member tmp = member; \ - if (!base.m_object_value->findGetter(&member)) { \ - stackPtr -= 4; \ - throwError(QLatin1String("No getter defined")); \ - HandleException(); \ - } \ - base.get(member, &getter); \ - member = tmp; \ - } \ - lhs = getter.call(object); \ - if (hasUncaughtException()) { \ - stackPtr -= 4; \ - Done(); \ - } \ - } \ - } else if (!isMemberAssignment) { \ - stackPtr -= 4; \ - throwNotDefined(memberName); \ - HandleException(); \ - } else { \ - base = object; \ - CREATE_MEMBER(base, memberName, &member, /*flags=*/0); \ - lhs = undefined; \ - } \ - QScriptValueImpl rhs = stackPtr[0]; - -#define END_INPLACE_OPERATOR \ - if (member.isSetter()) { \ - setter.call(object, QScriptValueImplList() << *stackPtr); \ - if (hasUncaughtException()) { \ - stackPtr -= 1; \ - Done(); \ - } \ - } else { \ - if (member.isWritable()) { \ - if (isMemberAssignment && (base.m_object_value != object.m_object_value)) { \ - base = object; \ - CREATE_MEMBER(base, memberName, &member, /*flags=*/0); \ - } \ - base.put(member, *stackPtr); \ - if (hasUncaughtException()) { \ - stackPtr -= 1; \ - HandleException(); \ - } \ - } \ - } \ - ++iPtr; - -namespace QScript { - -void ScriptFunction::execute(QScriptContextPrivate *context) -{ - if (! m_compiledCode) { - QScriptEnginePrivate *eng = context->engine(); - Compiler compiler(eng); - - CompilationUnit unit = compiler.compile(m_definition->body, formals); - if (! unit.isValid()) { - context->throwError(unit.errorMessage()); - return; - } - - m_compiledCode = m_astPool->createCompiledCode(m_definition->body, unit); - } - - context->execute(m_compiledCode); -} - -QString ScriptFunction::toString(QScriptContextPrivate *) const -{ - QString str; - QTextStream out(&str, QIODevice::WriteOnly); - PrettyPretty pp(out); - pp(m_definition, /*indent=*/ 0); - return str; -} - -QString ScriptFunction::fileName() const -{ - return m_astPool->fileName(); -} - -QString ScriptFunction::functionName() const -{ - if (!m_definition->name) - return QString(); - return m_definition->name->s; -} - -int ScriptFunction::startLineNumber() const -{ - return m_definition->startLine; -} - -int ScriptFunction::endLineNumber() const -{ - return m_definition->endLine; -} - -} // namespace QScript - -/*! - \internal - - Resolves and gets the value specified by \a stackPtr. - stackPtr[0] contains the member specifier, stackPtr[-1] contains the object. - If the member can be resolved, sets \a value to the value of that member, - otherwise returns false. -*/ -bool QScriptContextPrivate::resolveField(QScriptEnginePrivate *eng, - QScriptValueImpl *stackPtr, - QScriptValueImpl *value) -{ - const QScriptValueImpl &m = stackPtr[0]; - QScriptValueImpl &object = stackPtr[-1]; - - if (! object.isObject()) - object = eng->toObject(object); - - if (! object.isValid()) - return false; - - if (QScript::Ecma::Array::Instance *arrayInstance = eng->arrayConstructor->get(object)) { - quint32 pos = toArrayIndex(m); - if (pos != 0xFFFFFFFF) { - *value = arrayInstance->value.at(pos); - - if (! value->isValid()) - *value = eng->undefinedValue(); - - return true; - } - } - - QScriptNameIdImpl *nameId = m.isString() ? m.m_string_value : 0; - - if (! nameId || ! nameId->unique) - nameId = eng->nameId(QScriptEnginePrivate::convertToNativeString(m), /*persistent=*/false); // ### slow! - - QScript::Member member; - QScriptValueImpl base; - - if (! object.resolve(nameId, &member, &base, QScriptValue::ResolveFull, QScript::Read)) // ### ... - return false; - - if (QScriptEnginePrivate::strictlyEquals(base, eng->m_globalObject)) - stackPtr[-1] = base; - else if (object.classInfo() == eng->m_class_with) - stackPtr[-1] = object.prototype(); - - base.get(member, value); - - if (member.isGetterOrSetter()) { - // call the getter function - QScriptValueImpl getter; - if (member.isGetter()) { - getter = *value; - } else { - if (!base.m_object_value->findGetter(&member)) { - *value = eng->undefinedValue(); - return true; - } - base.get(member, &getter); - } - *value = getter.call(object); - } - - return true; -} - -void QScriptContextPrivate::execute(QScript::Code *code) -{ - int oldCurrentLine = currentLine; - int oldCurrentColumn = currentColumn; - QScript::Code *oldCode = m_code; - m_code = code; - -#ifndef Q_SCRIPT_NO_PRINT_GENERATED_CODE - qout << QLatin1String("function:") << endl; - for (QScriptInstruction *current = code->firstInstruction; current != code->lastInstruction; ++current) { - qout << int(current - code->firstInstruction) << QLatin1String(":\t"); - current->print(qout); - qout << endl; - } - qout << endl; -#endif - - QScriptEnginePrivate *eng = engine(); - - bool wasEvaluating = eng->m_evaluating; - if (!wasEvaluating) { - eng->setupProcessEvents(); - eng->resetAbortFlag(); - } - eng->m_evaluating = true; - - // set up the temp stack - if (! tempStack) - stackPtr = tempStack = eng->tempStackBegin; - - QScriptValueImpl undefined(eng->undefinedValue()); - - catching = false; - m_state = QScriptContext::NormalState; - m_result = undefined; - firstInstruction = code->firstInstruction; - lastInstruction = code->lastInstruction; - iPtr = code->firstInstruction; - - if (!m_scopeChain.isValid()) - m_scopeChain = m_activation; - -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - eng->notifyFunctionEntry(this); -#endif - -#ifndef Q_SCRIPT_DIRECT_CODE - -# define I(opc) case QScriptInstruction::OP_##opc -# define Next() goto Lfetch -# define Done() goto Ldone -# define HandleException() goto Lhandle_exception -# define Abort() goto Labort - -Lfetch: - - -#else - -# define I(opc) qscript_execute_##opc -# define Next() goto *iPtr->code -# define Done() goto Ldone -# define HandleException() goto Lhandle_exception -# define Abort() goto Labort - - static void * const jump_table[] = { - -# define Q_SCRIPT_DEFINE_OPERATOR(op) &&I(op), -# include "instruction.table" -# undef Q_SCRIPT_DEFINE_OPERATOR - }; // jump_table - - - if (!code->optimized) { - for (QScriptInstruction *current = code->firstInstruction; current != code->lastInstruction; ++current) { - current->code = jump_table[current->op]; - } - - code->optimized = true; - } - -#endif -Ltop: - -#ifndef Q_SCRIPT_DIRECT_CODE - switch (iPtr->op) { -#else - goto *iPtr->code; -#endif - - I(Nop): - { - ++iPtr; - } Next(); - - I(LoadUndefined): - { - CHECK_TEMPSTACK(1); - *(++stackPtr) = undefined; - ++iPtr; - } Next(); - - I(LoadTrue): - { - CHECK_TEMPSTACK(1); - *(++stackPtr) = QScriptValueImpl(true); - ++iPtr; - } Next(); - - I(LoadFalse): - { - CHECK_TEMPSTACK(1); - *(++stackPtr) = QScriptValueImpl(false); - ++iPtr; - } Next(); - - I(LoadThis): - { - CHECK_TEMPSTACK(1); - Q_ASSERT(m_thisObject.isObject()); - *++stackPtr = m_thisObject; - ++iPtr; - } Next(); - - I(LoadActivation): - { - CHECK_TEMPSTACK(1); - *++stackPtr = m_activation; - ++iPtr; - } Next(); - - I(LoadNull): - { - CHECK_TEMPSTACK(1); - *(++stackPtr) = eng->nullValue(); - ++iPtr; - } Next(); - - I(LoadNumber): - { - CHECK_TEMPSTACK(1); - *++stackPtr = iPtr->operand[0]; - ++iPtr; - } Next(); - - - I(LoadString): - { - CHECK_TEMPSTACK(1); - *++stackPtr = iPtr->operand[0]; - ++iPtr; - } Next(); - - I(NewString): - { - CHECK_TEMPSTACK(1); - eng->newNameId(++stackPtr, iPtr->operand[0].m_string_value); - ++iPtr; - } Next(); - - I(Duplicate): - { - CHECK_TEMPSTACK(1); - ++stackPtr; - *stackPtr = stackPtr[-1]; - ++iPtr; - } Next(); - - I(Swap): - { - QScriptValueImpl tmp = stackPtr[0]; - *stackPtr = stackPtr[-1]; - stackPtr[-1] = tmp; - ++iPtr; - } Next(); - - - I(Receive): - { - int n = iPtr->operand[0].m_int_value; - - if (n >= argc) { - throwError(QLatin1String("invalid argument")); - HandleException(); - } - - CHECK_TEMPSTACK(1); - *++stackPtr = argument(n); - ++iPtr; - } Next(); - - I(Fetch): - { - CHECK_TEMPSTACK(1); - - QScriptNameIdImpl *memberName = iPtr->operand[0].m_string_value; - - QScriptValueImpl base; - QScript::Member member; - - QScriptObject *instance = m_scopeChain.m_object_value; - if (instance->findMember(memberName, &member)) { - instance->get(member, ++stackPtr); - base = m_scopeChain; - } else { - if (m_scopeChain.resolve_helper(memberName, &member, &base, QScriptValue::ResolveFull, QScript::Read)) { - base.get(member, ++stackPtr); - if (hasUncaughtException()) { - stackPtr -= 1; - HandleException(); - } - } else { - throwNotDefined(memberName); - HandleException(); - } - } - if (member.isGetterOrSetter()) { - // locate the getter function - QScriptValueImpl getter; - if (member.isGetter()) { - getter = *stackPtr; - } else { - if (!base.m_object_value->findGetter(&member)) { - stackPtr -= 1; - throwError(QLatin1String("No getter defined")); - HandleException(); - } - base.get(member, &getter); - } - // decide the this-object. This is the object that actually - // has the getter (in its prototype chain). - QScriptValueImpl object = m_scopeChain; - while (!object.resolve(memberName, &member, &base, QScriptValue::ResolvePrototype, QScript::Read)) - object = object.scope(); - if (object.classInfo() == eng->m_class_with) - object = object.prototype(); - - *stackPtr = getter.call(object); - if (hasUncaughtException()) { - stackPtr -= 1; - Done(); - } - } - ++iPtr; - } Next(); - - I(Resolve): - { - Q_ASSERT(iPtr->operand[0].isString()); - - CHECK_TEMPSTACK(2); - *++stackPtr = m_scopeChain; - *++stackPtr = iPtr->operand[0]; - eng->newReference(++stackPtr, QScriptValue::ResolveScope); - ++iPtr; - } Next(); - - I(PutField): - { - Q_ASSERT(stackPtr[-1].isReference()); - - const QScriptValueImpl &object = stackPtr[-3]; - QScriptNameIdImpl *memberName = stackPtr[-2].m_string_value; - const QScriptValueImpl &value = stackPtr[0]; - - QScript::Member member; - QScriptValueImpl base; - - if (! object.resolve(memberName, &member, &base, QScriptValue::ResolveLocal, QScript::Write)) { - base = object; - CREATE_MEMBER(base, memberName, &member, /*flags=*/0); - } - - base.put(member, value); - stackPtr -= 4; - if (hasUncaughtException()) - HandleException(); - ++iPtr; - } Next(); - - I(Call): - { - int argc = iPtr->operand[0].m_int_value; - QScriptValueImpl *argp = stackPtr - argc; - - QScriptValueImpl base; - QScriptValueImpl callee; - - bool isReference = argp[0].isReference(); - - if (! isReference) { // we have a value - base = eng->m_globalObject; - callee = argp[0]; - } else if (resolveField(eng, &argp[-1], &callee)) { - if (hasUncaughtException()) { - stackPtr = argp - 3; - HandleException(); - } - base = argp[-2]; - } else { - QScriptValueImpl member = argp[-1]; - stackPtr = argp - 1; - Q_ASSERT(isReference); - stackPtr -= 2; - - if (member.isString()) - throwNotDefined(member.toString()); - else - throwNotDefined(QLatin1String("function")); - HandleException(); - } - - Q_ASSERT(base.isValid()); - Q_ASSERT(callee.isValid()); - - QScriptFunction *function = QScriptEnginePrivate::convertToNativeFunction(callee); - if (! function) { - QScriptValueImpl member = argp[-1]; - QString message; - if (member.isString()) { - message = QString::fromLatin1("%0 is not a function") - .arg(member.toString()); - } else { - message = QLatin1String("not a function"); - } - throwTypeError(message); - HandleException(); - } - - if (++eng->m_callDepth == eng->m_maxCallDepth) { - throwError(QLatin1String("call stack overflow")); - HandleException(); - } - - QScriptContextPrivate *nested_data = eng->pushContext(); - nested_data->m_thisObject = base; - nested_data->m_callee = callee; - - // create the activation - eng->newActivation(&nested_data->m_activation); - QScriptObject *activation_data = nested_data->m_activation.m_object_value; - - int formalCount = function->formals.count(); - int mx = qMax(formalCount, argc); - activation_data->m_members.resize(mx); - activation_data->m_values.resize(mx); - for (int i = 0; i < mx; ++i) { - QScriptNameIdImpl *nameId = 0; - if (i < formalCount) - nameId = function->formals.at(i); - - activation_data->m_members[i].object(nameId, i, - QScriptValue::Undeletable - | QScriptValue::SkipInEnumeration); - activation_data->m_values[i] = (i < argc) ? argp[i + 1] : undefined; - } - - nested_data->argc = argc; - if (callee.m_object_value->m_scope.isValid()) - activation_data->m_scope = callee.m_object_value->m_scope; - else - activation_data->m_scope = eng->m_globalObject; - nested_data->tempStack = stackPtr; - nested_data->args = &argp[1]; - - function->execute(nested_data); - - --eng->m_callDepth; - - stackPtr = argp - 1; - if (isReference) - stackPtr -= 2; - - if (nested_data->m_state == QScriptContext::ExceptionState) { - eng->popContext(); - if (eng->shouldAbort()) - Abort(); - else - Done(); - } - - CHECK_TEMPSTACK(1); - *++stackPtr = nested_data->m_result; - - eng->popContext(); - - if (eng->shouldAbort()) - Abort(); - - if (eng->m_processEventsInterval > 0) - eng->processEvents(); - - ++iPtr; - } Next(); - - - I(NewArray): - { - CHECK_TEMPSTACK(1); - eng->arrayConstructor->newArray(++stackPtr, QScript::Array(eng)); - ++iPtr; - } Next(); - - I(NewRegExp): - { - CHECK_TEMPSTACK(1); - - QString pattern = eng->toString(iPtr->operand[0].m_string_value); -#ifndef QT_NO_REGEXP - QString literal = pattern; -#endif - int flags = 0; - if (iPtr->operand[1].isValid()) { - flags = iPtr->operand[1].m_int_value; -#ifndef QT_NO_REGEXP - if (flags != 0) { - literal += QLatin1Char('/'); - literal += QString::number(flags); - } -#endif - } - -#ifndef QT_NO_REGEXP - QRegExp rx; - // lazy compilation of regexp literals - QHash<QString, QRegExp>::const_iterator it; - it = eng->m_regExpLiterals.constFind(literal); - if (it == eng->m_regExpLiterals.constEnd()) { - rx = QScript::Ecma::RegExp::toRegExp(pattern, flags); - eng->m_regExpLiterals.insert(literal, rx); - } else { - rx = *it; - } - eng->regexpConstructor->newRegExp(++stackPtr, rx, flags); -#else - eng->regexpConstructor->newRegExp(++stackPtr, pattern, flags); -#endif - ++iPtr; - } Next(); - - I(NewObject): - { - CHECK_TEMPSTACK(1); - eng->objectConstructor->newObject(++stackPtr); - ++iPtr; - } Next(); - - I(New): - { - int argc = iPtr->operand[0].m_int_value; - QScriptValueImpl *argp = stackPtr - argc; - - // QScriptValueImpl base; - QScriptValueImpl callee; - - bool isReference = argp[0].isReference(); - - if (! isReference) { // we have a value - // base = eng->globalObject; - callee = argp[0]; - } else if (resolveField(eng, &argp[-1], &callee)) { - // base = argp[-2]; - if (hasUncaughtException()) { - stackPtr = argp - 3; - HandleException(); - } - } else { - QScriptValueImpl member = argp[-1]; - stackPtr = argp - 1; - Q_ASSERT(isReference); - stackPtr -= 2; - - if (member.isString()) - throwNotDefined(member.toString()); - else - throwNotDefined(QLatin1String("constructor")); - HandleException(); - } - - // Q_ASSERT(base.isValid()); - Q_ASSERT(callee.isValid()); - - QScriptFunction *function = QScriptEnginePrivate::convertToNativeFunction(callee); - if (! function) { - QScriptValueImpl member = argp[-1]; - QString message; - if (member.isString()) { - message = QString::fromLatin1("%0 is not a constructor") - .arg(member.toString()); - } else { - message = QLatin1String("not a constructor"); - } - throwTypeError(message); - HandleException(); - } - - if (++eng->m_callDepth == eng->m_maxCallDepth) { - throwError(QLatin1String("call stack overflow")); - HandleException(); - } - - QScriptContextPrivate *nested_data = eng->pushContext(); - nested_data->m_callee = callee; - nested_data->m_calledAsConstructor = true; - - // create the activation - eng->newActivation(&nested_data->m_activation); - QScriptObject *activation_data = nested_data->m_activation.m_object_value; - - int formalCount = function->formals.count(); - int mx = qMax(formalCount, argc); - activation_data->m_members.resize(mx); - activation_data->m_values.resize(mx); - for (int i = 0; i < mx; ++i) { - QScriptNameIdImpl *nameId = 0; - if (i < formalCount) - nameId = function->formals.at(i); - - activation_data->m_members[i].object(nameId, i, - QScriptValue::Undeletable - | QScriptValue::SkipInEnumeration); - activation_data->m_values[i] = (i < argc) ? argp[i + 1] : undefined; - } - - eng->objectConstructor->newObject(&nested_data->m_thisObject); - nested_data->argc = argc; - if (callee.m_object_value->m_scope.isValid()) - activation_data->m_scope = callee.m_object_value->m_scope; - else - activation_data->m_scope = eng->m_globalObject; - nested_data->tempStack = stackPtr; - nested_data->args = &argp[1]; - nested_data->m_result = undefined; - - QScriptObject *instance = nested_data->m_thisObject.m_object_value; - - // set [[prototype]] - QScriptValueImpl dummy; - QScript::Member proto; - if (callee.resolve(eng->idTable()->id_prototype, &proto, &dummy, QScriptValue::ResolveLocal, QScript::Read)) - callee.get(proto, &instance->m_prototype); - if (!instance->m_prototype.isObject()) - instance->m_prototype = eng->objectConstructor->publicPrototype; - - function->execute(nested_data); - - --eng->m_callDepth; - - stackPtr = argp - 1; - if (isReference) - stackPtr -= 2; - - if (! nested_data->m_result.isValid()) - nested_data->m_result = undefined; - else if (! nested_data->m_result.isObject()) - nested_data->m_result = nested_data->m_thisObject; - - if (nested_data->m_state == QScriptContext::ExceptionState) { - eng->popContext(); - if (eng->shouldAbort()) - Abort(); - else - Done(); - } - - CHECK_TEMPSTACK(1); - - *++stackPtr = nested_data->m_result; - - eng->popContext(); - - if (eng->shouldAbort()) - Abort(); - - if (eng->m_processEventsInterval > 0) - eng->processEvents(); - - ++iPtr; - } Next(); - - I(FetchField): - { - QScriptValueImpl object = eng->toObject(stackPtr[-1]); - if (! object.isValid()) { - stackPtr -= 2; - throwTypeError(QLatin1String("not an object")); - HandleException(); - } - - QScriptValueImpl m = stackPtr[0]; - - QScript::Ecma::Array::Instance *arrayInstance = 0; - if (object.classInfo() == eng->arrayConstructor->classInfo()) - arrayInstance = static_cast<QScript::Ecma::Array::Instance *> (object.m_object_value->m_data); - - if (arrayInstance) { - quint32 pos = toArrayIndex(m); - if (pos != 0xFFFFFFFF) { - QScriptValueImpl val = arrayInstance->value.at(pos); - if (val.isValid()) { - *--stackPtr = val; - ++iPtr; - Next(); - } - } - } - - QScriptNameIdImpl *nameId = m.isString() ? m.m_string_value : 0; - - if (! nameId || ! nameId->unique) { - QString str; - - if (m.isNumber()) - qscript_uint_to_string(m.m_number_value, str); - - if (str.isEmpty()) - str = QScriptEnginePrivate::convertToNativeString(m); - - nameId = eng->nameId(str, /*persistent=*/false); - } - - QScript::Member member; - QScriptValueImpl base; - - if (object.resolve(nameId, &member, &base, QScriptValue::ResolvePrototype, QScript::Read)) { - base.get(member, --stackPtr); - if (hasUncaughtException()) { - stackPtr -= 1; - HandleException(); - } else if (member.isGetterOrSetter()) { - // call the getter function - QScriptValueImpl getter; - if (member.isGetter()) { - getter = *stackPtr; - } else { - if (!base.m_object_value->findGetter(&member)) { - stackPtr -= 1; - throwError(QLatin1String("No getter defined")); - HandleException(); - } - base.get(member, &getter); - } - *stackPtr = getter.call(object); - if (hasUncaughtException()) { - stackPtr -= 1; - Done(); - } - } - } else { - *(--stackPtr) = undefined; - } - - ++iPtr; - } Next(); - - I(LazyArguments): - { - QScript::Member member; - QScriptValueImpl base; - QScriptNameIdImpl *arguments = eng->idTable()->id_arguments; - if (!m_activation.resolve(arguments, &member, &base, QScriptValue::ResolveLocal, QScript::Read)) { - CREATE_MEMBER(m_activation, arguments, &member, QScriptValue::Undeletable); - if (!m_arguments.isValid()) { - if (eng->strictlyEquals(m_activation, eng->globalObject())) - m_arguments = undefined; - else - eng->newArguments(&m_arguments, m_activation, argc, m_callee); - } - m_activation.put(member, m_arguments); - } - ++iPtr; - } Next(); - - I(DeclareLocal): - { - QScriptValueImpl &act = m_activation; - - QScriptNameIdImpl *memberName = iPtr->operand[0].m_string_value; - bool readOnly = iPtr->operand[1].m_int_value != 0; - QScript::Member member; - QScriptValueImpl object; - - if (! act.resolve(memberName, &member, &object, QScriptValue::ResolveLocal, QScript::ReadWrite)) { - uint flags = QScriptValue::Undeletable; - if (readOnly) - flags |= QScript::Member::UninitializedConst | QScriptValue::ReadOnly; - CREATE_MEMBER(act, memberName, &member, flags); - act.put(member, undefined); - } - ++iPtr; - } Next(); - - I(Assign): - { - if (! stackPtr[-1].isReference()) { - stackPtr -= 2; - throwSyntaxError(QLatin1String("invalid assignment lvalue")); - HandleException(); - } - - QScriptValue::ResolveFlags mode; - mode = QScriptValue::ResolveFlags(stackPtr[-1].m_int_value) - | QScriptValue::ResolvePrototype; - - QScriptValueImpl object = eng->toObject(stackPtr[-3]); - if (! object.isValid()) { - stackPtr -= 4; - throwTypeError(QLatin1String("invalid assignment lvalue")); - HandleException(); - } - - QScriptValueImpl m = stackPtr[-2]; - QScriptValueImpl value = stackPtr[0]; - - quint32 pos = 0xFFFFFFFF; - - QScript::Ecma::Array::Instance *arrayInstance = eng->arrayConstructor->get(object); - if (arrayInstance) - pos = toArrayIndex(m); - - stackPtr -= 3; - - if (pos != 0xFFFFFFFF) - arrayInstance->value.assign(pos, value); - - else { - QScriptNameIdImpl *memberName; - - if (m.isString() && m.m_string_value->unique) - memberName = m.m_string_value; - else - memberName = eng->nameId(QScriptEnginePrivate::convertToNativeString(m), /*persistent=*/false); - - QScriptValueImpl base; - QScript::Member member; - - const bool isMemberAssignment = (object.m_object_value != m_scopeChain.m_object_value); - if (! object.resolve(memberName, &member, &base, mode, QScript::Write)) { - if (isMemberAssignment) - base = object; - else - base = eng->m_globalObject; - - CREATE_MEMBER(base, memberName, &member, /*flags=*/0); - } - - if (value.isString() && ! value.m_string_value->unique) - eng->newNameId(&value, value.m_string_value->s); - - if (member.isGetterOrSetter()) { - // find and call setter(value) - QScriptValueImpl setter; - if (!member.isSetter()) { - if (!base.m_object_value->findSetter(&member)) { - stackPtr -= 1; - throwError(QLatin1String("no setter defined")); - HandleException(); - } - } - base.get(member, &setter); - - if (!isMemberAssignment) { - // decide the this-object. This is the object that actually - // has the setter (in its prototype chain). - while (!object.resolve(memberName, &member, &base, QScriptValue::ResolvePrototype, QScript::Write)) - object = object.scope(); - if (object.classInfo() == eng->m_class_with) - object = object.prototype(); - } - - value = setter.call(object, QScriptValueImplList() << value); - if (hasUncaughtException()) { - stackPtr -= 1; - Done(); - } - } else { - if (object.classInfo() == eng->m_class_with) - object = object.prototype(); - - if (member.isWritable()) { - if (isMemberAssignment && (base.m_object_value != object.m_object_value)) { - base = object; - CREATE_MEMBER(base, memberName, &member, /*flags=*/0); - } - base.put(member, value); - } else if (member.isUninitializedConst()) { - base.put(member, value); - if (member.isObjectProperty()) { - base.m_object_value->m_members[member.id()] - .unsetFlags(QScript::Member::UninitializedConst); - } - } - if (hasUncaughtException()) { - stackPtr -= 1; - HandleException(); - } - } - } - - *stackPtr = value; - ++iPtr; - } Next(); - - I(BitAnd): - { - qint32 v1 = QScriptEnginePrivate::convertToNativeInt32(stackPtr[-1]); - qint32 v2 = QScriptEnginePrivate::convertToNativeInt32(stackPtr[0]); - *(--stackPtr) = QScriptValueImpl(v1 & v2); - ++iPtr; - } Next(); - - I(BitOr): - { - qint32 v1 = QScriptEnginePrivate::convertToNativeInt32(stackPtr[-1]); - qint32 v2 = QScriptEnginePrivate::convertToNativeInt32(stackPtr[0]); - *(--stackPtr) = QScriptValueImpl(v1 | v2); - ++iPtr; - } Next(); - - I(BitXor): - { - qint32 v1 = QScriptEnginePrivate::convertToNativeInt32(stackPtr[-1]); - qint32 v2 = QScriptEnginePrivate::convertToNativeInt32(stackPtr[0]); - *(--stackPtr) = QScriptValueImpl(v1 ^ v2); - ++iPtr; - } Next(); - - I(BitNot): - { - qint32 v1 = QScriptEnginePrivate::convertToNativeInt32(stackPtr[0]); - *stackPtr = QScriptValueImpl(~v1); - ++iPtr; - } Next(); - - I(Not): - { - bool v1 = QScriptEnginePrivate::convertToNativeBoolean(stackPtr[0]); - *stackPtr = QScriptValueImpl(!v1); - ++iPtr; - } Next(); - - I(LeftShift): - { - qint32 v1 = QScriptEnginePrivate::convertToNativeInt32(stackPtr[-1]); - qint32 v2 = QScriptEnginePrivate::convertToNativeInt32(stackPtr[0]) & 0x1f; - *(--stackPtr) = QScriptValueImpl(v1 << v2); - ++iPtr; - } Next(); - - I(Mod): - { - qsreal v1 = QScriptEnginePrivate::convertToNativeDouble(stackPtr[-1]); - qsreal v2 = QScriptEnginePrivate::convertToNativeDouble(stackPtr[0]); - - *(--stackPtr) = QScriptValueImpl(::fmod(v1, v2)); - ++iPtr; - } Next(); - - I(RightShift): - { - qint32 v1 = QScriptEnginePrivate::convertToNativeInt32(stackPtr[-1]); - quint32 v2 = QScriptEnginePrivate::toUint32 (eng->convertToNativeDouble(stackPtr[0])) & 0x1f; - *(--stackPtr) = QScriptValueImpl(v1 >> v2); - ++iPtr; - } Next(); - - I(URightShift): - { - quint32 v1 = QScriptEnginePrivate::toUint32 (eng->convertToNativeDouble(stackPtr[-1])); - qint32 v2 = QScriptEnginePrivate::convertToNativeInt32(stackPtr[0]) & 0x1f; - *(--stackPtr) = QScriptValueImpl(v1 >> v2); - ++iPtr; - } Next(); - - I(InstanceOf): - { - QScriptValueImpl object = stackPtr[-1]; - QScriptValueImpl ctor = stackPtr[0]; - - if (!ctor.isObject() || !ctor.implementsHasInstance()) { - stackPtr -= 2; - throwTypeError(QLatin1String("invalid 'instanceof' operand")); - HandleException(); - } - - bool result = ctor.hasInstance(object); - if (eng->hasUncaughtException()) { - stackPtr -= 2; - HandleException(); - } - - *(--stackPtr) = QScriptValueImpl(result); - ++iPtr; - } Next(); - - I(In): - { - QScriptValueImpl object = stackPtr[0]; - if (!object.isObject()) { - stackPtr -= 2; - throwTypeError(QLatin1String("invalid 'in' operand")); - HandleException(); - } - QString propertyName = QScriptEnginePrivate::convertToNativeString(stackPtr[-1]); - bool result = object.property(propertyName, QScriptValue::ResolvePrototype).isValid(); // ### hasProperty() - *(--stackPtr) = QScriptValueImpl(result); - ++iPtr; - } Next(); - - I(Add): - { - QScriptValueImpl lhs = eng->toPrimitive(stackPtr[-1], QScriptValueImpl::NoTypeHint); - QScriptValueImpl rhs = eng->toPrimitive(stackPtr[0], QScriptValueImpl::NoTypeHint); - - if (lhs.isString() || rhs.isString()) { - QString tmp = QScriptEnginePrivate::convertToNativeString(lhs); - tmp += QScriptEnginePrivate::convertToNativeString(rhs); - eng->newString(--stackPtr, tmp); - } else { - qsreal tmp = QScriptEnginePrivate::convertToNativeDouble(lhs); - tmp += QScriptEnginePrivate::convertToNativeDouble(rhs); - *(--stackPtr) = QScriptValueImpl(tmp); - } - - ++iPtr; - } Next(); - - I(Div): - { - qsreal v1 = QScriptEnginePrivate::convertToNativeDouble(stackPtr[-1]); - qsreal v2 = QScriptEnginePrivate::convertToNativeDouble(stackPtr[0]); - *(--stackPtr) = QScriptValueImpl(v1 / v2); - ++iPtr; - } Next(); - - I(Equal): - { - QScriptValueImpl v1 = stackPtr[-1]; - QScriptValueImpl v2 = stackPtr[0]; - *(--stackPtr) = QScriptValueImpl(eq_cmp(v1, v2)); - ++iPtr; - } Next(); - - I(GreatOrEqual): - { - QScriptValueImpl v1 = stackPtr[0]; - QScriptValueImpl v2 = stackPtr[-1]; - *(--stackPtr) = QScriptValueImpl(le_cmp(v1, v2)); - ++iPtr; - } Next(); - - I(GreatThan): - { - QScriptValueImpl v1 = stackPtr[0]; - QScriptValueImpl v2 = stackPtr[-1]; - *(--stackPtr) = QScriptValueImpl(lt_cmp(v1, v2)); - ++iPtr; - } Next(); - - I(LessOrEqual): - { - QScriptValueImpl v1 = stackPtr[-1]; - QScriptValueImpl v2 = stackPtr[0]; - *(--stackPtr) = QScriptValueImpl(le_cmp(v1, v2)); - ++iPtr; - } Next(); - - I(LessThan): - { - QScriptValueImpl v1 = stackPtr[-1]; - QScriptValueImpl v2 = stackPtr[0]; - *(--stackPtr) = QScriptValueImpl(lt_cmp(v1, v2)); - ++iPtr; - } Next(); - - I(NotEqual): - { - QScriptValueImpl v1 = stackPtr[-1]; - QScriptValueImpl v2 = stackPtr[0]; - *(--stackPtr) = QScriptValueImpl(!eq_cmp(v1, v2)); - ++iPtr; - } Next(); - - I(Mul): - { - qsreal v1 = QScriptEnginePrivate::convertToNativeDouble(stackPtr[-1]); - qsreal v2 = QScriptEnginePrivate::convertToNativeDouble(stackPtr[0]); - *(--stackPtr) = QScriptValueImpl(v1 * v2); - ++iPtr; - } Next(); - - I(StrictEqual): - { - QScriptValueImpl v1 = stackPtr[-1]; - QScriptValueImpl v2 = stackPtr[0]; - *(--stackPtr) = strict_eq_cmp(v1, v2); - ++iPtr; - } Next(); - - I(StrictNotEqual): - { - QScriptValueImpl v1 = stackPtr[-1]; - QScriptValueImpl v2 = stackPtr[0]; - *(--stackPtr) = ! strict_eq_cmp(v1, v2); - ++iPtr; - } Next(); - - I(Sub): - { - qsreal v1 = QScriptEnginePrivate::convertToNativeDouble(stackPtr[-1]); - qsreal v2 = QScriptEnginePrivate::convertToNativeDouble(stackPtr[0]); - *(--stackPtr) = QScriptValueImpl(v1 - v2); - ++iPtr; - } Next(); - - I(UnaryMinus): - { - qsreal v1 = QScriptEnginePrivate::convertToNativeDouble(*stackPtr); - *stackPtr = QScriptValueImpl(-v1); - ++iPtr; - } Next(); - - I(UnaryPlus): - { - qsreal v1 = QScriptEnginePrivate::convertToNativeDouble(*stackPtr); - *stackPtr = QScriptValueImpl(+v1); - ++iPtr; - } Next(); - - I(Branch): - { - eng->maybeProcessEvents(); - if (hasUncaughtException()) - HandleException(); - if (eng->shouldAbort()) - Abort(); - iPtr += iPtr->operand[0].m_int_value; - } Next(); - - I(BranchFalse): - { - if (! QScriptEnginePrivate::convertToNativeBoolean(*stackPtr--)) - iPtr += iPtr->operand[0].m_int_value; - else - ++iPtr; - } Next(); - - I(BranchTrue): - { - if (eng->convertToNativeBoolean(*stackPtr--)) - iPtr += iPtr->operand[0].m_int_value; - else - ++iPtr; - } Next(); - - I(NewClosure): - { - CHECK_TEMPSTACK(1); - - QScript::AST::FunctionExpression *expr = static_cast<QScript::AST::FunctionExpression *> (iPtr->operand[0].m_ptr_value); - -#ifndef Q_SCRIPT_NO_JOINED_FUNCTION - if (QScript::Code *code = eng->findCode(functionBody)) { - QScriptValueImpl value = code->value; - - if (isValid(value)) { - QScriptObject *instance = value.m_object_value; - Q_ASSERT(instance != 0); - - if (instance->m_scope.m_object_value == m_scopeChain.m_object_value) - { - *++stackPtr = value; - ++iPtr; - Next(); - } - } - } -#endif - - QScript::ScriptFunction *function = new QScript::ScriptFunction(expr, code->astPool); - - // update the formals - for (QScript::AST::FormalParameterList *it = expr->formals; it != 0; it = it->next) { - function->formals.append(it->name); - } - function->length = function->formals.count(); - - eng->functionConstructor->newFunction(++stackPtr, function); - - QScriptObject *instance = stackPtr->m_object_value; - // initialize [[scope]] - instance->m_scope = m_scopeChain; - - // create and initialize `prototype' - QScriptValueImpl proto; - eng->objectConstructor->newObject(&proto); - - QScript::Member member; - CREATE_MEMBER(proto, eng->idTable()->id_constructor, &member, - QScriptValue::Undeletable - | QScriptValue::SkipInEnumeration); - proto.put(member, *stackPtr); - - stackPtr->createMember(eng->idTable()->id_prototype, &member, - QScriptValue::Undeletable); - stackPtr->put(member, proto); - - ++iPtr; - } Next(); - - I(Incr): - { - if (! stackPtr[0].isReference()) { - stackPtr -= 1; - throwSyntaxError(QLatin1String("invalid increment operand")); - HandleException(); - } - - BEGIN_PREFIX_OPERATOR - - qsreal x = QScriptEnginePrivate::convertToNativeDouble(value); - value = QScriptValueImpl(x + 1); - - END_PREFIX_OPERATOR - } Next(); - - I(Decr): - { - if (! stackPtr[0].isReference()) { - stackPtr -= 1; - throwSyntaxError(QLatin1String("invalid decrement operand")); - HandleException(); - } - - BEGIN_PREFIX_OPERATOR - - qsreal x = QScriptEnginePrivate::convertToNativeDouble(value); - value = QScriptValueImpl(x - 1); - - END_PREFIX_OPERATOR - } Next(); - - I(PostIncr): - { - if (! stackPtr[0].isReference()) { - stackPtr -= 1; - throwSyntaxError(QLatin1String("invalid increment operand")); - HandleException(); - } - - QScriptValue::ResolveFlags mode; - mode = QScriptValue::ResolveFlags(stackPtr[0].m_int_value) - | QScriptValue::ResolvePrototype; - - --stackPtr; - - QScriptValueImpl object = eng->toObject(stackPtr[-1]); - if (!object.isObject()) { - stackPtr -= 2; - throwTypeError(QLatin1String("not an object")); - HandleException(); - } - - QScriptNameIdImpl *memberName = 0; - if (stackPtr[0].isString() && stackPtr[0].m_string_value->unique) - memberName = stackPtr[0].m_string_value; - else - memberName = eng->nameId(stackPtr[0].toString(), /*persistent=*/false); - - QScript::Member member; - QScriptValueImpl base; - QScriptValueImpl value; - QScriptObject *instance = object.m_object_value; - const bool isMemberAssignment = (instance != m_scopeChain.m_object_value); - if (instance->findMember(memberName, &member)) { - if (!member.isGetterOrSetter()) { - QScriptValueImpl &r = instance->reference(member); - if (r.isNumber()) { - *(--stackPtr) = QScriptValueImpl(r.m_number_value); - r.incr(); - ++iPtr; - Next(); - } - } - base = object; - } else if (!object.resolve_helper(memberName, &member, &base, mode, QScript::ReadWrite)) { - if (!isMemberAssignment) { - stackPtr -= 2; - throwNotDefined(memberName); - HandleException(); - } - base = object; - CREATE_MEMBER(base, memberName, &member, /*flags=*/0); - base.put(member, undefined); - } - - QScriptValueImpl getter; - QScriptValueImpl setter; - base.get(member, &value); - if (hasUncaughtException()) { - stackPtr -= 2; - HandleException(); - } else if (member.isGetterOrSetter()) { - if (member.isGetter()) { - getter = value; - if (!member.isSetter() && !base.m_object_value->findSetter(&member)) { - stackPtr -= 2; - throwError(QLatin1String("No setter defined")); - HandleException(); - } - base.get(member, &setter); - } else { - setter = value; - QScript::Member tmp = member; - if (!base.m_object_value->findGetter(&member)) { - stackPtr -= 2; - throwError(QLatin1String("No getter defined")); - HandleException(); - } - base.get(member, &getter); - member = tmp; - } - value = getter.call(object); - if (hasUncaughtException()) { - stackPtr -= 2; - Done(); - } - } - - qsreal x = QScriptEnginePrivate::convertToNativeDouble(value); - - value = QScriptValueImpl(x + 1); - - if (member.isSetter()) { - setter.call(object, QScriptValueImplList() << value); - if (hasUncaughtException()) { - stackPtr -= 2; - Done(); - } - } else { - if (isMemberAssignment && (base.m_object_value != object.m_object_value)) { - base = object; - CREATE_MEMBER(base, memberName, &member, /*flags=*/0); - } - if (member.isWritable()) { - base.put(member, value); - if (hasUncaughtException()) { - stackPtr -= 2; - HandleException(); - } - } - } - - *(--stackPtr) = QScriptValueImpl(x); - - ++iPtr; - } Next(); - - I(PostDecr): - { - // ### most of the code is duplicated from PostIncr -- try to merge - if (! stackPtr[0].isReference()) { - stackPtr -= 1; - throwSyntaxError(QLatin1String("invalid decrement operand")); - HandleException(); - } - - QScriptValue::ResolveFlags mode = QScriptValue::ResolveFlags(stackPtr[0].m_int_value) - | QScriptValue::ResolvePrototype; - - --stackPtr; - - QScriptValueImpl object = eng->toObject(stackPtr[-1]); - if (!object.isObject()) { - stackPtr -= 2; - throwTypeError(QLatin1String("not an object")); - HandleException(); - } - - QScriptNameIdImpl *memberName = 0; - if (stackPtr[0].isString() && stackPtr[0].m_string_value->unique) - memberName = stackPtr[0].m_string_value; - else - memberName = eng->nameId(stackPtr[0].toString(), /*persistent=*/false); - - QScript::Member member; - QScriptValueImpl base; - QScriptValueImpl value; - QScriptObject *instance = object.m_object_value; - const bool isMemberAssignment = (instance != m_scopeChain.m_object_value); - if (instance->findMember(memberName, &member)) { - if (!member.isGetterOrSetter()) { - QScriptValueImpl &r = instance->reference(member); - if (r.isNumber()) { - *(--stackPtr) = QScriptValueImpl(r.m_number_value); - r.decr(); - ++iPtr; - Next(); - } - } - base = object; - } else if (! object.resolve_helper(memberName, &member, &base, mode, QScript::ReadWrite)) { - if (!isMemberAssignment) { - stackPtr -= 2; - throwNotDefined(memberName); - HandleException(); - } - base = object; - CREATE_MEMBER(base, memberName, &member, /*flags=*/0); - base.put(member, undefined); - } - - QScriptValueImpl getter; - QScriptValueImpl setter; - base.get(member, &value); - if (hasUncaughtException()) { - stackPtr -= 2; - HandleException(); - } else if (member.isGetterOrSetter()) { - if (member.isGetter()) { - getter = value; - if (!member.isSetter() && !base.m_object_value->findSetter(&member)) { - stackPtr -= 2; - throwError(QLatin1String("No setter defined")); - HandleException(); - } - base.get(member, &setter); - } else { - setter = value; - QScript::Member tmp = member; - if (!base.m_object_value->findGetter(&member)) { - stackPtr -= 2; - throwError(QLatin1String("No getter defined")); - HandleException(); - } - base.get(member, &getter); - member = tmp; - } - value = getter.call(object); - if (hasUncaughtException()) { - stackPtr -= 2; - Done(); - } - } - - qsreal x = QScriptEnginePrivate::convertToNativeDouble(value); - - value = QScriptValueImpl(x - 1); - - if (member.isSetter()) { - setter.call(object, QScriptValueImplList() << value); - if (hasUncaughtException()) { - stackPtr -= 2; - Done(); - } - } else { - if (isMemberAssignment && (base.m_object_value != object.m_object_value)) { - base = object; - CREATE_MEMBER(base, memberName, &member, /*flags=*/0); - } - if (member.isWritable()) { - base.put(member, value); - if (hasUncaughtException()) { - stackPtr -= 2; - HandleException(); - } - } - } - - *(--stackPtr) = QScriptValueImpl(x); - - ++iPtr; - } Next(); - - I(InplaceAdd): - { - BEGIN_INPLACE_OPERATOR - - lhs = eng->toPrimitive(lhs); - rhs = eng->toPrimitive(rhs); - if (lhs.isString() || rhs.isString()) { - if (lhs.isString() && !lhs.m_string_value->unique) { - lhs.m_string_value->s += QScriptEnginePrivate::convertToNativeString(rhs); - stackPtr -= 3; - *stackPtr = lhs; - } else { - QString tmp = QScriptEnginePrivate::convertToNativeString(lhs); - tmp += QScriptEnginePrivate::convertToNativeString(rhs); - stackPtr -= 3; - eng->newString(stackPtr, tmp); - } - } else { - qsreal tmp = QScriptEnginePrivate::convertToNativeDouble(lhs); - tmp += QScriptEnginePrivate::convertToNativeDouble(rhs); - stackPtr -= 3; - *stackPtr = QScriptValueImpl(tmp); - } - - END_INPLACE_OPERATOR - } Next(); - - I(InplaceSub): - { - BEGIN_INPLACE_OPERATOR - - qsreal v1 = QScriptEnginePrivate::convertToNativeDouble(lhs); - qsreal v2 = QScriptEnginePrivate::convertToNativeDouble(rhs); - - stackPtr -= 3; - *stackPtr = QScriptValueImpl(v1 - v2); - - END_INPLACE_OPERATOR - } Next(); - - I(InplaceAnd): - { - BEGIN_INPLACE_OPERATOR - - qint32 v1 = QScriptEnginePrivate::convertToNativeInt32(lhs); - qint32 v2 = QScriptEnginePrivate::convertToNativeInt32(rhs); - - stackPtr -= 3; - *stackPtr = QScriptValueImpl(v1 & v2); - - END_INPLACE_OPERATOR - } Next(); - - I(InplaceDiv): - { - BEGIN_INPLACE_OPERATOR - - qsreal v1 = QScriptEnginePrivate::convertToNativeDouble(lhs); - qsreal v2 = QScriptEnginePrivate::convertToNativeDouble(rhs); - - stackPtr -= 3; - *stackPtr = QScriptValueImpl(v1 / v2); - - END_INPLACE_OPERATOR - } Next(); - - I(InplaceLeftShift): - { - BEGIN_INPLACE_OPERATOR - - qint32 v1 = QScriptEnginePrivate::convertToNativeInt32(lhs); - qint32 v2 = QScriptEnginePrivate::convertToNativeInt32(rhs); - - stackPtr -= 3; - *stackPtr = QScriptValueImpl(v1 << v2); - - END_INPLACE_OPERATOR - } Next(); - - I(InplaceMod): - { - BEGIN_INPLACE_OPERATOR - - qsreal v1 = QScriptEnginePrivate::convertToNativeDouble(lhs); - qsreal v2 = QScriptEnginePrivate::convertToNativeDouble(rhs); - - stackPtr -= 3; - *stackPtr = QScriptValueImpl(::fmod (v1, v2)); - - END_INPLACE_OPERATOR - } Next(); - - I(InplaceMul): - { - BEGIN_INPLACE_OPERATOR - - qsreal v1 = QScriptEnginePrivate::convertToNativeDouble(lhs); - qsreal v2 = QScriptEnginePrivate::convertToNativeDouble(rhs); - - stackPtr -= 3; - *stackPtr = QScriptValueImpl(v1 * v2); - - END_INPLACE_OPERATOR - } Next(); - - I(InplaceOr): - { - BEGIN_INPLACE_OPERATOR - - qint32 v1 = QScriptEnginePrivate::convertToNativeInt32(lhs); - qint32 v2 = QScriptEnginePrivate::convertToNativeInt32(rhs); - - stackPtr -= 3; - *stackPtr = QScriptValueImpl(v1 | v2); - - END_INPLACE_OPERATOR - } Next(); - - I(InplaceRightShift): - { - BEGIN_INPLACE_OPERATOR - - qint32 v1 = QScriptEnginePrivate::convertToNativeInt32(lhs); - qint32 v2 = QScriptEnginePrivate::convertToNativeInt32(rhs); - - stackPtr -= 3; - *stackPtr = QScriptValueImpl(v1 >> v2); - - END_INPLACE_OPERATOR - } Next(); - - I(InplaceURightShift): - { - BEGIN_INPLACE_OPERATOR - - quint32 v1 = QScriptEnginePrivate::toUint32 (eng->convertToNativeDouble(lhs)); - qint32 v2 = QScriptEnginePrivate::convertToNativeInt32(rhs); - - stackPtr -= 3; - *stackPtr = QScriptValueImpl(v1 >> v2); - - END_INPLACE_OPERATOR - } Next(); - - I(InplaceXor): - { - BEGIN_INPLACE_OPERATOR - - qint32 v1 = QScriptEnginePrivate::convertToNativeInt32(lhs); - qint32 v2 = QScriptEnginePrivate::convertToNativeInt32(rhs); - - stackPtr -= 3; - *stackPtr = QScriptValueImpl(v1 ^ v2); - - END_INPLACE_OPERATOR - } Next(); - - I(MakeReference): - { - CHECK_TEMPSTACK(1); - eng->newReference(++stackPtr, QScriptValue::ResolveLocal); - ++iPtr; - } Next(); - - I(TypeOf): - { - QScriptValueImpl value; - - bool isReference = stackPtr[0].isReference(); - - if (! isReference) { // we have a value - value = stackPtr[0]; - } else if (resolveField(eng, &stackPtr[-1], &value)) { - stackPtr -= 2; - if (hasUncaughtException()) { - stackPtr -= 1; - HandleException(); - } - } else { - value = undefined; - stackPtr -= 2; - } - - QString typeName; - - switch (value.type()) { - case QScript::InvalidType: - typeName = QLatin1String("invalid"); - break; - - case QScript::UndefinedType: - typeName = QLatin1String("undefined"); - break; - - case QScript::NullType: - typeName = QLatin1String("object"); - break; - - case QScript::BooleanType: - typeName = QLatin1String("boolean"); - break; - - case QScript::IntegerType: - case QScript::NumberType: - typeName = QLatin1String("number"); - break; - - case QScript::StringType: - case QScript::LazyStringType: - typeName = QLatin1String("string"); - break; - - case QScript::ReferenceType: - typeName = QLatin1String("reference"); - break; - - case QScript::PointerType: - typeName = QLatin1String("pointer"); - break; - - case QScript::ObjectType: - if (value.isFunction()) - typeName = QLatin1String("function"); - else - typeName = QLatin1String("object"); - break; - } - - eng->newString(stackPtr, typeName); - ++iPtr; - } Next(); - - I(Line): - { - eng->maybeGC(); - eng->maybeProcessEvents(); - if (hasUncaughtException()) - HandleException(); - if (eng->shouldAbort()) - Abort(); - currentLine = iPtr->operand[0].m_int_value; - currentColumn = iPtr->operand[1].m_int_value; -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - if (eng->shouldNotify()) { - eng->notifyPositionChange(this); - if (hasUncaughtException()) - HandleException(); - if (eng->shouldAbort()) - Abort(); - } -#endif - ++iPtr; - } Next(); - - I(Delete): - { - bool result; - if (! stackPtr[0].isReference()) - result = true; - - else { - QScriptValueImpl object = stackPtr[-2]; - if (!object.isObject()) - object = eng->toObject(object); - - QScriptNameIdImpl *nameId = 0; - if (stackPtr[-1].isString() && stackPtr[-1].m_string_value->unique) { - nameId = stackPtr[-1].m_string_value; - } else { - nameId = eng->nameId(QScriptEnginePrivate::convertToNativeString(stackPtr[-1]), - /*persistent=*/false); - } - if (object.classInfo() == eng->m_class_with) - object = object.prototype(); - result = object.deleteProperty(nameId, QScriptValue::ResolveScope); - stackPtr -= 2; - } - - *stackPtr = QScriptValueImpl(result); - - ++iPtr; - } Next(); - - - I(NewEnumeration): { - QScriptValueImpl e; - QScriptValueImpl object = eng->toObject(stackPtr[0]); - eng->enumerationConstructor->newEnumeration(&e, object); - *stackPtr = e; - ++iPtr; - } Next(); - - - I(ToFirstElement): { - QScript::Ext::Enumeration::Instance *e = eng->enumerationConstructor->get(stackPtr[0]); - Q_ASSERT(e != 0); - e->toFront(); - --stackPtr; - ++iPtr; - } Next(); - - - I(HasNextElement): { - QScript::Ext::Enumeration::Instance *e = eng->enumerationConstructor->get(stackPtr[0]); - Q_ASSERT(e != 0); - e->hasNext(this, stackPtr); - ++iPtr; - } Next(); - - - I(NextElement): { - // the Enumeration should be located below the result of I(Resolve) - if (! stackPtr[0].isReference()) { - throwTypeError(QLatin1String("QScript.VM.NextElement")); - HandleException(); - } - - QScript::Ext::Enumeration::Instance *e = eng->enumerationConstructor->get(stackPtr[-3]); - if (! e) { - throwTypeError(QLatin1String("QScript.VM.NextElement")); - HandleException(); - } - e->next(this, ++stackPtr); - ++iPtr; - } Next(); - - - I(Pop): - { - --stackPtr; - ++iPtr; - } Next(); - - I(Sync): - { - m_result = *stackPtr; - --stackPtr; - ++iPtr; - } Next(); - - I(Throw): - { - Q_ASSERT(stackPtr->isValid()); - m_result = *stackPtr--; - if (!m_result.isError() && !exceptionHandlerContext()) - eng->m_exceptionBacktrace = backtrace(); - m_state = QScriptContext::ExceptionState; -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - eng->notifyException(this); -#endif - } HandleException(); - - I(Ret): - { - Q_ASSERT(stackPtr->isValid()); - m_result = *stackPtr--; - ++iPtr; - } Done(); - - I(Halt): - { - ++iPtr; - } Done(); - - I(EnterWith): - { - QScriptValueImpl object = eng->toObject(*stackPtr--); - if (! object.isValid()) { - throwTypeError(QLatin1String("value has no properties")); - HandleException(); - } - QScriptValueImpl withObject; - eng->newObject(&withObject, object, eng->m_class_with); - withObject.m_object_value->m_scope = m_scopeChain; - m_scopeChain = withObject; - ++iPtr; - } Next(); - - I(LeaveWith): - { - QScriptValueImpl withObject = m_scopeChain; - m_scopeChain = withObject.m_object_value->m_scope; - ++iPtr; - } Next(); - - I(BeginCatch): - { - // result contains the thrown object - QScriptValueImpl object; - eng->newObject(&object, undefined); // ### prototype - QScript::Member member; - CREATE_MEMBER(object, iPtr->operand[0].m_string_value, &member, /*flags=*/0); - object.put(member, m_result); - // make catch-object head of scopechain - object.m_object_value->m_scope = m_scopeChain; - m_scopeChain = object; - - catching = true; - ++iPtr; - } Next(); - - I(EndCatch): - { - // remove catch-object from scopechain - QScriptValueImpl object = m_scopeChain; - m_scopeChain = object.m_object_value->m_scope; - - catching = false; - ++iPtr; - } Next(); - - I(Debugger): - { -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - eng->notifyDebugger(this); -#endif - ++iPtr; - } Next(); - -#ifndef Q_SCRIPT_DIRECT_CODE - I(Dummy): - { ; } - - } // end switch -#endif - -Lhandle_exception: - errorLineNumber = currentLine; - -Ldone: - Q_ASSERT(m_result.isValid()); - - if (m_state == QScriptContext::ExceptionState) { - if (catching) { - // exception thrown in catch -- clean up scopechain - QScriptValueImpl object = m_scopeChain; - m_scopeChain = object.m_object_value->m_scope; - catching = false; - } - - // see if we have an exception handler in this context - const QScriptInstruction *exPtr = findExceptionHandler(iPtr); - if (exPtr) { - if (m_scopeChain.classInfo() == eng->m_class_with) { - // clean up effects of with-statements if necessary - int withLevel = 0; - for (++iPtr; iPtr != exPtr; ++iPtr) { - if (iPtr->op == QScriptInstruction::OP_EnterWith) { - ++withLevel; - } else if (iPtr->op == QScriptInstruction::OP_LeaveWith) { - --withLevel; - if (withLevel < 0) { - QScriptValueImpl withObject = m_scopeChain; - m_scopeChain = withObject.m_object_value->m_scope; - } - } - } - } else { - iPtr = exPtr; - } - // go to the handler - recover(); -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - eng->notifyExceptionCatch(this); -#endif - goto Ltop; - } else { - if (!parentContext()) { - // pop all the top-level with-objects - while ((m_scopeChain.classInfo() == eng->m_class_with) - && !m_scopeChain.internalValue().isValid()) { - QScriptValueImpl withObject = m_scopeChain; - m_scopeChain = withObject.m_object_value->m_scope; - } - } - } - } - -Labort: -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - eng->notifyFunctionExit(this); -#endif - - eng->maybeGC(); - - currentLine = oldCurrentLine; - currentColumn = oldCurrentColumn; - m_code = oldCode; - - eng->m_evaluating = wasEvaluating; -} - -QScriptValueImpl QScriptContextPrivate::throwError(QScriptContext::Error error, const QString &text) -{ - QScriptEnginePrivate *eng_p = engine(); - QScript::Ecma::Error *ctor = eng_p->errorConstructor; - m_result.invalidate(); - switch (error) { - case QScriptContext::ReferenceError: - ctor->newReferenceError(&m_result, text); - break; - case QScriptContext::SyntaxError: - ctor->newSyntaxError(&m_result, text); - break; - case QScriptContext::TypeError: - ctor->newTypeError(&m_result, text); - break; - case QScriptContext::RangeError: - ctor->newRangeError(&m_result, text); - break; - case QScriptContext::URIError: - ctor->newURIError(&m_result, text); - break; - case QScriptContext::UnknownError: - default: - ctor->newError(&m_result, text); - } - setDebugInformation(&m_result); - m_state = QScriptContext::ExceptionState; -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - eng_p->notifyException(this); -#endif - return m_result; -} - -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY -qint64 QScriptContextPrivate::scriptId() const -{ - if (!m_code) - return -1; - return m_code->astPool->id(); -} -#endif - -QString QScriptContextPrivate::fileName() const -{ - if (!m_code) - return QString(); - return m_code->astPool->fileName(); -} - -QString QScriptContextPrivate::functionName() const -{ - if (!m_callee.isValid()) - return QString(); - QScriptFunction *fun = m_callee.toFunction(); - if (fun) - return fun->functionName(); - return QString(); -} - -void QScriptContextPrivate::setDebugInformation(QScriptValueImpl *error) const -{ - QScriptEnginePrivate *eng_p = engine(); - error->setProperty(QLatin1String("lineNumber"), QScriptValueImpl(currentLine)); - if (!fileName().isEmpty()) - error->setProperty(QLatin1String("fileName"), QScriptValueImpl(eng_p, fileName())); - - const QScriptContextPrivate *ctx = this; - QScriptValueImpl stackArray = eng_p->newArray(); - int i = 0; - while (ctx) { - QScriptValueImpl obj = eng_p->newObject(); - obj.setProperty(QLatin1String("frame"), ctx->activationObject()); - obj.setProperty(QLatin1String("lineNumber"), QScriptValueImpl(ctx->currentLine)); - if (!ctx->fileName().isEmpty()) - obj.setProperty(QLatin1String("fileName"), QScriptValueImpl(eng_p, ctx->fileName())); - if (!ctx->functionName().isEmpty()) - obj.setProperty(QLatin1String("functionName"), QScriptValueImpl(eng_p, ctx->functionName())); - stackArray.setProperty(i, obj); - ctx = ctx->parentContext(); - ++i; - } - error->setProperty(QLatin1String("stack"), stackArray); -} - -QStringList QScriptContextPrivate::backtrace() const -{ - QStringList result; - const QScriptContextPrivate *ctx = this; - while (ctx) { - QString s; - QString functionName = ctx->functionName(); - if (!functionName.isEmpty()) - s += functionName; - else { - if (ctx->parentContext()) { - if (ctx->callee().isFunction() - && ctx->callee().toFunction()->type() != QScriptFunction::Script) { - s += QLatin1String("<native>"); - } else { - s += QLatin1String("<anonymous>"); - } - } else { - s += QLatin1String("<global>"); - } - } - s += QLatin1Char('('); - for (int i = 0; i < ctx->argc; ++i) { - if (i > 0) - s += QLatin1Char(','); - QScriptValueImpl arg = ctx->args[i]; - if (arg.isObject()) - s += QLatin1String("[object Object]"); // don't do a function call - else - s += arg.toString(); - } - s += QLatin1String(")@"); - s += ctx->fileName(); - s += QString::fromLatin1(":%0").arg(ctx->currentLine); - result.append(s); - ctx = ctx->parentContext(); - } - return result; -} - -QScriptValueImpl QScriptContextPrivate::throwError(const QString &text) -{ - return throwError(QScriptContext::UnknownError, text); -} - -QScriptValueImpl QScriptContextPrivate::throwNotImplemented(const QString &name) -{ - return throwTypeError(QString::fromUtf8("%1 is not implemented").arg(name)); -} - -QScriptValueImpl QScriptContextPrivate::throwNotDefined(const QString &name) -{ - return throwError(QScriptContext::ReferenceError, - QString::fromUtf8("%1 is not defined").arg(name)); -} - -QScriptValueImpl QScriptContextPrivate::throwNotDefined(QScriptNameIdImpl *nameId) -{ - return throwNotDefined(QScriptEnginePrivate::toString(nameId)); -} - -bool QScriptContextPrivate::eq_cmp_helper(QScriptValueImpl lhs, QScriptValueImpl rhs) -{ - if (lhs.isNull() && rhs.isUndefined()) - return true; - - else if (lhs.isUndefined() && rhs.isNull()) - return true; - - else if (isNumerical(lhs) && rhs.isString()) - return QScriptEnginePrivate::convertToNativeDouble(lhs) == QScriptEnginePrivate::convertToNativeDouble(rhs); - - else if (lhs.isString() && isNumerical(rhs)) - return QScriptEnginePrivate::convertToNativeDouble(lhs) == QScriptEnginePrivate::convertToNativeDouble(rhs); - - else if (lhs.isBoolean()) - return eq_cmp(QScriptValueImpl(QScriptEnginePrivate::convertToNativeDouble(lhs)), rhs); - - else if (rhs.isBoolean()) - return eq_cmp(lhs, QScriptValueImpl(QScriptEnginePrivate::convertToNativeDouble(rhs))); - - else if (lhs.isObject() && ! rhs.isNull()) { - lhs = lhs.engine()->toPrimitive(lhs); - - if (lhs.isValid() && ! lhs.isObject()) - return eq_cmp(lhs, rhs); - } - - else if (rhs.isObject() && ! lhs.isNull()) { - rhs = rhs.engine()->toPrimitive(rhs); - - if (rhs.isValid() && ! rhs.isObject()) - return eq_cmp(lhs, rhs); - } - - return false; -} - -#if defined(Q_CC_GNU) && __GNUC__ <= 3 -bool QScriptContextPrivate::lt_cmp(QScriptValueImpl lhs, QScriptValueImpl rhs) -{ - if (lhs.type() == rhs.type()) { - switch (lhs.type()) { - case QScript::InvalidType: - case QScript::UndefinedType: - case QScript::NullType: - return false; - - case QScript::NumberType: - return lhs.m_number_value < rhs.m_number_value; - - case QScript::IntegerType: - return lhs.m_int_value < rhs.m_int_value; - - case QScript::BooleanType: - return lhs.m_bool_value < rhs.m_bool_value; - - default: - break; - } // switch - } -#else -bool QScriptContextPrivate::lt_cmp_helper(QScriptValueImpl lhs, QScriptValueImpl rhs) -{ -#endif - if ((lhs.type() == rhs.type()) && (lhs.type() == QScript::StringType)) - return lhs.m_string_value->s < rhs.m_string_value->s; - - if (lhs.isObject()) - lhs = lhs.engine()->toPrimitive(lhs, QScriptValueImpl::NumberTypeHint); - - if (rhs.isObject()) - rhs = rhs.engine()->toPrimitive(rhs, QScriptValueImpl::NumberTypeHint); - - if (lhs.isString() && rhs.isString()) - return QScriptEnginePrivate::convertToNativeString(lhs) < QScriptEnginePrivate::convertToNativeString(rhs); - - qsreal n1 = QScriptEnginePrivate::convertToNativeDouble(lhs); - qsreal n2 = QScriptEnginePrivate::convertToNativeDouble(rhs); -#if defined Q_CC_MSVC && !defined Q_CC_MSVC_NET - if (qIsNaN(n1) || qIsNaN(n2)) - return false; -#endif - return n1 < n2; -} - -bool QScriptContextPrivate::le_cmp_helper(QScriptValueImpl lhs, QScriptValueImpl rhs) -{ - if ((lhs.type() == rhs.type()) && (lhs.type() == QScript::StringType)) - return lhs.m_string_value->s <= rhs.m_string_value->s; - - if (lhs.isObject()) - lhs = lhs.engine()->toPrimitive(lhs, QScriptValueImpl::NumberTypeHint); - - if (rhs.isObject()) - rhs = rhs.engine()->toPrimitive(rhs, QScriptValueImpl::NumberTypeHint); - - if (lhs.isString() && rhs.isString()) - return QScriptEnginePrivate::convertToNativeString(lhs) <= QScriptEnginePrivate::convertToNativeString(rhs); - - qsreal n1 = QScriptEnginePrivate::convertToNativeDouble(lhs); - qsreal n2 = QScriptEnginePrivate::convertToNativeDouble(rhs); - return n1 <= n2; -} - -const QScriptInstruction *QScriptContextPrivate::findExceptionHandler( - const QScriptInstruction *ip) const -{ - Q_ASSERT(m_code); - int offset = ip - m_code->firstInstruction; - for (int i = 0; i < m_code->exceptionHandlers.count(); ++i) { - QScript::ExceptionHandlerDescriptor e = m_code->exceptionHandlers.at(i); - if (offset >= e.startInstruction() && offset <= e.endInstruction()) { - return m_code->firstInstruction + e.handlerInstruction(); - } - } - return 0; -} - -const QScriptInstruction *QScriptContextPrivate::findExceptionHandlerRecursive( - const QScriptInstruction *ip, QScriptContextPrivate **handlerContext) const -{ - const QScriptContextPrivate *ctx = this; - const QScriptInstruction *iip = ip; - while (ctx) { - if (ctx->m_code) { - const QScriptInstruction *ep = ctx->findExceptionHandler(iip); - if (ep) { - Q_ASSERT(handlerContext); - *handlerContext = const_cast<QScriptContextPrivate*>(ctx); - return ep; - } - } - ctx = ctx->parentContext(); - if (ctx) - iip = ctx->iPtr; - } - return 0; -} - -/*! - Requires that iPtr in current context is in sync -*/ -QScriptContextPrivate *QScriptContextPrivate::exceptionHandlerContext() const -{ - QScriptContextPrivate *handlerContext; - if (findExceptionHandlerRecursive(iPtr, &handlerContext)) - return handlerContext; - return 0; -} - -QScriptContext *QScriptContextPrivate::get(QScriptContextPrivate *d) -{ - if (d) - return d->q_func(); - return 0; -} - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptcontext_p.h b/src/script/qscriptcontext_p.h deleted file mode 100644 index 22e7c6b..0000000 --- a/src/script/qscriptcontext_p.h +++ /dev/null @@ -1,361 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTCONTEXT_P_H -#define QSCRIPTCONTEXT_P_H - -#include "qscriptcontextfwd_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptenginefwd_p.h" -#include "qscriptnameid_p.h" - -#include <QtCore/qnumeric.h> - -QT_BEGIN_NAMESPACE - -// -// 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. -// - -inline QScriptContextPrivate::QScriptContextPrivate() - : previous(0), - argc(0), - m_state(QScriptContext::NormalState), - args(0), - tempStack(0), - stackPtr(0), - m_code(0), - iPtr(0), - firstInstruction(0), - lastInstruction(0), - currentLine(0), - currentColumn(0), - errorLineNumber(0), - catching(false), - m_calledAsConstructor(false), - calleeMetaIndex(0), - q_ptr(0) -{ -} - -inline QScriptContextPrivate *QScriptContextPrivate::get(QScriptContext *q) -{ - if (q) - return q->d_func(); - return 0; -} - -inline const QScriptContextPrivate *QScriptContextPrivate::get(const QScriptContext *q) -{ - if (q) - return q->d_func(); - return 0; -} - -inline QScriptContext *QScriptContextPrivate::create() -{ - return new QScriptContext; -} - -inline QScriptEnginePrivate *QScriptContextPrivate::engine() const -{ - return m_activation.engine(); -} - -inline QScriptContextPrivate *QScriptContextPrivate::parentContext() const -{ - return previous; -} - -inline void QScriptContextPrivate::init(QScriptContextPrivate *parent) -{ - m_state = QScriptContext::NormalState; - previous = parent; - args = 0; - argc = 0; - m_code = 0; - iPtr = firstInstruction = lastInstruction = 0; - stackPtr = tempStack = (parent != 0) ? parent->stackPtr : 0; - m_activation.invalidate(); - m_thisObject.invalidate(); - m_result.invalidate(); - m_scopeChain.invalidate(); - m_callee.invalidate(); - m_arguments.invalidate(); - currentLine = -1; - currentColumn = -1; - errorLineNumber = -1; - m_calledAsConstructor = false; -} - -inline QScriptValueImpl QScriptContextPrivate::argument(int index) const -{ - if (index >= argc) - return engine()->undefinedValue(); - - Q_ASSERT(args != 0); - return args[index]; -} - -inline int QScriptContextPrivate::argumentCount() const -{ - return argc; -} - -inline QScriptValueImpl QScriptContextPrivate::argumentsObject() const -{ - if (!m_arguments.isValid() && m_activation.isValid()) { - QScriptContextPrivate *dd = const_cast<QScriptContextPrivate*>(this); - engine()->newArguments(&dd->m_arguments, m_activation, - argc, m_callee); - } - return m_arguments; -} - -inline void QScriptContextPrivate::throwException() -{ - m_state = QScriptContext::ExceptionState; -} - -inline bool QScriptContextPrivate::hasUncaughtException() const -{ - return m_state == QScriptContext::ExceptionState; -} - -inline void QScriptContextPrivate::recover() -{ - m_state = QScriptContext::NormalState; - errorLineNumber = -1; -} - -inline bool QScriptContextPrivate::isNumerical(const QScriptValueImpl &v) -{ - switch (v.type()) { - case QScript::BooleanType: - case QScript::IntegerType: - case QScript::NumberType: - return true; - - default: - return false; - } -} - -inline bool QScriptContextPrivate::eq_cmp(const QScriptValueImpl &lhs, const QScriptValueImpl &rhs) -{ - if (lhs.type() == rhs.type()) { - switch (lhs.type()) { - case QScript::InvalidType: - case QScript::UndefinedType: - case QScript::NullType: - return true; - - case QScript::NumberType: - return lhs.m_number_value == rhs.m_number_value; - - case QScript::ReferenceType: - case QScript::IntegerType: - return lhs.m_int_value == rhs.m_int_value; - - case QScript::BooleanType: - return lhs.m_bool_value == rhs.m_bool_value; - - case QScript::StringType: - if (lhs.m_string_value->unique && rhs.m_string_value->unique) - return lhs.m_string_value == rhs.m_string_value; - return lhs.m_string_value->s == rhs.m_string_value->s; - - case QScript::PointerType: - return lhs.m_ptr_value == rhs.m_ptr_value; - - case QScript::ObjectType: - if (lhs.isVariant()) - return lhs.m_object_value == rhs.m_object_value || lhs.toVariant() == rhs.toVariant(); -#ifndef QT_NO_QOBJECT - else if (lhs.isQObject()) - return lhs.m_object_value == rhs.m_object_value || lhs.toQObject() == rhs.toQObject(); -#endif - else - return lhs.m_object_value == rhs.m_object_value; - - case QScript::LazyStringType: - return *lhs.m_lazy_string_value == *rhs.m_lazy_string_value; - } - } - - return eq_cmp_helper(lhs, rhs); -} - -inline bool QScriptContextPrivate::strict_eq_cmp( const QScriptValueImpl &lhs, const QScriptValueImpl &rhs) -{ - if (lhs.type() != rhs.type()) - return false; - - switch (lhs.type()) { - case QScript::InvalidType: - case QScript::UndefinedType: - case QScript::NullType: - return true; - - case QScript::NumberType: - if (qIsNaN(lhs.m_number_value) || qIsNaN(rhs.m_number_value)) - return false; - return lhs.m_number_value == rhs.m_number_value; - - case QScript::IntegerType: - return lhs.m_int_value == rhs.m_int_value; - - case QScript::BooleanType: - return lhs.m_bool_value == rhs.m_bool_value; - - case QScript::StringType: - if (lhs.m_string_value->unique && rhs.m_string_value->unique) - return lhs.m_string_value == rhs.m_string_value; - return lhs.m_string_value->s == rhs.m_string_value->s; - - case QScript::ObjectType: - return lhs.m_object_value == rhs.m_object_value; - - case QScript::ReferenceType: - return lhs.m_int_value == rhs.m_int_value; - - case QScript::PointerType: - return lhs.m_ptr_value == rhs.m_ptr_value; - - case QScript::LazyStringType: - return *lhs.m_lazy_string_value == *rhs.m_lazy_string_value; - } - - return false; -} - -inline QScriptValueImpl QScriptContextPrivate::throwTypeError(const QString &text) -{ - return throwError(QScriptContext::TypeError, text); -} - -inline QScriptValueImpl QScriptContextPrivate::throwSyntaxError(const QString &text) -{ - return throwError(QScriptContext::SyntaxError, text); -} - -inline QScriptValueImpl QScriptContextPrivate::thisObject() const -{ - return m_thisObject; -} - -inline void QScriptContextPrivate::setThisObject(const QScriptValueImpl &object) -{ - m_thisObject = object; -} - -inline QScriptValueImpl QScriptContextPrivate::callee() const -{ - return m_callee; -} - -inline bool QScriptContextPrivate::isCalledAsConstructor() const -{ - return m_calledAsConstructor; -} - -inline QScriptValueImpl QScriptContextPrivate::returnValue() const -{ - return m_result; -} - -inline void QScriptContextPrivate::setReturnValue(const QScriptValueImpl &value) -{ - m_result = value; -} - -inline QScriptValueImpl QScriptContextPrivate::activationObject() const -{ - if (previous && !m_activation.property(QLatin1String("arguments")).isValid()) { - QScriptContextPrivate *dd = const_cast<QScriptContextPrivate*>(this); - dd->m_activation.setProperty(QLatin1String("arguments"), argumentsObject()); - } - return m_activation; -} - -inline void QScriptContextPrivate::setActivationObject(const QScriptValueImpl &activation) -{ - m_activation = activation; -} - -inline const QScriptInstruction *QScriptContextPrivate::instructionPointer() -{ - return iPtr; -} - -inline void QScriptContextPrivate::setInstructionPointer(const QScriptInstruction *instructionPointer) -{ - iPtr = instructionPointer; -} - -inline const QScriptValueImpl *QScriptContextPrivate::baseStackPointer() const -{ - return tempStack; -} - -inline const QScriptValueImpl *QScriptContextPrivate::currentStackPointer() const -{ - return stackPtr; -} - -inline QScriptContext::ExecutionState QScriptContextPrivate::state() const -{ - return m_state; -} - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT -#endif diff --git a/src/script/qscriptcontextfwd_p.h b/src/script/qscriptcontextfwd_p.h deleted file mode 100644 index 6b0c954..0000000 --- a/src/script/qscriptcontextfwd_p.h +++ /dev/null @@ -1,257 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTCONTEXTFWD_P_H -#define QSCRIPTCONTEXTFWD_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 "qscriptvalueimplfwd_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptcontext.h" - -#include <QtCore/qobjectdefs.h> - -#if defined Q_CC_MSVC && !defined Q_CC_MSVC_NET -#include <QtCore/qnumeric.h> -#endif - -QT_BEGIN_NAMESPACE - -namespace QScript { - namespace AST { - class Node; - } -class Code; -} - -class QScriptInstruction; - -class QScriptContextPrivate -{ - Q_DECLARE_PUBLIC(QScriptContext) -public: - inline QScriptContextPrivate(); - - static inline QScriptContextPrivate *get(QScriptContext *q); - static inline const QScriptContextPrivate *get(const QScriptContext *q); - static QScriptContext *get(QScriptContextPrivate *d); - - static inline QScriptContext *create(); - - inline QScriptEnginePrivate *engine() const; - inline QScriptContextPrivate *parentContext() const; - - inline void init(QScriptContextPrivate *parent); - inline QScriptValueImpl argument(int index) const; - inline int argumentCount() const; - inline QScriptValueImpl argumentsObject() const; - - inline void throwException(); - inline bool hasUncaughtException() const; - const QScriptInstruction *findExceptionHandler(const QScriptInstruction *ip) const; - const QScriptInstruction *findExceptionHandlerRecursive( - const QScriptInstruction *ip, QScriptContextPrivate **handlerContext) const; - QScriptContextPrivate *exceptionHandlerContext() const; - inline void recover(); - QStringList backtrace() const; - - static inline bool isNumerical(const QScriptValueImpl &v); - - static inline bool eq_cmp(const QScriptValueImpl &lhs, const QScriptValueImpl &rhs); - - static bool eq_cmp_helper(QScriptValueImpl lhs, QScriptValueImpl rhs); - -#if defined(Q_CC_GNU) && __GNUC__ <= 3 - static bool lt_cmp(QScriptValueImpl lhs, QScriptValueImpl rhs); -#else - static bool lt_cmp(const QScriptValueImpl &lhs, const QScriptValueImpl &rhs) - { - if (lhs.type() == rhs.type()) { - switch (lhs.type()) { - case QScript::UndefinedType: - case QScript::NullType: - return false; - - case QScript::NumberType: -#if defined Q_CC_MSVC && !defined Q_CC_MSVC_NET - if (qIsNaN(lhs.m_number_value) || qIsNaN(rhs.m_number_value)) - return false; -#endif - return lhs.m_number_value < rhs.m_number_value; - - case QScript::IntegerType: - return lhs.m_int_value < rhs.m_int_value; - - case QScript::BooleanType: - return lhs.m_bool_value < rhs.m_bool_value; - - default: - break; - } // switch - } - - return lt_cmp_helper(lhs, rhs); - } - - static bool lt_cmp_helper(QScriptValueImpl lhs, QScriptValueImpl rhs); -#endif - - static bool le_cmp(const QScriptValueImpl &lhs, const QScriptValueImpl &rhs) - { - if (lhs.type() == rhs.type()) { - switch (lhs.type()) { - case QScript::UndefinedType: - case QScript::NullType: - return true; - - case QScript::NumberType: - return lhs.m_number_value <= rhs.m_number_value; - - case QScript::IntegerType: - return lhs.m_int_value <= rhs.m_int_value; - - case QScript::BooleanType: - return lhs.m_bool_value <= rhs.m_bool_value; - - default: - break; - } // switch - } - - return le_cmp_helper(lhs, rhs); - } - - static bool le_cmp_helper(QScriptValueImpl lhs, QScriptValueImpl rhs); - - static inline bool strict_eq_cmp(const QScriptValueImpl &lhs, const QScriptValueImpl &rhs); - - bool resolveField(QScriptEnginePrivate *eng, QScriptValueImpl *stackPtr, - QScriptValueImpl *value); - - void execute(QScript::Code *code); - - QScriptValueImpl throwError(QScriptContext::Error error, const QString &text); - QScriptValueImpl throwError(const QString &text); - -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - qint64 scriptId() const; -#endif - QString fileName() const; - QString functionName() const; - void setDebugInformation(QScriptValueImpl *error) const; - - QScriptValueImpl throwNotImplemented(const QString &name); - QScriptValueImpl throwNotDefined(const QString &name); - QScriptValueImpl throwNotDefined(QScriptNameIdImpl *nameId); - - inline QScriptValueImpl throwTypeError(const QString &text); - inline QScriptValueImpl throwSyntaxError(const QString &text); - - inline QScriptValueImpl thisObject() const; - inline void setThisObject(const QScriptValueImpl &object); - - inline QScriptValueImpl callee() const; - inline bool isCalledAsConstructor() const; - - inline QScriptValueImpl returnValue() const; - inline void setReturnValue(const QScriptValueImpl &value); - - inline QScriptValueImpl activationObject() const; - inline void setActivationObject(const QScriptValueImpl &activation); - - inline const QScriptInstruction *instructionPointer(); - inline void setInstructionPointer(const QScriptInstruction *instructionPointer); - - inline const QScriptValueImpl *baseStackPointer() const; - inline const QScriptValueImpl *currentStackPointer() const; - - inline QScriptContext::ExecutionState state() const; - -public: - QScriptContextPrivate *previous; - int argc; - QScriptContext::ExecutionState m_state; - - QScriptValueImpl m_activation; - QScriptValueImpl m_thisObject; - QScriptValueImpl m_result; - QScriptValueImpl m_scopeChain; - QScriptValueImpl m_callee; - QScriptValueImpl m_arguments; - - QScriptValueImpl *args; - QScriptValueImpl *tempStack; - QScriptValueImpl *stackPtr; - - QScript::Code *m_code; - const QScriptInstruction *iPtr; - const QScriptInstruction *firstInstruction; - const QScriptInstruction *lastInstruction; - - int currentLine; - int currentColumn; - - int errorLineNumber; - - bool catching; - bool m_calledAsConstructor; - - int calleeMetaIndex; - - QScriptContext *q_ptr; -}; - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT -#endif diff --git a/src/script/qscriptcontextinfo_p.h b/src/script/qscriptcontextinfo_p.h deleted file mode 100644 index 5b63161..0000000 --- a/src/script/qscriptcontextinfo_p.h +++ /dev/null @@ -1,99 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTCONTEXTINFO_P_H -#define QSCRIPTCONTEXTINFO_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 "qscriptcontextinfo.h" - -#ifndef QT_NO_SCRIPT - -#include <QtCore/qatomic.h> -#include <QtCore/qstring.h> - -QT_BEGIN_NAMESPACE - -class QScriptContext; - -class QScriptContextInfo; -class QScriptContextInfoPrivate -{ - Q_DECLARE_PUBLIC(QScriptContextInfo) -public: - QScriptContextInfoPrivate(); - QScriptContextInfoPrivate(const QScriptContext *context); - ~QScriptContextInfoPrivate(); - - qint64 scriptId; - int lineNumber; - int columnNumber; - QString fileName; - - QString functionName; - QScriptContextInfo::FunctionType functionType; - - int functionStartLineNumber; - int functionEndLineNumber; - int functionMetaIndex; - - QStringList parameterNames; - - QBasicAtomicInt ref; - - QScriptContextInfo *q_ptr; -}; - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT - -#endif diff --git a/src/script/qscriptecmaarray.cpp b/src/script/qscriptecmaarray.cpp deleted file mode 100644 index 3933a0d..0000000 --- a/src/script/qscriptecmaarray.cpp +++ /dev/null @@ -1,777 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qscriptecmaarray_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptengine_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" -#include "qscriptclassdata_p.h" - -#include <QtCore/QtDebug> - -QT_BEGIN_NAMESPACE - -namespace QScript { namespace Ecma { - -class ArrayClassData: public QScriptClassData -{ - QScriptClassInfo *m_classInfo; - -public: - ArrayClassData(QScriptClassInfo *classInfo); - virtual ~ArrayClassData(); - - inline QScriptClassInfo *classInfo() const - { return m_classInfo; } - - virtual void mark(const QScriptValueImpl &object, int generation); - virtual bool resolve(const QScriptValueImpl &object, - QScriptNameIdImpl *nameId, - QScript::Member *member, - QScriptValueImpl *base, - QScript::AccessMode mode); - virtual bool get(const QScriptValueImpl &obj, const Member &m, - QScriptValueImpl *out_value); - virtual bool put(QScriptValueImpl *object, const Member &member, - const QScriptValueImpl &value); - virtual bool removeMember(const QScriptValueImpl &object, - const QScript::Member &member); - virtual QScriptClassDataIterator *newIterator(const QScriptValueImpl &object); -}; - -class ArrayClassDataIterator: public QScriptClassDataIterator -{ -public: - ArrayClassDataIterator(Array::Instance *instance); - virtual ~ArrayClassDataIterator(); - - virtual bool hasNext() const; - virtual void next(QScript::Member *member); - - virtual bool hasPrevious() const; - virtual void previous(QScript::Member *member); - - virtual void toFront(); - virtual void toBack(); - -private: - Array::Instance *m_instance; - QList<uint> m_keys; - quint32 m_pos; -}; - -ArrayClassData::ArrayClassData(QScriptClassInfo *classInfo): - m_classInfo(classInfo) -{ -} - -ArrayClassData::~ArrayClassData() -{ -} - -void ArrayClassData::mark(const QScriptValueImpl &object, int generation) -{ - Array::Instance *instance = Array::Instance::get(object, classInfo()); - if (! instance) - return; - - instance->value.mark(generation); -} - -bool ArrayClassData::resolve(const QScriptValueImpl &object, - QScriptNameIdImpl *nameId, - QScript::Member *member, - QScriptValueImpl *base, - QScript::AccessMode access) -{ - QScriptEnginePrivate *eng_p = object.engine(); - - Array::Instance *instance = Array::Instance::get(object, classInfo()); - if (!instance) - return false; - - if (nameId == eng_p->idTable()->id_length) { - member->native(nameId, /*id=*/ 0, - QScriptValue::Undeletable - | QScriptValue::SkipInEnumeration); - *base = object; - return true; - } - - QString propertyName = eng_p->toString(nameId); - bool isNumber; - quint32 pos = propertyName.toUInt(&isNumber); - - if (!isNumber || (pos == 0xFFFFFFFF) - || (QScriptValueImpl(pos).toString() != propertyName)) { // ### improve me - return false; - } - - if ((access == QScript::Read) && ((pos >= instance->value.count()) || !instance->value.at(pos).isValid())) - return false; - - member->native(0, pos, /*flags=*/0); - *base = object; - return true; -} - -bool ArrayClassData::get(const QScriptValueImpl &object, - const QScript::Member &member, - QScriptValueImpl *result) -{ - Q_ASSERT(member.isValid()); - - if (! member.isNativeProperty()) - return false; - - QScriptEnginePrivate *eng = object.engine(); - - Array::Instance *instance = Array::Instance::get(object, classInfo()); - if (! instance) - return false; - - if (member.nameId() == eng->idTable()->id_length) - *result = QScriptValueImpl(instance->value.count()); - - else { - quint32 pos = quint32 (member.id()); - - if (pos < instance->value.count()) - *result = instance->value.at(pos); - else - *result = eng->undefinedValue(); - } - - return true; -} - -bool ArrayClassData::put(QScriptValueImpl *object, - const QScript::Member &member, - const QScriptValueImpl &value) -{ - Q_ASSERT(object != 0); - Q_ASSERT(member.isValid()); - - if (! member.isNativeProperty()) - return false; - - Array::Instance *instance = Array::Instance::get(*object, classInfo()); - if (! instance) - return false; - - QScriptEnginePrivate *eng_p = object->engine(); - - if (member.nameId() == eng_p->idTable()->id_length) { - qsreal length = value.toNumber(); - quint32 len = eng_p->toUint32(length); - instance->value.resize(len); - } - - else if (member.nameId() == 0) { - quint32 pos = quint32 (member.id()); - instance->value.assign(pos, value); - } - - return true; -} - -bool ArrayClassData::removeMember(const QScriptValueImpl &object, - const QScript::Member &member) -{ - if (!member.isNativeProperty() || !member.isDeletable() || (member.nameId() != 0)) - return false; - - Array::Instance *instance = Array::Instance::get(object, classInfo()); - if (! instance) - return false; - - quint32 pos = quint32 (member.id()); - if (instance->value.at(pos).isValid()) - instance->value.assign(pos, QScriptValueImpl()); - return true; -} - -QScriptClassDataIterator *ArrayClassData::newIterator(const QScriptValueImpl &object) -{ - Array::Instance *instance = Array::Instance::get(object, classInfo()); - return new ArrayClassDataIterator(instance); -} - -ArrayClassDataIterator::ArrayClassDataIterator(Array::Instance *instance) -{ - m_instance = instance; - toFront(); -} - -ArrayClassDataIterator::~ArrayClassDataIterator() -{ -} - -bool ArrayClassDataIterator::hasNext() const -{ - quint32 limit = m_keys.isEmpty() ? m_instance->value.size() : quint32(m_keys.size()); - for (quint32 i = m_pos; i < limit; ++i) { - quint32 realI = m_keys.isEmpty() ? i : m_keys.at(i); - if (m_instance->value.at(realI).isValid()) - return true; - } - return false; -} - -void ArrayClassDataIterator::next(QScript::Member *member) -{ - quint32 limit = m_keys.isEmpty() ? m_instance->value.size() : quint32(m_keys.size()); - for (quint32 i = m_pos; i < limit; ++i) { - quint32 realI = m_keys.isEmpty() ? i : m_keys.at(i); - if (m_instance->value.at(realI).isValid()) { - member->native(/*nameId=*/0, realI, /*flags=*/0); - m_pos = i + 1; - return; - } - } - member->invalidate(); -} - -bool ArrayClassDataIterator::hasPrevious() const -{ - for (quint32 i = m_pos - 1; i != 0xFFFFFFFF; --i) { - quint32 realI = m_keys.isEmpty() ? i : m_keys.at(i); - if (m_instance->value.at(realI).isValid()) - return true; - } - return false; -} - -void ArrayClassDataIterator::previous(QScript::Member *member) -{ - for (quint32 i = m_pos - 1; i != 0xFFFFFFFF; --i) { - quint32 realI = m_keys.isEmpty() ? i : m_keys.at(i); - if (m_instance->value.at(realI).isValid()) { - member->native(/*nameId=*/ 0, realI, /*flags=*/0); - m_pos = i; - return; - } - } - member->invalidate(); -} - -void ArrayClassDataIterator::toFront() -{ - m_keys = m_instance->value.keys(); - m_pos = 0; -} - -void ArrayClassDataIterator::toBack() -{ - m_keys = m_instance->value.keys(); - m_pos = m_keys.isEmpty() ? m_instance->value.count() : m_keys.size(); -} - - - -Array::Array(QScriptEnginePrivate *eng): - Core(eng, QLatin1String("Array"), QScriptClassInfo::ArrayType) -{ - classInfo()->setData(new ArrayClassData(classInfo())); - - newArray(&publicPrototype, QScript::Array(eng)); - - eng->newConstructor(&ctor, this, publicPrototype); - - addPrototypeFunction(QLatin1String("toString"), method_toString, 0); - addPrototypeFunction(QLatin1String("toLocaleString"), method_toLocaleString, 0); - addPrototypeFunction(QLatin1String("concat"), method_concat, 1); - addPrototypeFunction(QLatin1String("join"), method_join, 1); - addPrototypeFunction(QLatin1String("pop"), method_pop, 0); - addPrototypeFunction(QLatin1String("push"), method_push, 1); - addPrototypeFunction(QLatin1String("reverse"), method_reverse, 0); - addPrototypeFunction(QLatin1String("shift"), method_shift, 0); - addPrototypeFunction(QLatin1String("slice"), method_slice, 2); - addPrototypeFunction(QLatin1String("sort"), method_sort, 1); - addPrototypeFunction(QLatin1String("splice"), method_splice, 2); - addPrototypeFunction(QLatin1String("unshift"), method_unshift, 1); -} - -Array::~Array() -{ -} - -void Array::execute(QScriptContextPrivate *context) -{ -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - engine()->notifyFunctionEntry(context); -#endif - QScript::Array value(engine()); - - if (context->argumentCount() == 1 && context->argument(0).isNumber()) { - qsreal size = context->argument(0).toNumber(); - quint32 isize = QScriptEnginePrivate::toUint32(size); - - if (size != qsreal(isize)) { - context->throwError(QScriptContext::RangeError, QLatin1String("invalid array length")); - return; - } - - value.resize(isize); - } else { - for (int i = 0; i < context->argumentCount(); ++i) { - value.assign(i, context->argument(i)); - } - } - - if (context->isCalledAsConstructor()) { - QScriptValueImpl &object = context->m_thisObject; - object.setClassInfo(classInfo()); - object.setPrototype(publicPrototype); - initArray(&object, value); - } else { - newArray(&context->m_result, value); - } - -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - engine()->notifyFunctionExit(context); -#endif -} - -void Array::newArray(QScriptValueImpl *result, const QScript::Array &value) -{ - engine()->newObject(result, publicPrototype, classInfo()); - initArray(result, value); -} - -void Array::initArray(QScriptValueImpl *result, const QScript::Array &value) -{ - Instance *instance = new Instance(engine()); - instance->value = value; - result->setObjectData(instance); -} - -QScriptValueImpl Array::method_toString(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo) -{ - return method_join(context, eng, classInfo); // ### fixme -} - -QScriptValueImpl Array::method_toLocaleString(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo) -{ - return method_toString(context, eng, classInfo); -} - -QScriptValueImpl Array::method_concat(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo) -{ - QScript::Array result(eng); - - if (Instance *instance = Instance::get(context->thisObject(), classInfo)) - result = instance->value; - - else { - QString v = context->thisObject().toString(); - result.assign(0, QScriptValueImpl(eng, v)); - } - - for (int i = 0; i < context->argumentCount(); ++i) { - quint32 k = result.size(); - QScriptValueImpl arg = context->argument(i); - - if (Instance *elt = Instance::get(arg, classInfo)) - result.concat(elt->value); - - else - result.assign(k, QScriptValueImpl(eng, arg.toString())); - } - - return eng->newArray(result); -} - -QScriptValueImpl Array::method_join(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *) -{ - QScriptValueImpl arg = context->argument(0); - - QString r4; - if (arg.isUndefined()) - r4 = QLatin1String(","); - else - r4 = arg.toString(); - - QScriptValueImpl self = context->thisObject(); - - QScriptNameIdImpl *id_length = eng->idTable()->id_length; - QScriptValueImpl length = self.property(id_length); - qsreal r1 = length.isValid() ? length.toNumber() : 0; - quint32 r2 = QScriptEnginePrivate::toUint32(r1); - - if (! r2) - return QScriptValueImpl(eng, QString()); - - if (eng->visitedArrayElements.contains(self.objectValue())) { - // avoid infinite recursion - return QScriptValueImpl(eng, QString()); - } - eng->visitedArrayElements.insert(self.objectValue()); - - QString R; - - QScriptValueImpl r6 = self.property(QLatin1String("0")); - if (r6.isValid() && !(r6.isUndefined() || r6.isNull())) - R = r6.toString(); - - for (quint32 k = 1; k < r2; ++k) { - R += r4; - - QScriptNameIdImpl *name = eng->nameId(QScriptValueImpl(k).toString()); - QScriptValueImpl r12 = self.property(name); - - if (r12.isValid() && ! (r12.isUndefined() || r12.isNull())) - R += r12.toString(); - } - - eng->visitedArrayElements.remove(self.objectValue()); - return QScriptValueImpl(eng, R); -} - -QScriptValueImpl Array::method_pop(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (Instance *instance = Instance::get(self, classInfo)) { - QScriptValueImpl elt = instance->value.pop(); - if (! elt.isValid()) - elt = eng->undefinedValue(); - - return elt; - } - - QScriptNameIdImpl *id_length = eng->idTable()->id_length; - - QScriptValueImpl r1 = self.property(id_length); - quint32 r2 = r1.toUInt32(); - if (! r2) { - self.setProperty(id_length, QScriptValueImpl(0)); - return eng->undefinedValue(); - } - QScriptNameIdImpl *r6 = eng->nameId(QScriptValueImpl(r2 - 1).toString()); - QScriptValueImpl r7 = self.property(r6); - self.deleteProperty(r6); - self.setProperty(id_length, QScriptValueImpl(r2 - 1)); - if (!r7.isValid()) - return eng->undefinedValue(); - return r7; -} - -QScriptValueImpl Array::method_push(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (Instance *instance = Instance::get(self, classInfo)) { - uint pos = instance->value.size(); - for (int i = 0; i < context->argumentCount(); ++i) { - QScriptValueImpl val = context->argument(i); - if (pos == 0xFFFFFFFF) { - self.setProperty(pos++, val); - self.setProperty(eng->idTable()->id_length, 0); - } else { - instance->value.assign(pos++, val); - } - } - return QScriptValueImpl(pos); - } - - QScriptNameIdImpl *id_length = eng->idTable()->id_length; - QScriptValueImpl r1 = self.property(id_length); - quint32 n = r1.toUInt32(); - for (int index = 0; index < context->argumentCount(); ++index, ++n) { - QScriptValueImpl r3 = context->argument(index); - QScriptNameIdImpl *name = eng->nameId(QScriptValueImpl(n).toString()); - self.setProperty(name, r3); - } - QScriptValueImpl r(n); - self.setProperty(id_length, r); - return r; -} - -QScriptValueImpl Array::method_reverse(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (Instance *instance = Instance::get(self, classInfo)) { - int lo = 0, hi = instance->value.count () - 1; - - for (; lo < hi; ++lo, --hi) { - QScriptValueImpl tmp = instance->value.at(lo); - instance->value.assign(lo, instance->value.at(hi)); - instance->value.assign(hi, tmp); - } - - } else { - QScriptNameIdImpl *id_length = eng->idTable()->id_length; - - QScriptValueImpl lengthValue = self.property(id_length); - quint32 length = 0; - if (lengthValue.isValid()) - length = QScriptEnginePrivate::toUint32(lengthValue.toNumber()); - const quint32 m = length / 2; - for (quint32 i = 0; i < m; ++i) { - quint32 j = length - i - 1; - - QScriptNameIdImpl *iid = eng->nameId(QScriptValueImpl(i).toString()); - QScriptNameIdImpl *jid = eng->nameId(QScriptValueImpl(j).toString()); - - QScript::Member imember; - QScriptValueImpl ibase; - QScriptValueImpl ival; - bool iok = self.resolve(iid, &imember, &ibase, QScriptValue::ResolvePrototype, QScript::ReadWrite); - if (iok) - ibase.get(iid, &ival); - else - ival = eng->undefinedValue(); - - QScript::Member jmember; - QScriptValueImpl jbase; - QScriptValueImpl jval; - bool jok = self.resolve(jid, &jmember, &jbase, QScriptValue::ResolvePrototype, QScript::ReadWrite); - if (jok) - jbase.get(jid, &jval); - else - jval = eng->undefinedValue(); - - if (!jok) { - if (iok) { - if (eng->strictlyEquals(ibase, self)) - ibase.removeMember(imember); - self.setProperty(jid, ival); - } - } else if (!iok) { - self.setProperty(iid, jval); - if (eng->strictlyEquals(jbase, self)) - jbase.removeMember(jmember); - } else { - if (eng->strictlyEquals(self, ibase)) - self.put(imember, jval); - else - self.setProperty(iid, jval); - if (eng->strictlyEquals(self, jbase)) - self.put(jmember, ival); - else - self.setProperty(jid, ival); - } - } - } - - return context->thisObject(); -} - -QScriptValueImpl Array::method_shift(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *) -{ - QScriptNameIdImpl *id_length = eng->idTable()->id_length; - - QScriptValueImpl self = context->thisObject(); - quint32 length = self.property(id_length).toUInt32(); - if (length == 0) { - self.setProperty(id_length, QScriptValueImpl(0)); - return eng->undefinedValue(); - } - - QScript::Member member; - QScriptValueImpl base; - - QScriptValueImpl result = self.property(QLatin1String("0")); - if (! result.isValid()) - result = eng->undefinedValue(); - - for (quint32 index = 1; index < length; ++index) { - QScriptNameIdImpl *k = eng->nameId(QScriptValueImpl(index).toString()); - QScriptNameIdImpl *k1 = eng->nameId(QScriptValueImpl(index - 1).toString()); - - QScriptValueImpl v = self.property(k); - QScriptValueImpl v1 = self.property(k1); - - if (v.isValid()) - self.setProperty(k1, v); - - else if (v1.isValid() && self.resolve(k1, &member, &base, QScriptValue::ResolveLocal, QScript::ReadWrite)) - self.removeMember(member); - } - - QScriptValueImpl len = QScriptValueImpl(length - 1); - - if (self.resolve(eng->nameId(len.toString()), &member, &base, QScriptValue::ResolveLocal, QScript::ReadWrite)) - self.removeMember(member); - - self.setProperty(id_length, len); - return (result); -} - -QScriptValueImpl Array::method_slice(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *) -{ - QScript::Array result(eng); - - QScriptValueImpl start = context->argument(0); - QScriptValueImpl end = context->argument(1); - - QScriptValueImpl self = context->thisObject(); - QScriptNameIdImpl *id_length = eng->idTable()->id_length; - qsreal r2 = self.property(id_length).toNumber(); - quint32 r3 = QScriptEnginePrivate::toUint32(r2); - qint32 r4 = qint32 (start.toInteger()); - quint32 r5 = r4 < 0 ? qMax(quint32(r3 + r4), quint32(0)) : qMin(quint32(r4), r3); - quint32 k = r5; - qint32 r7 = end.isUndefined() ? r3 : qint32 (end.toInteger()); - quint32 r8 = r7 < 0 ? qMax(quint32(r3 + r7), quint32(0)) : qMin(quint32(r7), r3); - quint32 n = 0; - for (; k < r8; ++k) { - QString r11 = QScriptValueImpl(k).toString(); - QScriptValueImpl v = self.property(r11); - if (v.isValid()) - result.assign(n++, v); - } - return eng->newArray(result); -} - -QScriptValueImpl Array::method_sort(QScriptContextPrivate *context, - QScriptEnginePrivate *, - QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - QScriptValueImpl comparefn = context->argument(0); - if (Instance *instance = Instance::get(self, classInfo)) { - instance->value.sort(comparefn); - return context->thisObject(); - } - return context->throwNotImplemented(QLatin1String("Array.prototype.sort")); -} - -QScriptValueImpl Array::method_splice(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo) -{ - if (context->argumentCount() < 2) - return eng->undefinedValue(); - - QScriptValueImpl self = context->thisObject(); - - qsreal start = context->argument(0).toInteger(); - qsreal deleteCount = context->argument(1).toInteger(); - - QScriptValueImpl arrayCtor = eng->globalObject().property(QLatin1String("Array")); - QScriptValueImpl a = arrayCtor.construct(); - - if (Instance *instance = Instance::get(self, classInfo)) { - QVector<QScriptValueImpl> items; - for (int i = 2; i < context->argumentCount(); ++i) - items << context->argument(i); - Instance *otherInstance = Instance::get(a, classInfo); - Q_ASSERT(otherInstance); - instance->value.splice(start, deleteCount, items, otherInstance->value); - return a; - } - - return context->throwNotImplemented(QLatin1String("Array.prototype.splice")); -} - -QScriptValueImpl Array::method_unshift(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *) -{ - QScriptValueImpl self = context->thisObject(); - - QScriptNameIdImpl *id_length = eng->idTable()->id_length; - QScriptValueImpl r1 = self.property(id_length); - quint32 r2 = r1.isValid() ? QScriptEnginePrivate::toUint32(r1.toNumber()) : 0; - quint32 r3 = quint32 (context->argumentCount()); - quint32 k = r2; - for (; k != 0; --k) { - QScriptNameIdImpl *r6 = eng->nameId(QScriptValueImpl(k - 1).toString()); - QScriptNameIdImpl *r7 = eng->nameId(QScriptValueImpl(k + r3 - 1).toString()); - QScriptValueImpl r8 = self.property(r6); - if (r8.isValid()) - self.setProperty(r7, r8); - - else { - QScript::Member member; - QScriptValueImpl base; - - if (self.resolve(r7, &member, &base, QScriptValue::ResolveLocal, QScript::ReadWrite)) - self.removeMember(member); - } - } - - for (k = 0; k < r3; ++k) { - QScriptValueImpl r16 = context->argument(k); - QScriptNameIdImpl *r17 = eng->nameId(QScriptValueImpl(k).toString()); - self.setProperty(r17, r16); - } - QScriptValueImpl r(r2 + r3); - self.setProperty(id_length, r); - return (r); -} - -Array::Instance *Array::Instance::get(const QScriptValueImpl &object, QScriptClassInfo *klass) -{ - if (! klass || klass == object.classInfo()) - return static_cast<Instance*> (object.objectData()); - - return 0; -} - -} } // namespace QScript::Ecma - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptecmaarray_p.h b/src/script/qscriptecmaarray_p.h deleted file mode 100644 index 33e81d2..0000000 --- a/src/script/qscriptecmaarray_p.h +++ /dev/null @@ -1,141 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTECMAARRAY_P_H -#define QSCRIPTECMAARRAY_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 "qscriptarray_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptecmacore_p.h" - -QT_BEGIN_NAMESPACE - -namespace QScript { namespace Ecma { - -class Array: public Core -{ -public: - Array(QScriptEnginePrivate *engine); - virtual ~Array(); - - virtual void execute(QScriptContextPrivate *context); - - class Instance: public QScriptObjectData { - public: - Instance(QScriptEnginePrivate *engine) - : value(QScript::Array(engine)) {} - virtual ~Instance() {} - - static Instance *get(const QScriptValueImpl &object, - QScriptClassInfo *klass); - - public: // attributes - QScript::Array value; - }; - - inline Instance *get(const QScriptValueImpl &object) const - { return Instance::get(object, classInfo()); } - - void newArray(QScriptValueImpl *result, - const QScript::Array &value); - -protected: - static QScriptValueImpl method_toString(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_toLocaleString(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_concat(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_join(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_pop(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_push(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_reverse(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_shift(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_slice(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_sort(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_splice(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_unshift(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - -private: - void initArray(QScriptValueImpl *result, const QScript::Array &value); -}; - -} } // namespace QScript::Ecma - -#endif // QT_NO_SCRIPT - -QT_END_NAMESPACE - -#endif diff --git a/src/script/qscriptecmaboolean.cpp b/src/script/qscriptecmaboolean.cpp deleted file mode 100644 index 7d37237..0000000 --- a/src/script/qscriptecmaboolean.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qscriptecmaboolean_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptengine_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" - -#include <QtCore/QtDebug> - -QT_BEGIN_NAMESPACE - -namespace QScript { namespace Ecma { - -Boolean::Boolean(QScriptEnginePrivate *eng): - Core(eng, QLatin1String("Boolean"), QScriptClassInfo::BooleanType) -{ - newBoolean(&publicPrototype, false); - - eng->newConstructor(&ctor, this, publicPrototype); - - addPrototypeFunction(QLatin1String("toString"), method_toString, 0); - addPrototypeFunction(QLatin1String("valueOf"), method_valueOf, 0); -} - -Boolean::~Boolean() -{ -} - -void Boolean::execute(QScriptContextPrivate *context) -{ -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - engine()->notifyFunctionEntry(context); -#endif - bool value; - if (context->argumentCount() > 0) - value = context->argument(0).toBoolean(); - else - value = false; - - QScriptValueImpl boolean(value); - if (!context->isCalledAsConstructor()) { - context->setReturnValue(boolean); - } else { - QScriptValueImpl &obj = context->m_thisObject; - obj.setClassInfo(classInfo()); - obj.setInternalValue(boolean); - obj.setPrototype(publicPrototype); - context->setReturnValue(obj); - } -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - engine()->notifyFunctionExit(context); -#endif -} - -void Boolean::newBoolean(QScriptValueImpl *result, bool value) -{ - engine()->newObject(result, publicPrototype, classInfo()); - result->setInternalValue(QScriptValueImpl(value)); -} - -QScriptValueImpl Boolean::method_toString(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() != classInfo) { - return throwThisObjectTypeError( - context, QLatin1String("Boolean.prototype.toString")); - } - const QScript::IdTable *t = eng->idTable(); - bool v = self.internalValue().toBoolean(); - QScriptValueImpl result; - eng->newNameId(&result, v ? t->id_true : t->id_false); - return result; -} - -QScriptValueImpl Boolean::method_valueOf(QScriptContextPrivate *context, - QScriptEnginePrivate *, - QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() != classInfo) { - return throwThisObjectTypeError( - context, QLatin1String("Boolean.prototype.valueOf")); - } - return self.internalValue(); -} - -} } // namespace QScript::Ecma - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptecmaboolean_p.h b/src/script/qscriptecmaboolean_p.h deleted file mode 100644 index 9124035..0000000 --- a/src/script/qscriptecmaboolean_p.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTECMABOOLEAN_P_H -#define QSCRIPTECMABOOLEAN_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 "qscriptecmacore_p.h" - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_SCRIPT - -namespace QScript { namespace Ecma { - -class Boolean: public Core -{ -public: - Boolean(QScriptEnginePrivate *engine); - virtual ~Boolean(); - - virtual void execute(QScriptContextPrivate *context); - - void newBoolean(QScriptValueImpl *result, bool value = false); - -protected: - static QScriptValueImpl method_toString(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_valueOf(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); -}; - -} } // namespace QScript::Ecma - -#endif // QT_NO_SCRIPT - -QT_END_NAMESPACE - -#endif diff --git a/src/script/qscriptecmacore.cpp b/src/script/qscriptecmacore.cpp deleted file mode 100644 index d1bf645..0000000 --- a/src/script/qscriptecmacore.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qscriptecmacore_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptengine_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" - -QT_BEGIN_NAMESPACE - -namespace QScript { namespace Ecma { - -Core::Core(QScriptEnginePrivate *engine, const QString &className, - QScriptClassInfo::Type type) - : m_engine(engine) -{ - m_classInfo = engine->registerClass(className, type); - this->length = 1; -} - -Core::Core(QScriptEnginePrivate *engine, QScriptClassInfo *classInfo) - : m_engine(engine), m_classInfo(classInfo) -{ - this->length = 1; -} - -Core::~Core() -{ -} - -void Core::addPrototypeFunction(const QString &name, QScriptInternalFunctionSignature fun, - int length, const QScriptValue::PropertyFlags flags) -{ - addFunction(publicPrototype, name, fun, length, flags); -} - -void Core::addConstructorFunction(const QString &name, QScriptInternalFunctionSignature fun, - int length, const QScriptValue::PropertyFlags flags) -{ - addFunction(ctor, name, fun, length, flags); -} - -void Core::addFunction(QScriptValueImpl &object, const QString &name, - QScriptInternalFunctionSignature fun, int length, - const QScriptValue::PropertyFlags flags) -{ - QScriptValueImpl val = engine()->createFunction(fun, length, m_classInfo, name); - object.setProperty(name, val, flags); -} - -QString Core::functionName() const -{ - return m_classInfo->name(); -} - -void Core::mark(QScriptEnginePrivate *eng, int generation) -{ - QScriptFunction::mark(eng, generation); - eng->markObject(ctor, generation); - eng->markObject(publicPrototype, generation); -} - -QScriptValueImpl Core::throwThisObjectTypeError(QScriptContextPrivate *context, - const QString &functionName) -{ - return context->throwError(QScriptContext::TypeError, - QString::fromLatin1("%0 called on incompatible object") - .arg(functionName)); -} - -} // namespace Ecma - -} // namespace QScript - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptecmacore_p.h b/src/script/qscriptecmacore_p.h deleted file mode 100644 index 0b3a3ab..0000000 --- a/src/script/qscriptecmacore_p.h +++ /dev/null @@ -1,115 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTECMACORE_P_H -#define QSCRIPTECMACORE_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 "qscriptfunction_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptvalueimplfwd_p.h" -#include "qscriptclassinfo_p.h" - -QT_BEGIN_NAMESPACE - -namespace QScript { namespace Ecma { - -class Core: public QScriptFunction -{ -public: - Core(QScriptEnginePrivate *engine, const QString &className, - QScriptClassInfo::Type type); - Core(QScriptEnginePrivate *engine, QScriptClassInfo *classInfo); - virtual ~Core(); - - inline QScriptEnginePrivate *engine() const - { return m_engine; } - - inline QScriptClassInfo *classInfo() const - { return m_classInfo; } - - void addPrototypeFunction( - const QString &name, QScriptInternalFunctionSignature fun, int length, - const QScriptValue::PropertyFlags flags = QScriptValue::SkipInEnumeration); - void addConstructorFunction( - const QString &name, QScriptInternalFunctionSignature fun, int length, - const QScriptValue::PropertyFlags flags = QScriptValue::SkipInEnumeration); - - QString functionName() const; - - virtual void mark(QScriptEnginePrivate *eng, int generation); - -public: // attributes - QScriptValueImpl ctor; - QScriptValueImpl publicPrototype; - -protected: - static QScriptValueImpl throwThisObjectTypeError( - QScriptContextPrivate *context, const QString &functionName); - -private: - void addFunction(QScriptValueImpl &object, const QString &name, - QScriptInternalFunctionSignature fun, int length, - const QScriptValue::PropertyFlags flags); - - QScriptEnginePrivate *m_engine; - QScriptClassInfo *m_classInfo; -}; - -} } // namespace QScript::Ecma - -#endif // QT_NO_SCRIPT - -QT_END_NAMESPACE - -#endif diff --git a/src/script/qscriptecmadate.cpp b/src/script/qscriptecmadate.cpp deleted file mode 100644 index 3b2d72c..0000000 --- a/src/script/qscriptecmadate.cpp +++ /dev/null @@ -1,1285 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qscriptecmadate_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptengine_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" - -#include <QtCore/QDateTime> -#include <QtCore/QRegExp> -#include <QtCore/QtDebug> -#include <QtCore/QLocale> -#include <QtCore/qnumeric.h> - -#include <math.h> - -#ifndef Q_WS_WIN -# include <time.h> -# ifndef Q_OS_VXWORKS -# include <sys/time.h> -# else -# include "qplatformdefs.h" -# endif -#else -# include <windows.h> -#endif - -QT_BEGIN_NAMESPACE - -namespace QScript { - -static const qsreal HoursPerDay = 24.0; -static const qsreal MinutesPerHour = 60.0; -static const qsreal SecondsPerMinute = 60.0; -static const qsreal msPerSecond = 1000.0; -static const qsreal msPerMinute = 60000.0; -static const qsreal msPerHour = 3600000.0; -static const qsreal msPerDay = 86400000.0; - -static qsreal LocalTZA = 0.0; // initialized at startup - -static inline qsreal TimeWithinDay(qsreal t) -{ - qsreal r = ::fmod(t, msPerDay); - return (r >= 0) ? r : r + msPerDay; -} - -static inline int HourFromTime(qsreal t) -{ - int r = int(::fmod(::floor(t / msPerHour), HoursPerDay)); - return (r >= 0) ? r : r + int(HoursPerDay); -} - -static inline int MinFromTime(qsreal t) -{ - int r = int(::fmod(::floor(t / msPerMinute), MinutesPerHour)); - return (r >= 0) ? r : r + int(MinutesPerHour); -} - -static inline int SecFromTime(qsreal t) -{ - int r = int(::fmod(::floor(t / msPerSecond), SecondsPerMinute)); - return (r >= 0) ? r : r + int(SecondsPerMinute); -} - -static inline int msFromTime(qsreal t) -{ - int r = int(::fmod(t, msPerSecond)); - return (r >= 0) ? r : r + int(msPerSecond); -} - -static inline qsreal Day(qsreal t) -{ - return ::floor(t / msPerDay); -} - -static inline qsreal DaysInYear(qsreal y) -{ - if (::fmod(y, 4)) - return 365; - - else if (::fmod(y, 100)) - return 366; - - else if (::fmod(y, 400)) - return 365; - - return 366; -} - -static inline qsreal DayFromYear(qsreal y) -{ - return 365 * (y - 1970) - + ::floor((y - 1969) / 4) - - ::floor((y - 1901) / 100) - + ::floor((y - 1601) / 400); -} - -static inline qsreal TimeFromYear(qsreal y) -{ - return msPerDay * DayFromYear(y); -} - -static inline qsreal YearFromTime(qsreal t) -{ - int y = 1970; - y += (int) ::floor(t / (msPerDay * 365.2425)); - - qsreal t2 = TimeFromYear(y); - return (t2 > t) ? y - 1 : ((t2 + msPerDay * DaysInYear(y)) <= t) ? y + 1 : y; -} - -static inline bool InLeapYear(qsreal t) -{ - qsreal x = DaysInYear(YearFromTime(t)); - if (x == 365) - return 0; - - Q_ASSERT (x == 366); - return 1; -} - -static inline qsreal DayWithinYear(qsreal t) -{ - return Day(t) - DayFromYear(YearFromTime(t)); -} - -static inline qsreal MonthFromTime(qsreal t) -{ - qsreal d = DayWithinYear(t); - qsreal l = InLeapYear(t); - - if (d < 31.0) - return 0; - - else if (d < 59.0 + l) - return 1; - - else if (d < 90.0 + l) - return 2; - - else if (d < 120.0 + l) - return 3; - - else if (d < 151.0 + l) - return 4; - - else if (d < 181.0 + l) - return 5; - - else if (d < 212.0 + l) - return 6; - - else if (d < 243.0 + l) - return 7; - - else if (d < 273.0 + l) - return 8; - - else if (d < 304.0 + l) - return 9; - - else if (d < 334.0 + l) - return 10; - - else if (d < 365.0 + l) - return 11; - - return qSNaN(); // ### assert? -} - -static inline qsreal DateFromTime(qsreal t) -{ - int m = (int) QScriptEnginePrivate::toInteger(MonthFromTime(t)); - qsreal d = DayWithinYear(t); - qsreal l = InLeapYear(t); - - switch (m) { - case 0: return d + 1.0; - case 1: return d - 30.0; - case 2: return d - 58.0 - l; - case 3: return d - 89.0 - l; - case 4: return d - 119.0 - l; - case 5: return d - 150.0 - l; - case 6: return d - 180.0 - l; - case 7: return d - 211.0 - l; - case 8: return d - 242.0 - l; - case 9: return d - 272.0 - l; - case 10: return d - 303.0 - l; - case 11: return d - 333.0 - l; - } - - return qSNaN(); // ### assert -} - -static inline qsreal WeekDay(qsreal t) -{ - qsreal r = ::fmod (Day(t) + 4.0, 7.0); - return (r >= 0) ? r : r + 7.0; -} - - -static inline qsreal MakeTime(qsreal hour, qsreal min, qsreal sec, qsreal ms) -{ - return ((hour * MinutesPerHour + min) * SecondsPerMinute + sec) * msPerSecond + ms; -} - -static inline qsreal DayFromMonth(qsreal month, qsreal leap) -{ - switch ((int) month) { - case 0: return 0; - case 1: return 31.0; - case 2: return 59.0 + leap; - case 3: return 90.0 + leap; - case 4: return 120.0 + leap; - case 5: return 151.0 + leap; - case 6: return 181.0 + leap; - case 7: return 212.0 + leap; - case 8: return 243.0 + leap; - case 9: return 273.0 + leap; - case 10: return 304.0 + leap; - case 11: return 334.0 + leap; - } - - return qSNaN(); // ### assert? -} - -static qsreal MakeDay(qsreal year, qsreal month, qsreal day) -{ - year += ::floor(month / 12.0); - - month = ::fmod(month, 12.0); - if (month < 0) - month += 12.0; - - qsreal t = TimeFromYear(year); - qsreal leap = InLeapYear(t); - - day += ::floor(t / msPerDay); - day += DayFromMonth(month, leap); - - return day - 1; -} - -static inline qsreal MakeDate(qsreal day, qsreal time) -{ - return day * msPerDay + time; -} - -static inline qsreal DaylightSavingTA(double t) -{ -#ifndef Q_WS_WIN - long int tt = (long int)(t / msPerSecond); - struct tm *tmtm = localtime((const time_t*)&tt); - if (! tmtm) - return 0; - return (tmtm->tm_isdst > 0) ? msPerHour : 0; -#else - Q_UNUSED(t); - /// ### implement me - return 0; -#endif -} - -static inline qsreal LocalTime(qsreal t) -{ - return t + LocalTZA + DaylightSavingTA(t); -} - -static inline qsreal UTC(qsreal t) -{ - return t - LocalTZA - DaylightSavingTA(t - LocalTZA); -} - -static inline qsreal currentTime() -{ -#ifndef Q_WS_WIN - struct timeval tv; - - gettimeofday(&tv, 0); - return ::floor(tv.tv_sec * msPerSecond + (tv.tv_usec / 1000.0)); -#else - SYSTEMTIME st; - GetSystemTime(&st); - FILETIME ft; - SystemTimeToFileTime(&st, &ft); - LARGE_INTEGER li; - li.LowPart = ft.dwLowDateTime; - li.HighPart = ft.dwHighDateTime; - return double(li.QuadPart - Q_INT64_C(116444736000000000)) / 10000.0; -#endif -} - -static inline qsreal TimeClip(qsreal t) -{ - if (! qIsFinite(t) || fabs(t) > 8.64e15) - return qSNaN(); - return QScriptEnginePrivate::toInteger(t); -} - -static inline qsreal FromDateTime(const QDateTime &dt) -{ - if (!dt.isValid()) - return qSNaN(); - QDate date = dt.date(); - QTime taim = dt.time(); - int year = date.year(); - int month = date.month() - 1; - int day = date.day(); - int hours = taim.hour(); - int mins = taim.minute(); - int secs = taim.second(); - int ms = taim.msec(); - double t = MakeDate(MakeDay(year, month, day), - MakeTime(hours, mins, secs, ms)); - if (dt.timeSpec() == Qt::LocalTime) - t = UTC(t); - return TimeClip(t); -} - -static inline qsreal ParseString(const QString &s) -{ - QDateTime dt = QDateTime::fromString(s, Qt::TextDate); - if (!dt.isValid()) - dt = QDateTime::fromString(s, Qt::ISODate); - if (!dt.isValid()) { - QStringList formats; - formats << QLatin1String("M/d/yyyy") - << QLatin1String("M/d/yyyy hh:mm") - << QLatin1String("M/d/yyyy hh:mm A") - - << QLatin1String("M/d/yyyy, hh:mm") - << QLatin1String("M/d/yyyy, hh:mm A") - - << QLatin1String("MMM d yyyy") - << QLatin1String("MMM d yyyy hh:mm") - << QLatin1String("MMM d yyyy hh:mm:ss") - << QLatin1String("MMM d yyyy, hh:mm") - << QLatin1String("MMM d yyyy, hh:mm:ss") - - << QLatin1String("MMMM d yyyy") - << QLatin1String("MMMM d yyyy hh:mm") - << QLatin1String("MMMM d yyyy hh:mm:ss") - << QLatin1String("MMMM d yyyy, hh:mm") - << QLatin1String("MMMM d yyyy, hh:mm:ss") - - << QLatin1String("MMM d, yyyy") - << QLatin1String("MMM d, yyyy hh:mm") - << QLatin1String("MMM d, yyyy hh:mm:ss") - - << QLatin1String("MMMM d, yyyy") - << QLatin1String("MMMM d, yyyy hh:mm") - << QLatin1String("MMMM d, yyyy hh:mm:ss") - - << QLatin1String("d MMM yyyy") - << QLatin1String("d MMM yyyy hh:mm") - << QLatin1String("d MMM yyyy hh:mm:ss") - << QLatin1String("d MMM yyyy, hh:mm") - << QLatin1String("d MMM yyyy, hh:mm:ss") - - << QLatin1String("d MMMM yyyy") - << QLatin1String("d MMMM yyyy hh:mm") - << QLatin1String("d MMMM yyyy hh:mm:ss") - << QLatin1String("d MMMM yyyy, hh:mm") - << QLatin1String("d MMMM yyyy, hh:mm:ss") - - << QLatin1String("d MMM, yyyy") - << QLatin1String("d MMM, yyyy hh:mm") - << QLatin1String("d MMM, yyyy hh:mm:ss") - - << QLatin1String("d MMMM, yyyy") - << QLatin1String("d MMMM, yyyy hh:mm") - << QLatin1String("d MMMM, yyyy hh:mm:ss"); - - for (int i = 0; i < formats.size(); ++i) { - dt = QDateTime::fromString(s, formats.at(i)); - if (dt.isValid()) - break; - } - } - return FromDateTime(dt); -} - -/*! - \internal - - Converts the ECMA Date value \tt (in UTC form) to QDateTime - according to \a spec. -*/ -static inline QDateTime ToDateTime(qsreal t, Qt::TimeSpec spec) -{ - if (qIsNaN(t)) - return QDateTime(); - if (spec == Qt::LocalTime) - t = LocalTime(t); - int year = int(YearFromTime(t)); - int month = int(MonthFromTime(t) + 1); - int day = int(DateFromTime(t)); - int hours = HourFromTime(t); - int mins = MinFromTime(t); - int secs = SecFromTime(t); - int ms = msFromTime(t); - return QDateTime(QDate(year, month, day), QTime(hours, mins, secs, ms), spec); -} - -static inline QString ToString(qsreal t) -{ - if (qIsNaN(t)) - return QLatin1String("Invalid Date"); - QString str = ToDateTime(t, Qt::LocalTime).toString() + QLatin1String(" GMT"); - qsreal tzoffset = LocalTZA + DaylightSavingTA(t); - if (tzoffset) { - int hours = static_cast<int>(::fabs(tzoffset) / 1000 / 60 / 60); - int mins = int(::fabs(tzoffset) / 1000 / 60) % 60; - str.append(QLatin1Char((tzoffset > 0) ? '+' : '-')); - if (hours < 10) - str.append(QLatin1Char('0')); - str.append(QString::number(hours)); - if (mins < 10) - str.append(QLatin1Char('0')); - str.append(QString::number(mins)); - } - return str; -} - -static inline QString ToUTCString(qsreal t) -{ - if (qIsNaN(t)) - return QLatin1String("Invalid Date"); - return ToDateTime(t, Qt::UTC).toString() + QLatin1String(" GMT"); -} - -static inline QString ToDateString(qsreal t) -{ - return ToDateTime(t, Qt::LocalTime).date().toString(); -} - -static inline QString ToTimeString(qsreal t) -{ - return ToDateTime(t, Qt::LocalTime).time().toString(); -} - -static inline QString ToLocaleString(qsreal t) -{ - return ToDateTime(t, Qt::LocalTime).toString(Qt::LocaleDate); -} - -static inline QString ToLocaleDateString(qsreal t) -{ - return ToDateTime(t, Qt::LocalTime).date().toString(Qt::LocaleDate); -} - -static inline QString ToLocaleTimeString(qsreal t) -{ - return ToDateTime(t, Qt::LocalTime).time().toString(Qt::LocaleDate); -} - -static qsreal getLocalTZA() -{ -#ifndef Q_WS_WIN - struct tm* t; - time_t curr; - time(&curr); - t = localtime(&curr); - time_t locl = mktime(t); - t = gmtime(&curr); - time_t globl = mktime(t); - return double(locl - globl) * 1000.0; -#else - TIME_ZONE_INFORMATION tzInfo; - GetTimeZoneInformation(&tzInfo); - return -tzInfo.Bias * 60.0 * 1000.0; -#endif -} - -namespace Ecma { - -Date::Date(QScriptEnginePrivate *eng): - Core(eng, QLatin1String("Date"), QScriptClassInfo::DateType) -{ - LocalTZA = getLocalTZA(); - - newDate(&publicPrototype, qSNaN()); - - eng->newConstructor(&ctor, this, publicPrototype); - addConstructorFunction(QLatin1String("parse"), method_parse, 1); - addConstructorFunction(QLatin1String("UTC"), method_UTC, 7); - - addPrototypeFunction(QLatin1String("toString"), method_toString, 0); - addPrototypeFunction(QLatin1String("toDateString"), method_toDateString, 0); - addPrototypeFunction(QLatin1String("toTimeString"), method_toTimeString, 0); - addPrototypeFunction(QLatin1String("toLocaleString"), method_toLocaleString, 0); - addPrototypeFunction(QLatin1String("toLocaleDateString"), method_toLocaleDateString, 0); - addPrototypeFunction(QLatin1String("toLocaleTimeString"), method_toLocaleTimeString, 0); - addPrototypeFunction(QLatin1String("valueOf"), method_valueOf, 0); - addPrototypeFunction(QLatin1String("getTime"), method_getTime, 0); - addPrototypeFunction(QLatin1String("getYear"), method_getYear, 0); - addPrototypeFunction(QLatin1String("getFullYear"), method_getFullYear, 0); - addPrototypeFunction(QLatin1String("getUTCFullYear"), method_getUTCFullYear, 0); - addPrototypeFunction(QLatin1String("getMonth"), method_getMonth, 0); - addPrototypeFunction(QLatin1String("getUTCMonth"), method_getUTCMonth, 0); - addPrototypeFunction(QLatin1String("getDate"), method_getDate, 0); - addPrototypeFunction(QLatin1String("getUTCDate"), method_getUTCDate, 0); - addPrototypeFunction(QLatin1String("getDay"), method_getDay, 0); - addPrototypeFunction(QLatin1String("getUTCDay"), method_getUTCDay, 0); - addPrototypeFunction(QLatin1String("getHours"), method_getHours, 0); - addPrototypeFunction(QLatin1String("getUTCHours"), method_getUTCHours, 0); - addPrototypeFunction(QLatin1String("getMinutes"), method_getMinutes, 0); - addPrototypeFunction(QLatin1String("getUTCMinutes"), method_getUTCMinutes, 0); - addPrototypeFunction(QLatin1String("getSeconds"), method_getSeconds, 0); - addPrototypeFunction(QLatin1String("getUTCSeconds"), method_getUTCSeconds, 0); - addPrototypeFunction(QLatin1String("getMilliseconds"), method_getMilliseconds, 0); - addPrototypeFunction(QLatin1String("getUTCMilliseconds"), method_getUTCMilliseconds, 0); - addPrototypeFunction(QLatin1String("getTimezoneOffset"), method_getTimezoneOffset, 0); - addPrototypeFunction(QLatin1String("setTime"), method_setTime, 1); - addPrototypeFunction(QLatin1String("setMilliseconds"), method_setMilliseconds, 1); - addPrototypeFunction(QLatin1String("setUTCMilliseconds"), method_setUTCMilliseconds, 1); - addPrototypeFunction(QLatin1String("setSeconds"), method_setSeconds, 2); - addPrototypeFunction(QLatin1String("setUTCSeconds"), method_setUTCSeconds, 2); - addPrototypeFunction(QLatin1String("setMinutes"), method_setMinutes, 3); - addPrototypeFunction(QLatin1String("setUTCMinutes"), method_setUTCMinutes, 3); - addPrototypeFunction(QLatin1String("setHours"), method_setHours, 4); - addPrototypeFunction(QLatin1String("setUTCHours"), method_setUTCHours, 4); - addPrototypeFunction(QLatin1String("setDate"), method_setDate, 1); - addPrototypeFunction(QLatin1String("setUTCDate"), method_setUTCDate, 1); - addPrototypeFunction(QLatin1String("setMonth"), method_setMonth, 2); - addPrototypeFunction(QLatin1String("setUTCMonth"), method_setUTCMonth, 2); - addPrototypeFunction(QLatin1String("setYear"), method_setYear, 1); - addPrototypeFunction(QLatin1String("setFullYear"), method_setFullYear, 3); - addPrototypeFunction(QLatin1String("setUTCFullYear"), method_setUTCFullYear, 3); - addPrototypeFunction(QLatin1String("toUTCString"), method_toUTCString, 0); - addPrototypeFunction(QLatin1String("toGMTString"), method_toUTCString, 0); -} - -Date::~Date() -{ -} - -void Date::execute(QScriptContextPrivate *context) -{ -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - engine()->notifyFunctionEntry(context); -#endif - if (!context->isCalledAsConstructor()) { - double t = currentTime(); - context->setReturnValue(QScriptValueImpl(engine(), ToString(t))); - } else { - // called as constructor - qsreal t; - - if (context->argumentCount() == 0) - t = currentTime(); - - else if (context->argumentCount() == 1) { - QScriptValueImpl arg = context->argument(0); - if (arg.isDate()) - arg = arg.internalValue(); - else - arg = engine()->toPrimitive(arg); - if (arg.isString()) - t = ParseString(arg.toString()); - else - t = TimeClip(arg.toNumber()); - } - - else { // context->argumentCount() > 1 - qsreal year = context->argument(0).toNumber(); - qsreal month = context->argument(1).toNumber(); - qsreal day = context->argumentCount() >= 3 ? context->argument(2).toNumber() : 1; - qsreal hours = context->argumentCount() >= 4 ? context->argument(3).toNumber() : 0; - qsreal mins = context->argumentCount() >= 5 ? context->argument(4).toNumber() : 0; - qsreal secs = context->argumentCount() >= 6 ? context->argument(5).toNumber() : 0; - qsreal ms = context->argumentCount() >= 7 ? context->argument(6).toNumber() : 0; - if (year >= 0 && year <= 99) - year += 1900; - t = MakeDate(MakeDay(year, month, day), MakeTime(hours, mins, secs, ms)); - t = TimeClip(UTC(t)); - } - - QScriptValueImpl &obj = context->m_thisObject; - obj.setClassInfo(classInfo()); - obj.setInternalValue(QScriptValueImpl(t)); - obj.setPrototype(publicPrototype); - context->setReturnValue(obj); - } -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - engine()->notifyFunctionExit(context); -#endif -} - -void Date::newDate(QScriptValueImpl *result, qsreal t) -{ - engine()->newObject(result, publicPrototype, classInfo()); - result->setInternalValue(QScriptValueImpl(t)); -} - -void Date::newDate(QScriptValueImpl *result, const QDateTime &dt) -{ - newDate(result, FromDateTime(dt)); -} - -void Date::newDate(QScriptValueImpl *result, const QDate &d) -{ - newDate(result, QDateTime(d)); -} - -QDateTime Date::toDateTime(const QScriptValueImpl &date) const -{ - Q_ASSERT(date.classInfo() == classInfo()); - qsreal t = date.internalValue().toNumber(); - return ToDateTime(t, Qt::LocalTime); -} - -QScriptValueImpl Date::method_parse(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *) -{ - return QScriptValueImpl(ParseString(context->argument(0).toString())); -} - -QScriptValueImpl Date::method_UTC(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - const int numArgs = context->argumentCount(); - if (numArgs >= 2) { - qsreal year = context->argument(0).toNumber(); - qsreal month = context->argument(1).toNumber(); - qsreal day = numArgs >= 3 ? context->argument(2).toNumber() : 1; - qsreal hours = numArgs >= 4 ? context->argument(3).toNumber() : 0; - qsreal mins = numArgs >= 5 ? context->argument(4).toNumber() : 0; - qsreal secs = numArgs >= 6 ? context->argument(5).toNumber() : 0; - qsreal ms = numArgs >= 7 ? context->argument(6).toNumber() : 0; - if (year >= 0 && year <= 99) - year += 1900; - qsreal t = MakeDate(MakeDay(year, month, day), - MakeTime(hours, mins, secs, ms)); - return QScriptValueImpl(TimeClip(t)); - } - return (eng->undefinedValue()); -} - -QScriptValueImpl Date::method_toString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - return QScriptValueImpl(eng, ToString(t)); - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.toString")); -} - -QScriptValueImpl Date::method_toDateString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - return QScriptValueImpl(eng, ToDateString(t)); - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.toDateString")); -} - -QScriptValueImpl Date::method_toTimeString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - return QScriptValueImpl(eng, ToTimeString(t)); - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.toTimeString")); -} - -QScriptValueImpl Date::method_toLocaleString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - return QScriptValueImpl(eng, ToLocaleString(t)); - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.toLocaleString")); -} - -QScriptValueImpl Date::method_toLocaleDateString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - return QScriptValueImpl(eng, ToLocaleDateString(t)); - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.toLocaleDateString")); -} - -QScriptValueImpl Date::method_toLocaleTimeString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - return QScriptValueImpl(eng, ToLocaleTimeString(t)); - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.toLocaleTimeString")); -} - -QScriptValueImpl Date::method_valueOf(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) - return QScriptValueImpl(self.internalValue().toNumber()); - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.valueOf")); -} - -QScriptValueImpl Date::method_getTime(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) - return QScriptValueImpl(self.internalValue().toNumber()); - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.getTime")); -} - -QScriptValueImpl Date::method_getYear(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - if (! qIsNaN(t)) - t = YearFromTime(LocalTime(t)) - 1900; - return QScriptValueImpl(t); - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.getYear")); -} - -QScriptValueImpl Date::method_getFullYear(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - if (! qIsNaN(t)) - t = YearFromTime(LocalTime(t)); - return QScriptValueImpl(t); - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.getFullYear")); -} - -QScriptValueImpl Date::method_getUTCFullYear(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - if (! qIsNaN(t)) - t = YearFromTime(t); - return QScriptValueImpl(t); - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.getUTCFullYear")); -} - -QScriptValueImpl Date::method_getMonth(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - if (! qIsNaN(t)) - t = MonthFromTime(LocalTime(t)); - return QScriptValueImpl(t); - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.getMonth")); -} - -QScriptValueImpl Date::method_getUTCMonth(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - if (! qIsNaN(t)) - t = MonthFromTime(t); - return QScriptValueImpl(t); - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.getUTCMonth")); -} - -QScriptValueImpl Date::method_getDate(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - if (! qIsNaN(t)) - t = DateFromTime(LocalTime(t)); - return QScriptValueImpl(t); - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.getDate")); -} - -QScriptValueImpl Date::method_getUTCDate(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - if (! qIsNaN(t)) - t = DateFromTime(t); - return QScriptValueImpl(t); - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.getUTCDate")); -} - -QScriptValueImpl Date::method_getDay(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - if (! qIsNaN(t)) - t = WeekDay(LocalTime(t)); - return QScriptValueImpl(t); - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.getDay")); -} - -QScriptValueImpl Date::method_getUTCDay(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - if (! qIsNaN(t)) - t = WeekDay(t); - return QScriptValueImpl(t); - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.getUTCDay")); -} - -QScriptValueImpl Date::method_getHours(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - if (! qIsNaN(t)) - t = HourFromTime(LocalTime(t)); - return QScriptValueImpl(t); - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.getHours")); -} - -QScriptValueImpl Date::method_getUTCHours(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - if (! qIsNaN(t)) - t = HourFromTime(t); - return QScriptValueImpl(t); - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.getUTCHours")); -} - -QScriptValueImpl Date::method_getMinutes(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - if (! qIsNaN(t)) - t = MinFromTime(LocalTime(t)); - return QScriptValueImpl(t); - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.getMinutes")); -} - -QScriptValueImpl Date::method_getUTCMinutes(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - if (! qIsNaN(t)) - t = MinFromTime(t); - return QScriptValueImpl(t); - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.getUTCMinutes")); -} - -QScriptValueImpl Date::method_getSeconds(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - if (! qIsNaN(t)) - t = SecFromTime(LocalTime(t)); - return QScriptValueImpl(t); - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.getSeconds")); -} - -QScriptValueImpl Date::method_getUTCSeconds(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - if (! qIsNaN(t)) - t = SecFromTime(t); - return QScriptValueImpl(t); - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.getUTCSeconds")); -} - -QScriptValueImpl Date::method_getMilliseconds(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - if (! qIsNaN(t)) - t = msFromTime(LocalTime(t)); - return QScriptValueImpl(t); - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.getMilliseconds")); -} - -QScriptValueImpl Date::method_getUTCMilliseconds(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - if (! qIsNaN(t)) - t = msFromTime(t); - return QScriptValueImpl(t); - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.getUTCMilliseconds")); -} - -QScriptValueImpl Date::method_getTimezoneOffset(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - if (! qIsNaN(t)) - t = (t - LocalTime(t)) / msPerMinute; - return QScriptValueImpl(t); - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.getTimezoneOffset")); -} - -QScriptValueImpl Date::method_setTime(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = TimeClip(context->argument(0).toNumber()); - QScriptValueImpl r(t); - self.setInternalValue(r); - return r; - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.setTime")); -} - -QScriptValueImpl Date::method_setMilliseconds(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = LocalTime(self.internalValue().toNumber()); - qsreal ms = context->argument(0).toNumber(); - t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms)))); - QScriptValueImpl r(t); - self.setInternalValue(r); - return r; - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.setMilliseconds")); -} - -QScriptValueImpl Date::method_setUTCMilliseconds(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - qsreal ms = context->argument(0).toNumber(); - t = TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms))); - QScriptValueImpl r(t); - self.setInternalValue(r); - return r; - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.setUTCMilliseconds")); -} - -QScriptValueImpl Date::method_setSeconds(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = LocalTime(self.internalValue().toNumber()); - qsreal sec = context->argument(0).toNumber(); - qsreal ms = (context->argumentCount() < 2) ? msFromTime(t) : context->argument(1).toNumber(); - t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms)))); - QScriptValueImpl r(t); - self.setInternalValue(r); - return r; - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.setSeconds")); -} - -QScriptValueImpl Date::method_setUTCSeconds(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - qsreal sec = context->argument(0).toNumber(); - qsreal ms = (context->argumentCount() < 2) ? msFromTime(t) : context->argument(1).toNumber(); - t = TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms))); - QScriptValueImpl r(t); - self.setInternalValue(r); - return r; - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.setUTCSeconds")); -} - -QScriptValueImpl Date::method_setMinutes(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = LocalTime(self.internalValue().toNumber()); - qsreal min = context->argument(0).toNumber(); - qsreal sec = (context->argumentCount() < 2) ? SecFromTime(t) : context->argument(1).toNumber(); - qsreal ms = (context->argumentCount() < 3) ? msFromTime(t) : context->argument(2).toNumber(); - t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms)))); - QScriptValueImpl r(t); - self.setInternalValue(r); - return r; - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.setMinutes")); -} - -QScriptValueImpl Date::method_setUTCMinutes(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - qsreal min = context->argument(0).toNumber(); - qsreal sec = (context->argumentCount() < 2) ? SecFromTime(t) : context->argument(1).toNumber(); - qsreal ms = (context->argumentCount() < 3) ? msFromTime(t) : context->argument(2).toNumber(); - t = TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms))); - QScriptValueImpl r(t); - self.setInternalValue(r); - return r; - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.setUTCMinutes")); -} - -QScriptValueImpl Date::method_setHours(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = LocalTime(self.internalValue().toNumber()); - qsreal hour = context->argument(0).toNumber(); - qsreal min = (context->argumentCount() < 2) ? MinFromTime(t) : context->argument(1).toNumber(); - qsreal sec = (context->argumentCount() < 3) ? SecFromTime(t) : context->argument(2).toNumber(); - qsreal ms = (context->argumentCount() < 4) ? msFromTime(t) : context->argument(3).toNumber(); - t = TimeClip(UTC(MakeDate(Day(t), MakeTime(hour, min, sec, ms)))); - QScriptValueImpl r(t); - self.setInternalValue(r); - return r; - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.setHours")); -} - -QScriptValueImpl Date::method_setUTCHours(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - qsreal hour = context->argument(0).toNumber(); - qsreal min = (context->argumentCount() < 2) ? MinFromTime(t) : context->argument(1).toNumber(); - qsreal sec = (context->argumentCount() < 3) ? SecFromTime(t) : context->argument(2).toNumber(); - qsreal ms = (context->argumentCount() < 4) ? msFromTime(t) : context->argument(3).toNumber(); - t = TimeClip(MakeDate(Day(t), MakeTime(hour, min, sec, ms))); - QScriptValueImpl r(t); - self.setInternalValue(r); - return r; - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.setUTCHours")); -} - -QScriptValueImpl Date::method_setDate(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = LocalTime(self.internalValue().toNumber()); - qsreal date = context->argument(0).toNumber(); - t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t)))); - QScriptValueImpl r(t); - self.setInternalValue(r); - return r; - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.setDate")); -} - -QScriptValueImpl Date::method_setUTCDate(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - qsreal date = context->argument(0).toNumber(); - t = TimeClip(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t))); - QScriptValueImpl r(t); - self.setInternalValue(r); - return r; - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.setUTCDate")); -} - -QScriptValueImpl Date::method_setMonth(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = LocalTime(self.internalValue().toNumber()); - qsreal month = context->argument(0).toNumber(); - qsreal date = (context->argumentCount() < 2) ? DateFromTime(t) : context->argument(1).toNumber(); - t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t)))); - QScriptValueImpl r(t); - self.setInternalValue(r); - return r; - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.setMonth")); -} - -QScriptValueImpl Date::method_setUTCMonth(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - qsreal month = context->argument(0).toNumber(); - qsreal date = (context->argumentCount() < 2) ? DateFromTime(t) : context->argument(1).toNumber(); - t = TimeClip(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t))); - QScriptValueImpl r(t); - self.setInternalValue(r); - return r; - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.setUTCMonth")); -} - -QScriptValueImpl Date::method_setFullYear(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = LocalTime(self.internalValue().toNumber()); - qsreal year = context->argument(0).toNumber(); - qsreal month = (context->argumentCount() < 2) ? MonthFromTime(t) : context->argument(1).toNumber(); - qsreal date = (context->argumentCount() < 3) ? DateFromTime(t) : context->argument(2).toNumber(); - t = TimeClip(UTC(MakeDate(MakeDay(year, month, date), TimeWithinDay(t)))); - QScriptValueImpl r(t); - self.setInternalValue(r); - return r; - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.setFullYear")); -} - -QScriptValueImpl Date::method_setUTCFullYear(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - qsreal year = context->argument(0).toNumber(); - qsreal month = (context->argumentCount() < 2) ? MonthFromTime(t) : context->argument(1).toNumber(); - qsreal date = (context->argumentCount() < 3) ? DateFromTime(t) : context->argument(2).toNumber(); - t = TimeClip(MakeDate(MakeDay(year, month, date), TimeWithinDay(t))); - QScriptValueImpl r(t); - self.setInternalValue(r); - return r; - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.setUTCFullYear")); -} - -QScriptValueImpl Date::method_setYear(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) -{ - Q_UNUSED(eng); - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - if (qIsNaN(t)) - t = 0; - else - t = LocalTime(t); - qsreal year = context->argument(0).toNumber(); - qsreal r; - if (qIsNaN(year)) { - r = qSNaN(); - } else { - if ((eng->toInteger(year) >= 0) && (eng->toInteger(year) <= 99)) - year += 1900; - r = MakeDay(year, MonthFromTime(t), DateFromTime(t)); - r = UTC(MakeDate(r, TimeWithinDay(t))); - r = TimeClip(r); - } - QScriptValueImpl v = QScriptValueImpl(r); - self.setInternalValue(v); - return v; - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.setYear")); -} - -QScriptValueImpl Date::method_toUTCString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() == classInfo) { - qsreal t = self.internalValue().toNumber(); - return QScriptValueImpl(eng, ToUTCString(t)); - } - return throwThisObjectTypeError( - context, QLatin1String("Date.prototype.toUTCString")); -} - -} } // namespace QScript::Ecma - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptecmadate_p.h b/src/script/qscriptecmadate_p.h deleted file mode 100644 index f06201f..0000000 --- a/src/script/qscriptecmadate_p.h +++ /dev/null @@ -1,234 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTECMADATE_P_H -#define QSCRIPTECMADATE_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 "qscriptecmacore_p.h" - -#ifndef QT_NO_SCRIPT - -QT_BEGIN_NAMESPACE - -class QDate; -class QDateTime; - -namespace QScript { namespace Ecma { - -class Date: public Core -{ -public: - Date(QScriptEnginePrivate *engine); - virtual ~Date(); - - virtual void execute(QScriptContextPrivate *context); - - void newDate(QScriptValueImpl *result, double t); - void newDate(QScriptValueImpl *result, const QDateTime &dt); - void newDate(QScriptValueImpl *result, const QDate &d); - - QDateTime toDateTime(const QScriptValueImpl &date) const; - -protected: - static QScriptValueImpl method_MakeTime(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_MakeDate(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_TimeClip(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_parse(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_UTC(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_toString(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_toDateString(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_toTimeString(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_toLocaleString(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_toLocaleDateString(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_toLocaleTimeString(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_valueOf(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_getTime(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_getYear(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_getFullYear(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_getUTCFullYear(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_getMonth(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_getUTCMonth(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_getDate(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_getUTCDate(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_getDay(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_getUTCDay(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_getHours(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_getUTCHours(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_getMinutes(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_getUTCMinutes(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_getSeconds(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_getUTCSeconds(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_getMilliseconds(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_getUTCMilliseconds(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_getTimezoneOffset(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_setTime(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_setMilliseconds(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_setUTCMilliseconds(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_setSeconds(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_setUTCSeconds(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_setMinutes(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_setUTCMinutes(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_setHours(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_setUTCHours(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_setDate(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_setUTCDate(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_setMonth(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_setUTCMonth(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_setYear(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_setFullYear(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_setUTCFullYear(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_toUTCString(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); -}; - -} } // namespace QScript::Ecma - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT - -#endif diff --git a/src/script/qscriptecmaerror.cpp b/src/script/qscriptecmaerror.cpp deleted file mode 100644 index 84aea19..0000000 --- a/src/script/qscriptecmaerror.cpp +++ /dev/null @@ -1,368 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qscriptecmaerror_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptengine_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" - -#include <QtCore/QtDebug> - -QT_BEGIN_NAMESPACE - -namespace QScript { namespace Ecma { - -static QString getMessage(QScriptContextPrivate *context) -{ - if (context->argumentCount() > 0) - return context->argument(0).toString(); - return QString(); -} - -static void setDebugInformation(QScriptValueImpl *error, QScriptContextPrivate *context) -{ - Q_ASSERT(context->previous); - context->previous->setDebugInformation(error); -} - -static QScriptValueImpl method_EvalError(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - QScriptValueImpl result; - if (context->isCalledAsConstructor()) - result = context->thisObject(); - eng->errorConstructor->newEvalError(&result, getMessage(context)); - setDebugInformation(&result, context); - return result; -} - -static QScriptValueImpl method_RangeError(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - QScriptValueImpl result; - if (context->isCalledAsConstructor()) - result = context->thisObject(); - eng->errorConstructor->newRangeError(&result, getMessage(context)); - setDebugInformation(&result, context); - return result; -} - -static QScriptValueImpl method_ReferenceError(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - QScriptValueImpl result; - if (context->isCalledAsConstructor()) - result = context->thisObject(); - eng->errorConstructor->newReferenceError(&result, getMessage(context)); - setDebugInformation(&result, context); - return result; -} - -static QScriptValueImpl method_SyntaxError(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - QScriptValueImpl result; - if (context->isCalledAsConstructor()) - result = context->thisObject(); - eng->errorConstructor->newSyntaxError(&result, getMessage(context)); - setDebugInformation(&result, context); - return result; -} - -static QScriptValueImpl method_TypeError(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - QScriptValueImpl result; - if (context->isCalledAsConstructor()) - result = context->thisObject(); - eng->errorConstructor->newTypeError(&result, getMessage(context)); - setDebugInformation(&result, context); - return result; -} - -static QScriptValueImpl method_UriError(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - QScriptValueImpl result; - if (context->isCalledAsConstructor()) - result = context->thisObject(); - eng->errorConstructor->newURIError(&result, getMessage(context)); - setDebugInformation(&result, context); - return result; -} - -Error::Error(QScriptEnginePrivate *eng): - Core(eng, QLatin1String("Error"), QScriptClassInfo::ErrorType) -{ - eng->newFunction(&ctor, this); - newErrorPrototype(&publicPrototype, QScriptValueImpl(), ctor, QLatin1String("Error")); - addPrototypeFunction(QLatin1String("backtrace"), method_backtrace, 0); - addPrototypeFunction(QLatin1String("toString"), method_toString, 0); - - // native errors - - evalErrorCtor = eng->createFunction(method_EvalError, 3, - classInfo(), QLatin1String("EvalError")); - rangeErrorCtor = eng->createFunction(method_RangeError, 3, - classInfo(), QLatin1String("RangeError")); - referenceErrorCtor = eng->createFunction(method_ReferenceError, 3, - classInfo(), QLatin1String("ReferenceError")); - syntaxErrorCtor = eng->createFunction(method_SyntaxError, 3, - classInfo(), QLatin1String("SyntaxError")); - typeErrorCtor = eng->createFunction(method_TypeError, 3, - classInfo(), QLatin1String("TypeError")); - uriErrorCtor = eng->createFunction(method_UriError, 3, - classInfo(), QLatin1String("URIError")); - - newErrorPrototype(&evalErrorPrototype, publicPrototype, - evalErrorCtor, QLatin1String("EvalError")); - newErrorPrototype(&rangeErrorPrototype, publicPrototype, - rangeErrorCtor, QLatin1String("RangeError")); - newErrorPrototype(&referenceErrorPrototype, publicPrototype, - referenceErrorCtor, QLatin1String("ReferenceError")); - newErrorPrototype(&syntaxErrorPrototype, publicPrototype, - syntaxErrorCtor, QLatin1String("SyntaxError")); - newErrorPrototype(&typeErrorPrototype, publicPrototype, - typeErrorCtor, QLatin1String("TypeError")); - newErrorPrototype(&uriErrorPrototype, publicPrototype, - uriErrorCtor, QLatin1String("URIError")); -} - -Error::~Error() -{ -} - -void Error::execute(QScriptContextPrivate *context) -{ -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - engine()->notifyFunctionEntry(context); -#endif - QString message = QString(); - - if (context->argumentCount() > 0) - message = context->argument(0).toString(); - - QScriptValueImpl result; - newError(&result, publicPrototype, message); - - setDebugInformation(&result, context); - - context->setReturnValue(result); -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - engine()->notifyFunctionExit(context); -#endif -} - -void Error::mark(QScriptEnginePrivate *eng, int generation) -{ - Core::mark(eng, generation); - - eng->markObject(evalErrorCtor, generation); - eng->markObject(rangeErrorCtor, generation); - eng->markObject(referenceErrorCtor, generation); - eng->markObject(syntaxErrorCtor, generation); - eng->markObject(typeErrorCtor, generation); - eng->markObject(uriErrorCtor, generation); - - eng->markObject(evalErrorPrototype, generation); - eng->markObject(rangeErrorPrototype, generation); - eng->markObject(referenceErrorPrototype, generation); - eng->markObject(syntaxErrorPrototype, generation); - eng->markObject(typeErrorPrototype, generation); - eng->markObject(uriErrorPrototype, generation); -} - -void Error::newError(QScriptValueImpl *result, const QString &message) -{ - newError(result, publicPrototype, message); -} - -void Error::newEvalError(QScriptValueImpl *result, const QString &message) -{ - newError(result, evalErrorPrototype, message); -} - -void Error::newRangeError(QScriptValueImpl *result, const QString &message) -{ - newError(result, rangeErrorPrototype, message); -} - -void Error::newReferenceError(QScriptValueImpl *result, const QString &message) -{ - newError(result, referenceErrorPrototype, message); -} - -void Error::newSyntaxError(QScriptValueImpl *result, const QString &message) -{ - newError(result, syntaxErrorPrototype, message); -} - -void Error::newTypeError(QScriptValueImpl *result, const QString &message) -{ - newError(result, typeErrorPrototype, message); -} - -void Error::newURIError(QScriptValueImpl *result, const QString &message) -{ - newError(result, uriErrorPrototype, message); -} - -void Error::newError(QScriptValueImpl *result, const QScriptValueImpl &proto, - const QString &message) -{ - QScriptEnginePrivate *eng_p = engine(); - - if (!result->isValid()) - eng_p->newObject(result, proto, classInfo()); - else - result->setClassInfo(classInfo()); - result->setProperty(QLatin1String("message"), QScriptValueImpl(eng_p, message)); -} - -void Error::newErrorPrototype(QScriptValueImpl *result, const QScriptValueImpl &proto, - QScriptValueImpl &ztor, const QString &name) -{ - newError(result, proto); - result->setProperty(QLatin1String("name"), QScriptValueImpl(engine(), name)); - result->setProperty(QLatin1String("constructor"), ztor, - QScriptValue::Undeletable - | QScriptValue::SkipInEnumeration); - ztor.setProperty(QLatin1String("prototype"), *result, - QScriptValue::Undeletable - | QScriptValue::ReadOnly - | QScriptValue::SkipInEnumeration); -} - -bool Error::isEvalError(const QScriptValueImpl &value) const -{ - return value.instanceOf(evalErrorPrototype); -} - -bool Error::isRangeError(const QScriptValueImpl &value) const -{ - return value.instanceOf(rangeErrorPrototype); -} - -bool Error::isReferenceError(const QScriptValueImpl &value) const -{ - return value.instanceOf(referenceErrorPrototype); -} - -bool Error::isSyntaxError(const QScriptValueImpl &value) const -{ - return value.instanceOf(syntaxErrorPrototype); -} - -bool Error::isTypeError(const QScriptValueImpl &value) const -{ - return value.instanceOf(typeErrorPrototype); -} - -bool Error::isURIError(const QScriptValueImpl &value) const -{ - return value.instanceOf(uriErrorPrototype); -} - -QStringList Error::backtrace(const QScriptValueImpl &error) -{ - QStringList result; - QScriptValueImpl stack = error.property(QLatin1String("stack")); - int frameCount = stack.property(QLatin1String("length")).toInt32(); - for (int i = 0; i < frameCount; ++i) { - QScriptValueImpl o = stack.property(i); - QScriptValueImpl frame = o.property(QLatin1String("frame")); - QString s; - QString functionName = o.property(QLatin1String("functionName")).toString(); - if (functionName.isEmpty()) { - if (i == frameCount-1) - s += QLatin1String("<global>"); - else - s += QLatin1String("<anonymous>"); - } else { - s += functionName; - } - s += QLatin1Char('('); - QScriptValueImpl arguments = frame.property(QLatin1String("arguments")); - if (arguments.isObject()) { - int argCount = arguments.property(QLatin1String("length")).toInt32(); - for (int j = 0; j < argCount; ++j) { - if (j > 0) - s += QLatin1Char(','); - s += arguments.property(j).toString(); - } - } - s += QLatin1String(")@") + o.property(QLatin1String("fileName")).toString() - + QLatin1Char(':') + o.property(QLatin1String("lineNumber")).toString(); - result.append(s); - } - return result; -} - -QScriptValueImpl Error::method_toString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - QScriptValueImpl name = context->thisObject().property(QLatin1String("name"), - QScriptValue::ResolvePrototype); - QScriptValueImpl message = context->thisObject().property(QLatin1String("message"), - QScriptValue::ResolvePrototype); - QString result = QLatin1String(""); - if (name.isValid()) - result = name.toString(); - if (message.isValid()) { - QString str = message.toString(); - if (!str.isEmpty()) { - if (!result.isEmpty()) - result += QLatin1String(": "); - result += str; - } - } - return (QScriptValueImpl(eng, result)); -} - -QScriptValueImpl Error::method_backtrace(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - QScriptValueImpl self = context->thisObject(); - return eng->arrayFromStringList(backtrace(self)); -} - -} } // namespace QSA::Ecma - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptecmaerror_p.h b/src/script/qscriptecmaerror_p.h deleted file mode 100644 index d58f532..0000000 --- a/src/script/qscriptecmaerror_p.h +++ /dev/null @@ -1,121 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTECMAERROR_P_H -#define QSCRIPTECMAERROR_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 "qscriptecmacore_p.h" - -#ifndef QT_NO_SCRIPT - -QT_BEGIN_NAMESPACE - -namespace QScript { namespace Ecma { - -class Error: public Core -{ -public: - Error(QScriptEnginePrivate *engine); - virtual ~Error(); - - virtual void execute(QScriptContextPrivate *context); - - virtual void mark(QScriptEnginePrivate *eng, int generation); - - void newError(QScriptValueImpl *result, const QString &message = QString()); - void newEvalError(QScriptValueImpl *result, const QString &message = QString()); - void newRangeError(QScriptValueImpl *result, const QString &message = QString()); - void newReferenceError(QScriptValueImpl *result, const QString &message = QString()); - void newSyntaxError(QScriptValueImpl *result, const QString &message = QString()); - void newTypeError(QScriptValueImpl *result, const QString &message = QString()); - void newURIError(QScriptValueImpl *result, const QString &message = QString()); - - bool isEvalError(const QScriptValueImpl &value) const; - bool isRangeError(const QScriptValueImpl &value) const; - bool isReferenceError(const QScriptValueImpl &value) const; - bool isSyntaxError(const QScriptValueImpl &value) const; - bool isTypeError(const QScriptValueImpl &value) const; - bool isURIError(const QScriptValueImpl &value) const; - - static QStringList backtrace(const QScriptValueImpl &error); - - QScriptValueImpl evalErrorCtor; - QScriptValueImpl rangeErrorCtor; - QScriptValueImpl referenceErrorCtor; - QScriptValueImpl syntaxErrorCtor; - QScriptValueImpl typeErrorCtor; - QScriptValueImpl uriErrorCtor; - - QScriptValueImpl evalErrorPrototype; - QScriptValueImpl rangeErrorPrototype; - QScriptValueImpl referenceErrorPrototype; - QScriptValueImpl syntaxErrorPrototype; - QScriptValueImpl typeErrorPrototype; - QScriptValueImpl uriErrorPrototype; - -protected: - static QScriptValueImpl method_toString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo); - static QScriptValueImpl method_backtrace(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo); - -private: - void newError(QScriptValueImpl *result, const QScriptValueImpl &proto, - const QString &message = QString()); - void newErrorPrototype(QScriptValueImpl *result, const QScriptValueImpl &proto, - QScriptValueImpl &ztor, const QString &name); -}; - -} } // namespace QScript::Ecma - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT -#endif // QSCRIPTECMAERROR_P_H diff --git a/src/script/qscriptecmafunction.cpp b/src/script/qscriptecmafunction.cpp deleted file mode 100644 index 1604a72..0000000 --- a/src/script/qscriptecmafunction.cpp +++ /dev/null @@ -1,459 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qscriptecmafunction_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptengine_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" - -#include <QtCore/QtDebug> - -#ifndef QT_NO_QOBJECT -# include "qscriptextqobject_p.h" -# include <QtCore/QMetaMethod> -#endif - -QT_BEGIN_NAMESPACE - -namespace QScript { namespace Ecma { - -class FunctionClassData: public QScriptClassData -{ - QScriptClassInfo *m_classInfo; - -public: - FunctionClassData(QScriptClassInfo *classInfo); - virtual ~FunctionClassData(); - - inline QScriptClassInfo *classInfo() const - { return m_classInfo; } - - virtual bool resolve(const QScriptValueImpl &object, - QScriptNameIdImpl *nameId, - QScript::Member *member, QScriptValueImpl *base, - QScript::AccessMode access); - virtual bool get(const QScriptValueImpl &obj, const Member &m, - QScriptValueImpl *out_value); - virtual bool put(QScriptValueImpl *object, const QScript::Member &member, - const QScriptValueImpl &value); - virtual void mark(const QScriptValueImpl &object, int generation); -}; - -FunctionClassData::FunctionClassData(QScriptClassInfo *classInfo) - : m_classInfo(classInfo) -{ -} - -FunctionClassData::~FunctionClassData() -{ -} - -bool FunctionClassData::resolve(const QScriptValueImpl &object, - QScriptNameIdImpl *nameId, - QScript::Member *member, QScriptValueImpl *base, - QScript::AccessMode /*access*/) -{ - if (object.classInfo() != classInfo()) - return false; - - QScriptEnginePrivate *eng = object.engine(); - - if ((nameId == eng->idTable()->id_length) - || (nameId == eng->idTable()->id_arguments)) { - member->native(nameId, /*id=*/ 0, - QScriptValue::Undeletable - | QScriptValue::ReadOnly - | QScriptValue::SkipInEnumeration); - *base = object; - return true; - } - - return false; -} - -bool FunctionClassData::get(const QScriptValueImpl &object, const Member &member, - QScriptValueImpl *result) -{ - if (object.classInfo() != classInfo()) - return false; - - QScriptEnginePrivate *eng = object.engine(); - if (! member.isNativeProperty()) - return false; - - if (member.nameId() == eng->idTable()->id_length) { - *result = QScriptValueImpl(object.toFunction()->length); - return true; - } else if (member.nameId() == eng->idTable()->id_arguments) { - *result = eng->nullValue(); - return true; - } - - return false; -} - -bool FunctionClassData::put(QScriptValueImpl *, const QScript::Member &, - const QScriptValueImpl &) -{ - return false; -} - -void FunctionClassData::mark(const QScriptValueImpl &object, int generation) -{ - if (object.classInfo() != classInfo()) - return; - QScriptFunction *fun = object.toFunction(); - QScriptEnginePrivate *eng = object.engine(); - fun->mark(eng, generation); -} - -Function::Function(QScriptEnginePrivate *eng, QScriptClassInfo *classInfo): - Core(eng, classInfo) -{ - publicPrototype = eng->createFunction(method_void, 0, classInfo); // public prototype -} - -Function::~Function() -{ -} - -void Function::initialize() -{ - QScriptEnginePrivate *eng = engine(); - eng->newConstructor(&ctor, this, publicPrototype); - - addPrototypeFunction(QLatin1String("toString"), method_toString, 1); - addPrototypeFunction(QLatin1String("apply"), method_apply, 2); - addPrototypeFunction(QLatin1String("call"), method_call, 1); - addPrototypeFunction(QLatin1String("connect"), method_connect, 1); - addPrototypeFunction(QLatin1String("disconnect"), method_disconnect, 1); - - classInfo()->setData(new FunctionClassData(classInfo())); -} - -void Function::execute(QScriptContextPrivate *context) -{ -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - engine()->notifyFunctionEntry(context); -#endif - int lineNumber = context->currentLine; - QString contents = buildFunction(context); - engine()->evaluate(context, contents, lineNumber); -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - engine()->notifyFunctionExit(context); -#endif -} - -QString Function::buildFunction(QScriptContextPrivate *context) -{ - int argc = context->argumentCount(); - - QString code; - code += QLatin1String("function("); - - // the formals - for (int i = 0; i < argc - 1; ++i) { - if (i != 0) - code += QLatin1Char(','); - - code += context->argument(i).toString(); - } - - code += QLatin1String("){"); - - // the function body - if (argc != 0) - code += context->argument(argc - 1).toString(); - - code += QLatin1String("\n}"); - - return code; -} - -void Function::newFunction(QScriptValueImpl *result, QScriptFunction *foo) -{ - engine()->newFunction(result, foo); -} - -QScriptValueImpl Function::method_toString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - QScriptValueImpl self = context->thisObject(); - if (QScriptFunction *foo = self.toFunction()) { - QString code = foo->toString(context); - return QScriptValueImpl(eng, code); - } - - return throwThisObjectTypeError( - context, QLatin1String("Function.prototype.toString")); -} - -QScriptValueImpl Function::method_call(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - if (! context->thisObject().isFunction()) { - return throwThisObjectTypeError( - context, QLatin1String("Function.prototype.call")); - } - - QScriptValueImpl thisObject = eng->toObject(context->argument(0)); - if (! (thisObject.isValid () && thisObject.isObject())) - thisObject = eng->globalObject(); - - QScriptValueImplList args; - for (int i = 1; i < context->argumentCount(); ++i) - args << context->argument(i); - - return context->thisObject().call(thisObject, args); -} - -QScriptValueImpl Function::method_apply(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - if (! context->thisObject().isFunction()) { - return throwThisObjectTypeError( - context, QLatin1String("Function.prototype.apply")); - } - - QScriptValueImpl thisObject = eng->toObject(context->argument(0)); - if (! (thisObject.isValid () && thisObject.isObject())) - thisObject = eng->globalObject(); - - QScriptValueImplList args; - QScriptValueImpl undefined = eng->undefinedValue(); - - QScriptValueImpl arg = context->argument(1); - - if (Ecma::Array::Instance *arr = eng->arrayConstructor->get(arg)) { - QScript::Array actuals = arr->value; - - for (quint32 i = 0; i < actuals.count(); ++i) { - QScriptValueImpl a = actuals.at(i); - if (! a.isValid()) - args << undefined; - else - args << a; - } - } else if (arg.classInfo() == eng->m_class_arguments) { - QScript::ArgumentsObjectData *arguments; - arguments = static_cast<QScript::ArgumentsObjectData*> (arg.objectData()); - QScriptObject *activation = arguments->activation.objectValue(); - for (uint i = 0; i < arguments->length; ++i) - args << activation->m_values[i]; - } else if (!(arg.isUndefined() || arg.isNull())) { - return context->throwError(QScriptContext::TypeError, - QLatin1String("Function.prototype.apply: second argument is not an array")); - } - - return context->thisObject().call(thisObject, args); -} - -QScriptValueImpl Function::method_void(QScriptContextPrivate *, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - return eng->undefinedValue(); -} - -QScriptValueImpl Function::method_disconnect(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ -#ifndef QT_NO_QOBJECT - if (context->argumentCount() == 0) { - return context->throwError( - QLatin1String("Function.prototype.disconnect: no arguments given")); - } - - QScriptValueImpl self = context->thisObject(); - QScriptFunction *fun = self.toFunction(); - if ((fun == 0) || (fun->type() != QScriptFunction::Qt)) { - return context->throwError( - QScriptContext::TypeError, - QLatin1String("Function.prototype.disconnect: this object is not a signal")); - } - - QtFunction *qtSignal = static_cast<QtFunction*>(fun); - - const QMetaObject *meta = qtSignal->metaObject(); - if (!meta) { - return context->throwError( - QScriptContext::TypeError, - QString::fromLatin1("Function.prototype.disconnect: cannot disconnect from deleted QObject")); - } - - QMetaMethod sig = meta->method(qtSignal->initialIndex()); - if (sig.methodType() != QMetaMethod::Signal) { - return context->throwError(QScriptContext::TypeError, - QString::fromLatin1("Function.prototype.disconnect: %0::%1 is not a signal") - .arg(QLatin1String(qtSignal->metaObject()->className())) - .arg(QLatin1String(sig.signature()))); - } - - QScriptValueImpl receiver; - QScriptValueImpl slot; - QScriptValueImpl arg0 = context->argument(0); - if (context->argumentCount() < 2) { - receiver = QScriptValueImpl(); - slot = arg0; - } else { - receiver = arg0; - QScriptValueImpl arg1 = context->argument(1); - if (arg1.isFunction()) - slot = arg1; - else - slot = receiver.property(arg1.toString(), QScriptValue::ResolvePrototype); - } - - if (!slot.isFunction()) { - return context->throwError( - QScriptContext::TypeError, - QLatin1String("Function.prototype.disconnect: target is not a function")); - } - - bool ok = eng->scriptDisconnect(self, receiver, slot); - if (!ok) { - return context->throwError( - QString::fromLatin1("Function.prototype.disconnect: failed to disconnect from %0::%1") - .arg(QLatin1String(qtSignal->metaObject()->className())) - .arg(QLatin1String(sig.signature()))); - } - return eng->undefinedValue(); -#else - Q_UNUSED(eng); - return context->throwError(QScriptContext::TypeError, - QLatin1String("Function.prototype.disconnect")); -#endif // QT_NO_QOBJECT -} - -QScriptValueImpl Function::method_connect(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) -{ - Q_UNUSED(classInfo); - -#ifndef QT_NO_QOBJECT - if (context->argumentCount() == 0) { - return context->throwError( - QLatin1String("Function.prototype.connect: no arguments given")); - } - - QScriptValueImpl self = context->thisObject(); - QScriptFunction *fun = self.toFunction(); - if ((fun == 0) || (fun->type() != QScriptFunction::Qt)) { - return context->throwError( - QScriptContext::TypeError, - QLatin1String("Function.prototype.connect: this object is not a signal")); - } - - QtFunction *qtSignal = static_cast<QtFunction*>(fun); - - const QMetaObject *meta = qtSignal->metaObject(); - if (!meta) { - return context->throwError( - QScriptContext::TypeError, - QString::fromLatin1("Function.prototype.connect: cannot connect to deleted QObject")); - } - - QMetaMethod sig = meta->method(qtSignal->initialIndex()); - if (sig.methodType() != QMetaMethod::Signal) { - return context->throwError(QScriptContext::TypeError, - QString::fromLatin1("Function.prototype.connect: %0::%1 is not a signal") - .arg(QLatin1String(qtSignal->metaObject()->className())) - .arg(QLatin1String(sig.signature()))); - } - - { - QList<int> overloads = qtSignal->overloadedIndexes(); - if (!overloads.isEmpty()) { - overloads.append(qtSignal->initialIndex()); - QByteArray signature = sig.signature(); - QString message = QString::fromLatin1("Function.prototype.connect: ambiguous connect to %0::%1(); candidates are\n") - .arg(QLatin1String(qtSignal->metaObject()->className())) - .arg(QLatin1String(signature.left(signature.indexOf('(')))); - for (int i = 0; i < overloads.size(); ++i) { - QMetaMethod mtd = meta->method(overloads.at(i)); - message.append(QString::fromLatin1(" %0\n").arg(QString::fromLatin1(mtd.signature()))); - } - message.append(QString::fromLatin1("Use e.g. object['%0'].connect() to connect to a particular overload") - .arg(QLatin1String(signature))); - return context->throwError(message); - } - } - - QScriptValueImpl receiver; - QScriptValueImpl slot; - QScriptValueImpl arg0 = context->argument(0); - if (context->argumentCount() < 2) { - receiver = QScriptValueImpl(); - slot = arg0; - } else { - receiver = arg0; - QScriptValueImpl arg1 = context->argument(1); - if (arg1.isFunction()) - slot = arg1; - else - slot = receiver.property(arg1.toString(), QScriptValue::ResolvePrototype); - } - - if (!slot.isFunction()) { - return context->throwError( - QScriptContext::TypeError, - QLatin1String("Function.prototype.connect: target is not a function")); - } - - bool ok = eng->scriptConnect(self, receiver, slot, Qt::AutoConnection); - if (!ok) { - return context->throwError( - QString::fromLatin1("Function.prototype.connect: failed to connect to %0::%1") - .arg(QLatin1String(qtSignal->metaObject()->className())) - .arg(QLatin1String(sig.signature()))); - } - return eng->undefinedValue(); -#else - Q_UNUSED(eng); - Q_UNUSED(classInfo); - return context->throwError(QScriptContext::TypeError, - QLatin1String("Function.prototype.connect")); -#endif // QT_NO_QOBJECT -} - -} } // namespace QScript::Ecma - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptecmafunction_p.h b/src/script/qscriptecmafunction_p.h deleted file mode 100644 index 2a016cc..0000000 --- a/src/script/qscriptecmafunction_p.h +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTECMAFUNCTION_P_H -#define QSCRIPTECMAFUNCTION_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 "qscriptecmacore_p.h" - -#ifndef QT_NO_SCRIPT - -QT_BEGIN_NAMESPACE - -namespace QScript { namespace Ecma { - -class Function: public Core -{ -public: - Function(QScriptEnginePrivate *engine, QScriptClassInfo *classInfo); - virtual ~Function(); - - void initialize(); - - virtual void execute(QScriptContextPrivate *context); - - void newFunction(QScriptValueImpl *result, QScriptFunction *foo); - -protected: - QString buildFunction(QScriptContextPrivate *context); - - static QScriptValueImpl method_toString(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_apply(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_call(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_void(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_disconnect(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_connect(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); -}; - -} } // namespace QScript::Ecma - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT - -#endif diff --git a/src/script/qscriptecmaglobal.cpp b/src/script/qscriptecmaglobal.cpp deleted file mode 100644 index 10d3343..0000000 --- a/src/script/qscriptecmaglobal.cpp +++ /dev/null @@ -1,571 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// for strtoll -#include <qplatformdefs.h> - -#ifndef QT_NO_SCRIPT - -#include "qscriptecmaglobal_p.h" -#include "qscriptengine_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" - -#include <QtCore/QVarLengthArray> -#include <QtCore/qnumeric.h> - -QT_BEGIN_NAMESPACE - -extern double qstrtod(const char *s00, char const **se, bool *ok); - -namespace QScript { - -extern qsreal integerFromString(const QString &str, int radix); - -static inline char toHex(char c) -{ - static const char hexnumbers[] = "0123456789ABCDEF"; - return hexnumbers[c & 0xf]; -} - -static int fromHex(char c) -{ - if ((c >= '0') && (c <= '9')) - return c - '0'; - if ((c >= 'A') && (c <= 'F')) - return c - 'A' + 10; - if ((c >= 'a') && (c <= 'f')) - return c - 'a' + 10; - return -1; -} - -static QByteArray escape(const QString &input) -{ - QVarLengthArray<char> output; - output.reserve(input.size() * 3); - const int length = input.length(); - for (int i = 0; i < length; ++i) { - ushort uc = input.at(i).unicode(); - if (uc < 0x100) { - if ( (uc > 0x60 && uc < 0x7B) - || (uc > 0x3F && uc < 0x5B) - || (uc > 0x2C && uc < 0x3A) - || (uc == 0x2A) - || (uc == 0x2B) - || (uc == 0x5F)) { - output.append(char(uc)); - } else { - output.append('%'); - output.append(toHex(uc >> 4)); - output.append(toHex(uc)); - } - } else { - output.append('%'); - output.append('u'); - output.append(toHex(uc >> 12)); - output.append(toHex(uc >> 8)); - output.append(toHex(uc >> 4)); - output.append(toHex(uc)); - } - } - return QByteArray(output.constData(), output.size()); -} - -static QString unescape(const QByteArray &input) -{ - QString result; - int i = 0; - const int length = input.length(); - while (i < length) { - char c = input.at(i++); - if ((c == '%') && (i + 1 < length)) { - char a = input.at(i); - if ((a == 'u') && (i + 4 < length)) { - int d3 = fromHex(input.at(i+1)); - int d2 = fromHex(input.at(i+2)); - int d1 = fromHex(input.at(i+3)); - int d0 = fromHex(input.at(i+4)); - if ((d3 != -1) && (d2 != -1) && (d1 != -1) && (d0 != -1)) { - ushort uc = ushort((d3 << 12) | (d2 << 8) | (d1 << 4) | d0); - result.append(QChar(uc)); - i += 5; - } else { - result.append(QLatin1Char(c)); - } - } else { - int d1 = fromHex(a); - int d0 = fromHex(input.at(i+1)); - if ((d1 != -1) && (d0 != -1)) { - c = (d1 << 4) | d0; - i += 2; - } - result.append(QLatin1Char(c)); - } - } else { - result.append(QLatin1Char(c)); - } - } - return result; -} - -static const char uriReserved[] = ";/?:@&=+$,"; -static const char uriUnescaped[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.!~*'()"; - -static QString encode(const QString &input, const QString &unescapedSet, bool *ok) -{ - QString output; - const int length = input.length(); - int i = 0; - while (i < length) { - const QChar c = input.at(i); - if (!unescapedSet.contains(c)) { - ushort uc = c.unicode(); - if ((uc >= 0xDC00) && (uc <= 0xDFFF)) { - // URIError - break; - } - if (!((uc < 0xD800) || (uc > 0xDBFF))) { - ++i; - if (i == length) { - // URIError - break; - } - const ushort uc2 = input.at(i).unicode(); - if ((uc < 0xDC00) || (uc > 0xDFFF)) { - // URIError - break; - } - uc = ((uc - 0xD800) * 0x400) + (uc2 - 0xDC00) + 0x10000; - } - QString tmp(1, QChar(uc)); - QByteArray octets = tmp.toUtf8(); - for (int j = 0; j < octets.length(); ++j) { - output.append(QLatin1Char('%')); - output.append(QLatin1Char(toHex(octets.at(j) >> 4))); - output.append(QLatin1Char(toHex(octets.at(j)))); - } - } else { - output.append(c); - } - ++i; - } - *ok = (i == length); - return output; -} - -static QString decode(const QString &input, const QString &reservedSet, bool *ok) -{ - QString output; - const int length = input.length(); - int i = 0; - const QChar percent = QLatin1Char('%'); - while (i < length) { - const QChar c = input.at(i); - if (c == percent) { - int start = i; - if (i + 2 >= length) { - // URIError - break; - } - int d1 = fromHex(input.at(i+1).toLatin1()); - int d0 = fromHex(input.at(i+2).toLatin1()); - if ((d1 == -1) || (d0 == -1)) { - // URIError - break; - } - int b = (d1 << 4) | d0; - i += 2; - if (b & 0x80) { - int n = -1; - while ((b << ++n) & 0x80) ; - if ((n == 1) || (n > 4)) { - // URIError - break; - } - QByteArray octets; - octets.append(b); - if (i + (3 * (n - 1)) >= length) { - // URIError - break; - } - for (int j = 1; j < n; ++j) { - ++i; - if (input.at(i) != percent) { - // URIError - break; - } - d1 = fromHex(input.at(i+1).toLatin1()); - d0 = fromHex(input.at(i+2).toLatin1()); - if ((d1 == -1) || (d0 == -1)) { - // URIError - break; - } - b = (d1 << 4) | d0; - if ((b & 0xC0) != 0x80) { - // URIError - break; - } - i += 2; - octets.append(b); - } - QString tmp = QString::fromUtf8(octets); - Q_ASSERT(tmp.length() == 1); - uint v = tmp.at(0).unicode(); // ### need 32-bit value - if (v < 0x10000) { - QChar z = QChar(ushort(v)); - if (!reservedSet.contains(z)) { - output.append(z); - } else { - output.append(input.mid(start, i - start + 1)); - } - } else { - if (v > 0x10FFFF) { - // URIError - break; - } - ushort l = ushort(((v - 0x10000) & 0x3FF) + 0xDC00); - ushort h = ushort((((v - 0x10000) >> 10) & 0x3FF) + 0xD800); - output.append(QChar(l)); - output.append(QChar(h)); - } - } else { - output.append(ushort(b)); - } - } else { - output.append(c); - } - ++i; - } - *ok = (i == length); - return output; -} - -class PrintFunction : public QScriptFunction -{ -public: - PrintFunction() {} - - virtual ~PrintFunction() {} - - virtual void execute(QScriptContextPrivate *context) - { - QScriptEnginePrivate *eng = context->engine(); -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - eng->notifyFunctionEntry(context); -#endif - QString result; - for (int i = 0; i < context->argumentCount(); ++i) { - if (i != 0) - result.append(QLatin1Char(' ')); - - QString s = context->argument(i).toString(); - if (context->state() == QScriptContext::ExceptionState) - break; - result.append(s); - } - - if (context->state() != QScriptContext::ExceptionState) { - qDebug(qPrintable(result)); - context->setReturnValue(eng->undefinedValue()); - } -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - eng->notifyFunctionExit(context); -#endif - } - - QString functionName() const - { - return QLatin1String("print"); - } -}; - -} // anonumous - -namespace QScript { namespace Ecma { - -Global::Global(QScriptEnginePrivate *engine, QScriptClassInfo *classInfo) - : m_engine(engine), m_classInfo(classInfo) -{ -} - -Global::~Global() -{ -} - -void Global::construct(QScriptValueImpl *object, QScriptEnginePrivate *eng) -{ - QScriptClassInfo *classInfo = eng->registerClass(QLatin1String("global"), - QScriptClassInfo::ActivationType); - - // create with prototype null, since Object.prototype doesn't exist at this point - eng->newObject(object, eng->nullValue(), classInfo); - - Global *instance = new Global(eng, classInfo); - object->setObjectData(instance); -} - -void Global::initialize(QScriptValueImpl *object, QScriptEnginePrivate *eng) -{ - // set the real prototype - object->setPrototype(eng->objectConstructor->publicPrototype); - - const QScriptValue::PropertyFlags flags = QScriptValue::Undeletable - | QScriptValue::SkipInEnumeration; - - object->setProperty(QLatin1String("NaN"), QScriptValueImpl(qSNaN()), flags); - object->setProperty(QLatin1String("Infinity"), QScriptValueImpl(qInf()), flags); - object->setProperty(QLatin1String("undefined"), eng->undefinedValue(), flags); - - object->setProperty(QLatin1String("print"), - eng->createFunction(new PrintFunction()), flags); - addFunction(*object, QLatin1String("parseInt"), method_parseInt, 2, flags); - addFunction(*object, QLatin1String("parseFloat"), method_parseFloat, 1, flags); - addFunction(*object, QLatin1String("isNaN"), method_isNaN, 1, flags); - addFunction(*object, QLatin1String("isFinite"), method_isFinite, 1, flags); - addFunction(*object, QLatin1String("decodeURI"), method_decodeURI, 1, flags); - addFunction(*object, QLatin1String("decodeURIComponent"), method_decodeURIComponent, 1, flags); - addFunction(*object, QLatin1String("encodeURI"), method_encodeURI, 1, flags); - addFunction(*object, QLatin1String("encodeURIComponent"), method_encodeURIComponent, 1, flags); - addFunction(*object, QLatin1String("escape"), method_escape, 1, flags); - addFunction(*object, QLatin1String("unescape"), method_unescape, 1, flags); - addFunction(*object, QLatin1String("version"), method_version, 0, flags); - addFunction(*object, QLatin1String("gc"), method_gc, 0, flags); -} - -QScriptValueImpl Global::method_parseInt(QScriptContextPrivate *context, - QScriptEnginePrivate *, - QScriptClassInfo *) -{ - if (context->argumentCount() == 0) - return qSNaN(); - - qsreal radix = 0; - if (context->argumentCount() > 1) { - radix = context->argument(1).toInteger(); - if (qIsNaN(radix) || (radix && (radix < 2 || radix > 36))) { - return qSNaN(); - } - } - - return QScript::integerFromString(context->argument(0).toString(), static_cast<int>(radix)); -} - -QScriptValueImpl Global::method_parseFloat(QScriptContextPrivate *context, - QScriptEnginePrivate *, - QScriptClassInfo *) -{ - if (context->argumentCount() == 0) - return QScriptValueImpl(qSNaN()); - QString str = context->argument(0).toString().trimmed(); - QByteArray latin1 = str.toLatin1(); - const char *data = latin1.constData(); - const char *eptr = 0; - qsreal result = qstrtod(data, &eptr, 0); - if (eptr == data) { - if (str == QLatin1String("Infinity")) - result = +qInf(); - else if (str == QLatin1String("+Infinity")) - result = +qInf(); - else if (str == QLatin1String("-Infinity")) - result = -qInf(); - else - result = qSNaN(); - } - return result; -} - -QScriptValueImpl Global::method_isNaN(QScriptContextPrivate *context, - QScriptEnginePrivate *, - QScriptClassInfo *) -{ - qsreal v = qSNaN(); - if (context->argumentCount() > 0) - v = context->argument(0).toNumber(); - return (QScriptValueImpl(qIsNaN(v))); -} - -QScriptValueImpl Global::method_isFinite(QScriptContextPrivate *context, - QScriptEnginePrivate *, - QScriptClassInfo *) -{ - qsreal v = qInf(); - if (context->argumentCount() > 0) - v = context->argument(0).toNumber(); - return (QScriptValueImpl(qIsFinite(v))); -} - -QScriptValueImpl Global::method_decodeURI(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *) -{ - QScriptValueImpl result; - - if (context->argumentCount() > 0) { - QString str = context->argument(0).toString(); - bool ok; - QString out = decode(str, QString::fromUtf8(uriReserved) + QString::fromUtf8("#"), &ok); - if (ok) - return QScriptValueImpl(eng, out); - else - return context->throwError(QScriptContext::URIError, - QLatin1String("malformed URI sequence")); - } - - return eng->undefinedValue(); -} - -QScriptValueImpl Global::method_decodeURIComponent(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *) -{ - QScriptValueImpl result; - if (context->argumentCount() > 0) { - QString str = context->argument(0).toString(); - bool ok; - QString out = decode(str, QString::fromUtf8(""), &ok); - if (ok) - result = QScriptValueImpl(eng, out); - else - result = context->throwError(QScriptContext::URIError, - QLatin1String("malformed URI sequence")); - } else { - result = eng->undefinedValue(); - } - return result; -} - -QScriptValueImpl Global::method_encodeURI(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *) -{ - QScriptValueImpl result; - if (context->argumentCount() > 0) { - QString str = context->argument(0).toString(); - bool ok; - QString out = encode(str, - QLatin1String(uriReserved) - + QLatin1String(uriUnescaped) - + QString::fromUtf8("#"), - &ok); - if (ok) - result = QScriptValueImpl(eng, out); - else - result = context->throwError(QScriptContext::URIError, - QLatin1String("malformed URI sequence")); - } else { - result = eng->undefinedValue(); - } - return result; -} - -QScriptValueImpl Global::method_encodeURIComponent(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *) -{ - QScriptValueImpl result; - if (context->argumentCount() > 0) { - QString str = context->argument(0).toString(); - bool ok; - QString out = encode(str, QLatin1String(uriUnescaped), &ok); - if (ok) - result = QScriptValueImpl(eng, out); - else - result = context->throwError(QScriptContext::URIError, - QLatin1String("malformed URI sequence")); - } else { - result = eng->undefinedValue(); - } - return result; -} - -QScriptValueImpl Global::method_escape(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *) -{ - if (context->argumentCount() > 0) { - QString str = context->argument(0).toString(); - return QScriptValueImpl(eng, QLatin1String(escape(str))); - } - return QScriptValueImpl(eng, QLatin1String("undefined")); -} - -QScriptValueImpl Global::method_unescape(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *) -{ - if (context->argumentCount() > 0) { - QByteArray data = context->argument(0).toString().toLatin1(); - return QScriptValueImpl(eng, unescape(data)); - } - return QScriptValueImpl(eng, QLatin1String("undefined")); -} - -QScriptValueImpl Global::method_version(QScriptContextPrivate *, - QScriptEnginePrivate *, - QScriptClassInfo *) -{ - return (QScriptValueImpl(1)); -} - -QScriptValueImpl Global::method_gc(QScriptContextPrivate *, - QScriptEnginePrivate *eng, - QScriptClassInfo *) -{ - eng->gc(); - return QScriptValueImpl(eng->objectAllocator.freeBlocks()); -} - -void Global::addFunction(QScriptValueImpl &object, const QString &name, - QScriptInternalFunctionSignature fun, int length, - const QScriptValue::PropertyFlags flags) -{ - QScriptEnginePrivate *eng_p = object.engine(); - QScriptValueImpl val = eng_p->createFunction(fun, length, object.classInfo(), name); - object.setProperty(name, val, flags); -} - -} } // namespace QScript::Ecma - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptecmaglobal_p.h b/src/script/qscriptecmaglobal_p.h deleted file mode 100644 index 8d3316d..0000000 --- a/src/script/qscriptecmaglobal_p.h +++ /dev/null @@ -1,141 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTECMAGLOBAL_P_H -#define QSCRIPTECMAGLOBAL_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 "qscriptobjectdata_p.h" -#include "qscriptfunction_p.h" -#include "qscriptvalue.h" - -QT_BEGIN_NAMESPACE - -class QScriptEnginePrivate; -class QScriptContextPrivate; -class QScriptClassInfo; -class QScriptValueImpl; - -#ifndef QT_NO_SCRIPT - -namespace QScript { namespace Ecma { - -class Global: public QScriptObjectData -{ -protected: - Global(QScriptEnginePrivate *engine, QScriptClassInfo *classInfo); - -public: - virtual ~Global(); - - inline QScriptEnginePrivate *engine() const; - - static void construct(QScriptValueImpl *object, QScriptEnginePrivate *eng); - static void initialize(QScriptValueImpl *object, QScriptEnginePrivate *eng); - -protected: - static QScriptValueImpl method_parseInt(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_parseFloat(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_isNaN(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_isFinite(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_decodeURI(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_decodeURIComponent(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_encodeURI(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_encodeURIComponent(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_escape(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_unescape(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_version(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_gc(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - -private: - static void addFunction(QScriptValueImpl &object, const QString &name, - QScriptInternalFunctionSignature fun, int length, - const QScriptValue::PropertyFlags flags); - - QScriptEnginePrivate *m_engine; - QScriptClassInfo *m_classInfo; -}; - -inline QScriptEnginePrivate *Global::engine() const -{ return m_engine; } - - -} } // namespace QScript::Ecma - -#endif // QT_NO_SCRIPT - -QT_END_NAMESPACE - -#endif diff --git a/src/script/qscriptecmamath.cpp b/src/script/qscriptecmamath.cpp deleted file mode 100644 index 2e137de..0000000 --- a/src/script/qscriptecmamath.cpp +++ /dev/null @@ -1,391 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qscriptecmamath_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptengine_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" - -#include <QtCore/QtDebug> -#include <QtCore/qnumeric.h> -#include <QtCore/QSysInfo> -#include <math.h> - -QT_BEGIN_NAMESPACE - -namespace QScript { namespace Ecma { - -static const qsreal qt_PI = 2.0 * ::asin(1.0); - -Math::Math(QScriptEnginePrivate *engine, QScriptClassInfo *classInfo): - m_engine(engine), - m_classInfo(classInfo) -{ -} - -Math::~Math() -{ -} - -void Math::construct(QScriptValueImpl *object, QScriptEnginePrivate *eng) -{ - QScriptClassInfo *classInfo = eng->registerClass(QLatin1String("Math")); - - Math *instance = new Math(eng, classInfo); - eng->newObject(object, classInfo); - object->setObjectData(instance); - - QScriptValue::PropertyFlags flags = QScriptValue::Undeletable - | QScriptValue::ReadOnly - | QScriptValue::SkipInEnumeration; - - object->setProperty(QLatin1String("E"), - QScriptValueImpl(::exp(1.0)), flags); - object->setProperty(QLatin1String("LN2"), - QScriptValueImpl(::log(2.0)), flags); - object->setProperty(QLatin1String("LN10"), - QScriptValueImpl(::log(10.0)), flags); - object->setProperty(QLatin1String("LOG2E"), - QScriptValueImpl(1.0/::log(2.0)), flags); - object->setProperty(QLatin1String("LOG10E"), - QScriptValueImpl(1.0/::log(10.0)), flags); - object->setProperty(QLatin1String("PI"), - QScriptValueImpl(qt_PI), flags); - object->setProperty(QLatin1String("SQRT1_2"), - QScriptValueImpl(::sqrt(0.5)), flags); - object->setProperty(QLatin1String("SQRT2"), - QScriptValueImpl(::sqrt(2.0)), flags); - - flags = QScriptValue::SkipInEnumeration; - addFunction(*object, QLatin1String("abs"), method_abs, 1, flags); - addFunction(*object, QLatin1String("acos"), method_acos, 1, flags); - addFunction(*object, QLatin1String("asin"), method_asin, 0, flags); - addFunction(*object, QLatin1String("atan"), method_atan, 1, flags); - addFunction(*object, QLatin1String("atan2"), method_atan2, 2, flags); - addFunction(*object, QLatin1String("ceil"), method_ceil, 1, flags); - addFunction(*object, QLatin1String("cos"), method_cos, 1, flags); - addFunction(*object, QLatin1String("exp"), method_exp, 1, flags); - addFunction(*object, QLatin1String("floor"), method_floor, 1, flags); - addFunction(*object, QLatin1String("log"), method_log, 1, flags); - addFunction(*object, QLatin1String("max"), method_max, 2, flags); - addFunction(*object, QLatin1String("min"), method_min, 2, flags); - addFunction(*object, QLatin1String("pow"), method_pow, 2, flags); - addFunction(*object, QLatin1String("random"), method_random, 0, flags); - addFunction(*object, QLatin1String("round"), method_round, 1, flags); - addFunction(*object, QLatin1String("sin"), method_sin, 1, flags); - addFunction(*object, QLatin1String("sqrt"), method_sqrt, 1, flags); - addFunction(*object, QLatin1String("tan"), method_tan, 1, flags); -} - -/* copies the sign from y to x and returns the result */ -static qsreal copySign(qsreal x, qsreal y) -{ - uchar *xch = (uchar *)&x; - uchar *ych = (uchar *)&y; - if (QSysInfo::ByteOrder == QSysInfo::BigEndian) - xch[0] = (xch[0] & 0x7f) | (ych[0] & 0x80); - else - xch[7] = (xch[7] & 0x7f) | (ych[7] & 0x80); - return x; -} - -QScriptValueImpl Math::method_abs(QScriptContextPrivate *context, - QScriptEnginePrivate *, - QScriptClassInfo *) -{ - qsreal v = context->argument(0).toNumber(); - if (v == 0) // 0 | -0 - return (QScriptValueImpl(0)); - else - return (QScriptValueImpl(v < 0 ? -v : v)); -} - -QScriptValueImpl Math::method_acos(QScriptContextPrivate *context, - QScriptEnginePrivate *, - QScriptClassInfo *) -{ - qsreal v = context->argument(0).toNumber(); - if (v > 1) - return QScriptValueImpl(qSNaN()); - return (QScriptValueImpl(::acos(v))); -} - -QScriptValueImpl Math::method_asin(QScriptContextPrivate *context, - QScriptEnginePrivate *, - QScriptClassInfo *) -{ - qsreal v = context->argument(0).toNumber(); - if (v > 1) - return QScriptValueImpl(qSNaN()); - return (QScriptValueImpl(::asin(v))); -} - -QScriptValueImpl Math::method_atan(QScriptContextPrivate *context, - QScriptEnginePrivate *, - QScriptClassInfo *) -{ - qsreal v = context->argument(0).toNumber(); - if (v == 0.0) - return QScriptValueImpl(v); - return (QScriptValueImpl(::atan(v))); -} - -QScriptValueImpl Math::method_atan2(QScriptContextPrivate *context, - QScriptEnginePrivate *, - QScriptClassInfo *) -{ - qsreal v1 = context->argument(0).toNumber(); - qsreal v2 = context->argument(1).toNumber(); -#ifdef Q_OS_WINCE - if (v1 == 0.0) { - const bool v1MinusZero = _copysign(1.0, v1) < 0.0; - const bool v2MinusZero = (v2 == 0 && _copysign(1.0, v2) < 0.0); - if ((v1MinusZero && v2MinusZero) || (v1MinusZero && v2 == -1.0)) - return QScriptValueImpl(-qt_PI); - if (v2MinusZero) - return QScriptValueImpl(qt_PI); - if (v1MinusZero && v2 == 1.0) - return QScriptValueImpl(-0.0); -#if defined(_X86_) - if (v2 == 0.0 && (v1MinusZero || (!v1MinusZero && !v2MinusZero))) - return QScriptValueImpl(0.0); -#endif - } -#endif -#if defined(Q_OS_WINCE) && defined(_X86_) - if (v1 == -1.0 && !_finite(v2) && _copysign(1.0, v2) > 0.0) - return QScriptValueImpl(-0.0); -#endif - if ((v1 < 0) && qIsFinite(v1) && qIsInf(v2) && (copySign(1.0, v2) == 1.0)) - return QScriptValueImpl(copySign(0, -1.0)); - if ((v1 == 0.0) && (v2 == 0.0)) { - if ((copySign(1.0, v1) == 1.0) && (copySign(1.0, v2) == -1.0)) - return QScriptValueImpl(qt_PI); - else if ((copySign(1.0, v1) == -1.0) && (copySign(1.0, v2) == -1.0)) - return QScriptValueImpl(-qt_PI); - } - return (QScriptValueImpl(::atan2(v1, v2))); -} - -QScriptValueImpl Math::method_ceil(QScriptContextPrivate *context, - QScriptEnginePrivate *, - QScriptClassInfo *) -{ - qsreal v = context->argument(0).toNumber(); - if (v < 0.0 && v > -1.0) - return QScriptValueImpl(copySign(0, -1.0)); - return (QScriptValueImpl(::ceil(v))); -} - -QScriptValueImpl Math::method_cos(QScriptContextPrivate *context, - QScriptEnginePrivate *, - QScriptClassInfo *) -{ - qsreal v = context->argument(0).toNumber(); - return (QScriptValueImpl(::cos(v))); -} - -QScriptValueImpl Math::method_exp(QScriptContextPrivate *context, - QScriptEnginePrivate *, - QScriptClassInfo *) -{ - qsreal v = context->argument(0).toNumber(); - if (qIsInf(v)) { - if (copySign(1.0, v) == -1.0) - return QScriptValueImpl(0); - else - return QScriptValueImpl(qInf()); - } - return (QScriptValueImpl(::exp(v))); -} - -QScriptValueImpl Math::method_floor(QScriptContextPrivate *context, - QScriptEnginePrivate *, - QScriptClassInfo *) -{ - qsreal v = context->argument(0).toNumber(); - return (QScriptValueImpl(::floor(v))); -} - -QScriptValueImpl Math::method_log(QScriptContextPrivate *context, - QScriptEnginePrivate *, - QScriptClassInfo *) -{ - qsreal v = context->argument(0).toNumber(); - if (v < 0) - return QScriptValueImpl(qSNaN()); - return (QScriptValueImpl(::log(v))); -} - -QScriptValueImpl Math::method_max(QScriptContextPrivate *context, - QScriptEnginePrivate *, - QScriptClassInfo *) -{ - qsreal mx = -qInf(); - for (int i = 0; i < context->argumentCount(); ++i) { - qsreal x = context->argument(i).toNumber(); - if (x > mx || qIsNaN(x)) - mx = x; - } - return (QScriptValueImpl(mx)); -} - -QScriptValueImpl Math::method_min(QScriptContextPrivate *context, - QScriptEnginePrivate *, - QScriptClassInfo *) -{ - qsreal mx = qInf(); - for (int i = 0; i < context->argumentCount(); ++i) { - qsreal x = context->argument(i).toNumber(); - if ((x == 0 && mx == x && copySign(1.0, x) == -1.0) - || (x < mx) || qIsNaN(x)) { - mx = x; - } - } - return (QScriptValueImpl(mx)); -} - -QScriptValueImpl Math::method_pow(QScriptContextPrivate *context, - QScriptEnginePrivate *, - QScriptClassInfo *) -{ - qsreal x = context->argument(0).toNumber(); - qsreal y = context->argument(1).toNumber(); - if (qIsNaN(y)) - return QScriptValueImpl(qSNaN()); - if (y == 0) - return QScriptValueImpl(1); - if (((x == 1) || (x == -1)) && qIsInf(y)) - return QScriptValueImpl(qSNaN()); - if (((x == 0) && copySign(1.0, x) == 1.0) && (y < 0)) - return QScriptValueImpl(qInf()); - if ((x == 0) && copySign(1.0, x) == -1.0) { - if (y < 0) { - if (::fmod(-y, 2.0) == 1.0) - return QScriptValueImpl(-qInf()); - else - return QScriptValueImpl(qInf()); - } else if (y > 0) { - if (::fmod(y, 2.0) == 1.0) - return QScriptValueImpl(copySign(0, -1.0)); - else - return QScriptValueImpl(0); - } - } -#ifdef Q_OS_AIX - if (qIsInf(x) && copySign(1.0, x) == -1.0) { - if (y > 0) { - if (::fmod(y, 2.0) == 1.0) - return QScriptValueImpl(-qInf()); - else - return QScriptValueImpl(qInf()); - } else if (y < 0) { - if (::fmod(-y, 2.0) == 1.0) - return QScriptValueImpl(copySign(0, -1.0)); - else - return QScriptValueImpl(0); - } - } -#endif - return (QScriptValueImpl(::pow(x, y))); -} - -QScriptValueImpl Math::method_random(QScriptContextPrivate *, - QScriptEnginePrivate *, - QScriptClassInfo *) -{ - return (QScriptValueImpl(qrand() / (qsreal) RAND_MAX)); -} - -QScriptValueImpl Math::method_round(QScriptContextPrivate *context, - QScriptEnginePrivate *, - QScriptClassInfo *) -{ - qsreal v = context->argument(0).toNumber(); - v = copySign(::floor(v + 0.5), v); - return (QScriptValueImpl(v)); -} - -QScriptValueImpl Math::method_sin(QScriptContextPrivate *context, - QScriptEnginePrivate *, - QScriptClassInfo *) -{ - qsreal v = context->argument(0).toNumber(); - return (QScriptValueImpl(::sin(v))); -} - -QScriptValueImpl Math::method_sqrt(QScriptContextPrivate *context, - QScriptEnginePrivate *, - QScriptClassInfo *) -{ - qsreal v = context->argument(0).toNumber(); - return (QScriptValueImpl(::sqrt(v))); -} - -QScriptValueImpl Math::method_tan(QScriptContextPrivate *context, - QScriptEnginePrivate *, - QScriptClassInfo *) -{ - qsreal v = context->argument(0).toNumber(); - if (v == 0.0) - return QScriptValueImpl(v); - return (QScriptValueImpl(::tan(v))); -} - -void Math::addFunction(QScriptValueImpl &object, const QString &name, - QScriptInternalFunctionSignature fun, int length, - const QScriptValue::PropertyFlags flags) -{ - QScriptEnginePrivate *eng_p = object.engine(); - QScriptValueImpl val = eng_p->createFunction(fun, length, object.classInfo(), name); - object.setProperty(name, val, flags); -} - -} } // namespace QScript::Ecma - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptecmamath_p.h b/src/script/qscriptecmamath_p.h deleted file mode 100644 index 029fb91..0000000 --- a/src/script/qscriptecmamath_p.h +++ /dev/null @@ -1,158 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTECMAMATH_P_H -#define QSCRIPTECMAMATH_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 "qscriptobjectdata_p.h" -#include "qscriptfunction_p.h" -#include "qscriptvalue.h" - -QT_BEGIN_NAMESPACE - -class QScriptEnginePrivate; -class QScriptContextPrivate; -class QScriptClassInfo; -class QScriptValueImpl; - -#ifndef QT_NO_SCRIPT - -namespace QScript { namespace Ecma { - -class Math: public QScriptObjectData -{ -protected: - Math(QScriptEnginePrivate *engine, QScriptClassInfo *classInfo); - -public: - virtual ~Math(); - - static void construct(QScriptValueImpl *object, QScriptEnginePrivate *eng); - - inline QScriptEnginePrivate *engine() const; - -protected: - static QScriptValueImpl method_abs(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_acos(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_asin(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_atan(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_atan2(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_ceil(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_cos(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_exp(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_floor(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_log(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_max(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_min(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_pow(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_random(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_round(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_sin(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_sqrt(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_tan(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - -private: - static void addFunction(QScriptValueImpl &object, const QString &name, - QScriptInternalFunctionSignature fun, int length, - const QScriptValue::PropertyFlags flags); - - QScriptEnginePrivate *m_engine; - QScriptClassInfo *m_classInfo; -}; - -inline QScriptEnginePrivate *Math::engine() const -{ return m_engine; } - - -} } // namespace QScript::Ecma - -#endif // QT_NO_SCRIPT - -QT_END_NAMESPACE - -#endif diff --git a/src/script/qscriptecmanumber.cpp b/src/script/qscriptecmanumber.cpp deleted file mode 100644 index 59e84d4..0000000 --- a/src/script/qscriptecmanumber.cpp +++ /dev/null @@ -1,268 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qscriptecmanumber_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptengine_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" - -#include <QtCore/QtDebug> -#include <QtCore/qnumeric.h> -#include <math.h> - -QT_BEGIN_NAMESPACE - -namespace QScript { namespace Ecma { - -Number::Number(QScriptEnginePrivate *eng): - Core(eng, QLatin1String("Number"), QScriptClassInfo::NumberType) -{ - newNumber(&publicPrototype, 0); - - eng->newConstructor(&ctor, this, publicPrototype); - - addPrototypeFunction(QLatin1String("toString"), method_toString, 0); - addPrototypeFunction(QLatin1String("toLocaleString"), method_toLocaleString, 0); - addPrototypeFunction(QLatin1String("valueOf"), method_valueOf, 0); - addPrototypeFunction(QLatin1String("toFixed"), method_toFixed, 1); - addPrototypeFunction(QLatin1String("toExponential"), method_toExponential, 1); - addPrototypeFunction(QLatin1String("toPrecision"), method_toPrecision, 1); - - QScriptValue::PropertyFlags flags = QScriptValue::Undeletable - | QScriptValue::ReadOnly - | QScriptValue::SkipInEnumeration; - ctor.setProperty(QLatin1String("NaN"), - QScriptValueImpl(qSNaN()), flags); - ctor.setProperty(QLatin1String("NEGATIVE_INFINITY"), - QScriptValueImpl(-qInf()), flags); - ctor.setProperty(QLatin1String("POSITIVE_INFINITY"), - QScriptValueImpl(qInf()), flags); - ctor.setProperty(QLatin1String("MAX_VALUE"), - QScriptValueImpl(1.7976931348623158e+308), flags); -#ifdef __INTEL_COMPILER -# pragma warning( push ) -# pragma warning(disable: 239) -#endif - ctor.setProperty(QLatin1String("MIN_VALUE"), - QScriptValueImpl(5e-324), flags); -#ifdef __INTEL_COMPILER -# pragma warning( pop ) -#endif -} - -Number::~Number() -{ -} - -void Number::execute(QScriptContextPrivate *context) -{ -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - engine()->notifyFunctionEntry(context); -#endif - qsreal value; - if (context->argumentCount() > 0) - value = context->argument(0).toNumber(); - else - value = 0; - - QScriptValueImpl num(value); - if (!context->isCalledAsConstructor()) { - context->setReturnValue(num); - } else { - QScriptValueImpl &obj = context->m_thisObject; - obj.setClassInfo(classInfo()); - obj.setInternalValue(num); - obj.setPrototype(publicPrototype); - context->setReturnValue(obj); - } -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - engine()->notifyFunctionExit(context); -#endif -} - -void Number::newNumber(QScriptValueImpl *result, qsreal value) -{ - engine()->newObject(result, publicPrototype, classInfo()); - result->setInternalValue(QScriptValueImpl(value)); -} - -QScriptValueImpl Number::method_toString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() != classInfo) { - return throwThisObjectTypeError( - context, QLatin1String("Number.prototype.toString")); - } - QScriptValueImpl arg = context->argument(0); - if (!arg.isUndefined()) { - int radix = arg.toInt32(); - if (radix < 2 || radix > 36) - return context->throwError(QString::fromLatin1("Number.prototype.toString: %0 is not a valid radix") - .arg(radix)); - if (radix != 10) { - QString str; - qsreal num = self.internalValue().toNumber(); - if (qIsNaN(num)) - return QScriptValueImpl(eng, QLatin1String("NaN")); - else if (qIsInf(num)) - return QScriptValueImpl(eng, QLatin1String(num < 0 ? "-Infinity" : "Infinity")); - bool negative = false; - if (num < 0) { - negative = true; - num = -num; - } - qsreal frac = num - ::floor(num); - num = QScriptEnginePrivate::toInteger(num); - do { - char c = (char)::fmod(num, radix); - c = (c < 10) ? (c + '0') : (c - 10 + 'a'); - str.prepend(QLatin1Char(c)); - num = ::floor(num / radix); - } while (num != 0); - if (frac != 0) { - str.append(QLatin1Char('.')); - do { - frac = frac * radix; - char c = (char)::floor(frac); - c = (c < 10) ? (c + '0') : (c - 10 + 'a'); - str.append(QLatin1Char(c)); - frac = frac - ::floor(frac); - } while (frac != 0); - } - if (negative) - str.prepend(QLatin1Char('-')); - return QScriptValueImpl(eng, str); - } - } - QString str = self.internalValue().toString(); - return (QScriptValueImpl(eng, str)); -} - -QScriptValueImpl Number::method_toLocaleString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() != classInfo) { - return throwThisObjectTypeError( - context, QLatin1String("Number.prototype.toLocaleString")); - } - QString str = self.internalValue().toString(); - return (QScriptValueImpl(eng, str)); -} - -QScriptValueImpl Number::method_valueOf(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() != classInfo) { - return throwThisObjectTypeError( - context, QLatin1String("Number.prototype.valueOf")); - } - return (self.internalValue()); -} - -QScriptValueImpl Number::method_toFixed(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() != classInfo) { - return throwThisObjectTypeError( - context, QLatin1String("Number.prototype.toFixed")); - } - qsreal fdigits = 0; - - if (context->argumentCount() > 0) - fdigits = context->argument(0).toInteger(); - - if (qIsNaN(fdigits)) - fdigits = 0; - - qsreal v = self.internalValue().toNumber(); - QString str; - if (qIsNaN(v)) - str = QString::fromLatin1("NaN"); - else if (qIsInf(v)) - str = QString::fromLatin1(v < 0 ? "-Infinity" : "Infinity"); - else - str = QString::number(v, 'f', int (fdigits)); - return (QScriptValueImpl(eng, str)); -} - -QScriptValueImpl Number::method_toExponential(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() != classInfo) { - return throwThisObjectTypeError( - context, QLatin1String("Number.prototype.toExponential")); - } - qsreal fdigits = 0; - - if (context->argumentCount() > 0) - fdigits = context->argument(0).toInteger(); - - qsreal v = self.internalValue().toNumber(); - QString z = QString::number(v, 'e', int (fdigits)); - return (QScriptValueImpl(eng, z)); -} - -QScriptValueImpl Number::method_toPrecision(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() != classInfo) { - return throwThisObjectTypeError( - context, QLatin1String("Number.prototype.toPrecision")); - } - qsreal fdigits = 0; - - if (context->argumentCount() > 0) - fdigits = context->argument(0).toInteger(); - - qsreal v = self.internalValue().toNumber(); - return (QScriptValueImpl(eng, QString::number(v, 'g', int (fdigits)))); -} - -} } // namespace QScript::Ecma - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptecmanumber_p.h b/src/script/qscriptecmanumber_p.h deleted file mode 100644 index 5ba6039..0000000 --- a/src/script/qscriptecmanumber_p.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTECMANUMBER_P_H -#define QSCRIPTECMANUMBER_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 "qscriptecmacore_p.h" - -#ifndef QT_NO_SCRIPT - -QT_BEGIN_NAMESPACE - -namespace QScript { namespace Ecma { - -class Number: public Core -{ -public: - Number(QScriptEnginePrivate *engine); - virtual ~Number(); - - virtual void execute(QScriptContextPrivate *context); - - void newNumber(QScriptValueImpl *result, double value = 0); - -protected: - static QScriptValueImpl method_toString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo); - static QScriptValueImpl method_toLocaleString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo); - static QScriptValueImpl method_valueOf(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo); - static QScriptValueImpl method_toFixed(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo); - static QScriptValueImpl method_toExponential(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo); - static QScriptValueImpl method_toPrecision(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo); -}; - -} } // namespace QScript::Ecma - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT - -#endif diff --git a/src/script/qscriptecmaobject.cpp b/src/script/qscriptecmaobject.cpp deleted file mode 100644 index fb6da16..0000000 --- a/src/script/qscriptecmaobject.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qscriptecmaobject_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptengine_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" - -#include <QtCore/QtDebug> - -QT_BEGIN_NAMESPACE - -namespace QScript { namespace Ecma { - -Object::Object(QScriptEnginePrivate *eng, QScriptClassInfo *classInfo): - Core(eng, classInfo) -{ - newObject(&publicPrototype, eng->nullValue()); -} - -Object::~Object() -{ -} - -void Object::initialize() -{ - QScriptEnginePrivate *eng = engine(); - - eng->newConstructor(&ctor, this, publicPrototype); - - addPrototypeFunction(QLatin1String("toString"), method_toString, 1); - addPrototypeFunction(QLatin1String("toLocaleString"), method_toLocaleString, 1); - addPrototypeFunction(QLatin1String("valueOf"), method_valueOf, 0); - addPrototypeFunction(QLatin1String("hasOwnProperty"), method_hasOwnProperty, 1); - addPrototypeFunction(QLatin1String("isPrototypeOf"), method_isPrototypeOf, 1); - addPrototypeFunction(QLatin1String("propertyIsEnumerable"), method_propertyIsEnumerable, 1); - addPrototypeFunction(QLatin1String("__defineGetter__"), method_defineGetter, 2); - addPrototypeFunction(QLatin1String("__defineSetter__"), method_defineSetter, 2); -} - -void Object::execute(QScriptContextPrivate *context) -{ -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - engine()->notifyFunctionEntry(context); -#endif - QScriptValueImpl value; - - if (context->argumentCount() > 0) - value = engine()->toObject(context->argument(0)); - else - value.invalidate(); - - if (! value.isValid()) - newObject(&value); - - context->setReturnValue(value); -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - engine()->notifyFunctionExit(context); -#endif -} - -void Object::newObject(QScriptValueImpl *result, const QScriptValueImpl &proto) -{ - engine()->newObject(result, proto, classInfo()); -} - -QScriptValueImpl Object::method_toString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - QScriptValueImpl glo = eng->globalObject(); - QString s = QLatin1String("[object "); - QScriptValueImpl self = context->thisObject(); - s += self.classInfo()->name(); - s += QLatin1Char(']'); - return (QScriptValueImpl(eng, s)); -} - -QScriptValueImpl Object::method_toLocaleString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) -{ - return method_toString(context, eng, classInfo); -} - -QScriptValueImpl Object::method_valueOf(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *) -{ - return (context->thisObject()); -} - -QScriptValueImpl Object::method_hasOwnProperty(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - bool result = false; - - if (context->thisObject().isObject() && (context->argumentCount() > 0)) { - QScriptValueImpl arg = context->argument(0); - - QScriptNameIdImpl *id = 0; - if (arg.isString()) - id = arg.stringValue(); - - if (! id || ! id->unique) { - QString str = arg.toString(); - id = eng->nameId(str); - } - - QScript::Member member; - QScriptValueImpl base; - QScriptValueImpl self = context->thisObject(); - if (self.resolve(id, &member, &base, QScriptValue::ResolveLocal, QScript::Read)) - result = true; - } - - return (QScriptValueImpl(result)); -} - -QScriptValueImpl Object::method_isPrototypeOf(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *) -{ - bool result = false; - - if (context->thisObject().isObject() && (context->argumentCount() > 0)) { - QScriptValueImpl arg = context->argument(0); - - if (arg.isObject()) { - QScriptValueImpl proto = arg.prototype(); - - if (proto.isObject()) { - QScriptValueImpl self = context->thisObject(); - result = self.objectValue() == proto.objectValue(); - } - } - } - - return (QScriptValueImpl(result)); -} - -QScriptValueImpl Object::method_propertyIsEnumerable(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - bool result = false; - - if (context->thisObject().isObject() && (context->argumentCount() > 0)) { - QScriptValueImpl arg = context->argument(0); - - QScriptNameIdImpl *id = 0; - if (arg.isString()) - id = arg.stringValue(); - - if (! id || ! id->unique) { - QString str = arg.toString(); - id = eng->nameId(str); - } - - QScript::Member member; - QScriptValueImpl base; - QScriptValueImpl self = context->thisObject(); - if (self.resolve(id, &member, &base, QScriptValue::ResolveLocal, QScript::Read)) { - result = ! member.dontEnum(); - if (result) { - QScriptValueImpl tmp; - base.get(member, &tmp); - result = tmp.isValid(); - } - } - } - - return (QScriptValueImpl(result)); -} - -QScriptValueImpl Object::method_defineGetter(QScriptContextPrivate *context, QScriptEnginePrivate *eng, - QScriptClassInfo *) -{ - QString propertyName = context->argument(0).toString(); - if (context->thisObject().propertyFlags(propertyName) & QScriptValue::ReadOnly) - return context->throwError(QLatin1String("cannot redefine read-only property")); - QScriptValueImpl getter = context->argument(1); - if (!getter.isFunction()) - return context->throwError(QLatin1String("getter must be a function")); - context->thisObject().setProperty(propertyName, getter, QScriptValue::PropertyGetter); - return eng->undefinedValue(); -} - -QScriptValueImpl Object::method_defineSetter(QScriptContextPrivate *context, QScriptEnginePrivate *eng, - QScriptClassInfo *) -{ - QString propertyName = context->argument(0).toString(); - if (context->thisObject().propertyFlags(propertyName) & QScriptValue::ReadOnly) - return context->throwError(QLatin1String("cannot redefine read-only property")); - QScriptValueImpl setter = context->argument(1); - if (!setter.isFunction()) - return context->throwError(QLatin1String("setter must be a function")); - context->thisObject().setProperty(propertyName, setter, QScriptValue::PropertySetter); - return eng->undefinedValue(); -} - -} } // namespace QScript::Ecma - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptecmaobject_p.h b/src/script/qscriptecmaobject_p.h deleted file mode 100644 index 56d2cea..0000000 --- a/src/script/qscriptecmaobject_p.h +++ /dev/null @@ -1,109 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTECMAOBJECT_P_H -#define QSCRIPTECMAOBJECT_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 "qscriptecmacore_p.h" - -#ifndef QT_NO_SCRIPT - -QT_BEGIN_NAMESPACE - -namespace QScript { namespace Ecma { - -class Object: public Core -{ -public: - Object(QScriptEnginePrivate *engine, QScriptClassInfo *classInfo); - virtual ~Object(); - - void initialize(); - - virtual void execute(QScriptContextPrivate *context); - - void newObject(QScriptValueImpl *result, const QScriptValueImpl &proto = QScriptValueImpl()); - -protected: - static QScriptValueImpl method_toString(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_toLocaleString(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_valueOf(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_hasOwnProperty(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_isPrototypeOf(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_propertyIsEnumerable(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_defineGetter(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_defineSetter(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); -}; - -} } // namespace QScript::Ecma - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT - -#endif diff --git a/src/script/qscriptecmaregexp.cpp b/src/script/qscriptecmaregexp.cpp deleted file mode 100644 index 8a40e8b..0000000 --- a/src/script/qscriptecmaregexp.cpp +++ /dev/null @@ -1,339 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qscriptecmaregexp_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptengine_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" - -#include <QtCore/QStringList> -#include <QtCore/QRegExp> -#include <QtCore/QtDebug> - -QT_BEGIN_NAMESPACE - -namespace QScript { namespace Ecma { - -RegExp::RegExp(QScriptEnginePrivate *eng): - Core(eng, QLatin1String("RegExp"), QScriptClassInfo::RegExpType) -{ - newRegExp(&publicPrototype, QString(), /*flags=*/0); - - eng->newConstructor(&ctor, this, publicPrototype); - - addPrototypeFunction(QLatin1String("exec"), method_exec, 1); - addPrototypeFunction(QLatin1String("test"), method_test, 1); - addPrototypeFunction(QLatin1String("toString"), method_toString, 1); -} - -RegExp::~RegExp() -{ -} - -RegExp::Instance *RegExp::Instance::get(const QScriptValueImpl &object, QScriptClassInfo *klass) -{ - if (! klass || klass == object.classInfo()) - return static_cast<Instance*> (object.objectData()); - - return 0; -} - -void RegExp::execute(QScriptContextPrivate *context) -{ -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - engine()->notifyFunctionEntry(context); -#endif - QString P; - int F; - QScriptValueImpl pattern = context->argument(0); - QScriptValueImpl flags = context->argument(1); - if (!context->isCalledAsConstructor()) { - if ((pattern.classInfo() == classInfo()) && flags.isUndefined()) { - context->m_result = pattern; - goto Lout; - } - } - if (pattern.classInfo() == classInfo()) { - if (!flags.isUndefined()) { - context->throwTypeError(QString::fromLatin1("cannot specify flags when creating a copy of a RegExp")); - goto Lout; - } - Instance *data = Instance::get(pattern, classInfo()); -#ifndef QT_NO_REGEXP - P = data->value.pattern(); -#else - P = data->pattern; -#endif - F = data->flags; - } else { - if (!pattern.isUndefined()) - P = pattern.toString(); - F = 0; - if (!flags.isUndefined()) { - QString flagsStr = flags.toString(); - for (int i = 0; i < flagsStr.length(); ++i) { - int bitflag = flagFromChar(flagsStr.at(i)); - if (bitflag == 0) { - context->throwError( - QScriptContext::SyntaxError, - QString::fromUtf8("invalid regular expression flag '%0'") - .arg(flagsStr.at(i))); - goto Lout; - } - F |= bitflag; - } - } - } - if (context->isCalledAsConstructor()) { - QScriptValueImpl &object = context->m_thisObject; - object.setClassInfo(classInfo()); - object.setPrototype(publicPrototype); -#ifndef QT_NO_REGEXP - initRegExp(&object, toRegExp(P, F), F); -#else - initRegExp(&object, P, F); -#endif - } else { - newRegExp(&context->m_result, P, F); - } - Lout: ; -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - engine()->notifyFunctionExit(context); -#endif -} - -void RegExp::newRegExp(QScriptValueImpl *result, const QString &pattern, int flags) -{ -#ifndef QT_NO_REGEXP - QRegExp rx = toRegExp(pattern, flags); - newRegExp_helper(result, rx, flags); -#else - engine()->newObject(result, publicPrototype, classInfo()); - initRegExp(result, pattern, flags); -#endif // QT_NO_REGEXP -} - -#ifndef QT_NO_REGEXP -void RegExp::newRegExp(QScriptValueImpl *result, const QRegExp &rx, int flags) -{ - Q_ASSERT(!(flags & IgnoreCase) || (rx.caseSensitivity() == Qt::CaseInsensitive)); - newRegExp_helper(result, rx, flags); -} - -void RegExp::newRegExp_helper(QScriptValueImpl *result, const QRegExp &rx, - int flags) -{ - engine()->newObject(result, publicPrototype, classInfo()); - initRegExp(result, rx, flags); -} - -QRegExp RegExp::toRegExp(const QScriptValueImpl &value) const -{ - Instance *rx_data = Instance::get(value, classInfo()); - Q_ASSERT(rx_data != 0); - return rx_data->value; -} - -QRegExp RegExp::toRegExp(const QString &pattern, int flags) -{ - bool ignoreCase = (flags & IgnoreCase) != 0; - return QRegExp(pattern, - (ignoreCase ? Qt::CaseInsensitive: Qt::CaseSensitive), - QRegExp::RegExp2); -} - -#endif // QT_NO_REGEXP - -void RegExp::initRegExp(QScriptValueImpl *result, -#ifndef QT_NO_REGEXP - const QRegExp &rx, -#else - const QString &pattern, -#endif - int flags) -{ - Instance *instance = new Instance(); -#ifndef QT_NO_REGEXP - instance->value = rx; -#else - instance->pattern = pattern; -#endif - instance->flags = flags; - result->setObjectData(instance); - - bool global = (flags & Global) != 0; - bool ignoreCase = (flags & IgnoreCase) != 0; - bool multiline = (flags & Multiline) != 0; - - QScriptValue::PropertyFlags propertyFlags = QScriptValue::SkipInEnumeration - | QScriptValue::Undeletable - | QScriptValue::ReadOnly; - - result->setProperty(QLatin1String("global"), QScriptValueImpl(global), - propertyFlags); - result->setProperty(QLatin1String("ignoreCase"), QScriptValueImpl(ignoreCase), - propertyFlags); - result->setProperty(QLatin1String("multiline"), QScriptValueImpl(multiline), - propertyFlags); -#ifndef QT_NO_REGEXP - const QString &pattern = rx.pattern(); -#endif - result->setProperty(QLatin1String("source"), QScriptValueImpl(engine(), pattern), - propertyFlags); - result->setProperty(QLatin1String("lastIndex"), QScriptValueImpl(0), - propertyFlags & ~QScriptValue::ReadOnly); -} - -int RegExp::flagFromChar(const QChar &ch) -{ - static QHash<QChar, int> flagsHash; - if (flagsHash.isEmpty()) { - flagsHash[QLatin1Char('g')] = Global; - flagsHash[QLatin1Char('i')] = IgnoreCase; - flagsHash[QLatin1Char('m')] = Multiline; - } - QHash<QChar, int>::const_iterator it; - it = flagsHash.constFind(ch); - if (it == flagsHash.constEnd()) - return 0; - return it.value(); -} - -QString RegExp::flagsToString(int flags) -{ - QString result; - if (flags & Global) - result += QLatin1Char('g'); - if (flags & IgnoreCase) - result += QLatin1Char('i'); - if (flags & Multiline) - result += QLatin1Char('m'); - return result; -} - -QScriptValueImpl RegExp::method_exec(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() != classInfo) { - return throwThisObjectTypeError( - context, QLatin1String("RegExp.prototype.exec")); - } - Instance *rx_data = Instance::get(self, classInfo); - Q_ASSERT(rx_data != 0); - - QString S = context->argument(0).toString(); - int length = S.length(); - QScriptValueImpl lastIndex = self.property(QLatin1String("lastIndex")); - - int i = lastIndex.isValid() ? int (lastIndex.toInteger()) : 0; - bool global = self.property(QLatin1String("global")).toBoolean(); - - if (! global) - i = 0; - - if (i < 0 || i >= length) - return (eng->nullValue()); - -#ifndef QT_NO_REGEXP - int index = rx_data->value.indexIn(S, i); - if (index == -1) -#endif // QT_NO_REGEXP - return eng->nullValue(); - -#ifndef QT_NO_REGEXP - int e = index + rx_data->value.matchedLength(); - - if (global) - self.setProperty(QLatin1String("lastIndex"), QScriptValueImpl(e)); - - QScript::Array elts(eng); - QStringList capturedTexts = rx_data->value.capturedTexts(); - for (int i = 0; i < capturedTexts.count(); ++i) - elts.assign(i, QScriptValueImpl(eng, capturedTexts.at(i))); - - QScriptValueImpl r = eng->newArray(elts); - - r.setProperty(QLatin1String("index"), QScriptValueImpl(index)); - r.setProperty(QLatin1String("input"), QScriptValueImpl(eng, S)); - - return r; -#endif // QT_NO_REGEXP -} - -QScriptValueImpl RegExp::method_test(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) -{ - QScriptValueImpl r = method_exec(context, eng, classInfo); - return QScriptValueImpl(!r.isNull()); -} - -QScriptValueImpl RegExp::method_toString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) -{ - if (Instance *instance = Instance::get(context->thisObject(), classInfo)) { - QString result; - result += QLatin1Char('/'); -#ifndef QT_NO_REGEXP - const QString &pattern = instance->value.pattern(); -#else - const QString &pattern = instance->pattern; -#endif - if (pattern.isEmpty()) - result += QLatin1String("(?:)"); - else - result += pattern; // ### quote - result += QLatin1Char('/'); - result += flagsToString(instance->flags); - return (QScriptValueImpl(eng, result)); - } - - return throwThisObjectTypeError( - context, QLatin1String("RegExp.prototype.toString")); -} - -} } // namespace QScript::Ecma - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptecmaregexp_p.h b/src/script/qscriptecmaregexp_p.h deleted file mode 100644 index 1a33718..0000000 --- a/src/script/qscriptecmaregexp_p.h +++ /dev/null @@ -1,142 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTECMAREGEXP_P_H -#define QSCRIPTECMAREGEXP_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/QRegExp> - -#ifndef QT_NO_SCRIPT - -#include "qscriptecmacore_p.h" - -QT_BEGIN_NAMESPACE - -namespace QScript { namespace Ecma { - -class RegExp: public Core -{ -public: - enum RegExpFlag { - Global = 0x01, - IgnoreCase = 0x02, - Multiline = 0x04 - }; - - RegExp(QScriptEnginePrivate *engine); - virtual ~RegExp(); - - virtual void execute(QScriptContextPrivate *context); - - class Instance: public QScriptObjectData { - public: - Instance() : flags(0) {} - virtual ~Instance() {} - - static Instance *get(const QScriptValueImpl &object, - QScriptClassInfo *klass); - - public: // attributes -#ifndef QT_NO_REGEXP - QRegExp value; -#else - QString pattern; -#endif - int flags; - }; - - inline Instance *get(const QScriptValueImpl &object) const - { return Instance::get(object, classInfo()); } - - void newRegExp(QScriptValueImpl *result, const QString &pattern, - int flags); -#ifndef QT_NO_REGEXP - void newRegExp(QScriptValueImpl *result, const QRegExp &rx, - int flags = 0); - QRegExp toRegExp(const QScriptValueImpl &value) const; - static QRegExp toRegExp(const QString &pattern, int flags); -#endif - - static int flagFromChar(const QChar &ch); - static QString flagsToString(int flags); - -protected: - static QScriptValueImpl method_exec(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_test(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_toString(QScriptContextPrivate *context, - QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - -private: -#ifndef QT_NO_REGEXP - void newRegExp_helper(QScriptValueImpl *result, const QRegExp &rx, - int flags); -#endif - void initRegExp(QScriptValueImpl *result, -#ifndef QT_NO_REGEXP - const QRegExp &rx, -#else - const QString &pattern, -#endif - int flags); -}; - -} } // namespace QScript::Ecma - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT -#endif // QSCRIPTECMAREGEXP_P_H diff --git a/src/script/qscriptecmastring.cpp b/src/script/qscriptecmastring.cpp deleted file mode 100644 index d703657..0000000 --- a/src/script/qscriptecmastring.cpp +++ /dev/null @@ -1,778 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qscriptecmastring_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptengine_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" -#include "qscriptclassdata_p.h" - -#include <QtCore/QStringList> -#include <QtCore/QtDebug> -#include <QtCore/qnumeric.h> - -#include <limits.h> - -QT_BEGIN_NAMESPACE - -namespace QScript { namespace Ecma { - -class StringClassData: public QScriptClassData -{ - QScriptClassInfo *m_classInfo; - -public: - StringClassData(QScriptClassInfo *classInfo); - virtual ~StringClassData(); - - inline QScriptClassInfo *classInfo() const - { return m_classInfo; } - - virtual bool resolve(const QScriptValueImpl &object, - QScriptNameIdImpl *nameId, - QScript::Member *member, QScriptValueImpl *base, - QScript::AccessMode access); - virtual bool get(const QScriptValueImpl &object, const Member &member, - QScriptValueImpl *out_value); - virtual bool put(QScriptValueImpl *object, const Member &member, - const QScriptValueImpl &value); - virtual QScriptClassDataIterator *newIterator(const QScriptValueImpl &object); -}; - -class StringClassDataIterator: public QScriptClassDataIterator -{ -public: - StringClassDataIterator(int length); - virtual ~StringClassDataIterator(); - - virtual bool hasNext() const; - virtual void next(QScript::Member *member); - - virtual bool hasPrevious() const; - virtual void previous(QScript::Member *member); - - virtual void toFront(); - virtual void toBack(); - -private: - int m_length; - int m_pos; -}; - -StringClassData::StringClassData(QScriptClassInfo *classInfo): - m_classInfo(classInfo) -{ -} - -StringClassData::~StringClassData() -{ -} - -bool StringClassData::resolve(const QScriptValueImpl &object, - QScriptNameIdImpl *nameId, - QScript::Member *member, - QScriptValueImpl *base, - QScript::AccessMode /*access*/) -{ - if (object.classInfo() != classInfo()) - return false; - - QScriptEnginePrivate *eng = object.engine(); - - if (nameId == eng->idTable()->id_length) { - member->native(nameId, /*id=*/ 0, - QScriptValue::Undeletable - | QScriptValue::ReadOnly - | QScriptValue::SkipInEnumeration); - *base = object; - return true; - } - - bool ok = false; - int index = nameId->s.toInt(&ok); - if (!ok || (index < 0)) - return false; - - QScriptNameIdImpl *ref = object.internalValue().stringValue(); - if (index >= ref->s.length()) - return false; - - member->native(nameId, index, QScriptValue::Undeletable | QScriptValue::ReadOnly); - return true; -} - -bool StringClassData::get(const QScriptValueImpl &object, - const QScript::Member &member, - QScriptValueImpl *result) -{ - Q_ASSERT(member.isValid()); - - if (object.classInfo() != classInfo()) - return false; - - QScriptEnginePrivate *eng = object.engine(); - if (! member.isNativeProperty()) - return false; - - QScriptNameIdImpl *ref = object.internalValue().stringValue(); - int len = ref->s.length(); - - if (member.nameId() == eng->idTable()->id_length) - *result = QScriptValueImpl(len); - - else if (member.id() >= 0 && member.id() < len) - eng->newString(result, ref->s.at(member.id())); - - else - *result = eng->undefinedValue(); - - return true; -} - -bool StringClassData::put(QScriptValueImpl *, const Member &, - const QScriptValueImpl &) -{ - // writes to string elements are ignored - return true; -} - -QScriptClassDataIterator *StringClassData::newIterator(const QScriptValueImpl &object) -{ - QScriptNameIdImpl *id = object.internalValue().stringValue(); - return new StringClassDataIterator(id->s.length()); -} - -StringClassDataIterator::StringClassDataIterator(int length) -{ - m_length = length; - m_pos = 0; -} - -StringClassDataIterator::~StringClassDataIterator() -{ -} - -bool StringClassDataIterator::hasNext() const -{ - return m_pos < m_length; -} - -void StringClassDataIterator::next(QScript::Member *member) -{ - member->native(/*nameId=*/ 0, m_pos, QScriptValue::Undeletable | QScriptValue::ReadOnly); - ++m_pos; -} - -bool StringClassDataIterator::hasPrevious() const -{ - return (m_pos - 1) >= 0; -} - -void StringClassDataIterator::previous(QScript::Member *member) -{ - --m_pos; - member->native(/*nameId=*/ 0, m_pos, QScriptValue::Undeletable | QScriptValue::ReadOnly); -} - -void StringClassDataIterator::toFront() -{ - m_pos = 0; -} - -void StringClassDataIterator::toBack() -{ - m_pos = m_length; -} - - - -String::String(QScriptEnginePrivate *eng): - Core(eng, QLatin1String("String"), QScriptClassInfo::StringType) -{ - classInfo()->setData(new StringClassData(classInfo())); - - newString(&publicPrototype, QString()); - - eng->newConstructor(&ctor, this, publicPrototype); - - addPrototypeFunction(QLatin1String("toString"), method_toString, 0); - addPrototypeFunction(QLatin1String("valueOf"), method_valueOf, 0); - addPrototypeFunction(QLatin1String("charAt"), method_charAt, 1); - addPrototypeFunction(QLatin1String("charCodeAt"), method_charCodeAt, 1); - addPrototypeFunction(QLatin1String("concat"), method_concat, 1); - addPrototypeFunction(QLatin1String("indexOf"), method_indexOf, 1); - addPrototypeFunction(QLatin1String("lastIndexOf"), method_lastIndexOf, 1); - addPrototypeFunction(QLatin1String("localeCompare"), method_localeCompare, 1); - addPrototypeFunction(QLatin1String("match"), method_match, 1); - addPrototypeFunction(QLatin1String("replace"), method_replace, 2); - addPrototypeFunction(QLatin1String("search"), method_search, 1); - addPrototypeFunction(QLatin1String("slice"), method_slice, 2); - addPrototypeFunction(QLatin1String("split"), method_split, 2); - addPrototypeFunction(QLatin1String("substr"), method_substr, 2); - addPrototypeFunction(QLatin1String("substring"), method_substring, 2); - addPrototypeFunction(QLatin1String("toLowerCase"), method_toLowerCase, 0); - addPrototypeFunction(QLatin1String("toLocaleLowerCase"), method_toLocaleLowerCase, 0); - addPrototypeFunction(QLatin1String("toUpperCase"), method_toUpperCase, 0); - addPrototypeFunction(QLatin1String("toLocaleUpperCase"), method_toLocaleUpperCase, 0); - - addConstructorFunction(QLatin1String("fromCharCode"), method_fromCharCode, 1); -} - -String::~String() -{ -} - -void String::execute(QScriptContextPrivate *context) -{ -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - engine()->notifyFunctionEntry(context); -#endif - QString value; - - if (context->argumentCount() > 0) - value = context->argument(0).toString(); - - QScriptValueImpl str(engine(), value); - if (!context->isCalledAsConstructor()) { - context->setReturnValue(str); - } else { - QScriptValueImpl &obj = context->m_thisObject; - obj.setClassInfo(classInfo()); - obj.setInternalValue(str); - obj.setPrototype(publicPrototype); - context->setReturnValue(obj); - } -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - engine()->notifyFunctionExit(context); -#endif -} - -void String::newString(QScriptValueImpl *result, const QString &value) -{ - engine()->newObject(result, publicPrototype, classInfo()); - result->setInternalValue(QScriptValueImpl(engine(), value)); -} - -QScriptValueImpl String::method_toString(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() != classInfo) { - return context->throwError(QScriptContext::TypeError, QLatin1String("String.prototype.toString")); - } - return (self.internalValue()); -} - -QScriptValueImpl String::method_valueOf(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - QScriptValueImpl self = context->thisObject(); - if (self.classInfo() != classInfo) { - return throwThisObjectTypeError( - context, QLatin1String("String.prototype.valueOf")); - } - return (self.internalValue()); -} - -QScriptValueImpl String::method_charAt(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - QString str = context->thisObject().toString(); - - int pos = 0; - if (context->argumentCount() > 0) - pos = int (context->argument(0).toInteger()); - - QString result; - if (pos >= 0 && pos < str.length()) - result += str.at(pos); - - return (QScriptValueImpl(eng, result)); -} - -QScriptValueImpl String::method_charCodeAt(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *) -{ - QString str = context->thisObject().toString(); - - int pos = 0; - if (context->argumentCount() > 0) - pos = int (context->argument(0).toInteger()); - - qsreal result = qSNaN(); - - if (pos >= 0 && pos < str.length()) - result = str.at(pos).unicode(); - - return (QScriptValueImpl(result)); -} - -QScriptValueImpl String::method_concat(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - QString value = context->thisObject().toString(); - - for (int i = 0; i < context->argumentCount(); ++i) - value += context->argument(i).toString(); - - return (QScriptValueImpl(eng, value)); -} - -QScriptValueImpl String::method_indexOf(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *) -{ - QString value = context->thisObject().toString(); - - QString searchString = context->argument(0).toString(); - - int pos = 0; - if (context->argumentCount() > 1) - pos = int (context->argument(1).toInteger()); - - int index = -1; - if (! value.isEmpty()) - index = value.indexOf(searchString, qMin(qMax(pos, 0), value.length())); - - return (QScriptValueImpl(index)); -} - -QScriptValueImpl String::method_lastIndexOf(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *) -{ - QString value = context->thisObject().toString(); - - QString searchString = context->argument(0).toString(); - - qsreal position = context->argument(1).toNumber(); - if (qIsNaN(position)) - position = +qInf(); - else - position = QScriptEnginePrivate::toInteger(position); - - int pos = QScriptEnginePrivate::toInt32(qMin(qMax(position, 0.0), qsreal(value.length()))); - if (!searchString.isEmpty() && pos == value.length()) - --pos; - int index = value.lastIndexOf(searchString, pos); - return (QScriptValueImpl(index)); -} - -QScriptValueImpl String::method_localeCompare(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *) -{ - QString value = context->thisObject().toString(); - QString that = context->argument(0).toString(); - return QScriptValueImpl(QString::localeAwareCompare(value, that)); -} - -QScriptValueImpl String::method_match(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - QScriptValueImpl pattern = context->argument(0); - - if (! eng->regexpConstructor->get(pattern)) - eng->regexpConstructor->newRegExp(&pattern, context->argument(0).toString(), /*flags=*/0); - - QScriptValueImpl rx_exec = pattern.property(QLatin1String("exec"), QScriptValue::ResolvePrototype); - if (! (rx_exec.isValid() && rx_exec.isFunction())) { - return context->throwError(QScriptContext::TypeError, - QLatin1String("String.prototype.match")); - } - - QScriptValueImplList args; - args << context->thisObject(); - - QScriptValueImpl global = pattern.property(QLatin1String("global")); - if (! (global.isValid() && global.toBoolean())) - return (rx_exec.call(pattern, args)); - - QScript::Array result(eng); - - QScriptNameIdImpl *lastIndexId = eng->nameId(QLatin1String("lastIndex")); - QScriptNameIdImpl *zeroId = eng->nameId(QLatin1String("0")); - - pattern.setProperty(lastIndexId, QScriptValueImpl(0)); - int n = 0; - while (true) { - qsreal lastIndex = pattern.property(lastIndexId).toNumber(); - QScriptValueImpl r = rx_exec.call(pattern, args); - if (r.isNull()) - break; - qsreal newLastIndex = pattern.property(lastIndexId).toNumber(); - if (newLastIndex == lastIndex) - pattern.setProperty(lastIndexId, QScriptValueImpl(lastIndex + 1)); - result.assign(n++, r.property(zeroId)); - } - - return (eng->newArray(result)); -} - -QScriptValueImpl String::method_replace(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - QString input = context->thisObject().toString(); - QScriptValueImpl searchValue = context->argument(0); - QScriptValueImpl replaceValue = context->argument(1); - - QString output; - if (searchValue.classInfo() == eng->regexpConstructor->classInfo()) { - // searchValue is a RegExp - QScriptValueImpl rx_exec = searchValue.property(QLatin1String("exec"), QScriptValue::ResolvePrototype); - if (!rx_exec.isFunction()) { - return context->throwError(QScriptContext::TypeError, - QLatin1String("String.prototype.replace")); - } - QVector<QScriptValueImpl> occurrences; - QScriptValueImpl global = searchValue.property(QLatin1String("global")); - QScriptValueImplList args; - args << QScriptValueImpl(eng, input); - if (!global.toBoolean()) { - QScriptValueImpl r = rx_exec.call(searchValue, args); - if (!r.isNull()) - occurrences.append(r); - } else { - QScriptNameIdImpl *lastIndexId = eng->nameId(QLatin1String("lastIndex")); - searchValue.setProperty(lastIndexId, QScriptValueImpl(0)); - while (true) { - qsreal lastIndex = searchValue.property(lastIndexId).toNumber(); - QScriptValueImpl r = rx_exec.call(searchValue, args); - if (r.isNull()) - break; - qsreal newLastIndex = searchValue.property(lastIndexId).toNumber(); - if (newLastIndex == lastIndex) - searchValue.setProperty(lastIndexId, QScriptValueImpl(lastIndex + 1)); - occurrences.append(r); - } - } - int pos = 0; - if (replaceValue.isFunction()) { - QScriptNameIdImpl *indexId = eng->nameId(QLatin1String("index")); - QScriptNameIdImpl *lengthId = eng->nameId(QLatin1String("length")); - for (int i = 0; i < occurrences.count(); ++i) { - QScriptValueImpl needle = occurrences.at(i); - int index = int (needle.property(indexId).toInteger()); - uint length = eng->toUint32(needle.property(lengthId).toNumber()); - output += input.mid(pos, index - pos); - args.clear(); - for (uint j = 0; j < length; ++j) - args << needle.property(j); - args << QScriptValueImpl(index); - args << QScriptValueImpl(eng, input); - QScriptValueImpl ret = replaceValue.call(eng->nullValue(), args); - output += ret.toString(); - pos = index + args[0].toString().length(); - } - } else { - // use string representation of replaceValue - const QString replaceString = replaceValue.toString(); - const QLatin1Char dollar = QLatin1Char('$'); - QScriptNameIdImpl *indexId = eng->nameId(QLatin1String("index")); - QScriptNameIdImpl *zeroId = eng->nameId(QLatin1String("0")); - for (int i = 0; i < occurrences.count(); ++i) { - QScriptValueImpl needle = occurrences.at(i); - int index = int (needle.property(indexId).toInteger()); - output += input.mid(pos, index - pos); - int j = 0; - while (j < replaceString.length()) { - const QChar c = replaceString.at(j++); - if ((c == dollar) && (j < replaceString.length())) { - const QChar nc = replaceString.at(j); - if (nc == dollar) { - ++j; - } else if (nc == QLatin1Char('`')) { - ++j; - output += input.left(index); - continue; - } else if (nc == QLatin1Char('\'')) { - ++j; - output += input.mid(index + needle.property(zeroId).toString().length()); - continue; - } else if (nc.isDigit()) { - ++j; - int cap = nc.toLatin1() - '0'; - if ((j < replaceString.length()) && replaceString.at(j).isDigit()) { - cap = cap * 10; - cap = replaceString.at(j++).toLatin1() - '0'; - } - output += needle.property(QScriptValueImpl(cap).toString()).toString(); - continue; - } - } - output += c; - } - pos = index + needle.property(zeroId).toString().length(); - } - } - output += input.mid(pos); - } else { - // use string representation of searchValue - const QString searchString = searchValue.toString(); - int pos = 0; - if (replaceValue.isFunction()) { - int index = input.indexOf(searchString, pos); - if (index != -1) { - output += input.mid(pos, index - pos); - QScriptValueImplList args; - args << QScriptValueImpl(eng, searchString); - args << QScriptValueImpl(index); - args << QScriptValueImpl(eng, input); - QScriptValueImpl ret = replaceValue.call(eng->nullValue(), args); - output += ret.toString(); - pos = index + searchString.length(); - } - } else { - // use string representation of replaceValue - const QString replaceString = replaceValue.toString(); - const QLatin1Char dollar = QLatin1Char('$'); - int index = input.indexOf(searchString, pos); - if (index != -1) { - output += input.mid(pos, index - pos); - int j = 0; - while (j < replaceString.length()) { - const QChar c = replaceString.at(j++); - if ((c == dollar) && (j < replaceString.length())) { - const QChar nc = replaceString.at(j); - if (nc == dollar) { - ++j; - } else if (nc == QLatin1Char('`')) { - output += input.left(index); - ++j; - continue; - } else if (nc == QLatin1Char('\'')) { - output += input.mid(index + searchString.length()); - ++j; - continue; - } - } - output += c; - } - pos = index + searchString.length(); - } - } - output += input.mid(pos); - } - return QScriptValueImpl(eng, output); -} - -QScriptValueImpl String::method_search(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - QScriptValueImpl pattern = context->argument(0); - - Ecma::RegExp::Instance *rx_data = 0; - if (0 == (rx_data = eng->regexpConstructor->get(pattern))) { - eng->regexpConstructor->newRegExp(&pattern, context->argument(0).toString(), /*flags=*/0); - rx_data = eng->regexpConstructor->get(pattern); - } - - QString value = context->thisObject().toString(); -#ifndef QT_NO_REGEXP - return (QScriptValueImpl(value.indexOf(rx_data->value))); -#else - return eng->nullValue(); -#endif -} - -QScriptValueImpl String::method_slice(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - QString text = context->thisObject().toString(); - int length = text.length(); - - int start = int (context->argument(0).toInteger()); - int end = context->argument(1).isUndefined() - ? length : int (context->argument(1).toInteger()); - - if (start < 0) - start = qMax(length + start, 0); - else - start = qMin(start, length); - - if (end < 0) - end = qMax(length + end, 0); - else - end = qMin(end, length); - - int count = qMax(0, end - start); - return (QScriptValueImpl(eng, text.mid(start, count))); -} - -QScriptValueImpl String::method_split(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - QScriptValueImpl l = context->argument(1); - quint32 lim = l.isUndefined() ? UINT_MAX : QScriptEnginePrivate::toUint32(l.toNumber()); - - if (lim == 0) - return eng->newArray(); - - QString S = context->thisObject().toString(); - QScriptValueImpl separator = context->argument(0); - - QScript::Array A(eng); - // the argumentCount() check is for compatibility with spidermonkey; - // it is not according to ECMA-262 - if (separator.isUndefined() && (context->argumentCount() == 0)) { - A.assign(0, QScriptValueImpl(eng, S)); - } else { - QStringList matches; -#ifndef QT_NO_REGEXP - if (Ecma::RegExp::Instance *rx = eng->regexpConstructor->get(separator)) { - matches = S.split(rx->value, rx->value.pattern().isEmpty() - ? QString::SkipEmptyParts : QString::KeepEmptyParts); - } else -#endif // QT_NO_REGEXP - { - QString sep = separator.toString(); - matches = S.split(sep, sep.isEmpty() - ? QString::SkipEmptyParts : QString::KeepEmptyParts); - } - uint count = qMin(lim, uint(matches.count())); - for (uint i = 0; i < count; ++i) - A.assign(i, QScriptValueImpl(eng, matches.at(i))); - } - - return eng->newArray(A); -} - -QScriptValueImpl String::method_substr(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - QString value = context->thisObject().toString(); - - qsreal start = 0; - if (context->argumentCount() > 0) - start = context->argument(0).toInteger(); - - qsreal length = +qInf(); - if (context->argumentCount() > 1) - length = context->argument(1).toInteger(); - - qsreal count = value.length(); - if (start < 0) - start = qMax(count + start, 0.0); - - length = qMin(qMax(length, 0.0), count - start); - - qint32 x = QScriptEnginePrivate::toInt32(start); - qint32 y = QScriptEnginePrivate::toInt32(length); - return QScriptValueImpl(eng, value.mid(x, y)); -} - -QScriptValueImpl String::method_substring(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - QString value = context->thisObject().toString(); - int length = value.length(); - - qsreal start = 0; - qsreal end = length; - - if (context->argumentCount() > 0) - start = context->argument(0).toInteger(); - - if (context->argumentCount() > 1) - end = context->argument(1).toInteger(); - - if (qIsNaN(start) || start < 0) - start = 0; - - if (qIsNaN(end) || end < 0) - end = 0; - - if (start > length) - start = length; - - if (end > length) - end = length; - - if (start > end) { - qsreal was = start; - start = end; - end = was; - } - - qint32 x = QScriptEnginePrivate::toInt32(start); - qint32 y = QScriptEnginePrivate::toInt32(end - start); - - return (QScriptValueImpl(eng, value.mid(x, y))); -} - -QScriptValueImpl String::method_toLowerCase(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - QString value = context->thisObject().toString(); - return (QScriptValueImpl(eng, value.toLower())); -} - -QScriptValueImpl String::method_toLocaleLowerCase(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) -{ - return method_toLowerCase(context, eng, classInfo); // ### check me -} - -QScriptValueImpl String::method_toUpperCase(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - QString value = context->thisObject().toString(); - return (QScriptValueImpl(eng, value.toUpper())); -} - -QScriptValueImpl String::method_toLocaleUpperCase(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) -{ - return method_toUpperCase(context, eng, classInfo); // ### check me -} - -QScriptValueImpl String::method_fromCharCode(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - QString str; - for (int i = 0; i < context->argumentCount(); ++i) { - QChar c(context->argument(i).toUInt16()); - str += c; - } - return (QScriptValueImpl(eng, str)); -} - -// Qt extensions - -QScriptValueImpl String::method_ext_arg(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - QString value = context->thisObject().toString(); - QScriptValueImpl arg = context->argument(0); - QString result; - if (arg.isString()) - result = value.arg(arg.toString()); - else if (arg.isNumber()) - result = value.arg(arg.toNumber()); - return QScriptValueImpl(eng, result); -} - -} } // namespace QScript::Ecma - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptecmastring_p.h b/src/script/qscriptecmastring_p.h deleted file mode 100644 index 6d4c84a..0000000 --- a/src/script/qscriptecmastring_p.h +++ /dev/null @@ -1,128 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTECMASTRING_P_H -#define QSCRIPTECMASTRING_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 "qscriptecmacore_p.h" - -#ifndef QT_NO_SCRIPT - -QT_BEGIN_NAMESPACE - -namespace QScript { namespace Ecma { - -class String: public Core -{ -public: - String(QScriptEnginePrivate *engine); - virtual ~String(); - - virtual void execute(QScriptContextPrivate *context); - - void newString(QScriptValueImpl *result, const QString &value = QString()); - -protected: - static QScriptValueImpl method_toString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_valueOf(QScriptContextPrivate *context, QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_charAt(QScriptContextPrivate *context, QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_charCodeAt(QScriptContextPrivate *context, QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_concat(QScriptContextPrivate *context, QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_indexOf(QScriptContextPrivate *context, QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_lastIndexOf(QScriptContextPrivate *context, QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_localeCompare(QScriptContextPrivate *context, QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_match(QScriptContextPrivate *context, QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_replace(QScriptContextPrivate *context, QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_search(QScriptContextPrivate *context, QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_slice(QScriptContextPrivate *context, QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_split(QScriptContextPrivate *context, QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_substr(QScriptContextPrivate *context, QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_substring(QScriptContextPrivate *context, QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_toLowerCase(QScriptContextPrivate *context, QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_toLocaleLowerCase(QScriptContextPrivate *context, QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_toUpperCase(QScriptContextPrivate *context, QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_toLocaleUpperCase(QScriptContextPrivate *context, QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_fromCharCode(QScriptContextPrivate *context, QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - -public: - // Qt extensions - static QScriptValueImpl method_ext_arg(QScriptContextPrivate *context, QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); -}; - -} } // namespace QScript::Ecma - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT - -#endif diff --git a/src/script/qscriptengine.cpp b/src/script/qscriptengine.cpp deleted file mode 100644 index 59ce460..0000000 --- a/src/script/qscriptengine.cpp +++ /dev/null @@ -1,1881 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qscriptengine.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptengine_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" -#include "qscriptsyntaxcheckresult_p.h" - -QT_BEGIN_NAMESPACE - -/*! - \since 4.3 - \class QScriptEngine - \reentrant - - \brief The QScriptEngine class provides an environment for evaluating Qt Script code. - - \ingroup script - - - See the \l{QtScript} documentation for information about the Qt Script language, - and how to get started with scripting your C++ application. - - \section1 Evaluating Scripts - - Use evaluate() to evaluate script code; this is the C++ equivalent - of the built-in script function \c{eval()}. - - \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 0 - - evaluate() returns a QScriptValue that holds the result of the - evaluation. The QScriptValue class provides functions for converting - the result to various C++ types (e.g. QScriptValue::toString() - and QScriptValue::toNumber()). - - The following code snippet shows how a script function can be - defined and then invoked from C++ using QScriptValue::call(): - - \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 1 - - As can be seen from the above snippets, a script is provided to the - engine in the form of a string. One common way of loading scripts is - by reading the contents of a file and passing it to evaluate(): - - \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 2 - - Here we pass the name of the file as the second argument to - evaluate(). This does not affect evaluation in any way; the second - argument is a general-purpose string that is used to identify the - script for debugging purposes (for example, our filename will now - show up in any uncaughtExceptionBacktrace() involving the script). - - \section1 Engine Configuration - - The globalObject() function returns the \bold {Global Object} - associated with the script engine. Properties of the Global Object - are accessible from any script code (i.e. they are global - variables). Typically, before evaluating "user" scripts, you will - want to configure a script engine by adding one or more properties - to the Global Object: - - \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 3 - - Adding custom properties to the scripting environment is one of the - standard means of providing a scripting API that is specific to your - application. Usually these custom properties are objects created by - the newQObject() or newObject() functions, or constructor functions - created by newFunction(). - - \section1 Script Exceptions - - evaluate() can throw a script exception (e.g. due to a syntax - error); in that case, the return value is the value that was thrown - (typically an \c{Error} object). You can check whether the - evaluation caused an exception by calling hasUncaughtException(). In - that case, you can call toString() on the error object to obtain an - error message. The current uncaught exception is also available - through uncaughtException(). You can obtain a human-readable - backtrace of the exception with uncaughtExceptionBacktrace(). - Calling clearExceptions() will cause any uncaught exceptions to be - cleared. - - \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 4 - - The checkSyntax() function can be used to determine whether code can be - usefully passed to evaluate(). - - \section1 Script Object Creation - - Use newObject() to create a standard Qt Script object; this is the - C++ equivalent of the script statement \c{new Object()}. You can use - the object-specific functionality in QScriptValue to manipulate the - script object (e.g. QScriptValue::setProperty()). Similarly, use - newArray() to create a Qt Script array object. Use newDate() to - create a \c{Date} object, and newRegExp() to create a \c{RegExp} - object. - - \section1 QObject Integration - - Use newQObject() to wrap a QObject (or subclass) - pointer. newQObject() returns a proxy script object; properties, - children, and signals and slots of the QObject are available as - properties of the proxy object. No binding code is needed because it - is done dynamically using the Qt meta object system. - - \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 5 - - Use qScriptConnect() to connect a C++ signal to a script function; - this is the Qt Script equivalent of QObject::connect(). When a - script function is invoked in response to a C++ signal, it can cause - a script exception; you can connect to the signalHandlerException() - signal to catch such an exception. - - Use newQMetaObject() to wrap a QMetaObject; this gives you a "script - representation" of a QObject-based class. newQMetaObject() returns a - proxy script object; enum values of the class are available as - properties of the proxy object. You can also specify a function that - will be used to construct objects of the class (e.g. when the - constructor is invoked from a script). For classes that have a - "standard" Qt constructor, Qt Script can provide a default script - constructor for you; see scriptValueFromQMetaObject(). - - See the \l{QtScript} documentation for more information on - the QObject integration. - - \section1 Support for Custom C++ Types - - Use newVariant() to wrap a QVariant. This can be used to store - values of custom (non-QObject) C++ types that have been registered - with the Qt meta-type system. To make such types scriptable, you - typically associate a prototype (delegate) object with the C++ type - by calling setDefaultPrototype(); the prototype object defines the - scripting API for the C++ type. Unlike the QObject integration, - there is no automatic binding possible here; i.e. you have to create - the scripting API yourself, for example by using the QScriptable - class. - - Use fromScriptValue() to cast from a QScriptValue to another type, - and toScriptValue() to create a QScriptValue from another value. - You can specify how the conversion of C++ types is to be performed - with qScriptRegisterMetaType() and qScriptRegisterSequenceMetaType(). - By default, Qt Script will use QVariant to store values of custom - types. - - \section1 Importing Extensions - - Use importExtension() to import plugin-based extensions into the - engine. Call availableExtensions() to obtain a list naming all the - available extensions, and importedExtensions() to obtain a list - naming only those extensions that have been imported. - - Call pushContext() to open up a new variable scope, and popContext() - to close the current scope. This is useful if you are implementing - an extension that evaluates script code containing temporary - variable definitions (e.g. \c{var foo = 123;}) that are safe to - discard when evaluation has completed. - - \section1 Native Functions - - Use newFunction() to wrap native (C++) functions, including - constructors for your own custom types, so that these can be invoked - from script code. Such functions must have the signature - QScriptEngine::FunctionSignature. You may then pass the function as - argument to newFunction(). Here is an example of a function that - returns the sum of its first two arguments: - - \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 6 - - To expose this function to script code, you can set it as a property - of the Global Object: - - \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 7 - - Once this is done, script code can call your function in the exact - same manner as a "normal" script function: - - \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 8 - - \section1 Long-running Scripts - - If you need to evaluate possibly long-running scripts from the main - (GUI) thread, you should first call setProcessEventsInterval() to - make sure that the GUI stays responsive. You can abort a currently - running script by calling abortEvaluation(). You can determine - whether an engine is currently running a script by calling - isEvaluating(). - - \section1 Core Debugging/Tracing Facilities - - Since Qt 4.4, you can be notified of events pertaining to script - execution (e.g. script function calls and statement execution) - through the QScriptEngineAgent interface; see the setAgent() - function. This can be used to implement debugging and profiling of a - QScriptEngine. - - \sa QScriptValue, QScriptContext, QScriptEngineAgent - -*/ - -/*! - \enum QScriptEngine::ValueOwnership - - This enum specifies the ownership when wrapping a C++ value, e.g. by using newQObject(). - - \value QtOwnership The standard Qt ownership rules apply, i.e. the associated object will never be explicitly deleted by the script engine. This is the default. (QObject ownership is explained in \l{Object Trees and Object Ownership}.) - \value ScriptOwnership The value is owned by the script environment. The associated data will be deleted when appropriate (i.e. after the garbage collector has discovered that there are no more live references to the value). - \value AutoOwnership If the associated object has a parent, the Qt ownership rules apply (QtOwnership); otherwise, the object is owned by the script environment (ScriptOwnership). -*/ - -/*! - \enum QScriptEngine::QObjectWrapOption - - These flags specify options when wrapping a QObject pointer with newQObject(). - - \value ExcludeChildObjects The script object will not expose child objects as properties. - \value ExcludeSuperClassMethods The script object will not expose signals and slots inherited from the superclass. - \value ExcludeSuperClassProperties The script object will not expose properties inherited from the superclass. - \value ExcludeSuperClassContents Shorthand form for ExcludeSuperClassMethods | ExcludeSuperClassProperties - \value ExcludeDeleteLater The script object will not expose the QObject::deleteLater() slot. - \value AutoCreateDynamicProperties Properties that don't already exist in the QObject will be created as dynamic properties of that object, rather than as properties of the script object. - \value PreferExistingWrapperObject If a wrapper object with the requested configuration already exists, return that object. - \value SkipMethodsInEnumeration Don't include methods (signals and slots) when enumerating the object's properties. -*/ - -#ifdef QT_NO_QOBJECT - -QScriptEngine::QScriptEngine() - : d_ptr(new QScriptEnginePrivate) -{ - d_ptr->q_ptr = this; - d_ptr->init(); -} - -/*! \internal -*/ -QScriptEngine::QScriptEngine(QScriptEnginePrivate &dd) - : d_ptr(&dd) -{ - d_ptr->q_ptr = this; - d_ptr->init(); -} -#else - -/*! - Constructs a QScriptEngine object. - - The globalObject() is initialized to have properties as described in - \l{ECMA-262}, Section 15.1. -*/ -QScriptEngine::QScriptEngine() - : QObject(*new QScriptEnginePrivate, 0) -{ - Q_D(QScriptEngine); - d->init(); -} - -/*! - Constructs a QScriptEngine object with the given \a parent. - - The globalObject() is initialized to have properties as described in - \l{ECMA-262}, Section 15.1. -*/ - -QScriptEngine::QScriptEngine(QObject *parent) - : QObject(*new QScriptEnginePrivate, parent) -{ - Q_D(QScriptEngine); - d->init(); -} - -/*! \internal -*/ -QScriptEngine::QScriptEngine(QScriptEnginePrivate &dd, QObject *parent) - : QObject(dd, parent) -{ - Q_D(QScriptEngine); - d->init(); -} -#endif - -/*! - Destroys this QScriptEngine. -*/ -QScriptEngine::~QScriptEngine() -{ - Q_D(QScriptEngine); - d->m_frameRepository.release(currentContext()); - d->objectAllocator.destruct(); -#ifdef QT_NO_QOBJECT - delete d_ptr; - d_ptr = 0; -#endif -} - -/*! - Returns this engine's Global Object. - - By default, the Global Object contains the built-in objects that are - part of \l{ECMA-262}, such as Math, Date and String. Additionally, - you can set properties of the Global Object to make your own - extensions available to all script code. Non-local variables in - script code will be created as properties of the Global Object, as - well as local variables in global code. -*/ -QScriptValue QScriptEngine::globalObject() const -{ - Q_D(const QScriptEngine); - return const_cast<QScriptEnginePrivate*>(d)->toPublic(d->m_globalObject); -} - -/*! - \since 4.5 - - Sets this engine's Global Object to be the given \a object. - If \a object is not a valid script object, this function does - nothing. - - When setting a custom global object, you may want to use - QScriptValueIterator to copy the properties of the standard Global - Object; alternatively, you can set the internal prototype of your - custom object to be the original Global Object. -*/ -void QScriptEngine::setGlobalObject(const QScriptValue &object) -{ - Q_D(QScriptEngine); - if (!object.isObject()) - return; - QScriptValueImpl objectImpl = d->toImpl(object); - - // update properties of the global context - QScriptValueImpl old = d->m_globalObject; - QScriptContextPrivate *ctx = d->currentContext(); - while (ctx->parentContext() != 0) - ctx = ctx->parentContext(); - if (QScriptEnginePrivate::strictlyEquals(ctx->m_thisObject, old)) - ctx->m_thisObject = objectImpl; - if (QScriptEnginePrivate::strictlyEquals(ctx->m_activation, old)) - ctx->m_activation = objectImpl; - if (QScriptEnginePrivate::strictlyEquals(ctx->m_scopeChain, old)) - ctx->m_scopeChain = objectImpl; - - d->m_globalObject = objectImpl; -} - -/*! - Returns a QScriptValue of the primitive type Null. - - \sa undefinedValue() -*/ -QScriptValue QScriptEngine::nullValue() -{ - Q_D(QScriptEngine); - return d->toPublic(d->nullValue()); -} - -/*! - Returns a QScriptValue of the primitive type Undefined. - - \sa nullValue() -*/ -QScriptValue QScriptEngine::undefinedValue() -{ - Q_D(QScriptEngine); - return d->toPublic(d->undefinedValue()); -} - -/*! - Creates a constructor function from \a fun, with the given \a length. - The \c{prototype} property of the resulting function is set to be the - given \a prototype. The \c{constructor} property of \a prototype is - set to be the resulting function. - - When a function is called as a constructor (e.g. \c{new Foo()}), the - `this' object associated with the function call is the new object - that the function is expected to initialize; the prototype of this - default constructed object will be the function's public - \c{prototype} property. If you always want the function to behave as - a constructor (e.g. \c{Foo()} should also create a new object), or - if you need to create your own object rather than using the default - `this' object, you should make sure that the prototype of your - object is set correctly; either by setting it manually, or, when - wrapping a custom type, by having registered the defaultPrototype() - of that type. Example: - - \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 9 - - To wrap a custom type and provide a constructor for it, you'd typically - do something like this: - - \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 10 -*/ -QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, - const QScriptValue &prototype, - int length) -{ - Q_D(QScriptEngine); - QScriptValueImpl v = d->createFunction(new QScript::CFunction(fun, length)); - QScriptValueImpl proto = d->toImpl(prototype); - v.setProperty(d->idTable()->id_prototype, proto, - QScriptValue::Undeletable); - proto.setProperty(d->idTable()->id_constructor, v, - QScriptValue::Undeletable - | QScriptValue::SkipInEnumeration); - return d->toPublic(v); -} - -#ifndef QT_NO_REGEXP -/*! - Creates a QtScript object of class RegExp with the given - \a regexp. - - \sa QScriptValue::toRegExp() -*/ -QScriptValue QScriptEngine::newRegExp(const QRegExp ®exp) -{ - Q_D(QScriptEngine); - QScriptValueImpl v; - d->regexpConstructor->newRegExp(&v, regexp); - return d->toPublic(v); -} - -#endif // QT_NO_REGEXP - -/*! - Creates a QtScript object holding the given variant \a value. - - If a default prototype has been registered with the meta type id of - \a value, then the prototype of the created object will be that - prototype; otherwise, the prototype will be the Object prototype - object. - - \sa setDefaultPrototype(), QScriptValue::toVariant() -*/ -QScriptValue QScriptEngine::newVariant(const QVariant &value) -{ - Q_D(QScriptEngine); - QScriptValueImpl result; - d->newVariant(&result, value); - return d->toPublic(result); -} - -/*! - \since 4.4 - \overload - - Initializes the given Qt Script \a object to hold the given variant - \a value, and returns the \a object. - - This function enables you to "promote" a plain Qt Script object - (created by the newObject() function) to a variant, or to replace - the variant contained inside an object previously created by the - newVariant() function. - - The prototype() of the \a object will remain unchanged. - - If \a object is not an object, this function behaves like the normal - newVariant(), i.e. it creates a new script object and returns it. - - This function is useful when you want to provide a script - constructor for a C++ type. If your constructor is invoked in a - \c{new} expression (QScriptContext::isCalledAsConstructor() returns - true), you can pass QScriptContext::thisObject() (the default - constructed script object) to this function to initialize the new - object. -*/ -QScriptValue QScriptEngine::newVariant(const QScriptValue &object, - const QVariant &value) -{ - Q_D(QScriptEngine); - QScriptValuePrivate *p = QScriptValuePrivate::get(object); - if (!p || !p->value.isObject()) - return newVariant(value); - if (p->value.isVariant()) - p->value.setVariantValue(value); - else - d->newVariant(&p->value, value, /*setDefaultPrototype=*/false); - return object; -} - -#ifndef QT_NO_QOBJECT -/*! - Creates a QtScript object that wraps the given QObject \a - object, using the given \a ownership. The given \a options control - various aspects of the interaction with the resulting script object. - - Signals and slots, properties and children of \a object are - available as properties of the created QScriptValue. For more - information, see the \l{QtScript} documentation. - - If \a object is a null pointer, this function returns nullValue(). - - If a default prototype has been registered for the \a object's class - (or its superclass, recursively), the prototype of the new script - object will be set to be that default prototype. - - If the given \a object is deleted outside of QtScript's control, any - attempt to access the deleted QObject's members through the QtScript - wrapper object (either by script code or C++) will result in a - script exception. - - \sa QScriptValue::toQObject() -*/ -QScriptValue QScriptEngine::newQObject(QObject *object, ValueOwnership ownership, - const QObjectWrapOptions &options) -{ - Q_D(QScriptEngine); - QScriptValueImpl result; - d->newQObject(&result, object, ownership, options); - return d->toPublic(result); -} - -/*! - \since 4.4 - \overload - - Initializes the given \a scriptObject to hold the given \a qtObject, - and returns the \a scriptObject. - - This function enables you to "promote" a plain Qt Script object - (created by the newObject() function) to a QObject proxy, or to - replace the QObject contained inside an object previously created by - the newQObject() function. - - The prototype() of the \a scriptObject will remain unchanged. - - If \a scriptObject is not an object, this function behaves like the - normal newQObject(), i.e. it creates a new script object and returns - it. - - This function is useful when you want to provide a script - constructor for a QObject-based class. If your constructor is - invoked in a \c{new} expression - (QScriptContext::isCalledAsConstructor() returns true), you can pass - QScriptContext::thisObject() (the default constructed script object) - to this function to initialize the new object. -*/ -QScriptValue QScriptEngine::newQObject(const QScriptValue &scriptObject, - QObject *qtObject, - ValueOwnership ownership, - const QObjectWrapOptions &options) -{ - Q_D(QScriptEngine); - QScriptValuePrivate *p = QScriptValuePrivate::get(scriptObject); - if (!p || !p->value.isObject()) - return newQObject(qtObject, ownership, options); - if (p->value.isQObject()) { - QScript::ExtQObject::Instance *data; - data = d->qobjectConstructor->get(p->value); - Q_ASSERT(data != 0); - data->value = qtObject; - data->ownership = ownership; - data->options = options; - } else { - d->newQObject(&p->value, qtObject, ownership, options, - /*setDefaultPrototype=*/false); - } - return scriptObject; -} - -#endif // QT_NO_QOBJECT - -/*! - Creates a QtScript object of class Object. - - The prototype of the created object will be the Object - prototype object. - - \sa newArray(), QScriptValue::setProperty() -*/ -QScriptValue QScriptEngine::newObject() -{ - Q_D(QScriptEngine); - QScriptValueImpl v; - d->newObject(&v, d->objectConstructor->publicPrototype); - return d->toPublic(v); -} - -/*! - \since 4.4 - \overload - - Creates a QtScript Object of the given class, \a scriptClass. - - The prototype of the created object will be the Object - prototype object. - - \a data, if specified, is set as the internal data of the - new object (using QScriptValue::setData()). - - \sa QScriptValue::scriptClass() -*/ -QScriptValue QScriptEngine::newObject(QScriptClass *scriptClass, - const QScriptValue &data) -{ - Q_D(QScriptEngine); - return d->toPublic(d->newObject(scriptClass, d->toImpl(data))); -} - -/*! - \internal -*/ -QScriptValue QScriptEngine::newActivationObject() -{ - Q_D(QScriptEngine); - QScriptValueImpl v; - d->newActivation(&v); - return d->toPublic(v); -} - -/*! - Creates a QScriptValue that wraps a native (C++) function. \a fun - must be a C++ function with signature QScriptEngine::FunctionSignature. \a - length is the number of arguments that \a fun expects; this becomes - the \c{length} property of the created QScriptValue. - - Note that \a length only gives an indication of the number of - arguments that the function expects; an actual invocation of a - function can include any number of arguments. You can check the - \l{QScriptContext::argumentCount()}{argumentCount()} of the - QScriptContext associated with the invocation to determine the - actual number of arguments passed. - - A \c{prototype} property is automatically created for the resulting - function object, to provide for the possibility that the function - will be used as a constructor. - - By combining newFunction() and the property flags - QScriptValue::PropertyGetter and QScriptValue::PropertySetter, you - can create script object properties that behave like normal - properties in script code, but are in fact accessed through - functions (analogous to how properties work in \l{Qt's Property - System}). Example: - - \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 11 - - When the property \c{foo} of the script object is subsequently - accessed in script code, \c{getSetFoo()} will be invoked to handle - the access. In this particular case, we chose to store the "real" - value of \c{foo} as a property of the accessor function itself; you - are of course free to do whatever you like in this function. - - In the above example, a single native function was used to handle - both reads and writes to the property; the argument count is used to - determine if we are handling a read or write. You can also use two - separate functions; just specify the relevant flag - (QScriptValue::PropertyGetter or QScriptValue::PropertySetter) when - setting the property, e.g.: - - \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 12 - - \sa QScriptValue::call() -*/ -QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, int length) -{ - Q_D(QScriptEngine); - QScriptValueImpl v = d->createFunction(new QScript::CFunction(fun, length)); - QScriptValueImpl prototype = d->newObject(); - v.setProperty(d->idTable()->id_prototype, prototype, QScriptValue::Undeletable); - prototype.setProperty(d->idTable()->id_constructor, v, - QScriptValue::Undeletable | QScriptValue::SkipInEnumeration); - return d->toPublic(v); -} - -/*! - \internal - \since 4.4 -*/ -QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionWithArgSignature fun, void *arg) -{ - Q_D(QScriptEngine); - QScriptValueImpl v = d->createFunction(new QScript::C3Function(fun, arg, /*length=*/0)); - QScriptValueImpl prototype = d->newObject(); - v.setProperty(d->idTable()->id_prototype, prototype, QScriptValue::Undeletable); - prototype.setProperty(d->idTable()->id_constructor, v, - QScriptValue::Undeletable | QScriptValue::SkipInEnumeration); - return d->toPublic(v); -} - -/*! - Creates a QtScript object of class Array with the given \a length. - - \sa newObject() -*/ -QScriptValue QScriptEngine::newArray(uint length) -{ - Q_D(QScriptEngine); - QScriptValueImpl v; - QScript::Array a(d); - a.resize(length); - d->newArray(&v, a); - return d->toPublic(v); -} - -/*! - Creates a QtScript object of class RegExp with the given - \a pattern and \a flags. - - The legal flags are 'g' (global), 'i' (ignore case), and 'm' - (multiline). -*/ -QScriptValue QScriptEngine::newRegExp(const QString &pattern, const QString &flags) -{ - Q_D(QScriptEngine); - int bitflags = 0; - for (int i = 0; i < flags.size(); ++i) - bitflags |= QScript::Ecma::RegExp::flagFromChar(flags.at(i)); - QScriptValueImpl v; - d->regexpConstructor->newRegExp(&v, pattern, bitflags); - return d->toPublic(v); -} - -/*! - Creates a QtScript object of class Date with the given - \a value (the number of milliseconds since 01 January 1970, - UTC). -*/ -QScriptValue QScriptEngine::newDate(qsreal value) -{ - Q_D(QScriptEngine); - QScriptValueImpl v; - d->dateConstructor->newDate(&v, value); - return d->toPublic(v); -} - -/*! - Creates a QtScript object of class Date from the given \a value. - - \sa QScriptValue::toDateTime() -*/ -QScriptValue QScriptEngine::newDate(const QDateTime &value) -{ - Q_D(QScriptEngine); - QScriptValueImpl v; - d->dateConstructor->newDate(&v, value); - return d->toPublic(v); -} - -#ifndef QT_NO_QOBJECT -/*! - Creates a QtScript object that represents a QObject class, using the - the given \a metaObject and constructor \a ctor. - - Enums of \a metaObject (declared with Q_ENUMS) are available as - properties of the created QScriptValue. When the class is called as - a function, \a ctor will be called to create a new instance of the - class. - - Example: - - \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 27 - - \sa newQObject(), scriptValueFromQMetaObject() -*/ -QScriptValue QScriptEngine::newQMetaObject( - const QMetaObject *metaObject, const QScriptValue &ctor) -{ - Q_D(QScriptEngine); - QScriptValueImpl v; - d->qmetaObjectConstructor->newQMetaObject(&v, metaObject, d->toImpl(ctor)); - return d->toPublic(v); -} - -/*! - \fn QScriptValue QScriptEngine::scriptValueFromQMetaObject() - - Creates a QScriptValue that represents the Qt class \c{T}. - - This function is used in combination with one of the - Q_SCRIPT_DECLARE_QMETAOBJECT() macro. Example: - - \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 13 - - \warning This function is not available with MSVC 6. Use - qScriptValueFromQMetaObject() instead if you need to support that version - of the compiler. - - \sa QScriptEngine::newQMetaObject() -*/ - -/*! - \fn QScriptValue qScriptValueFromQMetaObject(QScriptEngine *engine) - \since 4.3 - \relates QScriptEngine - - Uses \a engine to create a QScriptValue that represents the Qt class - \c{T}. - - This function is equivalent to - QScriptEngine::scriptValueFromQMetaObject(). It is provided as a - work-around for MSVC 6, which doesn't support member template - functions. - - \sa QScriptEngine::newQMetaObject() -*/ -#endif // QT_NO_QOBJECT - -/*! - \obsolete - - Returns true if \a program can be evaluated; i.e. the code is - sufficient to determine whether it appears to be a syntactically - correct program, or contains a syntax error. - - This function returns false if \a program is incomplete; i.e. the - input is syntactically correct up to the point where the input is - terminated. - - Note that this function only does a static check of \a program; - e.g. it does not check whether references to variables are - valid, and so on. - - A typical usage of canEvaluate() is to implement an interactive - interpreter for QtScript. The user is repeatedly queried for - individual lines of code; the lines are concatened internally, and - only when canEvaluate() returns true for the resulting program is it - passed to evaluate(). - - The following are some examples to illustrate the behavior of - canEvaluate(). (Note that all example inputs are assumed to have an - explicit newline as their last character, since otherwise the - QtScript parser would automatically insert a semi-colon character at - the end of the input, and this could cause canEvaluate() to produce - different results.) - - Given the input - \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 14 - canEvaluate() will return true, since the program appears to be complete. - - Given the input - \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 15 - canEvaluate() will return false, since the if-statement is not complete, - but is syntactically correct so far. - - Given the input - \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 16 - canEvaluate() will return true, but evaluate() will throw a - SyntaxError given the same input. - - Given the input - \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 17 - canEvaluate() will return true, even though the code is clearly not - syntactically valid QtScript code. evaluate() will throw a - SyntaxError when this code is evaluated. - - Given the input - \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 18 - canEvaluate() will return true, but evaluate() will throw a - ReferenceError if \c{foo} is not defined in the script - environment. - - \sa evaluate(), checkSyntax() -*/ -bool QScriptEngine::canEvaluate(const QString &program) const -{ - return QScriptEnginePrivate::canEvaluate(program); -} - -/*! - \since 4.5 - - Checks the syntax of the given \a program. Returns a - QScriptSyntaxCheckResult object that contains the result of the check. -*/ -QScriptSyntaxCheckResult QScriptEngine::checkSyntax(const QString &program) -{ - return QScriptEnginePrivate::checkSyntax(program); -} - -/*! - Evaluates \a program, using \a lineNumber as the base line number, - and returns the result of the evaluation. - - The script code will be evaluated in the current context. - - The evaluation of \a program can cause an exception in the - engine; in this case the return value will be the exception - that was thrown (typically an \c{Error} object). You can call - hasUncaughtException() to determine if an exception occurred in - the last call to evaluate(). - - \a lineNumber is used to specify a starting line number for \a - program; line number information reported by the engine that pertain - to this evaluation (e.g. uncaughtExceptionLineNumber()) will be - based on this argument. For example, if \a program consists of two - lines of code, and the statement on the second line causes a script - exception, uncaughtExceptionLineNumber() would return the given \a - lineNumber plus one. When no starting line number is specified, line - numbers will be 1-based. - - \a fileName is used for error reporting. For example in error objects - the file name is accessible through the "fileName" property if it's - provided with this function. - - \sa checkSyntax(), hasUncaughtException(), isEvaluating(), abortEvaluation() -*/ -QScriptValue QScriptEngine::evaluate(const QString &program, const QString &fileName, int lineNumber) -{ - Q_D(QScriptEngine); - QScriptContextPrivate *ctx_p = d->currentContext(); - d->evaluate(ctx_p, program, lineNumber, fileName); - return d->toPublic(ctx_p->m_result); -} - -/*! - Returns the current context. - - The current context is typically accessed to retrieve the arguments - and `this' object in native functions; for convenience, it is - available as the first argument in QScriptEngine::FunctionSignature. -*/ -QScriptContext *QScriptEngine::currentContext() const -{ - Q_D(const QScriptEngine); - return QScriptContextPrivate::get(d->currentContext()); -} - -/*! - Enters a new execution context and returns the associated - QScriptContext object. - - Once you are done with the context, you should call popContext() to - restore the old context. - - By default, the `this' object of the new context is the Global Object. - The context's \l{QScriptContext::callee()}{callee}() will be invalid. - - This function is useful when you want to evaluate script code - as if it were the body of a function. You can use the context's - \l{QScriptContext::activationObject()}{activationObject}() to initialize - local variables that will be available to scripts. Example: - - \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 19 - - In the above example, the new variable "tmp" defined in the script - will be local to the context; in other words, the script doesn't - have any effect on the global environment. - - \sa popContext() -*/ -QScriptContext *QScriptEngine::pushContext() -{ - Q_D(QScriptEngine); - QScriptContextPrivate *ctx_p = d->pushContext(); - ctx_p->setThisObject(d->globalObject()); - QScriptValueImpl activation; - d->newActivation(&activation); - activation.setScope(d->globalObject()); - ctx_p->setActivationObject(activation); - return QScriptContextPrivate::get(ctx_p); -} - -/*! - Pops the current execution context and restores the previous one. - This function must be used in conjunction with pushContext(). - - \sa pushContext() -*/ -void QScriptEngine::popContext() -{ - Q_D(QScriptEngine); - if (d->currentContext() && d->currentContext()->parentContext()) - d->popContext(); -} - -/*! - Returns true if the last script evaluation resulted in an uncaught - exception; otherwise returns false. - - The exception state is cleared when evaluate() is called. - - \sa uncaughtException(), uncaughtExceptionLineNumber(), - uncaughtExceptionBacktrace() -*/ -bool QScriptEngine::hasUncaughtException() const -{ - Q_D(const QScriptEngine); - return d->hasUncaughtException(); -} - -/*! - Returns the current uncaught exception, or an invalid QScriptValue - if there is no uncaught exception. - - The exception value is typically an \c{Error} object; in that case, - you can call toString() on the return value to obtain an error - message. - - \sa hasUncaughtException(), uncaughtExceptionLineNumber(), - uncaughtExceptionBacktrace() -*/ -QScriptValue QScriptEngine::uncaughtException() const -{ - Q_D(const QScriptEngine); - return const_cast<QScriptEnginePrivate*>(d)->toPublic(d->uncaughtException()); -} - -/*! - Returns the line number where the last uncaught exception occurred. - - Line numbers are 1-based, unless a different base was specified as - the second argument to evaluate(). - - \sa hasUncaughtException(), uncaughtExceptionBacktrace() -*/ -int QScriptEngine::uncaughtExceptionLineNumber() const -{ - return QScriptContextPrivate::get(currentContext())->errorLineNumber; -} - -/*! - Returns a human-readable backtrace of the last uncaught exception. - - Each line is of the form \c{<function-name>(<arguments>)@<file-name>:<line-number>}. - - \sa uncaughtException() -*/ -QStringList QScriptEngine::uncaughtExceptionBacktrace() const -{ - Q_D(const QScriptEngine); - return d->uncaughtExceptionBacktrace(); -} - -/*! - \since 4.4 - - Clears any uncaught exceptions in this engine. - - \sa hasUncaughtException() -*/ -void QScriptEngine::clearExceptions() -{ - Q_D(QScriptEngine); - d->clearExceptions(); -} - -/*! - Returns the default prototype associated with the given \a metaTypeId, - or an invalid QScriptValue if no default prototype has been set. - - \sa setDefaultPrototype() -*/ -QScriptValue QScriptEngine::defaultPrototype(int metaTypeId) const -{ - Q_D(const QScriptEngine); - return const_cast<QScriptEnginePrivate*>(d)->toPublic(d->defaultPrototype(metaTypeId)); -} - -/*! - Sets the default prototype of the C++ type identified by the given - \a metaTypeId to \a prototype. - - The default prototype provides a script interface for values of - type \a metaTypeId when a value of that type is accessed from script - code. Whenever the script engine (implicitly or explicitly) creates - a QScriptValue from a value of type \a metaTypeId, the default - prototype will be set as the QScriptValue's prototype. - - The \a prototype object itself may be constructed using one of two - principal techniques; the simplest is to subclass QScriptable, which - enables you to define the scripting API of the type through QObject - properties and slots. Another possibility is to create a script - object by calling newObject(), and populate the object with the - desired properties (e.g. native functions wrapped with - newFunction()). - - \sa defaultPrototype(), qScriptRegisterMetaType(), QScriptable, {Default Prototypes Example} -*/ -void QScriptEngine::setDefaultPrototype(int metaTypeId, const QScriptValue &prototype) -{ - Q_D(QScriptEngine); - d->setDefaultPrototype(metaTypeId, d->toImpl(prototype)); -} - -/*! - \typedef QScriptEngine::FunctionSignature - \relates QScriptEngine - - The function signature \c{QScriptValue f(QScriptContext *, QScriptEngine *)}. - - A function with such a signature can be passed to - QScriptEngine::newFunction() to wrap the function. -*/ - -/*! - \typedef QScriptEngine::FunctionWithArgSignature - \relates QScriptEngine - - The function signature \c{QScriptValue f(QScriptContext *, QScriptEngine *, void *)}. - - A function with such a signature can be passed to - QScriptEngine::newFunction() to wrap the function. -*/ - -/*! - \typedef QScriptEngine::MarshalFunction - \internal -*/ - -/*! - \typedef QScriptEngine::DemarshalFunction - \internal -*/ - -/*! - \internal -*/ -QScriptValue QScriptEngine::create(int type, const void *ptr) -{ - Q_D(QScriptEngine); - return d->toPublic(d->create(type, ptr)); -} - -/*! - \internal -*/ -bool QScriptEngine::convert(const QScriptValue &value, int type, void *ptr) -{ - Q_D(QScriptEngine); - return QScriptEnginePrivate::convert(d->toImpl(value), type, ptr, d); -} - -/*! - \internal -*/ -bool QScriptEngine::convertV2(const QScriptValue &value, int type, void *ptr) -{ - QScriptValueImpl impl = QScriptValuePrivate::valueOf(value); - QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(value.engine()); - return QScriptEnginePrivate::convert(impl, type, ptr, eng_p); -} - -/*! - \internal -*/ -void QScriptEngine::registerCustomType(int type, MarshalFunction mf, - DemarshalFunction df, - const QScriptValue &prototype) -{ - Q_D(QScriptEngine); - QScriptCustomTypeInfo info = d->m_customTypes.value(type); - info.marshal = mf; - info.demarshal = df; - info.prototype = d->toImpl(prototype); - d->m_customTypes.insert(type, info); -} - -/*! - \since 4.5 - - Installs translator functions on the given \a object, or on the Global - Object if no object is specified. - - The relation between Qt Script translator functions and C++ translator - functions is described in the following table: - - \table - \header \o Script Function \o Corresponding C++ Function - \row \o qsTr() \o QObject::tr() - \row \o QT_TR_NOOP() \o QT_TR_NOOP() - \row \o qsTranslate() \o QCoreApplication::translate() - \row \o QT_TRANSLATE_NOOP() \o QT_TRANSLATE_NOOP() - \endtable - - \sa {Internationalization with Qt} -*/ -void QScriptEngine::installTranslatorFunctions(const QScriptValue &object) -{ - Q_D(QScriptEngine); - QScriptValue target = object.isObject() ? object : globalObject(); - QScriptValueImpl impl = QScriptValuePrivate::valueOf(target); - d->installTranslatorFunctions(impl); -} - -/*! - Imports the given \a extension into this QScriptEngine. Returns - undefinedValue() if the extension was successfully imported. You - can call hasUncaughtException() to check if an error occurred; in - that case, the return value is the value that was thrown by the - exception (usually an \c{Error} object). - - QScriptEngine ensures that a particular extension is only imported - once; subsequent calls to importExtension() with the same extension - name will do nothing and return undefinedValue(). - - \sa availableExtensions(), QScriptExtensionPlugin, {Creating QtScript Extensions} -*/ -QScriptValue QScriptEngine::importExtension(const QString &extension) -{ - Q_D(QScriptEngine); - return d->toPublic(d->importExtension(extension)); -} - -/*! - \since 4.4 - - Returns a list naming the available extensions that can be - imported using the importExtension() function. This list includes - extensions that have been imported. - - \sa importExtension(), importedExtensions() -*/ -QStringList QScriptEngine::availableExtensions() const -{ - Q_D(const QScriptEngine); - return d->availableExtensions(); -} - -/*! - \since 4.4 - - Returns a list naming the extensions that have been imported - using the importExtension() function. - - \sa availableExtensions() -*/ -QStringList QScriptEngine::importedExtensions() const -{ - Q_D(const QScriptEngine); - return d->importedExtensions(); -} - -/*! \fn QScriptValue QScriptEngine::toScriptValue(const T &value) - - Creates a QScriptValue with the given \a value. - - Note that the template type \c{T} must be known to QMetaType. - - See \l{Conversion Between QtScript and C++ Types} for a - description of the built-in type conversion provided by - QtScript. By default, the types that are not specially handled by - QtScript are represented as QVariants (e.g. the \a value is passed - to newVariant()); you can change this behavior by installing your - own type conversion functions with qScriptRegisterMetaType(). - - \warning This function is not available with MSVC 6. Use - qScriptValueFromValue() instead if you need to support that - version of the compiler. - - \sa fromScriptValue(), qScriptRegisterMetaType() -*/ - -/*! \fn T QScriptEngine::fromScriptValue(const QScriptValue &value) - - Returns the given \a value converted to the template type \c{T}. - - Note that \c{T} must be known to QMetaType. - - See \l{Conversion Between QtScript and C++ Types} for a - description of the built-in type conversion provided by - QtScript. - - \warning This function is not available with MSVC 6. Use - qScriptValueToValue() or qscriptvalue_cast() instead if you need - to support that version of the compiler. - - \sa toScriptValue(), qScriptRegisterMetaType() -*/ - -/*! - \fn QScriptValue qScriptValueFromValue(QScriptEngine *engine, const T &value) - \since 4.3 - \relates QScriptEngine - - Creates a QScriptValue using the given \a engine with the given \a - value of template type \c{T}. - - This function is equivalent to QScriptEngine::toScriptValue(). - It is provided as a work-around for MSVC 6, which doesn't support - member template functions. - - \sa qScriptValueToValue() -*/ - -/*! - \fn T qScriptValueToValue<T>(const QScriptValue &value) - \since 4.3 - \relates QScriptEngine - - Returns the given \a value converted to the template type \c{T}. - - This function is equivalent to QScriptEngine::fromScriptValue(). - It is provided as a work-around for MSVC 6, which doesn't - support member template functions. - - \sa qScriptValueFromValue() -*/ - -/*! - \fn QScriptValue qScriptValueFromSequence(QScriptEngine *engine, const Container &container) - \since 4.3 - \relates QScriptEngine - - Creates an array in the form of a QScriptValue using the given \a engine - with the given \a container of template type \c{Container}. - - The \c Container type must provide a \c const_iterator class to enable the - contents of the container to be copied into the array. - - Additionally, the type of each element in the sequence should be suitable - for conversion to a QScriptValue. - See \l{Making Applications Scriptable#Conversion Between QtScript and C++ Types} - {Conversion Between QtScript and C++ Types} for more information about the - restrictions on types that can be used with QScriptValue. - - \sa qScriptValueFromValue() -*/ - -/*! - \fn void qScriptValueToSequence(const QScriptValue &value, Container &container) - \since 4.3 - \relates QScriptEngine - - Copies the elements in the sequence specified by \a value to the given - \a container of template type \c{Container}. - - The \a value used is typically an array, but any container can be copied - as long as it provides a \c length property describing how many elements - it contains. - - Additionally, the type of each element in the sequence must be suitable - for conversion to a C++ type from a QScriptValue. - See \l{Making Applications Scriptable#Conversion Between QtScript and C++ Types} - {Conversion Between QtScript and C++ Types} for more information about the - restrictions on types that can be used with QScriptValue. - - \sa qscriptvalue_cast() -*/ - -/*! - \fn T qscriptvalue_cast<T>(const QScriptValue &value) - \since 4.3 - \relates QScriptValue - - Returns the given \a value converted to the template type \c{T}. - - \sa qScriptRegisterMetaType(), QScriptEngine::toScriptValue() -*/ - -/*! \fn int qScriptRegisterMetaType( - QScriptEngine *engine, - QScriptValue (*toScriptValue)(QScriptEngine *, const T &t), - void (*fromScriptValue)(const QScriptValue &, T &t), - const QScriptValue &prototype = QScriptValue()) - \relates QScriptEngine - - Registers the type \c{T} in the given \a engine. \a toScriptValue must - be a function that will convert from a value of type \c{T} to a - QScriptValue, and \a fromScriptValue a function that does the - opposite. \a prototype, if valid, is the prototype that's set on - QScriptValues returned by \a toScriptValue. - - Returns the internal ID used by QMetaType. - - You only need to call this function if you want to provide custom - conversion of values of type \c{T}, i.e. if the default - QVariant-based representation and conversion is not - appropriate. (Note that custom QObject-derived types also fall in - this category; e.g. for a QObject-derived class called MyObject, - you probably want to define conversion functions for MyObject* - that utilize QScriptEngine::newQObject() and - QScriptValue::toQObject().) - - If you only want to define a common script interface for values of - type \c{T}, and don't care how those values are represented - (i.e. storing them in QVariants is fine), use - \l{QScriptEngine::setDefaultPrototype()}{setDefaultPrototype}() - instead; this will minimize conversion costs. - - You need to declare the custom type first with - Q_DECLARE_METATYPE(). - - After a type has been registered, you can convert from a - QScriptValue to that type using - \l{QScriptEngine::fromScriptValue()}{fromScriptValue}(), and - create a QScriptValue from a value of that type using - \l{QScriptEngine::toScriptValue()}{toScriptValue}(). The engine - will take care of calling the proper conversion function when - calling C++ slots, and when getting or setting a C++ property; - i.e. the custom type may be used seamlessly on both the C++ side - and the script side. - - The following is an example of how to use this function. We will - specify custom conversion of our type \c{MyStruct}. Here's the C++ - type: - - \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 20 - - We must declare it so that the type will be known to QMetaType: - - \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 21 - - Next, the \c{MyStruct} conversion functions. We represent the - \c{MyStruct} value as a script object and just copy the properties: - - \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 22 - - Now we can register \c{MyStruct} with the engine: - \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 23 - - Working with \c{MyStruct} values is now easy: - \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 24 - - If you want to be able to construct values of your custom type - from script code, you have to register a constructor function for - the type. For example: - - \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 25 - - \sa qScriptRegisterSequenceMetaType(), qRegisterMetaType() -*/ - -/*! - \macro Q_SCRIPT_DECLARE_QMETAOBJECT(QMetaObject, ArgType) - \since 4.3 - \relates QScriptEngine - - Declares the given \a QMetaObject. Used in combination with - QScriptEngine::scriptValueFromQMetaObject() to make enums and - instantiation of \a QMetaObject available to script code. The - constructor generated by this macro takes a single argument of - type \a ArgType; typically the argument is the parent type of the - new instance, in which case \a ArgType is \c{QWidget*} or - \c{QObject*}. Objects created by the constructor will have - QScriptEngine::AutoOwnership ownership. -*/ - -/*! \fn int qScriptRegisterSequenceMetaType( - QScriptEngine *engine, - const QScriptValue &prototype = QScriptValue()) - \relates QScriptEngine - - Registers the sequence type \c{T} in the given \a engine. This - function provides conversion functions that convert between \c{T} - and Qt Script \c{Array} objects. \c{T} must provide a - const_iterator class and begin(), end() and push_back() - functions. If \a prototype is valid, it will be set as the - prototype of \c{Array} objects due to conversion from \c{T}; - otherwise, the standard \c{Array} prototype will be used. - - Returns the internal ID used by QMetaType. - - You need to declare the container type first with - Q_DECLARE_METATYPE(). If the element type isn't a standard Qt/C++ - type, it must be declared using Q_DECLARE_METATYPE() as well. - Example: - - \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 26 - - \sa qScriptRegisterMetaType() -*/ - -/*! - Runs the garbage collector. - - The garbage collector will attempt to reclaim memory by locating and - disposing of objects that are no longer reachable in the script - environment. - - Normally you don't need to call this function; the garbage collector - will automatically be invoked when the QScriptEngine decides that - it's wise to do so (i.e. when a certain number of new objects have - been created). However, you can call this function to explicitly - request that garbage collection should be performed as soon as - possible. -*/ -void QScriptEngine::collectGarbage() -{ - Q_D(QScriptEngine); - d->gc(); -} - -/*! - - Sets the interval between calls to QCoreApplication::processEvents - to \a interval milliseconds. - - While the interpreter is running, all event processing is by default - blocked. This means for instance that the gui will not be updated - and timers will not be fired. To allow event processing during - interpreter execution one can specify the processing interval to be - a positive value, indicating the number of milliseconds between each - time QCoreApplication::processEvents() is called. - - The default value is -1, which disables event processing during - interpreter execution. - - You can use QCoreApplication::postEvent() to post an event that - performs custom processing at the next interval. For example, you - could keep track of the total running time of the script and call - abortEvaluation() when you detect that the script has been running - for a long time without completing. - - \sa processEventsInterval() -*/ -void QScriptEngine::setProcessEventsInterval(int interval) -{ - Q_D(QScriptEngine); - d->m_processEventsInterval = interval; -} - -/*! - - Returns the interval in milliseconds between calls to - QCoreApplication::processEvents() while the interpreter is running. - - \sa setProcessEventsInterval() -*/ -int QScriptEngine::processEventsInterval() const -{ - Q_D(const QScriptEngine); - return d->m_processEventsInterval; -} - -/*! - \since 4.4 - - Returns true if this engine is currently evaluating a script, - otherwise returns false. - - \sa evaluate(), abortEvaluation() -*/ -bool QScriptEngine::isEvaluating() const -{ - Q_D(const QScriptEngine); - return d->m_evaluating; -} - -/*! - \since 4.4 - - Aborts any script evaluation currently taking place in this engine. - The given \a result is passed back as the result of the evaluation - (i.e. it is returned from the call to evaluate() being aborted). - - If the engine isn't evaluating a script (i.e. isEvaluating() returns - false), this function does nothing. - - Call this function if you need to abort a running script for some - reason, e.g. when you have detected that the script has been - running for several seconds without completing. - - \sa evaluate(), isEvaluating(), setProcessEventsInterval() -*/ -void QScriptEngine::abortEvaluation(const QScriptValue &result) -{ - Q_D(QScriptEngine); - d->abortEvaluation(d->toImpl(result)); -} - -#ifndef QT_NO_QOBJECT - -/*! - \since 4.4 - \relates QScriptEngine - - Creates a connection from the \a signal in the \a sender to the - given \a function. If \a receiver is an object, it will act as the - `this' object when the signal handler function is invoked. Returns - true if the connection succeeds; otherwise returns false. - - \sa qScriptDisconnect(), QScriptEngine::signalHandlerException() -*/ -bool qScriptConnect(QObject *sender, const char *signal, - const QScriptValue &receiver, const QScriptValue &function) -{ - if (!sender || !signal) - return false; - if (!function.isFunction()) - return false; - if (receiver.isObject() && (receiver.engine() != function.engine())) - return false; - QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(function.engine()); - return eng_p->scriptConnect(sender, signal, - eng_p->toImpl(receiver), - eng_p->toImpl(function), - Qt::AutoConnection); -} - -/*! - \since 4.4 - \relates QScriptEngine - - Disconnects the \a signal in the \a sender from the given (\a - receiver, \a function) pair. Returns true if the connection is - successfully broken; otherwise returns false. - - \sa qScriptConnect() -*/ -bool qScriptDisconnect(QObject *sender, const char *signal, - const QScriptValue &receiver, const QScriptValue &function) -{ - if (!sender || !signal) - return false; - if (!function.isFunction()) - return false; - if (receiver.isObject() && (receiver.engine() != function.engine())) - return false; - QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(function.engine()); - return eng_p->scriptDisconnect(sender, signal, - eng_p->toImpl(receiver), - eng_p->toImpl(function)); -} - -/*! - \since 4.4 - \fn void QScriptEngine::signalHandlerException(const QScriptValue &exception) - - This signal is emitted when a script function connected to a signal causes - an \a exception. - - \sa qScriptConnect() -*/ - -QT_BEGIN_INCLUDE_NAMESPACE -#include "moc_qscriptengine.cpp" -QT_END_INCLUDE_NAMESPACE - -#endif // QT_NO_QOBJECT - -/*! - \since 4.4 - - Installs the given \a agent on this engine. The agent will be - notified of various events pertaining to script execution. This is - useful when you want to find out exactly what the engine is doing, - e.g. when evaluate() is called. The agent interface is the basis of - tools like debuggers and profilers. - - The engine maintains ownership of the \a agent. - - Calling this function will replace the existing agent, if any. - - \sa agent() -*/ -void QScriptEngine::setAgent(QScriptEngineAgent *agent) -{ - Q_D(QScriptEngine); - d->setAgent(agent); -} - -/*! - \since 4.4 - - Returns the agent currently installed on this engine, or 0 if no - agent is installed. - - \sa setAgent() -*/ -QScriptEngineAgent *QScriptEngine::agent() const -{ - Q_D(const QScriptEngine); - return d->agent(); -} - -/*! - \since 4.4 - - Returns a handle that represents the given string, \a str. - - QScriptString can be used to quickly look up properties, and - compare property names, of script objects. - - \sa QScriptValue::property() -*/ -QScriptString QScriptEngine::toStringHandle(const QString &str) -{ - Q_D(QScriptEngine); - return d->internedString(str); -} - -/*! - \since 4.5 - - Converts the given \a value to an object, if such a conversion is - possible; otherwise returns an invalid QScriptValue. The conversion - is performed according to the following table: - - \table - \header \o Input Type \o Result - \row \o Undefined \o An invalid QScriptValue. - \row \o Null \o An invalid QScriptValue. - \row \o Boolean \o A new Boolean object whose internal value is set to the value of the boolean. - \row \o Number \o A new Number object whose internal value is set to the value of the number. - \row \o String \o A new String object whose internal value is set to the value of the string. - \row \o Object \o The result is the object itself (no conversion). - \endtable - - \sa newObject() -*/ -QScriptValue QScriptEngine::toObject(const QScriptValue &value) -{ - Q_D(QScriptEngine); - return d->toPublic(d->toObject(d->toImpl(value))); -} - -/*! - \internal - - Returns the object with the given \a id, or an invalid - QScriptValue if there is no object with that id. - - \sa QScriptValue::objectId() -*/ -QScriptValue QScriptEngine::objectById(qint64 id) const -{ - Q_D(const QScriptEngine); - return const_cast<QScriptEnginePrivate*>(d)->toPublic(d->objectById(id)); -} - -/*! - \since 4.5 - \class QScriptSyntaxCheckResult - - \brief The QScriptSyntaxCheckResult class provides the result of a script syntax check. - - \ingroup script - - - QScriptSyntaxCheckResult is returned by QScriptEngine::checkSyntax() to - provide information about the syntactical (in)correctness of a script. -*/ - -/*! - \enum QScriptSyntaxCheckResult::State - - This enum specifies the state of a syntax check. - - \value Error The program contains a syntax error. - \value Intermediate The program is incomplete. - \value Valid The program is a syntactically correct Qt Script program. -*/ - -/*! - Constructs a new QScriptSyntaxCheckResult from the \a other result. -*/ -QScriptSyntaxCheckResult::QScriptSyntaxCheckResult(const QScriptSyntaxCheckResult &other) - : d_ptr(other.d_ptr) -{ - if (d_ptr) - d_ptr->ref.ref(); -} - -/*! - \internal -*/ -QScriptSyntaxCheckResult::QScriptSyntaxCheckResult(QScriptSyntaxCheckResultPrivate *d) - : d_ptr(d) -{ - if (d_ptr) - d_ptr->ref.ref(); -} - -/*! - \internal -*/ -QScriptSyntaxCheckResult::QScriptSyntaxCheckResult() - : d_ptr(0) -{ -} - -/*! - Destroys this QScriptSyntaxCheckResult. -*/ -QScriptSyntaxCheckResult::~QScriptSyntaxCheckResult() -{ - if (d_ptr && !d_ptr->ref.deref()) { - delete d_ptr; - d_ptr = 0; - } -} - -/*! - Returns the state of this QScriptSyntaxCheckResult. -*/ -QScriptSyntaxCheckResult::State QScriptSyntaxCheckResult::state() const -{ - Q_D(const QScriptSyntaxCheckResult); - return d->state; -} - -/*! - Returns the error line number of this QScriptSyntaxCheckResult, or -1 if - there is no error. - - \sa state(), errorMessage() -*/ -int QScriptSyntaxCheckResult::errorLineNumber() const -{ - Q_D(const QScriptSyntaxCheckResult); - return d->errorLineNumber; -} - -/*! - Returns the error column number of this QScriptSyntaxCheckResult, or -1 if - there is no error. - - \sa state(), errorLineNumber() -*/ -int QScriptSyntaxCheckResult::errorColumnNumber() const -{ - Q_D(const QScriptSyntaxCheckResult); - return d->errorColumnNumber; -} - -/*! - Returns the error message of this QScriptSyntaxCheckResult, or an empty - string if there is no error. - - \sa state(), errorLineNumber() -*/ -QString QScriptSyntaxCheckResult::errorMessage() const -{ - Q_D(const QScriptSyntaxCheckResult); - return d->errorMessage; -} - -/*! - Assigns the \a other result to this QScriptSyntaxCheckResult, and returns a - reference to this QScriptSyntaxCheckResult. -*/ -QScriptSyntaxCheckResult &QScriptSyntaxCheckResult::operator=(const QScriptSyntaxCheckResult &other) -{ - if (d_ptr == other.d_ptr) - return *this; - if (d_ptr && !d_ptr->ref.deref()) { - delete d_ptr; - d_ptr = 0; - } - d_ptr = other.d_ptr; - if (d_ptr) - d_ptr->ref.ref(); - return *this; -} - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptengine_p.cpp b/src/script/qscriptengine_p.cpp deleted file mode 100644 index 8f64512..0000000 --- a/src/script/qscriptengine_p.cpp +++ /dev/null @@ -1,2732 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qscriptengine_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" -#include "qscriptlexer_p.h" -#include "qscriptnodepool_p.h" -#include "qscriptparser_p.h" -#include "qscriptcompiler_p.h" -#include "qscriptvalueiteratorimpl_p.h" -#include "qscriptecmaglobal_p.h" -#include "qscriptecmamath_p.h" -#include "qscriptecmaarray_p.h" -#include "qscriptextenumeration_p.h" -#include "qscriptsyntaxchecker_p.h" -#include "qscriptsyntaxcheckresult_p.h" -#include "qscriptclass.h" -#include "qscriptclass_p.h" -#include "qscriptengineagent.h" - -#include <QtCore/QDate> -#include <QtCore/QDateTime> -#include <QtCore/QRegExp> -#include <QtCore/QStringList> -#include <QtCore/QVariant> - -#ifndef QT_NO_QOBJECT -#include "qscriptextensioninterface.h" -#include <QtCore/QDir> -#include <QtCore/QFile> -#include <QtCore/QFileInfo> -#include <QtCore/QTextStream> -#include <QtCore/QCoreApplication> -#include <QtCore/QPluginLoader> -#endif - -Q_DECLARE_METATYPE(QScriptValue) -#ifndef QT_NO_QOBJECT -Q_DECLARE_METATYPE(QObjectList) -#endif -Q_DECLARE_METATYPE(QList<int>) - -QT_BEGIN_NAMESPACE - -extern char *qdtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **digits_str); -extern double qstrtod(const char *s00, char const **se, bool *ok); - -namespace QScript { - -QString numberToString(qsreal value) -{ - if (qIsNaN(value)) - return QLatin1String("NaN"); - - else if (qIsInf(value)) - return QLatin1String(value < 0 ? "-Infinity" : "Infinity"); - - else if (value == 0) - return QLatin1String("0"); - - QByteArray buf; - buf.reserve(80); - - int decpt; - int sign; - char *result = 0; - (void) qdtoa(value, 0, 0, &decpt, &sign, 0, &result); - - if (! result) - return QString(); - - else if (decpt <= 0 && decpt > -6) { - - buf.fill('0', -decpt + 2 + sign); - - if (sign) // fix the sign. - buf[0] = '-'; - - buf[sign + 1] = '.'; - buf += result; - } - - else { - if (sign) - buf += '-'; - - buf += result; - int length = buf.length() - sign; - - if (decpt <= 21 && decpt > 0) { - if (length <= decpt) - buf += QByteArray().fill('0', decpt - length); - else - buf.insert(decpt + sign, '.'); - } - - else if (result[0] >= '0' && result[0] <= '9') { - if (length > 1) - buf.insert(1 + sign, '.'); - - buf += 'e'; - buf += (decpt >= 0) ? '+' : '-'; - - int e = decpt - 1; - - if (e < 0) - e = -e; - - if (e >= 100) - buf += '0' + e / 100; - - if (e >= 10) - buf += '0' + (e % 100) / 10; - - buf += '0' + e % 10; - } - } - - free(result); - - return QString::fromLatin1(buf); -} - -static int toDigit(char c) -{ - if ((c >= '0') && (c <= '9')) - return c - '0'; - else if ((c >= 'a') && (c <= 'z')) - return 10 + c - 'a'; - else if ((c >= 'A') && (c <= 'Z')) - return 10 + c - 'A'; - return -1; -} - -qsreal integerFromString(const char *buf, int size, int radix) -{ - if (size == 0) - return qSNaN(); - - qsreal sign = 1.0; - int i = 0; - if (buf[0] == '+') { - ++i; - } else if (buf[0] == '-') { - sign = -1.0; - ++i; - } - - if (((size-i) >= 2) && (buf[i] == '0')) { - if (((buf[i+1] == 'x') || (buf[i+1] == 'X')) - && (radix < 34)) { - if ((radix != 0) && (radix != 16)) - return 0; - radix = 16; - i += 2; - } else { - if (radix == 0) { - radix = 8; - ++i; - } - } - } else if (radix == 0) { - radix = 10; - } - - int j = i; - for ( ; i < size; ++i) { - int d = toDigit(buf[i]); - if ((d == -1) || (d >= radix)) - break; - } - qsreal result; - if (j == i) { - if (!qstrcmp(buf, "Infinity")) - result = qInf(); - else - result = qSNaN(); - } else { - result = 0; - qsreal multiplier = 1; - for (--i ; i >= j; --i, multiplier *= radix) - result += toDigit(buf[i]) * multiplier; - } - result *= sign; - return result; -} - -qsreal integerFromString(const QString &str, int radix) -{ - QByteArray ba = str.trimmed().toUtf8(); - return integerFromString(ba.constData(), ba.size(), radix); -} - -qsreal numberFromString(const QString &repr) -{ - QString str = repr.trimmed(); - if ((str.length() > 2) && (str.at(0) == QLatin1Char('0')) && (str.at(1).toUpper() == QLatin1Char('X'))) - return integerFromString(str.mid(2), 16); - QByteArray latin1 = str.toLatin1(); - const char *data = latin1.constData(); - const char *eptr = 0; - qsreal result = qstrtod(data, &eptr, 0); - if (eptr == data) { - if (str == QLatin1String("Infinity")) - result = +qInf(); - else if (str == QLatin1String("+Infinity")) - result = +qInf(); - else if (str == QLatin1String("-Infinity")) - result = -qInf(); - else if (str.isEmpty()) - result = 0; - else - result = qSNaN(); - } else if (eptr != (data + latin1.length())) { - result = qSNaN(); - } - return result; -} - -NodePool::NodePool(const QString &fileName, QScriptEnginePrivate *engine) - : m_fileName(fileName), m_engine(engine) -{ -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - m_id = engine->nextScriptId(); -#endif -} - -NodePool::~NodePool() -{ - qDeleteAll(m_codeCache); - m_codeCache.clear(); - -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - m_engine->notifyScriptUnload(id()); -#endif -} - -Code *NodePool::createCompiledCode(AST::Node *node, CompilationUnit &compilation) -{ - QHash<AST::Node*, Code*>::const_iterator it = m_codeCache.constFind(node); - if (it != m_codeCache.constEnd()) - return it.value(); - - Code *code = new Code(); - code->init(compilation, this); - - m_codeCache.insert(node, code); - return code; -} - -class EvalFunction : public QScriptFunction -{ -public: - EvalFunction(QScriptEnginePrivate *) - { length = 1; } - - virtual ~EvalFunction() {} - - void evaluate(QScriptContextPrivate *context, const QString &contents, - int lineNo, const QString &fileName, bool calledFromScript) - { - QScriptEnginePrivate *eng_p = context->engine(); - - QExplicitlySharedDataPointer<NodePool> pool; - pool = new NodePool(fileName, eng_p); - eng_p->setNodePool(pool.data()); - - QString errorMessage; - int errorLineNumber; - AST::Node *program = eng_p->createAbstractSyntaxTree( - contents, lineNo, &errorMessage, &errorLineNumber); - - eng_p->setNodePool(0); - -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - eng_p->notifyScriptLoad(pool->id(), contents, fileName, lineNo); -#endif - - Code *code = 0; - if (program) { - Compiler compiler(eng_p); - compiler.setTopLevelCompiler(true); - CompilationUnit compilation = compiler.compile(program); - if (!compilation.isValid()) { - errorMessage = compilation.errorMessage(); - errorLineNumber = compilation.errorLineNumber(); - } else { - code = pool->createCompiledCode(program, compilation); - } - } - - if (!code) { - context->errorLineNumber = errorLineNumber; - context->currentLine = errorLineNumber; -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - Code *oldCode = context->m_code; - Code dummy; - dummy.astPool = pool.data(); - context->m_code = &dummy; // so agents get the script ID - bool wasEvaluating = eng_p->m_evaluating; - eng_p->m_evaluating = true; - eng_p->notifyFunctionEntry(context); -#endif - context->throwError(QScriptContext::SyntaxError, errorMessage); -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - eng_p->notifyFunctionExit(context); - eng_p->m_evaluating = wasEvaluating; - context->m_code = oldCode; -#endif - return; - } - - if (calledFromScript) { - if (QScriptContextPrivate *pc = context->parentContext()) { - context->setActivationObject(pc->activationObject()); - context->setThisObject(pc->thisObject()); - context->m_scopeChain = pc->m_scopeChain; - } - } - - const QScriptInstruction *iPtr = context->instructionPointer(); - context->execute(code); - context->setInstructionPointer(iPtr); - } - - virtual void execute(QScriptContextPrivate *context) - { - QScriptEnginePrivate *eng = context->engine(); - int lineNo = context->currentLine; - if (lineNo == -1) { - QScriptContextPrivate *pc = context->parentContext(); - if (pc) - lineNo = pc->currentLine; - else - lineNo = 1; - } - QString fileName; // don't set this for now, we don't want to change the official eval() for now. - - if (context->argumentCount() == 0) { - context->setReturnValue(eng->undefinedValue()); - } else { - QScriptValueImpl arg = context->argument(0); - if (arg.isString()) { - QString contents = arg.toString(); - evaluate(context, contents, lineNo, fileName, /*calledFromScript=*/true); - } else { - context->setReturnValue(arg); - } - } - } - - QString functionName() const - { - return QLatin1String("eval"); - } -}; - -class ArgumentsClassData: public QScriptClassData -{ - -public: - - static inline QScript::ArgumentsObjectData *get(const QScriptValueImpl &object) - { return static_cast<QScript::ArgumentsObjectData*>(object.objectData()); } - - virtual bool resolve(const QScriptValueImpl &object, QScriptNameIdImpl *nameId, - QScript::Member *member, QScriptValueImpl *base, - QScript::AccessMode access); - virtual bool get(const QScriptValueImpl &object, const QScript::Member &member, - QScriptValueImpl *out_value); - virtual bool put(QScriptValueImpl *object, const QScript::Member &member, - const QScriptValueImpl &value); - virtual void mark(const QScriptValueImpl &object, int generation); - virtual QScriptClassDataIterator *newIterator(const QScriptValueImpl &object); -}; - -class ArgumentsClassDataIterator: public QScriptClassDataIterator -{ -public: - ArgumentsClassDataIterator(ArgumentsObjectData *data); - virtual ~ArgumentsClassDataIterator(); - - virtual bool hasNext() const; - virtual void next(QScript::Member *member); - - virtual bool hasPrevious() const; - virtual void previous(QScript::Member *member); - - virtual void toFront(); - virtual void toBack(); - -private: - ArgumentsObjectData *m_data; - uint m_pos; -}; - -bool ArgumentsClassData::resolve(const QScriptValueImpl &object, QScriptNameIdImpl *nameId, - QScript::Member *member, QScriptValueImpl *base, - QScript::AccessMode /*access*/) -{ - QString propertyName = object.engine()->toString(nameId); - bool isNumber; - quint32 index = propertyName.toUInt(&isNumber); - if (isNumber) { - QScript::ArgumentsObjectData *data = ArgumentsClassData::get(object); - if (index < data->length) { - member->native(/*nameId=*/0, index, QScriptValue::SkipInEnumeration); - *base = object; - return true; - } - } - - return false; -} - -bool ArgumentsClassData::get(const QScriptValueImpl &object, const QScript::Member &member, - QScriptValueImpl *out_value) -{ - QScript::ArgumentsObjectData *data = ArgumentsClassData::get(object); - if (member.nameId() == 0) { - QScriptObject *activation_data = data->activation.objectValue(); - *out_value = activation_data->m_values[member.id()]; - return true; - } - return false; -} - -bool ArgumentsClassData::put(QScriptValueImpl *object, const QScript::Member &member, - const QScriptValueImpl &value) -{ - Q_ASSERT(member.nameId() == 0); - QScript::ArgumentsObjectData *data = ArgumentsClassData::get(*object); - QScriptObject *activation_data = data->activation.objectValue(); - activation_data->m_values[member.id()] = value; - return true; -} - -void ArgumentsClassData::mark(const QScriptValueImpl &object, int generation) -{ - QScript::ArgumentsObjectData *data = ArgumentsClassData::get(object); - data->activation.mark(generation); -} - -QScriptClassDataIterator *ArgumentsClassData::newIterator(const QScriptValueImpl &object) -{ - QScript::ArgumentsObjectData *data = ArgumentsClassData::get(object); - return new ArgumentsClassDataIterator(data); -} - -ArgumentsClassDataIterator::ArgumentsClassDataIterator(ArgumentsObjectData *data) - : m_data(data), m_pos(0) -{ -} - -ArgumentsClassDataIterator::~ArgumentsClassDataIterator() -{ -} - -bool ArgumentsClassDataIterator::hasNext() const -{ - return m_pos < m_data->length; -} - -void ArgumentsClassDataIterator::next(QScript::Member *member) -{ - if (m_pos == m_data->length) { - member->invalidate(); - } else { - member->native(/*nameId=*/0, m_pos, QScriptValue::SkipInEnumeration); - ++m_pos; - } -} - -bool ArgumentsClassDataIterator::hasPrevious() const -{ - return (m_pos != 0); -} - -void ArgumentsClassDataIterator::previous(QScript::Member *member) -{ - if (m_pos == 0) { - member->invalidate(); - } else { - --m_pos; - member->native(/*nameId=*/0, m_pos, QScriptValue::SkipInEnumeration); - } -} - -void ArgumentsClassDataIterator::toFront() -{ - m_pos = 0; -} - -void ArgumentsClassDataIterator::toBack() -{ - m_pos = m_data->length; -} - -} // namespace QScript - -const qsreal QScriptEnginePrivate::D16 = 65536.0; -const qsreal QScriptEnginePrivate::D32 = 4294967296.0; - -QScriptEnginePrivate::~QScriptEnginePrivate() -{ - while (!m_agents.isEmpty()) - delete m_agents.takeFirst(); - - // invalidate values that we have references to - { - QHash<QScriptObject*, QScriptValuePrivate*>::const_iterator it; - for (it = m_objectHandles.constBegin(); it != m_objectHandles.constEnd(); ++it) - (*it)->invalidate(); - } - { - QHash<QScriptNameIdImpl*, QScriptValuePrivate*>::const_iterator it; - for (it = m_stringHandles.constBegin(); it != m_stringHandles.constEnd(); ++it) - (*it)->invalidate(); - } - { - QVector<QScriptValuePrivate*>::const_iterator it; - for (it = m_otherHandles.constBegin(); it != m_otherHandles.constEnd(); ++it) - (*it)->invalidate(); - } - - // invalidate interned strings that are known to the outside world - { - QHash<QScriptNameIdImpl*, QScriptStringPrivate*>::const_iterator it; - for (it = m_internedStrings.constBegin(); it != m_internedStrings.constEnd(); ++it) - it.value()->nameId = 0; - } - - delete[] m_string_hash_base; - qDeleteAll(m_stringRepository); - qDeleteAll(m_tempStringRepository); - - if (tempStackBegin) - delete[] tempStackBegin; - -#ifndef QT_NO_QOBJECT - deletePendingQObjects(); - qDeleteAll(m_qobjectData); -# ifndef Q_SCRIPT_NO_QMETAOBJECT_CACHE - qDeleteAll(m_cachedMetaObjects); -# endif -#endif - - qDeleteAll(m_allocated_classes); -} - -QScript::AST::Node *QScriptEnginePrivate::changeAbstractSyntaxTree(QScript::AST::Node *prg) -{ - QScript::AST::Node *was = m_abstractSyntaxTree; - m_abstractSyntaxTree = prg; - return was; -} - -QScript::AST::Node *QScriptEnginePrivate::createAbstractSyntaxTree( - const QString &source, int lineNumber, QString *errorMessage, int *errorLineNumber) -{ - QScript::Lexer lex(this); - setLexer(&lex); - lex.setCode(source, lineNumber); - - QScriptParser parser; - - if (! parser.parse(this)) { - if (errorMessage) - *errorMessage = parser.errorMessage(); - if (errorLineNumber) - *errorLineNumber = parser.errorLineNumber(); - return 0; - } - - return abstractSyntaxTree(); -} - -void QScriptEnginePrivate::markObject(const QScriptValueImpl &object, int generation) -{ - QScriptObject *instance = object.objectValue(); - QScript::GCBlock *block = QScript::GCBlock::get(instance); - - enum { MAX_GC_DEPTH = 32 }; - - if (block->generation + 1 != generation) - return; - - if (m_gc_depth >= MAX_GC_DEPTH) { - // do the marking later - m_markStack.append(object); - return; - } - - ++block->generation; - ++m_gc_depth; - - if (QScriptClassData *data = object.classInfo()->data()) - data->mark(object, generation); - - if (instance->m_prototype.isObject()) - markObject(instance->m_prototype, generation); - - if (instance->m_scope.isObject()) - markObject(instance->m_scope, generation); - - const QScriptValueImpl &internalValue = instance->m_internalValue; - - if (internalValue.isValid()) { - if (internalValue.isObject()) - markObject(internalValue, generation); - - else if (internalValue.isString()) - markString(internalValue.m_string_value, generation); - } - - int garbage = 0; - - for (int i = 0; i < instance->memberCount(); ++i) { - QScript::Member m; - instance->member(i, &m); - - if (! m.isValid()) { - ++garbage; - continue; - } - - Q_ASSERT(m.isObjectProperty()); - - QScriptValueImpl child; - instance->get(m, &child); - - if (m.nameId()) - markString(m.nameId(), generation); - - if (! child.isValid()) - continue; - - else if (child.isObject()) - markObject(child, generation); - - else if (child.isString()) - markString(child.m_string_value, generation); - } - - --m_gc_depth; - - if (garbage < 128) // ### - return; - - int j = 0; - for (int i = 0; i < instance->memberCount(); ++i) { - QScript::Member m; - instance->member(i, &m); - - if (! m.isValid()) - continue; - - if (i != j) { - instance->m_members[j].object(m.nameId(), j, m.flags()); - instance->m_values[j] = instance->m_values[i]; - } - ++j; - } - //qDebug() << "==> old:" << instance->m_members.size() << "new:" << j; - instance->m_members.resize(j); - instance->m_values.resize(j); -} - -void QScriptEnginePrivate::markFrame(QScriptContextPrivate *context, int generation) -{ - QScriptValueImpl activation = context->activationObject(); - QScriptValueImpl thisObject = context->thisObject(); - QScriptValueImpl scopeChain = context->m_scopeChain; - QScriptValueImpl callee = context->m_callee; - QScriptValueImpl arguments = context->m_arguments; - - if (activation.isObject()) - markObject(activation, generation); - - if (scopeChain.isObject()) - markObject(scopeChain, generation); - - if (thisObject.isObject()) - markObject(thisObject, generation); - - if (callee.isObject()) - markObject(callee, generation); - - if (arguments.isObject()) - markObject(arguments, generation); - - if (context->returnValue().isValid()) { - if (context->returnValue().isObject()) - markObject(context->returnValue(), generation); - - else if (context->returnValue().isString()) - markString(context->returnValue().m_string_value, generation); - } - - if (context->baseStackPointer() != context->currentStackPointer()) { - // mark the temp stack - - for (const QScriptValueImpl *it = context->baseStackPointer(); it != (context->currentStackPointer() + 1); ++it) { - if (! it) { - qWarning() << "no temp stack!!!"; - break; - } - - else if (! it->isValid()) // ### assert? - continue; - - else if (it->isObject()) - markObject(*it, generation); - - else if (it->isString()) - markString(it->m_string_value, generation); - } - } -} - -bool QScriptEnginePrivate::isCollecting() const -{ - return (m_gc_depth != -1) || objectAllocator.sweeping(); -} - -void QScriptEnginePrivate::maybeGC_helper(bool do_string_gc) -{ - // qDebug() << "==>" << objectAllocator.newAllocatedBlocks() << "free:" << objectAllocator.freeBlocks(); - Q_ASSERT(m_gc_depth == -1); - ++m_gc_depth; - - int generation = m_objectGeneration + 1; - - markObject(m_globalObject, generation); - - objectConstructor->mark(this, generation); - numberConstructor->mark(this, generation); - booleanConstructor->mark(this, generation); - stringConstructor->mark(this, generation); - dateConstructor->mark(this, generation); - functionConstructor->mark(this, generation); - arrayConstructor->mark(this, generation); - regexpConstructor->mark(this, generation); - errorConstructor->mark(this, generation); - enumerationConstructor->mark(this, generation); - variantConstructor->mark(this, generation); -#ifndef QT_NO_QOBJECT - qobjectConstructor->mark(this, generation); - qmetaObjectConstructor->mark(this, generation); -#endif - - { - QScriptContextPrivate *current = currentContext(); - while (current != 0) { - markFrame (current, generation); - current = current->parentContext(); - } - } - - { - QHash<QScriptObject*, QScriptValuePrivate*>::const_iterator it; - for (it = m_objectHandles.constBegin(); it != m_objectHandles.constEnd(); ++it) - markObject((*it)->value, generation); - } - - { - QHash<QScriptNameIdImpl*, QScriptValuePrivate*>::const_iterator it; - for (it = m_stringHandles.constBegin(); it != m_stringHandles.constEnd(); ++it) - markString((*it)->value.stringValue(), generation); - } - - { - QHash<int, QScriptCustomTypeInfo>::const_iterator it; - for (it = m_customTypes.constBegin(); it != m_customTypes.constEnd(); ++it) - (*it).prototype.mark(generation); - } - -#ifndef QT_NO_QOBJECT -# ifndef Q_SCRIPT_NO_QMETAOBJECT_CACHE - { - QHash<const QMetaObject*, QScriptMetaObject*>::const_iterator it; - for (it = m_cachedMetaObjects.constBegin(); it != m_cachedMetaObjects.constEnd(); ++it) { - { - QList<QScriptNameIdImpl*> memberNames = (*it)->registeredMemberNames(); - QList<QScriptNameIdImpl*>::const_iterator it2; - for (it2 = memberNames.constBegin(); it2 != memberNames.constEnd(); ++it2) - markString(*it2, generation); - } - { - QList<QScriptValueImpl> propertyAccessors = (*it)->registeredPropertyAccessors(); - QList<QScriptValueImpl>::const_iterator it2; - for (it2 = propertyAccessors.constBegin(); it2 != propertyAccessors.constEnd(); ++it2) - markObject(*it2, generation); - } - } - } -# endif - processMarkStack(generation); // make sure everything is marked before marking qobject data - { - QHash<QObject*, QScriptQObjectData*>::const_iterator it; - for (it = m_qobjectData.constBegin(); it != m_qobjectData.constEnd(); ++it) { - QScriptQObjectData *qdata = it.value(); - qdata->mark(generation); - } - } -#endif - processMarkStack(generation); - - Q_ASSERT(m_gc_depth == 0); - --m_gc_depth; - - objectAllocator.sweep(generation); - - m_objectGeneration = generation; - - //qDebug() << "free blocks:" << objectAllocator.freeBlocks(); - -#ifndef QT_NO_QOBJECT - deletePendingQObjects(); -#endif - - if (! do_string_gc) - return; - - { - QHash<QScriptNameIdImpl*, QScriptStringPrivate*>::const_iterator it; - for (it = m_internedStrings.constBegin(); it != m_internedStrings.constEnd(); ++it) { - it.value()->nameId->used = true; - } - } - -#if 0 - qDebug() << "do_string_gc:" << do_string_gc - << ((m_stringRepository.size() - m_oldStringRepositorySize) > 256) - << ((m_tempStringRepository.size() - m_oldTempStringRepositorySize) > 2048); -#endif - - QVector<QScriptNameIdImpl*> compressed; - compressed.reserve(m_stringRepository.size()); - - for (int i = 0; i < m_stringRepository.size(); ++i) { - QScriptNameIdImpl *entry = m_stringRepository.at(i); - - if (entry->used || entry->persistent) { - compressed.append(entry); - entry->used = false; - } - - else { - //qDebug() << "deleted unique:" << entry->s; - delete entry; - } - } - - // qDebug() << "before:" << m_stringRepository.size() << "after:" << compressed.size() << globalObject.objectValue()->m_members.size(); - m_stringRepository = compressed; - rehashStringRepository(/*resize=*/ false); - m_oldStringRepositorySize = m_stringRepository.size(); - m_newAllocatedStringRepositoryChars = 0; - - compressed.clear(); - for (int i = 0; i < m_tempStringRepository.size(); ++i) { - QScriptNameIdImpl *entry = m_tempStringRepository.at(i); - - if (entry->used || entry->persistent) { - compressed.append(entry); - entry->used = false; - } - - else { - //qDebug() << "deleted:" << entry->s; - delete entry; - } - } - - //qDebug() << "before:" << m_tempStringRepository.size() << "after:" << compressed.size(); - - m_tempStringRepository = compressed; - m_oldTempStringRepositorySize = m_tempStringRepository.size(); - m_newAllocatedTempStringRepositoryChars = 0; -} - -void QScriptEnginePrivate::processMarkStack(int generation) -{ - // mark the objects we couldn't process due to recursion depth - while (!m_markStack.isEmpty()) - markObject(m_markStack.takeLast(), generation); -} - -void QScriptEnginePrivate::evaluate(QScriptContextPrivate *context, const QString &contents, int lineNumber, const QString &fileName) -{ - // ### try to remove cast - QScript::EvalFunction *evalFunction = static_cast<QScript::EvalFunction*>(m_evalFunction); - evalFunction->evaluate(context, contents, lineNumber, fileName, /*calledFromScript=*/ false); -} - -qsreal QScriptEnginePrivate::convertToNativeDouble_helper(const QScriptValueImpl &value) -{ - switch (value.type()) { - case QScript::InvalidType: - Q_ASSERT(value.isValid()); - break; - - case QScript::UndefinedType: - case QScript::PointerType: - break; - - case QScript::NullType: - return 0; - - case QScript::BooleanType: - return value.m_bool_value; - - case QScript::IntegerType: - case QScript::ReferenceType: - return value.m_int_value; - - case QScript::NumberType: - return value.m_number_value; - - case QScript::StringType: - return QScript::numberFromString(toString(value.m_string_value)); - - case QScript::ObjectType: { - QScriptValueImpl p = value.engine()->toPrimitive(value, QScriptValueImpl::NumberTypeHint); - if (! p.isValid() || p.isObject()) - break; - - return convertToNativeDouble(p); - } - - case QScript::LazyStringType: - return QScript::numberFromString(*value.m_lazy_string_value); - - } // switch - - return qSNaN(); -} - -bool QScriptEnginePrivate::convertToNativeBoolean_helper(const QScriptValueImpl &value) -{ - switch (value.type()) { - case QScript::InvalidType: - Q_ASSERT(value.isValid()); - return false; - - case QScript::UndefinedType: - case QScript::PointerType: - case QScript::NullType: - case QScript::ReferenceType: - return false; - - case QScript::BooleanType: - return value.m_bool_value; - - case QScript::IntegerType: - return value.m_int_value != 0; - - case QScript::NumberType: - return value.m_number_value != 0 && !qIsNaN(value.m_number_value); - - case QScript::StringType: - return toString(value.m_string_value).length() != 0; - - case QScript::ObjectType: - return true; - - case QScript::LazyStringType: - return value.m_lazy_string_value->length() != 0; - - } // switch - - return false; -} - -QString QScriptEnginePrivate::convertToNativeString_helper(const QScriptValueImpl &value) -{ - static QStringList predefined; - if (predefined.isEmpty()) { - predefined.append(QString::fromLatin1("undefined")); - predefined.append(QString::fromLatin1("null")); - predefined.append(QString::fromLatin1("true")); - predefined.append(QString::fromLatin1("false")); - predefined.append(QString::fromLatin1("pointer")); - } - - switch (value.type()) { - case QScript::InvalidType: - Q_ASSERT(value.isValid()); - return QString(); - - case QScript::UndefinedType: - return predefined.at(0); - - case QScript::NullType: - return predefined.at(1); - - case QScript::BooleanType: - return value.m_bool_value ? predefined.at(2) : predefined.at(3); - - case QScript::IntegerType: - return QString::number(value.m_int_value); - - case QScript::NumberType: - return QScript::numberToString(value.m_number_value); - - case QScript::PointerType: - return predefined.at(4); - - case QScript::StringType: - return toString(value.m_string_value); - - case QScript::ReferenceType: - return QString(); - - case QScript::ObjectType: { - QScriptValueImpl p = value.engine()->toPrimitive(value, QScriptValueImpl::StringTypeHint); - - if (!p.isValid() || strictlyEquals(p, value)) - return p.classInfo()->name(); - - return convertToNativeString(p); - } - - case QScript::LazyStringType: - return *value.m_lazy_string_value; - - } // switch - - return QString(); -} - -QScriptValueImpl QScriptEnginePrivate::toObject_helper(const QScriptValueImpl &value) -{ - QScriptValueImpl result; - switch (value.type()) { - case QScript::BooleanType: - booleanConstructor->newBoolean(&result, value.m_bool_value); - break; - - case QScript::NumberType: - numberConstructor->newNumber(&result, value.m_number_value); - break; - - case QScript::StringType: - stringConstructor->newString(&result, value.m_string_value->s); - break; - - case QScript::LazyStringType: - stringConstructor->newString(&result, *value.m_lazy_string_value); - break; - - case QScript::InvalidType: - case QScript::UndefinedType: - case QScript::NullType: - case QScript::IntegerType: - case QScript::ReferenceType: - case QScript::PointerType: - case QScript::ObjectType: - break; - } // switch - - return result; -} - -// [[defaultValue]] -QScriptValueImpl QScriptEnginePrivate::toPrimitive_helper(const QScriptValueImpl &object, - QScriptValueImpl::TypeHint hint) -{ - QScriptNameIdImpl *functionIds[2]; - - if ((hint == QScriptValueImpl::NumberTypeHint) - || (hint == QScriptValueImpl::NoTypeHint - && object.classInfo() != dateConstructor->classInfo())) { - functionIds[0] = idTable()->id_valueOf; - functionIds[1] = idTable()->id_toString; - } else { - functionIds[0] = idTable()->id_toString; - functionIds[1] = idTable()->id_valueOf; - } - - for (int i = 0; i < 2; ++i) { - QScriptValueImpl base; - QScript::Member member; - - if (! object.resolve(functionIds[i], &member, &base, QScriptValue::ResolvePrototype, QScript::Read)) - return object; - - QScriptValueImpl f_valueOf; - base.get(member, &f_valueOf); - - if (QScriptFunction *foo = convertToNativeFunction(f_valueOf)) { - QScriptContextPrivate *me = pushContext(); - QScriptValueImpl activation; - newActivation(&activation); - if (f_valueOf.scope().isValid()) - activation.setScope(f_valueOf.scope()); - else - activation.setScope(m_globalObject); - me->setActivationObject(activation); - me->setThisObject(object); - me->m_callee = f_valueOf; - foo->execute(me); - QScriptValueImpl result = me->returnValue(); - bool exception = (me->state() == QScriptContext::ExceptionState); - popContext(); - if (exception || (result.isValid() && !result.isObject())) - return result; - } - } - - return object; -} - -void QScriptEnginePrivate::rehashStringRepository(bool resize) -{ - if (resize) { - delete[] m_string_hash_base; - m_string_hash_size <<= 1; // ### use primes - - m_string_hash_base = new QScriptNameIdImpl* [m_string_hash_size]; - } - - memset(m_string_hash_base, 0, sizeof(QScriptNameIdImpl*) * m_string_hash_size); - - for (int index = 0; index < m_stringRepository.size(); ++index) { - QScriptNameIdImpl *entry = m_stringRepository.at(index); - uint h = _q_scriptHash(entry->s) % m_string_hash_size; - entry->h = h; - entry->next = m_string_hash_base[h]; - m_string_hash_base[h] = entry; - } -} - -QScriptNameIdImpl *QScriptEnginePrivate::insertStringEntry(const QString &s) -{ - QScriptNameIdImpl *entry = new QScriptNameIdImpl(s); - entry->unique = true; - m_stringRepository.append(entry); - m_newAllocatedStringRepositoryChars += s.length(); - - uint h = _q_scriptHash(s) % m_string_hash_size; - entry->h = h; - entry->next = m_string_hash_base[h]; - m_string_hash_base[h] = entry; - - if (m_stringRepository.count() == m_string_hash_size) - rehashStringRepository(); - - return entry; -} - -QScriptValueImpl QScriptEnginePrivate::call(const QScriptValueImpl &callee, - const QScriptValueImpl &thisObject, - const QScriptValueImplList &args, - bool asConstructor) -{ - QScriptFunction *function = callee.toFunction(); - Q_ASSERT(function); - - if (++m_callDepth == m_maxCallDepth) { - QScriptContextPrivate *ctx_p = currentContext(); - return ctx_p->throwError(QLatin1String("call stack overflow")); - } - - QScriptContextPrivate *nested = pushContext(); - // set up the temp stack - if (! nested->tempStack) - nested->stackPtr = nested->tempStack = tempStackBegin; - - newActivation(&nested->m_activation); - if (callee.m_object_value->m_scope.isValid()) - nested->m_activation.m_object_value->m_scope = callee.m_object_value->m_scope; - else - nested->m_activation.m_object_value->m_scope = m_globalObject; - - QScriptObject *activation_data = nested->m_activation.m_object_value; - - int formalCount = function->formals.count(); - int argc = args.count(); - int mx = qMax(formalCount, argc); - activation_data->m_members.resize(mx); - activation_data->m_values.resize(mx); - for (int i = 0; i < mx; ++i) { - QScriptNameIdImpl *nameId = 0; - if (i < formalCount) - nameId = function->formals.at(i); - - activation_data->m_members[i].object(nameId, i, QScriptValue::SkipInEnumeration); - QScriptValueImpl arg = (i < argc) ? args.at(i) : m_undefinedValue; - if (arg.isValid() && arg.engine() && (arg.engine() != this)) { - qWarning("QScriptValue::call() failed: " - "cannot call function with argument created in " - "a different engine"); - popContext(); - return QScriptValueImpl(); - } - activation_data->m_values[i] = arg.isValid() ? arg : m_undefinedValue; - } - - nested->argc = argc; - QVector<QScriptValueImpl> argsv = args.toVector(); - nested->args = const_cast<QScriptValueImpl*> (argsv.constData()); - - if (thisObject.isObject()) - nested->m_thisObject = thisObject; - else - nested->m_thisObject = m_globalObject; - nested->m_callee = callee; - nested->m_calledAsConstructor = asConstructor; - - nested->m_result = m_undefinedValue; - function->execute(nested); - --m_callDepth; - QScriptValueImpl result = nested->m_result; - nested->args = 0; - popContext(); - - return result; -} - -QScriptValueImpl QScriptEnginePrivate::call(const QScriptValueImpl &callee, - const QScriptValueImpl &thisObject, - const QScriptValueImpl &args, - bool asConstructor) -{ - QScriptValueImplList argsList; - if (QScript::Ecma::Array::Instance *arr = arrayConstructor->get(args)) { - QScript::Array actuals = arr->value; - for (quint32 i = 0; i < actuals.count(); ++i) { - QScriptValueImpl a = actuals.at(i); - if (! a.isValid()) - argsList << undefinedValue(); - else - argsList << a; - } - } else if (args.classInfo() == m_class_arguments) { - QScript::ArgumentsObjectData *arguments; - arguments = static_cast<QScript::ArgumentsObjectData*> (args.objectData()); - QScriptObject *activation = arguments->activation.objectValue(); - for (uint i = 0; i < arguments->length; ++i) - argsList << activation->m_values[i]; - } else if (!(args.isUndefined() || args.isNull())) { - return currentContext()->throwError( - QScriptContext::TypeError, - QLatin1String("QScriptValue::call(): arguments must be an array")); - } - return call(callee, thisObject, argsList, asConstructor); -} - -QScriptValueImpl QScriptEnginePrivate::arrayFromStringList(const QStringList &lst) -{ - QScriptValueImpl arr = newArray(lst.size()); - for (int i = 0; i < lst.size(); ++i) - arr.setProperty(i, QScriptValueImpl(this, lst.at(i))); - return arr; -} - -QStringList QScriptEnginePrivate::stringListFromArray(const QScriptValueImpl &arr) -{ - QStringList lst; - uint len = arr.property(QLatin1String("length")).toUInt32(); - for (uint i = 0; i < len; ++i) - lst.append(arr.property(i).toString()); - return lst; -} - -QScriptValueImpl QScriptEnginePrivate::arrayFromVariantList(const QVariantList &lst) -{ - QScriptValueImpl arr = newArray(lst.size()); - for (int i = 0; i < lst.size(); ++i) - arr.setProperty(i, valueFromVariant(lst.at(i))); - return arr; -} - -QVariantList QScriptEnginePrivate::variantListFromArray(const QScriptValueImpl &arr) -{ - QVariantList lst; - uint len = arr.property(QLatin1String("length")).toUInt32(); - for (uint i = 0; i < len; ++i) - lst.append(arr.property(i).toVariant()); - return lst; -} - -QScriptValueImpl QScriptEnginePrivate::objectFromVariantMap(const QVariantMap &vmap) -{ - QScriptValueImpl obj = newObject(); - QVariantMap::const_iterator it; - for (it = vmap.constBegin(); it != vmap.constEnd(); ++it) - obj.setProperty(it.key(), valueFromVariant(it.value())); - return obj; -} - -QVariantMap QScriptEnginePrivate::variantMapFromObject(const QScriptValueImpl &obj) -{ - QVariantMap vmap; - QScriptValueIteratorImpl it(obj); - while (it.hasNext()) { - it.next(); - vmap.insert(it.name(), it.value().toVariant()); - } - return vmap; -} - -QScriptValueImpl QScriptEnginePrivate::create(int type, const void *ptr) -{ - Q_Q(QScriptEngine); - Q_ASSERT(ptr); - QScriptValueImpl result; - QScriptCustomTypeInfo info = m_customTypes.value(type); - if (info.marshal) { - result = toImpl(info.marshal(q, ptr)); - } else { - // check if it's one of the types we know - switch (QMetaType::Type(type)) { - case QMetaType::Void: - result = m_undefinedValue; - break; - case QMetaType::Bool: - result = QScriptValueImpl(*reinterpret_cast<const bool*>(ptr)); - break; - case QMetaType::Int: - result = QScriptValueImpl(*reinterpret_cast<const int*>(ptr)); - break; - case QMetaType::UInt: - result = QScriptValueImpl(*reinterpret_cast<const uint*>(ptr)); - break; - case QMetaType::LongLong: - result = QScriptValueImpl(qsreal(*reinterpret_cast<const qlonglong*>(ptr))); - break; - 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 = QScriptValueImpl(qsreal((qlonglong)*reinterpret_cast<const qulonglong*>(ptr))); -#elif defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET) - result = QScriptValueImpl(qsreal((qlonglong)*reinterpret_cast<const qulonglong*>(ptr))); -#else - result = QScriptValueImpl(qsreal(*reinterpret_cast<const qulonglong*>(ptr))); -#endif - break; - case QMetaType::Double: - result = QScriptValueImpl(*reinterpret_cast<const double*>(ptr)); - break; - case QMetaType::QString: - result = QScriptValueImpl(this, *reinterpret_cast<const QString*>(ptr)); - break; - case QMetaType::Float: - result = QScriptValueImpl(*reinterpret_cast<const float*>(ptr)); - break; - case QMetaType::Short: - result = QScriptValueImpl(*reinterpret_cast<const short*>(ptr)); - break; - case QMetaType::UShort: - result = QScriptValueImpl(*reinterpret_cast<const unsigned short*>(ptr)); - break; - case QMetaType::Char: - result = QScriptValueImpl(*reinterpret_cast<const char*>(ptr)); - break; - case QMetaType::UChar: - result = QScriptValueImpl(*reinterpret_cast<const unsigned char*>(ptr)); - break; - case QMetaType::QChar: - result = QScriptValueImpl((*reinterpret_cast<const QChar*>(ptr)).unicode()); - break; - case QMetaType::QStringList: - result = arrayFromStringList(*reinterpret_cast<const QStringList *>(ptr)); - break; - case QMetaType::QVariantList: - result = arrayFromVariantList(*reinterpret_cast<const QVariantList *>(ptr)); - break; - case QMetaType::QVariantMap: - result = objectFromVariantMap(*reinterpret_cast<const QVariantMap *>(ptr)); - break; - case QMetaType::QDateTime: { - QDateTime dateTime = *reinterpret_cast<const QDateTime *>(ptr); - dateConstructor->newDate(&result, dateTime); - } break; - case QMetaType::QDate: { - QDate date = *reinterpret_cast<const QDate *>(ptr); - dateConstructor->newDate(&result, date); - } break; -#ifndef QT_NO_REGEXP - case QMetaType::QRegExp: { - QRegExp rx = *reinterpret_cast<const QRegExp *>(ptr); - regexpConstructor->newRegExp(&result, rx); - } break; -#endif -#ifndef QT_NO_QOBJECT - case QMetaType::QObjectStar: - case QMetaType::QWidgetStar: - newQObject(&result, *reinterpret_cast<QObject* const *>(ptr)); - break; -#endif - default: - if (type == qMetaTypeId<QScriptValue>()) { - result = toImpl(*reinterpret_cast<const QScriptValue*>(ptr)); - if (!result.isValid()) - result = m_undefinedValue; - } - -#ifndef QT_NO_QOBJECT - // lazy registration of some common list types - else if (type == qMetaTypeId<QObjectList>()) { - qScriptRegisterSequenceMetaType<QObjectList>(q); - return create(type, ptr); - } -#endif - else if (type == qMetaTypeId<QList<int> >()) { - qScriptRegisterSequenceMetaType<QList<int> >(q); - return create(type, ptr); - } - - else { - QByteArray typeName = QMetaType::typeName(type); - if (typeName == "QVariant") - result = valueFromVariant(*reinterpret_cast<const QVariant*>(ptr)); - else if (typeName.endsWith('*') && !*reinterpret_cast<void* const *>(ptr)) - result = nullValue(); - else - newVariant(&result, QVariant(type, ptr)); - } - } - } - if (result.isObject() && info.prototype.isValid() - && strictlyEquals(result.prototype(), objectConstructor->publicPrototype)) { - result.setPrototype(info.prototype); - } - return result; -} - -bool QScriptEnginePrivate::convert(const QScriptValueImpl &value, - int type, void *ptr, - QScriptEnginePrivate *eng) -{ - if (!eng) - eng = value.engine(); - if (eng) { - QScriptCustomTypeInfo info = eng->m_customTypes.value(type); - if (info.demarshal) { - info.demarshal(eng->toPublic(value), ptr); - return true; - } - } - - // check if it's one of the types we know - switch (QMetaType::Type(type)) { - case QMetaType::Bool: - *reinterpret_cast<bool*>(ptr) = value.toBoolean(); - return true; - case QMetaType::Int: - *reinterpret_cast<int*>(ptr) = value.toInt32(); - return true; - case QMetaType::UInt: - *reinterpret_cast<uint*>(ptr) = value.toUInt32(); - return true; - case QMetaType::LongLong: - *reinterpret_cast<qlonglong*>(ptr) = qlonglong(value.toInteger()); - return true; - case QMetaType::ULongLong: - *reinterpret_cast<qulonglong*>(ptr) = qulonglong(value.toInteger()); - return true; - case QMetaType::Double: - *reinterpret_cast<double*>(ptr) = value.toNumber(); - return true; - case QMetaType::QString: - if (value.isUndefined() || value.isNull()) - *reinterpret_cast<QString*>(ptr) = QString(); - else - *reinterpret_cast<QString*>(ptr) = value.toString(); - return true; - case QMetaType::Float: - *reinterpret_cast<float*>(ptr) = value.toNumber(); - return true; - case QMetaType::Short: - *reinterpret_cast<short*>(ptr) = short(value.toInt32()); - return true; - case QMetaType::UShort: - *reinterpret_cast<unsigned short*>(ptr) = value.toUInt16(); - return true; - case QMetaType::Char: - *reinterpret_cast<char*>(ptr) = char(value.toInt32()); - return true; - case QMetaType::UChar: - *reinterpret_cast<unsigned char*>(ptr) = (unsigned char)(value.toInt32()); - return true; - case QMetaType::QChar: - if (value.isString()) { - QString str = value.toString(); - *reinterpret_cast<QChar*>(ptr) = str.isEmpty() ? QChar() : str.at(0); - } else { - *reinterpret_cast<QChar*>(ptr) = QChar(value.toUInt16()); - } - return true; - case QMetaType::QDateTime: - if (value.isDate()) { - *reinterpret_cast<QDateTime *>(ptr) = value.toDateTime(); - return true; - } break; - case QMetaType::QDate: - if (value.isDate()) { - *reinterpret_cast<QDate *>(ptr) = value.toDateTime().date(); - return true; - } break; -#ifndef QT_NO_REGEXP - case QMetaType::QRegExp: - if (value.isRegExp()) { - *reinterpret_cast<QRegExp *>(ptr) = value.toRegExp(); - return true; - } break; -#endif -#ifndef QT_NO_QOBJECT - case QMetaType::QObjectStar: - if (value.isQObject() || value.isNull()) { - *reinterpret_cast<QObject* *>(ptr) = value.toQObject(); - return true; - } break; - case QMetaType::QWidgetStar: - if (value.isQObject() || value.isNull()) { - QObject *qo = value.toQObject(); - if (!qo || qo->isWidgetType()) { - *reinterpret_cast<QWidget* *>(ptr) = reinterpret_cast<QWidget*>(qo); - return true; - } - } break; -#endif - case QMetaType::QStringList: - if (value.isArray()) { - *reinterpret_cast<QStringList *>(ptr) = stringListFromArray(value); - return true; - } break; - case QMetaType::QVariantList: - if (value.isArray()) { - *reinterpret_cast<QVariantList *>(ptr) = variantListFromArray(value); - return true; - } break; - case QMetaType::QVariantMap: - if (value.isObject()) { - *reinterpret_cast<QVariantMap *>(ptr) = variantMapFromObject(value); - return true; - } break; - default: - ; - } - - QByteArray name = QMetaType::typeName(type); -#ifndef QT_NO_QOBJECT - if (convertToNativeQObject(value, name, reinterpret_cast<void* *>(ptr))) - return true; -#endif - if (value.isVariant() && name.endsWith('*')) { - int valueType = QMetaType::type(name.left(name.size()-1)); - QVariant &var = value.variantValue(); - if (valueType == var.userType()) { - *reinterpret_cast<void* *>(ptr) = var.data(); - return true; - } else { - // look in the prototype chain - QScriptValueImpl proto = value.prototype(); - while (proto.isObject()) { - bool canCast = false; - if (proto.isVariant()) { - canCast = (type == proto.variantValue().userType()) - || (valueType && (valueType == proto.variantValue().userType())); - } -#ifndef QT_NO_QOBJECT - else if (proto.isQObject()) { - QByteArray className = name.left(name.size()-1); - if (QObject *qobject = proto.toQObject()) - canCast = qobject->qt_metacast(className) != 0; - } -#endif - if (canCast) { - QByteArray varTypeName = QMetaType::typeName(var.userType()); - if (varTypeName.endsWith('*')) - *reinterpret_cast<void* *>(ptr) = *reinterpret_cast<void* *>(var.data()); - else - *reinterpret_cast<void* *>(ptr) = var.data(); - return true; - } - proto = proto.prototype(); - } - } - } else if (value.isNull() && name.endsWith('*')) { - *reinterpret_cast<void* *>(ptr) = 0; - return true; - } else if (type == qMetaTypeId<QScriptValue>()) { - if (!eng) - return false; - *reinterpret_cast<QScriptValue*>(ptr) = eng->toPublic(value); - return true; - } else if (name == "QVariant") { - *reinterpret_cast<QVariant*>(ptr) = value.toVariant(); - return true; - } - - // lazy registration of some common list types -#ifndef QT_NO_QOBJECT - else if (type == qMetaTypeId<QObjectList>()) { - if (!eng) - return false; - qScriptRegisterSequenceMetaType<QObjectList>(eng->q_func()); - return convert(value, type, ptr, eng); - } -#endif - else if (type == qMetaTypeId<QList<int> >()) { - if (!eng) - return false; - qScriptRegisterSequenceMetaType<QList<int> >(eng->q_func()); - return convert(value, type, ptr, eng); - } - -#if 0 - if (!name.isEmpty()) { - qWarning("QScriptEngine::convert: unable to convert value to type `%s'", - name.constData()); - } -#endif - return false; -} - -QScriptEngine::DemarshalFunction QScriptEnginePrivate::demarshalFunction(int type) const -{ - return m_customTypes.value(type).demarshal; -} - -QScriptValuePrivate *QScriptEnginePrivate::registerValue(const QScriptValueImpl &value) -{ - if (value.isString()) { - QScriptNameIdImpl *id = value.stringValue(); - QScriptValuePrivate *p = m_stringHandles.value(id); - if (p) - return p; - p = m_handleRepository.get(); - p->engine = q_func(); - p->value = value; - m_stringHandles.insert(id, p); - return p; - } else if (value.isObject()) { - QScriptObject *instance = value.objectValue(); - QScriptValuePrivate *p = m_objectHandles.value(instance); - if (p) - return p; - p = m_handleRepository.get(); - p->engine = q_func(); - p->value = value; - m_objectHandles.insert(instance, p); - return p; - } - QScriptValuePrivate *p = m_handleRepository.get(); - p->engine = q_func(); - p->value = value; - m_otherHandles.append(p); - return p; -} - -QScriptEnginePrivate::QScriptEnginePrivate() -{ - m_undefinedValue = QScriptValueImpl(QScriptValue::UndefinedValue); - m_nullValue = QScriptValueImpl(QScriptValue::NullValue); - - m_evaluating = false; - m_abort = false; - m_callDepth = 0; -#if defined(Q_OS_WIN) - m_maxCallDepth = 88; -#elif defined(Q_OS_MAC) - m_maxCallDepth = 640; -#elif defined(QT_ARCH_ARM) || defined(QT_ARCH_ARMV6) - m_maxCallDepth = 360; -#else - m_maxCallDepth = 512; -#endif - m_oldStringRepositorySize = 0; - m_oldTempStringRepositorySize = 0; - m_newAllocatedStringRepositoryChars = 0; - m_newAllocatedTempStringRepositoryChars = 0; - m_context = 0; - m_abstractSyntaxTree = 0; - m_lexer = 0; - m_scriptCounter = 0; - m_agent = 0; - m_objectGeneration = 0; - m_class_prev_id = QScriptClassInfo::CustomType; - m_next_object_id = 0; - m_gc_depth = -1; - - objectConstructor = 0; - numberConstructor = 0; - booleanConstructor = 0; - stringConstructor = 0; - dateConstructor = 0; - functionConstructor = 0; - arrayConstructor = 0; - regexpConstructor = 0; - errorConstructor = 0; - enumerationConstructor = 0; - variantConstructor = 0; - qobjectConstructor = 0; - qmetaObjectConstructor = 0; - - m_processEventsInterval = -1; - m_nextProcessEvents = 0; - m_processEventIncr = 0; - - m_stringRepository.reserve(DefaultHashSize); - m_string_hash_size = DefaultHashSize; - m_string_hash_base = new QScriptNameIdImpl* [m_string_hash_size]; - memset(m_string_hash_base, 0, sizeof(QScriptNameIdImpl*) * m_string_hash_size); - - tempStackBegin = 0; -} - -void QScriptEnginePrivate::init() -{ - qMetaTypeId<QScriptValue>(); - qMetaTypeId<QList<int> >(); -#ifndef QT_NO_QOBJECT - qMetaTypeId<QObjectList>(); -#endif - - m_class_prev_id = QScriptClassInfo::CustomType; - m_class_object = registerClass(QLatin1String("Object"), QScriptClassInfo::ObjectType); - m_class_function = registerClass(QLatin1String("Function"), QScriptClassInfo::FunctionType); - m_class_activation = registerClass(QLatin1String("activation"), QScriptClassInfo::ActivationType); - - m_class_arguments = registerClass(QLatin1String("arguments"), QScript::ObjectType); - m_class_arguments->setData(new QScript::ArgumentsClassData()); - - m_class_with = registerClass(QLatin1String("__qscript_internal_with"), QScript::ObjectType); - - // public name ids - m_id_table.id_constructor = nameId(QLatin1String("constructor"), true); - m_id_table.id_false = nameId(QLatin1String("false"), true); - m_id_table.id_null = nameId(QLatin1String("null"), true); - m_id_table.id_object = nameId(QLatin1String("object"), true); - m_id_table.id_pointer = nameId(QLatin1String("pointer"), true); - m_id_table.id_prototype = nameId(QLatin1String("prototype"), true); - m_id_table.id_arguments = nameId(QLatin1String("arguments"), true); - m_id_table.id_this = nameId(QLatin1String("this"), true); - m_id_table.id_toString = nameId(QLatin1String("toString"), true); - m_id_table.id_true = nameId(QLatin1String("true"), true); - m_id_table.id_undefined = nameId(QLatin1String("undefined"), true); - m_id_table.id_valueOf = nameId(QLatin1String("valueOf"), true); - m_id_table.id_length = nameId(QLatin1String("length"), true); - m_id_table.id_callee = nameId(QLatin1String("callee"), true); - m_id_table.id___proto__ = nameId(QLatin1String("__proto__"), true); - m_id_table.id___qt_sender__ = nameId(QLatin1String("__qt_sender__"), true); - - const int TEMP_STACK_SIZE = 10 * 1024; - tempStackBegin = new QScriptValueImpl[TEMP_STACK_SIZE]; - tempStackEnd = tempStackBegin + TEMP_STACK_SIZE; - tempStackBegin[0] = m_undefinedValue; - - objectAllocator.blockGC(true); - - QScript::Ecma::Global::construct(&m_globalObject, this); - - // create the prototypes first... - objectConstructor = new QScript::Ecma::Object(this, m_class_object); - functionConstructor = new QScript::Ecma::Function(this, m_class_function); - // ... then we can initialize - functionConstructor->initialize(); - objectConstructor->initialize(); - - numberConstructor = new QScript::Ecma::Number(this); - booleanConstructor = new QScript::Ecma::Boolean(this); - stringConstructor = new QScript::Ecma::String(this); - dateConstructor = new QScript::Ecma::Date(this); - arrayConstructor = new QScript::Ecma::Array(this); - regexpConstructor = new QScript::Ecma::RegExp(this); - errorConstructor = new QScript::Ecma::Error(this); - - QScript::Ecma::Global::initialize(&m_globalObject, this); - - const QScriptValue::PropertyFlags flags = QScriptValue::SkipInEnumeration; - - m_globalObject.setProperty(QLatin1String("Object"), - objectConstructor->ctor, flags); - m_globalObject.setProperty(QLatin1String("Function"), - functionConstructor->ctor, flags); - m_globalObject.setProperty(QLatin1String("Number"), - numberConstructor->ctor, flags); - m_globalObject.setProperty(QLatin1String("Boolean"), - booleanConstructor->ctor, flags); - m_globalObject.setProperty(QLatin1String("String"), - stringConstructor->ctor, flags); - m_globalObject.setProperty(QLatin1String("Date"), - dateConstructor->ctor, flags); - m_globalObject.setProperty(QLatin1String("Array"), - arrayConstructor->ctor, flags); - m_globalObject.setProperty(QLatin1String("RegExp"), - regexpConstructor->ctor, flags); - m_globalObject.setProperty(QLatin1String("Error"), - errorConstructor->ctor, flags); - - m_globalObject.setProperty(QLatin1String("EvalError"), - errorConstructor->evalErrorCtor, flags); - m_globalObject.setProperty(QLatin1String("RangeError"), - errorConstructor->rangeErrorCtor, flags); - m_globalObject.setProperty(QLatin1String("ReferenceError"), - errorConstructor->referenceErrorCtor, flags); - m_globalObject.setProperty(QLatin1String("SyntaxError"), - errorConstructor->syntaxErrorCtor, flags); - m_globalObject.setProperty(QLatin1String("TypeError"), - errorConstructor->typeErrorCtor, flags); - m_globalObject.setProperty(QLatin1String("URIError"), - errorConstructor->uriErrorCtor, flags); - - QScriptValueImpl tmp; // ### fixme - m_evalFunction = new QScript::EvalFunction(this); - functionConstructor->newFunction(&tmp, m_evalFunction); - m_globalObject.setProperty(QLatin1String("eval"), tmp, flags); - - QScriptValueImpl mathObject; - QScript::Ecma::Math::construct(&mathObject, this); - m_globalObject.setProperty(QLatin1String("Math"), mathObject, flags); - - enumerationConstructor = new QScript::Ext::Enumeration(this); - - variantConstructor = new QScript::Ext::Variant(this); - -#ifndef QT_NO_QOBJECT - qobjectConstructor = new QScript::ExtQObject(this); - qmetaObjectConstructor = new QScript::ExtQMetaObject(this); -#endif - - objectAllocator.blockGC(false); - - QScriptContextPrivate *context_p = pushContext(); - context_p->setActivationObject(m_globalObject); - context_p->setThisObject(m_globalObject); -} - -#if !defined(QT_NO_QOBJECT) && !defined(QT_NO_LIBRARY) -static QScriptValueImpl __setupPackage__(QScriptContextPrivate *ctx, - QScriptEnginePrivate *eng, - QScriptClassInfo *) -{ - QString path = ctx->argument(0).toString(); - QStringList components = path.split(QLatin1Char('.')); - QScriptValueImpl o = eng->globalObject(); - for (int i = 0; i < components.count(); ++i) { - QString name = components.at(i); - QScriptValueImpl oo = o.property(name); - if (!oo.isValid()) { - oo = eng->newObject(); - o.setProperty(name, oo); - } - o = oo; - } - return o; -} -#endif - -QScriptValueImpl QScriptEnginePrivate::importExtension(const QString &extension) -{ -#if defined(QT_NO_QOBJECT) || defined(QT_NO_LIBRARY) || defined(QT_NO_SETTINGS) - Q_UNUSED(extension); -#else - Q_Q(QScriptEngine); - if (m_importedExtensions.contains(extension)) - return undefinedValue(); // already imported - - QScriptContextPrivate *context = currentContext(); - QCoreApplication *app = QCoreApplication::instance(); - if (!app) - return context->throwError(QLatin1String("No application object")); - - QObjectList staticPlugins = QPluginLoader::staticInstances(); - QStringList libraryPaths = app->libraryPaths(); - QString dot = QLatin1String("."); - QStringList pathComponents = extension.split(dot); - QString initDotJs = QLatin1String("__init__.js"); - - QString ext; - for (int i = 0; i < pathComponents.count(); ++i) { - if (!ext.isEmpty()) - ext.append(dot); - ext.append(pathComponents.at(i)); - if (m_importedExtensions.contains(ext)) - continue; // already imported - - if (m_extensionsBeingImported.contains(ext)) { - return context->throwError(QString::fromLatin1("recursive import of %0") - .arg(extension)); - } - m_extensionsBeingImported.insert(ext); - - QScriptExtensionInterface *iface = 0; - QString initjsContents; - QString initjsFileName; - - // look for the extension in static plugins - for (int j = 0; j < staticPlugins.size(); ++j) { - iface = qobject_cast<QScriptExtensionInterface*>(staticPlugins.at(j)); - if (!iface) - continue; - if (iface->keys().contains(ext)) - break; // use this one - else - iface = 0; // keep looking - } - - { - // look for __init__.js resource - QString path = QString::fromLatin1(":/qtscriptextension"); - for (int j = 0; j <= i; ++j) { - path.append(QLatin1Char('/')); - path.append(pathComponents.at(j)); - } - path.append(QLatin1Char('/')); - path.append(initDotJs); - QFile file(path); - if (file.open(QIODevice::ReadOnly)) { - QTextStream ts(&file); - initjsContents = ts.readAll(); - initjsFileName = path; - file.close(); - } - } - - if (!iface && initjsContents.isEmpty()) { - // look for the extension in library paths - for (int j = 0; j < libraryPaths.count(); ++j) { - QString libPath = libraryPaths.at(j) + QDir::separator() + QLatin1String("script"); - QDir dir(libPath); - if (!dir.exists(dot)) - continue; - - // look for C++ plugin - QFileInfoList files = dir.entryInfoList(QDir::Files); - for (int k = 0; k < files.count(); ++k) { - QFileInfo entry = files.at(k); - QString filePath = entry.canonicalFilePath(); - QPluginLoader loader(filePath); - iface = qobject_cast<QScriptExtensionInterface*>(loader.instance()); - if (iface) { - if (iface->keys().contains(ext)) - break; // use this one - else - iface = 0; // keep looking - } - } - - // look for __init__.js in the corresponding dir - QDir dirdir(libPath); - bool dirExists = dirdir.exists(); - for (int k = 0; dirExists && (k <= i); ++k) - dirExists = dirdir.cd(pathComponents.at(k)); - if (dirExists && dirdir.exists(initDotJs)) { - QFile file(dirdir.canonicalPath() - + QDir::separator() + initDotJs); - if (file.open(QIODevice::ReadOnly)) { - QTextStream ts(&file); - initjsContents = ts.readAll(); - initjsFileName = file.fileName(); - file.close(); - } - } - - if (iface || !initjsContents.isEmpty()) - break; - } - } - - if (!iface && initjsContents.isEmpty()) { - m_extensionsBeingImported.remove(ext); - return context->throwError( - QString::fromLatin1("Unable to import %0: no such extension") - .arg(extension)); - } - - // initialize the extension in a new context - QScriptContextPrivate *ctx_p = pushContext(); - ctx_p->setThisObject(globalObject()); - newActivation(&ctx_p->m_activation); - QScriptObject *activation_data = ctx_p->m_activation.m_object_value; - activation_data->m_scope = globalObject(); - - activation_data->m_members.resize(4); - activation_data->m_values.resize(4); - activation_data->m_members[0].object( - nameId(QLatin1String("__extension__")), 0, - QScriptValue::ReadOnly | QScriptValue::Undeletable); - activation_data->m_values[0] = QScriptValueImpl(this, ext); - activation_data->m_members[1].object( - nameId(QLatin1String("__setupPackage__")), 1, 0); - activation_data->m_values[1] = createFunction(__setupPackage__, 0, 0); - activation_data->m_members[2].object( - nameId(QLatin1String("__all__")), 2, 0); - activation_data->m_values[2] = undefinedValue(); - activation_data->m_members[3].object( - nameId(QLatin1String("__postInit__")), 3, 0); - activation_data->m_values[3] = undefinedValue(); - - // the script is evaluated first - if (!initjsContents.isEmpty()) { - evaluate(ctx_p, initjsContents, /*lineNumber=*/1, initjsFileName); - if (hasUncaughtException()) { - QScriptValueImpl r = ctx_p->returnValue(); - popContext(); - m_extensionsBeingImported.remove(ext); - return r; - } - } - - // next, the C++ plugin is called - if (iface) { - iface->initialize(ext, q); - if (hasUncaughtException()) { - QScriptValueImpl r = ctx_p->returnValue(); - popContext(); - m_extensionsBeingImported.remove(ext); - return r; - } - } - - // if the __postInit__ function has been set, we call it - QScriptValueImpl postInit = ctx_p->m_activation.property(QLatin1String("__postInit__")); - if (postInit.isFunction()) { - postInit.call(globalObject()); - if (hasUncaughtException()) { - QScriptValueImpl r = ctx_p->returnValue(); - popContext(); - m_extensionsBeingImported.remove(ext); - return r; - } - } - - popContext(); - - m_importedExtensions.insert(ext); - m_extensionsBeingImported.remove(ext); - } // for (i) -#endif // QT_NO_QOBJECT - return undefinedValue(); -} - -QStringList QScriptEnginePrivate::availableExtensions() const -{ -#if defined(QT_NO_QOBJECT) || defined(QT_NO_LIBRARY) || defined(QT_NO_SETTINGS) - return QStringList(); -#else - QCoreApplication *app = QCoreApplication::instance(); - if (!app) - return QStringList(); - - QSet<QString> result; - - QObjectList staticPlugins = QPluginLoader::staticInstances(); - for (int i = 0; i < staticPlugins.size(); ++i) { - QScriptExtensionInterface *iface; - iface = qobject_cast<QScriptExtensionInterface*>(staticPlugins.at(i)); - if (iface) { - QStringList keys = iface->keys(); - for (int j = 0; j < keys.count(); ++j) - result << keys.at(j); - } - } - - QStringList libraryPaths = app->libraryPaths(); - for (int i = 0; i < libraryPaths.count(); ++i) { - QString libPath = libraryPaths.at(i) + QDir::separator() + QLatin1String("script"); - QDir dir(libPath); - if (!dir.exists()) - continue; - - // look for C++ plugins - QFileInfoList files = dir.entryInfoList(QDir::Files); - for (int j = 0; j < files.count(); ++j) { - QFileInfo entry = files.at(j); - QString filePath = entry.canonicalFilePath(); - QPluginLoader loader(filePath); - QScriptExtensionInterface *iface; - iface = qobject_cast<QScriptExtensionInterface*>(loader.instance()); - if (iface) { - QStringList keys = iface->keys(); - for (int k = 0; k < keys.count(); ++k) - result << keys.at(k); - } - } - - // look for scripts - QString initDotJs = QLatin1String("__init__.js"); - QList<QFileInfo> stack; - stack << dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); - while (!stack.isEmpty()) { - QFileInfo entry = stack.takeLast(); - QDir dd(entry.canonicalFilePath()); - if (dd.exists(initDotJs)) { - QString rpath = dir.relativeFilePath(dd.canonicalPath()); - QStringList components = rpath.split(QLatin1Char('/')); - result << components.join(QLatin1String(".")); - stack << dd.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); - } - } - } - - QStringList lst = result.toList(); - qSort(lst); - return lst; -#endif -} - -QStringList QScriptEnginePrivate::importedExtensions() const -{ - QStringList lst = m_importedExtensions.toList(); - qSort(lst); - return lst; -} - -void QScriptEnginePrivate::gc() -{ - if (!objectAllocator.blocked()) { - // do the GC now - maybeGC_helper(/*do_string_gc=*/true); - } else { - // GC will be performed the next time maybeGC() - // is called and the allocator is not blocked - objectAllocator.requestGC(); - } -} - -QStringList QScriptEnginePrivate::uncaughtExceptionBacktrace() const -{ - QScriptValueImpl value = uncaughtException(); - if (!value.isError()) - return m_exceptionBacktrace; - return QScript::Ecma::Error::backtrace(value); -} - -void QScriptEnginePrivate::clearExceptions() -{ - m_exceptionBacktrace = QStringList(); - QScriptContextPrivate *ctx_p = currentContext(); - while (ctx_p) { - ctx_p->m_state = QScriptContext::NormalState; - ctx_p = ctx_p->parentContext(); - } -} - -#ifndef QT_NO_QOBJECT -void QScriptEnginePrivate::emitSignalHandlerException() -{ - Q_Q(QScriptEngine); - emit q->signalHandlerException(toPublic(uncaughtException())); -} -#endif - -void QScriptEnginePrivate::processEvents() -{ -#ifndef QT_NO_QOBJECT - Q_ASSERT(m_processEventTracker.isValid()); - int elapsed = m_processEventTracker.elapsed(); - if (m_nextProcessEvents < elapsed) { - do { - m_nextProcessEvents = m_nextProcessEvents + m_processEventsInterval; - } while (m_nextProcessEvents < elapsed); - QCoreApplication::processEvents(); - } -#endif -} - -void QScriptEnginePrivate::setupProcessEvents() -{ - if (m_processEventsInterval > 0) { - m_nextProcessEvents = m_processEventsInterval; - m_processEventIncr = 0; - m_processEventTracker.restart(); - } -} - -void QScriptEnginePrivate::abortEvaluation(const QScriptValueImpl &result) -{ - m_abort = true; - currentContext()->setReturnValue(result); -} - -#ifndef QT_NO_QOBJECT - -void QScriptEnginePrivate::newQObject(QScriptValueImpl *out, QObject *object, - QScriptEngine::ValueOwnership ownership, - const QScriptEngine::QObjectWrapOptions &options, - bool setDefaultPrototype) -{ - if (!object) { - *out = m_nullValue; - return; - } - Q_ASSERT(qobjectConstructor != 0); - QScriptQObjectData *data = qobjectData(object); - bool preferExisting = (options & QScriptEngine::PreferExistingWrapperObject) != 0; - QScriptEngine::QObjectWrapOptions opt = options & ~QScriptEngine::PreferExistingWrapperObject; - QScriptValueImpl existingWrapper; - bool hasExisting = data->findWrapper(ownership, opt, &existingWrapper); - if (preferExisting) { - if (hasExisting) { - *out = existingWrapper; - } else { - qobjectConstructor->newQObject(out, object, ownership, opt); - data->registerWrapper(*out, ownership, opt); - } - } else { - qobjectConstructor->newQObject(out, object, ownership, opt); - if (!hasExisting) - data->registerWrapper(*out, ownership, opt); - } - - if (setDefaultPrototype) { - const QMetaObject *meta = object->metaObject(); - while (meta) { - QByteArray typeString = meta->className(); - typeString.append('*'); - int typeId = QMetaType::type(typeString); - if (typeId != 0) { - QScriptValueImpl proto = defaultPrototype(typeId); - if (proto.isValid()) { - out->setPrototype(proto); - break; - } - } - meta = meta->superClass(); - } - } -} - -QScriptQObjectData *QScriptEnginePrivate::qobjectData(QObject *object) -{ - QHash<QObject*, QScriptQObjectData*>::const_iterator it; - it = m_qobjectData.constFind(object); - if (it != m_qobjectData.constEnd()) - return it.value(); - - QScriptQObjectData *data = new QScriptQObjectData(); - m_qobjectData.insert(object, data); - QObject::connect(object, SIGNAL(destroyed(QObject*)), - q_func(), SLOT(_q_objectDestroyed(QObject *))); - return data; -} - -void QScriptEnginePrivate::_q_objectDestroyed(QObject *object) -{ - QHash<QObject*, QScriptQObjectData*>::iterator it; - it = m_qobjectData.find(object); - Q_ASSERT(it != m_qobjectData.end()); - QScriptQObjectData *data = it.value(); - m_qobjectData.erase(it); - delete data; -} - -void QScriptEnginePrivate::disposeQObject(QObject *object) -{ - if (isCollecting()) { - // wait until we're done with GC before deleting it - int index = m_qobjectsToBeDeleted.indexOf(object); - if (index == -1) - m_qobjectsToBeDeleted.append(object); - } else { - delete object; - } -} - -void QScriptEnginePrivate::deletePendingQObjects() -{ - while (!m_qobjectsToBeDeleted.isEmpty()) - delete m_qobjectsToBeDeleted.takeFirst(); -} - -bool QScriptEnginePrivate::scriptConnect(QObject *sender, const char *signal, - const QScriptValueImpl &receiver, - const QScriptValueImpl &function, - Qt::ConnectionType type) -{ - Q_ASSERT(sender); - Q_ASSERT(signal); - const QMetaObject *meta = sender->metaObject(); - int index = meta->indexOfSignal(QMetaObject::normalizedSignature(signal+1)); - if (index == -1) - return false; - return scriptConnect(sender, index, receiver, function, /*wrapper=*/QScriptValueImpl(), type); -} - -bool QScriptEnginePrivate::scriptDisconnect(QObject *sender, const char *signal, - const QScriptValueImpl &receiver, - const QScriptValueImpl &function) -{ - Q_ASSERT(sender); - Q_ASSERT(signal); - const QMetaObject *meta = sender->metaObject(); - int index = meta->indexOfSignal(QMetaObject::normalizedSignature(signal+1)); - if (index == -1) - return false; - return scriptDisconnect(sender, index, receiver, function); -} - -bool QScriptEnginePrivate::scriptConnect(QObject *sender, int signalIndex, - const QScriptValueImpl &receiver, - const QScriptValueImpl &function, - const QScriptValueImpl &senderWrapper, - Qt::ConnectionType type) -{ - QScriptQObjectData *data = qobjectData(sender); - return data->addSignalHandler(sender, signalIndex, receiver, function, senderWrapper, type); -} - -bool QScriptEnginePrivate::scriptDisconnect(QObject *sender, int signalIndex, - const QScriptValueImpl &receiver, - const QScriptValueImpl &function) -{ - QScriptQObjectData *data = qobjectData(sender); - if (!data) - return false; - return data->removeSignalHandler(sender, signalIndex, receiver, function); -} - -bool QScriptEnginePrivate::scriptConnect(const QScriptValueImpl &signal, - const QScriptValueImpl &receiver, - const QScriptValueImpl &function, - Qt::ConnectionType type) -{ - QScript::QtFunction *fun = static_cast<QScript::QtFunction*>(signal.toFunction()); - int index = fun->mostGeneralMethod(); - return scriptConnect(fun->qobject(), index, receiver, function, fun->object(), type); -} - -bool QScriptEnginePrivate::scriptDisconnect(const QScriptValueImpl &signal, - const QScriptValueImpl &receiver, - const QScriptValueImpl &function) -{ - QScript::QtFunction *fun = static_cast<QScript::QtFunction*>(signal.toFunction()); - int index = fun->mostGeneralMethod(); - return scriptDisconnect(fun->qobject(), index, receiver, function); -} - -bool QScriptEnginePrivate::convertToNativeQObject(const QScriptValueImpl &value, - const QByteArray &targetType, - void **result) -{ - if (!targetType.endsWith('*')) - return false; - if (QObject *qobject = value.toQObject()) { - int start = targetType.startsWith("const ") ? 6 : 0; - QByteArray className = targetType.mid(start, targetType.size()-start-1); - if (void *instance = qobject->qt_metacast(className)) { - *result = instance; - return true; - } - } - return false; -} - -#endif // QT_NO_QOBJECT - -void QScriptEnginePrivate::setAgent(QScriptEngineAgent *agent) -{ - Q_Q(QScriptEngine); - if (agent && (agent->engine() != q)) { - qWarning("QScriptEngine::setAgent(): " - "cannot set agent belonging to different engine"); - return; - } - if (agent) { - int index = m_agents.indexOf(agent); - if (index == -1) - m_agents.append(agent); - } - m_agent = agent; -} - -QScriptEngineAgent *QScriptEnginePrivate::agent() const -{ - return m_agent; -} - -void QScriptEnginePrivate::agentDeleted(QScriptEngineAgent *agent) -{ - m_agents.removeOne(agent); - if (m_agent == agent) - m_agent = 0; -} - -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY -qint64 QScriptEnginePrivate::nextScriptId() -{ - // ### reuse IDs by using a pool - return m_scriptCounter++; -} - -void QScriptEnginePrivate::notifyScriptLoad_helper(qint64 id, const QString &program, - const QString &fileName, int lineNumber) -{ - m_agent->scriptLoad(id, program, fileName, lineNumber); -} - -void QScriptEnginePrivate::notifyScriptUnload_helper(qint64 id) -{ - m_agent->scriptUnload(id); -} - -void QScriptEnginePrivate::notifyPositionChange_helper(QScriptContextPrivate *ctx) -{ - m_agent->positionChange(ctx->scriptId(), ctx->currentLine, ctx->currentColumn); -} - -void QScriptEnginePrivate::notifyContextPush_helper() -{ - m_agent->contextPush(); -} - -void QScriptEnginePrivate::notifyContextPop_helper() -{ - m_agent->contextPop(); -} - -void QScriptEnginePrivate::notifyFunctionEntry_helper(QScriptContextPrivate *ctx) -{ - m_agent->functionEntry(ctx->scriptId()); -} - -void QScriptEnginePrivate::notifyFunctionExit_helper(QScriptContextPrivate *ctx) -{ - m_agent->functionExit(ctx->scriptId(), toPublic(ctx->returnValue())); -} - -void QScriptEnginePrivate::notifyException_helper(QScriptContextPrivate *ctx) -{ - bool hasHandler = (ctx->exceptionHandlerContext() != 0); - m_agent->exceptionThrow(ctx->scriptId(), toPublic(ctx->returnValue()), hasHandler); -} - -void QScriptEnginePrivate::notifyExceptionCatch_helper(QScriptContextPrivate *ctx) -{ - m_agent->exceptionCatch(ctx->scriptId(), toPublic(ctx->returnValue())); -} - -void QScriptEnginePrivate::notifyDebugger(QScriptContextPrivate *ctx) -{ - if (m_agent && m_agent->supportsExtension(QScriptEngineAgent::DebuggerInvocationRequest)) { - QVariantList args; - args.append(ctx->scriptId()); - args.append(ctx->currentLine); - args.append(ctx->currentColumn); - QVariant ret = m_agent->extension(QScriptEngineAgent::DebuggerInvocationRequest, args); - QScriptValueImpl val = valueFromVariant(ret); - if (val.isValid()) - ctx->m_result = val; - } -} - -#endif // Q_SCRIPT_NO_EVENT_NOTIFY - -QScriptString QScriptEnginePrivate::internedString(const QString &str) -{ - return internedString(nameId(str, /*persistent=*/false)); -} - -QScriptString QScriptEnginePrivate::internedString(QScriptNameIdImpl *nid) -{ - if (!nid) - return QScriptString(); - QScriptStringPrivate *d = m_internedStrings.value(nid); - if (!d) { - d = m_internedStringRepository.get(); - d->nameId = nid; - d->engine = this; - m_internedStrings.insert(d->nameId, d); - } - QScriptString result; - QScriptStringPrivate::init(result, d); - return result; -} - -void QScriptEnginePrivate::uninternString(QScriptStringPrivate *d) -{ - Q_ASSERT(d->nameId); - QHash<QScriptNameIdImpl*, QScriptStringPrivate*>::iterator it; - it = m_internedStrings.find(d->nameId); - Q_ASSERT(it != m_internedStrings.end()); - m_internedStrings.erase(it); - m_internedStringRepository.release(d); -} - -QScriptValueImpl QScriptEnginePrivate::toImpl_helper(const QScriptValue &value) -{ - QScriptValuePrivate *p = QScriptValuePrivate::get(value); - Q_ASSERT(p != 0); - Q_ASSERT(p->value.type() == QScript::LazyStringType); - QString str = *p->value.m_lazy_string_value; - if (!p->ref.deref()) - delete p; - QScriptValueImpl v; - newString(&v, str); - p = registerValue(v); - QScriptValuePrivate::init(const_cast<QScriptValue&>(value), p); - return v; -} - -QScriptValueImpl QScriptEnginePrivate::newObject(QScriptClass *scriptClass, - const QScriptValueImpl &data) -{ - if (!scriptClass) - return QScriptValueImpl(); - QScriptValueImpl v; - QScriptValueImpl proto = toImpl(scriptClass->prototype()); - if (!proto.isObject()) - proto = objectConstructor->publicPrototype; - newObject(&v, proto); - QScriptClassPrivate *cls_p = QScriptClassPrivate::get(scriptClass); - QScriptClassInfo *info = cls_p->classInfo(); - v.setClassInfo(info); - if (info->type() & QScriptClassInfo::FunctionBased) { - QScriptFunction *fun = cls_p->newFunction(); - v.setObjectData(fun); - } - v.setInternalValue(data); - return v; -} - -int QScriptEnginePrivate::registerCustomClassType() -{ - return ++m_class_prev_id; -} - -QScriptValueImpl QScriptEnginePrivate::objectById(qint64 id) const -{ - QScript::GCAlloc<QScriptObject>::const_iterator it; - for (it = objectAllocator.constBegin(); it != objectAllocator.constEnd(); ++it) { - const QScriptObject *obj = it.data(); - if (obj->m_id == id) { - QScriptValueImpl ret; - ret.m_type = QScript::ObjectType; - ret.m_object_value = const_cast<QScriptObject*>(obj); - return ret; - } - } - return QScriptValueImpl(); -} - -namespace QScript { - -static QScriptValueImpl qsTranslate(QScriptContextPrivate *ctx, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - if (ctx->argumentCount() < 2) - return ctx->throwError(QString::fromLatin1("qsTranslate() requires at least two arguments")); - if (!ctx->argument(0).isString()) - return ctx->throwError(QString::fromLatin1("qsTranslate(): first argument (context) must be a string")); - if (!ctx->argument(1).isString()) - return ctx->throwError(QString::fromLatin1("qsTranslate(): second argument (text) must be a string")); - if ((ctx->argumentCount() > 2) && !ctx->argument(2).isString()) - return ctx->throwError(QString::fromLatin1("qsTranslate(): third argument (comment) must be a string")); - if ((ctx->argumentCount() > 3) && !ctx->argument(3).isString()) - return ctx->throwError(QString::fromLatin1("qsTranslate(): fourth argument (encoding) must be a string")); - if ((ctx->argumentCount() > 4) && !ctx->argument(4).isNumber()) - return ctx->throwError(QString::fromLatin1("qsTranslate(): fifth argument (n) must be a number")); -#ifndef QT_NO_QOBJECT - QString context = ctx->argument(0).toString(); -#endif - QString text = ctx->argument(1).toString(); -#ifndef QT_NO_QOBJECT - QString comment; - if (ctx->argumentCount() > 2) - comment = ctx->argument(2).toString(); - QCoreApplication::Encoding encoding = QCoreApplication::CodecForTr; - if (ctx->argumentCount() > 3) { - QString encStr = ctx->argument(3).toString(); - if (encStr == QLatin1String("CodecForTr")) - encoding = QCoreApplication::CodecForTr; - else if (encStr == QLatin1String("UnicodeUTF8")) - encoding = QCoreApplication::UnicodeUTF8; - else - return ctx->throwError(QString::fromLatin1("qsTranslate(): invalid encoding '%s'").arg(encStr)); - } - int n = -1; - if (ctx->argumentCount() > 4) - n = ctx->argument(4).toInt32(); -#endif - QString result; -#ifndef QT_NO_QOBJECT - result = QCoreApplication::translate(context.toLatin1().constData(), - text.toLatin1().constData(), - comment.toLatin1().constData(), - encoding, n); -#else - result = text; -#endif - return QScriptValueImpl(eng, result); -} - -static QScriptValueImpl qTranslateNoOp(QScriptContextPrivate *ctx, QScriptEnginePrivate *, QScriptClassInfo *) -{ - return ctx->argument(1); -} - -static QScriptValueImpl qsTr(QScriptContextPrivate *ctx, QScriptEnginePrivate *eng, QScriptClassInfo *) -{ - if (ctx->argumentCount() < 1) - return ctx->throwError(QString::fromLatin1("qsTr() requires at least one argument")); - if (!ctx->argument(0).isString()) - return ctx->throwError(QString::fromLatin1("qsTr(): first argument (text) must be a string")); - if ((ctx->argumentCount() > 1) && !ctx->argument(1).isString()) - return ctx->throwError(QString::fromLatin1("qsTr(): second argument (comment) must be a string")); - if ((ctx->argumentCount() > 2) && !ctx->argument(2).isNumber()) - return ctx->throwError(QString::fromLatin1("qsTranslate(): third argument (n) must be a number")); -#ifndef QT_NO_QOBJECT - QString context; - if (ctx->parentContext()) - context = QFileInfo(ctx->parentContext()->fileName()).baseName(); -#endif - QString text = ctx->argument(0).toString(); -#ifndef QT_NO_QOBJECT - QString comment; - if (ctx->argumentCount() > 1) - comment = ctx->argument(1).toString(); - int n = -1; - if (ctx->argumentCount() > 2) - n = ctx->argument(2).toInt32(); -#endif - QString result; -#ifndef QT_NO_QOBJECT - result = QCoreApplication::translate(context.toLatin1().constData(), - text.toLatin1().constData(), - comment.toLatin1().constData(), - QCoreApplication::CodecForTr, n); -#else - result = text; -#endif - return QScriptValueImpl(eng, result); -} - -static QScriptValueImpl qTrNoOp(QScriptContextPrivate *ctx, QScriptEnginePrivate *, QScriptClassInfo *) -{ - return ctx->argument(0); -} - -} // namespace QScript - -void QScriptEnginePrivate::installTranslatorFunctions(QScriptValueImpl &object) -{ - Q_ASSERT(object.isObject()); - const QScriptValue::PropertyFlags flags = QScriptValue::SkipInEnumeration; - object.setProperty(QLatin1String("qsTranslate"), - createFunction(QScript::qsTranslate, /*length=*/5, /*classInfo=*/0), - flags); - object.setProperty(QLatin1String("QT_TRANSLATE_NOOP"), - createFunction(QScript::qTranslateNoOp, /*length=*/2, /*classInfo=*/0), - flags); - object.setProperty(QLatin1String("qsTr"), - createFunction(QScript::qsTr, /*length=*/3, /*classInfo=*/0), - flags); - object.setProperty(QLatin1String("QT_TR_NOOP"), - createFunction(QScript::qTrNoOp, /*length=*/1, /*classInfo=*/0), - flags); - - stringConstructor->addPrototypeFunction(QLatin1String("arg"), QScript::Ecma::String::method_ext_arg, 1); -} - -bool QScriptEnginePrivate::canEvaluate(const QString &program) -{ - QScript::SyntaxChecker checker; - QScript::SyntaxChecker::Result result = checker.checkSyntax(program); - return (result.state != QScript::SyntaxChecker::Intermediate); -} - -QScriptSyntaxCheckResult QScriptEnginePrivate::checkSyntax(const QString &program) -{ - QScript::SyntaxChecker checker; - QScript::SyntaxChecker::Result result = checker.checkSyntax(program); - QScriptSyntaxCheckResultPrivate *p = new QScriptSyntaxCheckResultPrivate(); - switch (result.state) { - case QScript::SyntaxChecker::Error: - p->state = QScriptSyntaxCheckResult::Error; - break; - case QScript::SyntaxChecker::Intermediate: - p->state = QScriptSyntaxCheckResult::Intermediate; - break; - case QScript::SyntaxChecker::Valid: - p->state = QScriptSyntaxCheckResult::Valid; - break; - } - p->errorLineNumber = result.errorLineNumber; - p->errorColumnNumber = result.errorColumnNumber; - p->errorMessage = result.errorMessage; - return QScriptSyntaxCheckResult(p); -} - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptengine_p.h b/src/script/qscriptengine_p.h deleted file mode 100644 index f3fb57f..0000000 --- a/src/script/qscriptengine_p.h +++ /dev/null @@ -1,828 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTENGINE_P_H -#define QSCRIPTENGINE_P_H - -#include "qscriptenginefwd_p.h" - -#ifndef QT_NO_SCRIPT - -#include <QtCore/QDateTime> -#include <QtCore/QMutex> -#include <QtCore/QLinkedList> -#include <QtCore/QString> -#include <QtCore/QVector> -#include <QtCore/QHash> -#include <QtCore/qnumeric.h> - -#include "qscriptengine.h" -#include "qscriptnameid_p.h" -#include "qscriptobjectfwd_p.h" -#include "qscriptrepository_p.h" -#include "qscriptgc_p.h" -#include "qscriptecmaarray_p.h" -#include "qscriptecmadate_p.h" -#include "qscriptecmaobject_p.h" -#include "qscriptecmaboolean_p.h" -#include "qscriptecmanumber_p.h" -#include "qscriptecmastring_p.h" -#include "qscriptecmafunction_p.h" -#include "qscriptextvariant_p.h" -#include "qscriptextqobject_p.h" -#include "qscriptvalue_p.h" -#include "qscriptcontextfwd_p.h" - -#include <math.h> - -QT_BEGIN_NAMESPACE - -// -// 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. -// - -namespace QScript { - -class ArgumentsObjectData: public QScriptObjectData -{ -public: - ArgumentsObjectData() : length(0) {} - virtual ~ArgumentsObjectData() {} - -public: // attributes - QScriptValueImpl activation; - uint length; -}; - -} // namespace QScript - -inline QScriptEnginePrivate *QScriptEnginePrivate::get(QScriptEngine *q) -{ - if (q) - return q->d_func(); - return 0; -} - -inline const QScriptEnginePrivate *QScriptEnginePrivate::get(const QScriptEngine *q) -{ - if (q) - return q->d_func(); - return 0; -} - -inline QScriptEngine *QScriptEnginePrivate::get(QScriptEnginePrivate *d) -{ - return d->q_func(); -} - -inline QString QScriptEnginePrivate::toString(QScriptNameIdImpl *id) -{ - if (! id) - return QString(); - - return id->s; -} - -inline QString QScriptEnginePrivate::memberName(const QScript::Member &member) const -{ - return toString(member.nameId()); -} - -inline void QScriptEnginePrivate::newReference(QScriptValueImpl *o, int mode) -{ - Q_ASSERT(o); - o->m_type = QScript::ReferenceType; - o->m_int_value = (mode); -} - -inline void QScriptEnginePrivate::newActivation(QScriptValueImpl *o) -{ - Q_ASSERT(o); - newObject(o, nullValue(), m_class_activation); -} - -inline void QScriptEnginePrivate::newPointer(QScriptValueImpl *o, void *ptr) -{ - Q_ASSERT(o); - o->m_type = QScript::PointerType; - o->m_ptr_value = ptr; -} - -inline void QScriptEnginePrivate::newInteger(QScriptValueImpl *o, int i) -{ - Q_ASSERT(o); - o->m_type = QScript::IntegerType; - o->m_int_value = (i); -} - -inline void QScriptEnginePrivate::newNameId(QScriptValueImpl *o, const QString &s) -{ - Q_ASSERT(o); - o->m_type = QScript::StringType; - o->m_string_value = (nameId(s, /*persistent=*/false)); -} - -inline void QScriptEnginePrivate::newString(QScriptValueImpl *o, const QString &s) -{ - Q_ASSERT(o); - o->m_type = QScript::StringType; - QScriptNameIdImpl *entry = new QScriptNameIdImpl(s); - m_tempStringRepository.append(entry); - o->m_string_value = (entry); - m_newAllocatedTempStringRepositoryChars += s.length(); -} - -inline void QScriptEnginePrivate::newNameId(QScriptValueImpl *o, QScriptNameIdImpl *id) -{ - Q_ASSERT(o); - o->m_type = QScript::StringType; - o->m_string_value = (id); -} - -inline const QScript::IdTable *QScriptEnginePrivate::idTable() const -{ - return &m_id_table; -} - -inline qsreal QScriptEnginePrivate::convertToNativeDouble(const QScriptValueImpl &value) -{ - Q_ASSERT (value.isValid()); - - if (value.isNumber()) - return value.m_number_value; - - return convertToNativeDouble_helper(value); -} - -inline qint32 QScriptEnginePrivate::convertToNativeInt32(const QScriptValueImpl &value) -{ - Q_ASSERT (value.isValid()); - - return toInt32 (convertToNativeDouble(value)); -} - - -inline bool QScriptEnginePrivate::convertToNativeBoolean(const QScriptValueImpl &value) -{ - Q_ASSERT (value.isValid()); - - if (value.isBoolean()) - return value.m_bool_value; - - return convertToNativeBoolean_helper(value); -} - -inline QString QScriptEnginePrivate::convertToNativeString(const QScriptValueImpl &value) -{ - Q_ASSERT (value.isValid()); - - if (value.isString()) - return value.m_string_value->s; - - return convertToNativeString_helper(value); -} - -inline qsreal QScriptEnginePrivate::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)); -} - -inline qint32 QScriptEnginePrivate::toInt32(qsreal n) -{ - if (qIsNaN(n) || qIsInf(n) || (n == 0)) - return 0; - - double 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); -} - -inline quint32 QScriptEnginePrivate::toUint32(qsreal n) -{ - if (qIsNaN(n) || qIsInf(n) || (n == 0)) - return 0; - - double 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); -} - -inline quint16 QScriptEnginePrivate::toUint16(qsreal n) -{ - if (qIsNaN(n) || qIsInf(n) || (n == 0)) - return 0; - - double 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); -} - -inline QScript::AST::Node *QScriptEnginePrivate::abstractSyntaxTree() const -{ - return m_abstractSyntaxTree; -} - -inline QScript::MemoryPool *QScriptEnginePrivate::nodePool() -{ - return m_pool; -} - -inline void QScriptEnginePrivate::setNodePool(QScript::MemoryPool *pool) -{ - m_pool = pool; -} - -inline QScript::Lexer *QScriptEnginePrivate::lexer() -{ - return m_lexer; -} - -inline void QScriptEnginePrivate::setLexer(QScript::Lexer *lexer) -{ - m_lexer = lexer; -} - -inline QScriptObject *QScriptEnginePrivate::allocObject() -{ - return objectAllocator(m_objectGeneration); -} - -inline QScriptContextPrivate *QScriptEnginePrivate::currentContext() const -{ - return m_context; -} - -inline QScriptContextPrivate *QScriptEnginePrivate::pushContext() -{ - QScriptContext *context = m_frameRepository.get(); - QScriptContextPrivate *ctx_p = QScriptContextPrivate::get(context); - ctx_p->init(m_context); - m_context = ctx_p; -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - notifyContextPush(); -#endif - return m_context; -} - -inline void QScriptEnginePrivate::popContext() -{ - Q_ASSERT(m_context != 0); -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - notifyContextPop(); -#endif - QScriptContextPrivate *context = m_context; - m_context = context->parentContext(); - if (m_context) { - QScriptContextPrivate *p1 = m_context; - QScriptContextPrivate *p2 = context; - if ((p1->m_state != QScriptContext::ExceptionState) - || (p2->m_state == QScriptContext::ExceptionState)) { - // propagate the state - p1->m_result = p2->m_result; - p1->m_state = p2->m_state; - // only update errorLineNumber if there actually was an exception - if (p2->m_state == QScriptContext::ExceptionState) { - if (p2->errorLineNumber != -1) - p1->errorLineNumber = p2->errorLineNumber; - else - p1->errorLineNumber = p1->currentLine; - } - } - } - m_frameRepository.release(QScriptContextPrivate::get(context)); -} - -inline void QScriptEnginePrivate::maybeGC() -{ - if (objectAllocator.blocked()) - return; - - bool do_string_gc = ((m_stringRepository.size() - m_oldStringRepositorySize) > 256) - || (m_newAllocatedStringRepositoryChars > 0x800000); - do_string_gc |= ((m_tempStringRepository.size() - m_oldTempStringRepositorySize) > 1024) - || (m_newAllocatedTempStringRepositoryChars > 0x800000); - - if (! do_string_gc && ! objectAllocator.poll()) - return; - - maybeGC_helper(do_string_gc); -} - -inline void QScriptEnginePrivate::adjustBytesAllocated(int bytes) -{ - objectAllocator.adjustBytesAllocated(bytes); -} - -inline bool QScriptEnginePrivate::blockGC(bool block) -{ - return objectAllocator.blockGC(block); -} - -inline void QScriptEnginePrivate::markString(QScriptNameIdImpl *id, int /*generation*/) -{ - id->used = true; -} - -inline QScriptValueImpl QScriptEnginePrivate::createFunction(QScriptFunction *fun) -{ - QScriptValueImpl v; - newFunction(&v, fun); - return v; -} - -inline QScriptValueImpl QScriptEnginePrivate::newArray(const QScript::Array &value) -{ - QScriptValueImpl v; - newArray(&v, value); - return v; -} - -inline QScriptValueImpl QScriptEnginePrivate::newArray(uint length) -{ - QScriptValueImpl v; - QScript::Array a(this); - a.resize(length); - newArray(&v, a); - return v; -} - -inline QScriptClassInfo *QScriptEnginePrivate::registerClass(const QString &pname, int type) -{ - if (type == -1) - type = ++m_class_prev_id; - - QScriptClassInfo *oc = new QScriptClassInfo(this, QScriptClassInfo::Type(type), pname); - m_allocated_classes.append(oc); - - return oc; -} - -inline QScriptClassInfo *QScriptEnginePrivate::registerClass(const QString &name) -{ - return registerClass(name, -1); -} - -inline QScriptValueImpl QScriptEnginePrivate::createFunction(QScriptInternalFunctionSignature fun, - int length, QScriptClassInfo *classInfo, const QString &name) -{ - return createFunction(new QScript::C2Function(fun, length, classInfo, name)); -} - -inline void QScriptEnginePrivate::newFunction(QScriptValueImpl *o, QScriptFunction *function) -{ - QScriptValueImpl proto; - if (functionConstructor) - proto = functionConstructor->publicPrototype; - else { - // creating the Function prototype object - Q_ASSERT(objectConstructor); - proto = objectConstructor->publicPrototype; - } - newObject(o, proto, m_class_function); - o->setObjectData(function); -} - -inline void QScriptEnginePrivate::newConstructor(QScriptValueImpl *ctor, - QScriptFunction *function, - QScriptValueImpl &proto) -{ - newFunction(ctor, function); - ctor->setProperty(m_id_table.id_prototype, proto, - QScriptValue::Undeletable - | QScriptValue::ReadOnly - | QScriptValue::SkipInEnumeration); - proto.setProperty(m_id_table.id_constructor, *ctor, - QScriptValue::Undeletable - | QScriptValue::SkipInEnumeration); -} - -inline void QScriptEnginePrivate::newArguments(QScriptValueImpl *object, - const QScriptValueImpl &activation, - uint length, - const QScriptValueImpl &callee) -{ - QScript::ArgumentsObjectData *data = new QScript::ArgumentsObjectData(); - data->activation = activation; - data->length = length; - newObject(object, m_class_arguments); - object->setObjectData(data); - object->setProperty(m_id_table.id_callee, callee, - QScriptValue::SkipInEnumeration); - object->setProperty(m_id_table.id_length, QScriptValueImpl(length), - QScriptValue::SkipInEnumeration); -} - -inline QScriptFunction *QScriptEnginePrivate::convertToNativeFunction(const QScriptValueImpl &object) -{ - if (object.isFunction()) - return static_cast<QScriptFunction*> (object.objectData()); - return 0; -} - -inline QScriptValue QScriptEnginePrivate::toPublic(const QScriptValueImpl &value) -{ - if (!value.isValid()) - return QScriptValue(); - - QScriptValuePrivate *p = registerValue(value); - QScriptValue v; - QScriptValuePrivate::init(v, p); - return v; -} - -inline QScriptValueImpl QScriptEnginePrivate::toImpl(const QScriptValue &value) -{ - QScriptValuePrivate *p = QScriptValuePrivate::get(value); - if (!p) - return QScriptValueImpl(); - if (p->value.type() == QScript::LazyStringType) - return toImpl_helper(value); - return p->value; -} - -inline QScriptValueImplList QScriptEnginePrivate::toImplList(const QScriptValueList &lst) -{ - QScriptValueImplList result; - QScriptValueList::const_iterator it; - for (it = lst.constBegin(); it != lst.constEnd(); ++it) - result.append(toImpl(*it)); - return result; -} - -inline QScriptValueImpl QScriptEnginePrivate::toObject(const QScriptValueImpl &value) -{ - if (value.isObject() || !value.isValid()) - return value; - return toObject_helper(value); -} - -inline QScriptValueImpl QScriptEnginePrivate::toPrimitive(const QScriptValueImpl &object, - QScriptValueImpl::TypeHint hint) -{ - Q_ASSERT(object.isValid()); - - if (! object.isObject()) - return object; - - return toPrimitive_helper(object, hint); -} - -inline QDateTime QScriptEnginePrivate::toDateTime(const QScriptValueImpl &value) const -{ - return dateConstructor->toDateTime(value); -} - -inline void QScriptEnginePrivate::newArray(QScriptValueImpl *object, const QScript::Array &value) -{ - arrayConstructor->newArray(object, value); -} - -inline void QScriptEnginePrivate::newObject(QScriptValueImpl *o, const QScriptValueImpl &proto, - QScriptClassInfo *oc) -{ - Q_ASSERT(o != 0); - - QScriptObject *od = allocObject(); - od->reset(); - od->m_id = ++m_next_object_id; - if (proto.isValid()) - od->m_prototype = proto; - else { - Q_ASSERT(objectConstructor); - od->m_prototype = objectConstructor->publicPrototype; - } - - o->m_type = QScript::ObjectType; - od->m_class = (oc ? oc : m_class_object); - o->m_object_value = od; -} - -inline void QScriptEnginePrivate::newObject(QScriptValueImpl *o, QScriptClassInfo *oc) -{ - newObject(o, objectConstructor->publicPrototype, oc); -} - -inline QScriptValueImpl QScriptEnginePrivate::newObject() -{ - QScriptValueImpl v; - newObject(&v); - return v; -} - -inline void QScriptEnginePrivate::newVariant(QScriptValueImpl *out, - const QVariant &value, - bool setDefaultPrototype) -{ - Q_ASSERT(variantConstructor != 0); - variantConstructor->newVariant(out, value); - if (setDefaultPrototype) { - QScriptValueImpl proto = defaultPrototype(value.userType()); - if (proto.isValid()) - out->setPrototype(proto); - } -} - -#ifndef QT_NO_QOBJECT -# ifndef Q_SCRIPT_NO_QMETAOBJECT_CACHE -inline QScriptMetaObject *QScriptEnginePrivate::cachedMetaObject(const QMetaObject *meta) -{ - QScriptMetaObject *value = m_cachedMetaObjects.value(meta); - if (!value) { - value = new QScriptMetaObject; - m_cachedMetaObjects.insert(meta, value); - } - return value; -} -# endif -#endif // !QT_NO_QOBJECT - -inline QScriptNameIdImpl *QScriptEnginePrivate::nameId(const QString &str, bool persistent) -{ - QScriptNameIdImpl *entry = toStringEntry(str); - if (! entry) - entry = insertStringEntry(str); - - Q_ASSERT(entry->unique); - - if (persistent) - entry->persistent = true; - - return entry; -} - -inline QScriptNameIdImpl *QScriptEnginePrivate::intern(const QChar *u, int s) -{ - QString tmp(u, s); - return nameId(tmp, /*persistent=*/ true); -} - -inline QScriptValueImpl QScriptEnginePrivate::valueFromVariant(const QVariant &v) -{ - QScriptValueImpl result = create(v.userType(), v.data()); - Q_ASSERT(result.isValid()); - return result; -} - -inline QScriptValueImpl QScriptEnginePrivate::undefinedValue() -{ - return m_undefinedValue; -} - -inline QScriptValueImpl QScriptEnginePrivate::nullValue() -{ - return m_nullValue; -} - -inline QScriptValueImpl QScriptEnginePrivate::defaultPrototype(int metaTypeId) const -{ - QScriptCustomTypeInfo info = m_customTypes.value(metaTypeId); - return info.prototype; -} - -inline void QScriptEnginePrivate::setDefaultPrototype(int metaTypeId, const QScriptValueImpl &prototype) -{ - QScriptCustomTypeInfo info = m_customTypes.value(metaTypeId); - info.prototype = prototype; - m_customTypes.insert(metaTypeId, info); -} - -inline uint _q_scriptHash(const QString &key) -{ - const QChar *p = key.unicode(); - int n = qMin(key.size(), 128); - uint h = key.size(); - uint g; - - while (n--) { - h = (h << 4) + (*p++).unicode(); - if ((g = (h & 0xf0000000)) != 0) - h ^= g >> 23; - h &= ~g; - } - return h; -} - -inline QScriptNameIdImpl *QScriptEnginePrivate::toStringEntry(const QString &s) -{ - uint h = _q_scriptHash(s) % m_string_hash_size; - - for (QScriptNameIdImpl *entry = m_string_hash_base[h]; entry && entry->h == h; entry = entry->next) { - if (entry->s == s) - return entry; - } - - return 0; -} - -inline bool QScriptEnginePrivate::lessThan(const QScriptValueImpl &lhs, const QScriptValueImpl &rhs) -{ - return QScriptContextPrivate::lt_cmp(lhs, rhs); -} - -inline bool QScriptEnginePrivate::equals(const QScriptValueImpl &lhs, const QScriptValueImpl &rhs) -{ - return QScriptContextPrivate::eq_cmp(lhs, rhs); -} - -inline bool QScriptEnginePrivate::strictlyEquals(const QScriptValueImpl &lhs, const QScriptValueImpl &rhs) -{ - return QScriptContextPrivate::strict_eq_cmp(lhs, rhs); -} - -inline void QScriptEnginePrivate::unregisterValue(QScriptValuePrivate *p) -{ - QScriptValueImpl &v = p->value; - Q_ASSERT(v.isValid()); - if (v.isString()) { - QScriptNameIdImpl *id = v.stringValue(); - m_stringHandles.remove(id); - } else if (v.isObject()) { - QScriptObject *instance = v.objectValue(); - m_objectHandles.remove(instance); - } else { - int i = m_otherHandles.indexOf(p); - Q_ASSERT(i != -1); - m_otherHandles.remove(i); - } - m_handleRepository.release(p); -} - -inline QScriptValueImpl QScriptEnginePrivate::globalObject() const -{ - return m_globalObject; -} - -inline bool QScriptEnginePrivate::hasUncaughtException() const -{ - return (currentContext()->state() == QScriptContext::ExceptionState); -} - -inline QScriptValueImpl QScriptEnginePrivate::uncaughtException() const -{ - if (!hasUncaughtException()) - return QScriptValueImpl(); - return currentContext()->returnValue(); -} - -inline void QScriptEnginePrivate::maybeProcessEvents() -{ - if (m_processEventsInterval > 0 && ++m_processEventIncr > 512) { - m_processEventIncr = 0; - processEvents(); - } -} - -inline bool QScriptEnginePrivate::shouldAbort() const -{ - return m_abort; -} - -inline void QScriptEnginePrivate::resetAbortFlag() -{ - m_abort = false; -} - -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - -inline bool QScriptEnginePrivate::shouldNotify() const -{ - return m_agent != 0; -} - -inline void QScriptEnginePrivate::notifyScriptLoad( - qint64 id, const QString &program, - const QString &fileName, int lineNumber) -{ - if (shouldNotify()) - notifyScriptLoad_helper(id, program, fileName, lineNumber); -} - -inline void QScriptEnginePrivate::notifyScriptUnload(qint64 id) -{ - if (shouldNotify()) - notifyScriptUnload_helper(id); -} - -inline void QScriptEnginePrivate::notifyPositionChange(QScriptContextPrivate *ctx) -{ - Q_ASSERT(m_agent != 0); - notifyPositionChange_helper(ctx); -} - -inline void QScriptEnginePrivate::notifyContextPush() -{ - if (shouldNotify()) - notifyContextPush_helper(); -} - -inline void QScriptEnginePrivate::notifyContextPop() -{ - if (shouldNotify()) - notifyContextPop_helper(); -} - -inline void QScriptEnginePrivate::notifyFunctionEntry(QScriptContextPrivate *ctx) -{ - if (shouldNotify()) - notifyFunctionEntry_helper(ctx); -} - -inline void QScriptEnginePrivate::notifyFunctionExit(QScriptContextPrivate *ctx) -{ - if (shouldNotify()) - notifyFunctionExit_helper(ctx); -} - -inline void QScriptEnginePrivate::notifyException(QScriptContextPrivate *ctx) -{ - if (shouldNotify()) - notifyException_helper(ctx); -} - -inline void QScriptEnginePrivate::notifyExceptionCatch(QScriptContextPrivate *ctx) -{ - if (shouldNotify()) - notifyExceptionCatch_helper(ctx); -} - -#endif // Q_SCRIPT_NO_EVENT_NOTIFY - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT - -#endif diff --git a/src/script/qscriptengineagent_p.h b/src/script/qscriptengineagent_p.h deleted file mode 100644 index b4f5454..0000000 --- a/src/script/qscriptengineagent_p.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTENGINEAGENT_P_H -#define QSCRIPTENGINEAGENT_P_H - -#include <QtCore/qobjectdefs.h> - -#ifndef QT_NO_SCRIPT - -// -// 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. -// - -QT_BEGIN_NAMESPACE - -class QScriptEngine; - -class QScriptEngineAgent; -class Q_SCRIPT_EXPORT QScriptEngineAgentPrivate -{ - Q_DECLARE_PUBLIC(QScriptEngineAgent) -public: - QScriptEngineAgentPrivate(); - virtual ~QScriptEngineAgentPrivate(); - - QScriptEngine *engine; - - QScriptEngineAgent *q_ptr; -}; - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT - -#endif diff --git a/src/script/qscriptenginefwd_p.h b/src/script/qscriptenginefwd_p.h deleted file mode 100644 index fa539a5..0000000 --- a/src/script/qscriptenginefwd_p.h +++ /dev/null @@ -1,563 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTENGINEFWD_P_H -#define QSCRIPTENGINEFWD_P_H - -#ifndef QT_NO_QOBJECT -#include "private/qobject_p.h" -#endif - -#ifndef QT_NO_SCRIPT - -#include <QtCore/qobjectdefs.h> - -#include <QtCore/QHash> -#include <QtCore/QList> -#include <QtCore/QRegExp> -#include <QtCore/QSet> -#include <QtCore/QStringList> -#include <QtCore/QTime> -#include <QtCore/QVector> - -#include "qscriptengine.h" -#include "qscriptrepository_p.h" -#include "qscriptgc_p.h" -#include "qscriptobjectfwd_p.h" -#include "qscriptclassinfo_p.h" -#include "qscriptstring_p.h" - -QT_BEGIN_NAMESPACE - -// -// 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. -// - -class QScriptClass; -class QScriptContext; - -namespace QScript { - -namespace AST { - class Node; -} // namespace AST - -namespace Ecma { - class Object; - class Number; - class Boolean; - class String; - class Math; - class Date; - class Function; - class Array; - class RegExp; - class Error; -} // namespace Ecma - -namespace Ext { - class Enumeration; - class Variant; -} // namespace Ext - -class ExtQObject; -class ExtQMetaObject; - -class Array; -class Lexer; -class Code; -class CompilationUnit; -class IdTable; -class MemoryPool; - -class IdTable -{ -public: - inline IdTable() - : id_constructor(0), id_false(0), id_null(0), - id_object(0), id_pointer(0), id_prototype(0), - id_arguments(0), id_this(0), id_toString(0), - id_true(0), id_undefined(0), id_valueOf(0), - id_length(0), id_callee(0), id___proto__(0), - id___qt_sender__(0) - {} - - QScriptNameIdImpl *id_constructor; - QScriptNameIdImpl *id_false; - QScriptNameIdImpl *id_null; - QScriptNameIdImpl *id_object; - QScriptNameIdImpl *id_pointer; - QScriptNameIdImpl *id_prototype; - QScriptNameIdImpl *id_arguments; - QScriptNameIdImpl *id_this; - QScriptNameIdImpl *id_toString; - QScriptNameIdImpl *id_true; - QScriptNameIdImpl *id_undefined; - QScriptNameIdImpl *id_valueOf; - QScriptNameIdImpl *id_length; - QScriptNameIdImpl *id_callee; - QScriptNameIdImpl *id___proto__; - QScriptNameIdImpl *id___qt_sender__; -}; - -} // namespace QScript - -#ifndef QT_NO_QOBJECT -class QScriptQObjectData; -class QScriptMetaObject; -#endif - -class QScriptCustomTypeInfo -{ -public: - QScriptCustomTypeInfo() : signature(0, '\0'), marshal(0), demarshal(0) - { prototype.invalidate(); } - - QByteArray signature; - QScriptEngine::MarshalFunction marshal; - QScriptEngine::DemarshalFunction demarshal; - QScriptValueImpl prototype; -}; - -class QScriptEnginePrivate -#ifndef QT_NO_QOBJECT - : public QObjectPrivate -#endif -{ - Q_DECLARE_PUBLIC(QScriptEngine) - - enum { - DefaultHashSize = 1021 - }; - -public: - QScriptEnginePrivate(); - virtual ~QScriptEnginePrivate(); - - void init(); - void initStringRepository(); - - static inline QScriptEnginePrivate *get(QScriptEngine *q); - static inline const QScriptEnginePrivate *get(const QScriptEngine *q); - static inline QScriptEngine *get(QScriptEnginePrivate *d); - - QScript::AST::Node *createAbstractSyntaxTree( - const QString &source, int lineNumber, - QString *errorMessage, int *errorLineNumber); - QScript::AST::Node *changeAbstractSyntaxTree(QScript::AST::Node *program); - - inline QScript::AST::Node *abstractSyntaxTree() const; - inline bool hasUncaughtException() const; - inline QScriptValueImpl uncaughtException() const; - QStringList uncaughtExceptionBacktrace() const; - void clearExceptions(); -#ifndef QT_NO_QOBJECT - void emitSignalHandlerException(); -#endif - - static bool canEvaluate(const QString &program); - static QScriptSyntaxCheckResult checkSyntax(const QString &program); - - inline QScriptContextPrivate *currentContext() const; - inline QScriptContextPrivate *pushContext(); - inline void popContext(); - - inline QScript::MemoryPool *nodePool(); - inline QScript::Lexer *lexer(); - inline QScriptObject *allocObject(); - - inline void maybeGC(); - - void maybeGC_helper(bool do_string_gc); - - inline bool blockGC(bool block); - - void gc(); - bool isCollecting() const; - void processMarkStack(int generation); - - inline void adjustBytesAllocated(int bytes); - - void markObject(const QScriptValueImpl &object, int generation); - void markFrame(QScriptContextPrivate *context, int generation); - - inline void markString(QScriptNameIdImpl *id, int generation); - - inline QScriptValueImpl createFunction(QScriptFunction *fun); - inline QScriptValueImpl newArray(const QScript::Array &value); - inline QScriptValueImpl newArray(uint length = 0); - - void evaluate(QScriptContextPrivate *context, const QString &contents, - int lineNumber, const QString &fileName = QString()); - - inline void setLexer(QScript::Lexer *lexer); - - inline void setNodePool(QScript::MemoryPool *pool); - - inline QScriptClassInfo *registerClass(const QString &pname, int type); - - inline QScriptClassInfo *registerClass(const QString &name); - - int registerCustomClassType(); - - inline QScriptValueImpl createFunction(QScriptInternalFunctionSignature fun, - int length, QScriptClassInfo *classInfo, - const QString &name = QString()); - - static inline QString toString(QScriptNameIdImpl *id); - inline QString memberName(const QScript::Member &member) const; - inline void newReference(QScriptValueImpl *object, int mode); - inline void newActivation(QScriptValueImpl *object); - inline void newFunction(QScriptValueImpl *object, QScriptFunction *function); - inline void newConstructor(QScriptValueImpl *ctor, QScriptFunction *function, - QScriptValueImpl &proto); - inline void newInteger(QScriptValueImpl *object, int i); - inline void newPointer(QScriptValueImpl *object, void *ptr); - inline void newNameId(QScriptValueImpl *object, const QString &s); - inline void newNameId(QScriptValueImpl *object, QScriptNameIdImpl *id); - inline void newString(QScriptValueImpl *object, const QString &s); - inline void newArguments(QScriptValueImpl *object, const QScriptValueImpl &activation, - uint length, const QScriptValueImpl &callee); - static inline QString convertToNativeString(const QScriptValueImpl &value); - static QString convertToNativeString_helper(const QScriptValueImpl &value); - static inline qsreal convertToNativeDouble(const QScriptValueImpl &value); - static qsreal convertToNativeDouble_helper(const QScriptValueImpl &value); - static inline bool convertToNativeBoolean(const QScriptValueImpl &value); - static bool convertToNativeBoolean_helper(const QScriptValueImpl &value); - static inline qint32 convertToNativeInt32(const QScriptValueImpl &value); - static inline QScriptFunction *convertToNativeFunction(const QScriptValueImpl &value); - - inline QScriptValue toPublic(const QScriptValueImpl &value); - inline QScriptValueImpl toImpl(const QScriptValue &value); - QScriptValueImpl toImpl_helper(const QScriptValue &value); - inline QScriptValueImplList toImplList(const QScriptValueList &lst); - - inline const QScript::IdTable *idTable() const; - - inline QScriptValueImpl toObject(const QScriptValueImpl &value); - QScriptValueImpl toObject_helper(const QScriptValueImpl &value); - - inline QScriptValueImpl toPrimitive(const QScriptValueImpl &object, - QScriptValueImpl::TypeHint hint = QScriptValueImpl::NoTypeHint); - QScriptValueImpl toPrimitive_helper(const QScriptValueImpl &object, - QScriptValueImpl::TypeHint hint); - - static const qsreal D16; - static const qsreal D32; - - inline static qsreal toInteger(qsreal n); - inline static qint32 toInt32(qsreal m); - inline static quint32 toUint32(qsreal n); - inline static quint16 toUint16(qsreal n); - - inline QDateTime toDateTime(const QScriptValueImpl &value) const; - - inline void newArray(QScriptValueImpl *object, const QScript::Array &value); - - inline void newObject(QScriptValueImpl *o, const QScriptValueImpl &proto, - QScriptClassInfo *oc = 0); - inline void newObject(QScriptValueImpl *o, QScriptClassInfo *oc = 0); - QScriptValueImpl newObject(QScriptClass *scriptClass, const QScriptValueImpl &data); - - inline QScriptValueImpl newObject(); - - inline void newVariant(QScriptValueImpl *out, const QVariant &value, - bool setDefaultPrototype = true); - -#ifndef QT_NO_QOBJECT - void newQObject(QScriptValueImpl *out, QObject *object, - QScriptEngine::ValueOwnership ownership = QScriptEngine::QtOwnership, - const QScriptEngine::QObjectWrapOptions &options = 0, - bool setDefaultPrototype = true); - -# ifndef Q_SCRIPT_NO_QMETAOBJECT_CACHE - inline QScriptMetaObject *cachedMetaObject(const QMetaObject *meta); -# endif -#endif - - inline QScriptNameIdImpl *nameId(const QString &str, bool persistent = false); - - inline QScriptNameIdImpl *intern(const QChar *u, int s); - - QScriptString internedString(const QString &str); - QScriptString internedString(QScriptNameIdImpl *nid); - void uninternString(QScriptStringPrivate *d); - - inline QScriptValueImpl valueFromVariant(const QVariant &v); - - inline QScriptValueImpl undefinedValue(); - - inline QScriptValueImpl nullValue(); - - inline QScriptValueImpl defaultPrototype(int metaTypeId) const; - - inline void setDefaultPrototype(int metaTypeId, const QScriptValueImpl &prototype); - - QScriptValueImpl call(const QScriptValueImpl &callee, const QScriptValueImpl &thisObject, - const QScriptValueImplList &args, bool asConstructor); - QScriptValueImpl call(const QScriptValueImpl &callee, const QScriptValueImpl &thisObject, - const QScriptValueImpl &args, bool asConstructor); - - void rehashStringRepository(bool resize = true); - inline QScriptNameIdImpl *toStringEntry(const QString &s); - QScriptNameIdImpl *insertStringEntry(const QString &s); - - QScriptValueImpl create(int type, const void *ptr); - static bool convert(const QScriptValueImpl &value, int type, void *ptr, - QScriptEnginePrivate *eng); - QScriptEngine::DemarshalFunction demarshalFunction(int type) const; - - QScriptValueImpl arrayFromStringList(const QStringList &lst); - static QStringList stringListFromArray(const QScriptValueImpl &arr); - - QScriptValueImpl arrayFromVariantList(const QVariantList &lst); - static QVariantList variantListFromArray(const QScriptValueImpl &arr); - - QScriptValueImpl objectFromVariantMap(const QVariantMap &vmap); - static QVariantMap variantMapFromObject(const QScriptValueImpl &obj); - - static inline bool lessThan(const QScriptValueImpl &lhs, const QScriptValueImpl &rhs); - static inline bool equals(const QScriptValueImpl &lhs, const QScriptValueImpl &rhs); - static inline bool strictlyEquals(const QScriptValueImpl &lhs, const QScriptValueImpl &rhs); - - QScriptValuePrivate *registerValue(const QScriptValueImpl &value); - inline void unregisterValue(QScriptValuePrivate *p); - - inline QScriptValueImpl globalObject() const; - - QScriptValueImpl objectById(qint64 id) const; - - QScriptValueImpl importExtension(const QString &extension); - QStringList availableExtensions() const; - QStringList importedExtensions() const; - - inline void maybeProcessEvents(); - void setupProcessEvents(); - void processEvents(); - -#ifndef QT_NO_QOBJECT - QScriptQObjectData *qobjectData(QObject *object); - - bool scriptConnect(QObject *sender, const char *signal, - const QScriptValueImpl &receiver, - const QScriptValueImpl &function, - Qt::ConnectionType type); - bool scriptDisconnect(QObject *sender, const char *signal, - const QScriptValueImpl &receiver, - const QScriptValueImpl &function); - - bool scriptConnect(QObject *sender, int index, - const QScriptValueImpl &receiver, - const QScriptValueImpl &function, - const QScriptValueImpl &senderWrapper, - Qt::ConnectionType type); - bool scriptDisconnect(QObject *sender, int index, - const QScriptValueImpl &receiver, - const QScriptValueImpl &function); - - bool scriptConnect(const QScriptValueImpl &signal, - const QScriptValueImpl &receiver, - const QScriptValueImpl &function, - Qt::ConnectionType type); - bool scriptDisconnect(const QScriptValueImpl &signal, - const QScriptValueImpl &receiver, - const QScriptValueImpl &function); - - void _q_objectDestroyed(QObject *object); - - void disposeQObject(QObject *object); - void deletePendingQObjects(); - - static bool convertToNativeQObject(const QScriptValueImpl &value, - const QByteArray &targetType, - void **result); -#endif - - void abortEvaluation(const QScriptValueImpl &result); - inline bool shouldAbort() const; - inline void resetAbortFlag(); - - void setAgent(QScriptEngineAgent *agent); - QScriptEngineAgent *agent() const; - - void agentDeleted(QScriptEngineAgent *agent); - - void installTranslatorFunctions(QScriptValueImpl &object); - -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - qint64 nextScriptId(); - inline bool shouldNotify() const; - inline void notifyScriptLoad(qint64 id, const QString &program, - const QString &fileName, int lineNumber); - void notifyScriptLoad_helper(qint64 id, const QString &program, - const QString &fileName, int lineNumber); - inline void notifyScriptUnload(qint64 id); - void notifyScriptUnload_helper(qint64 id); - inline void notifyPositionChange(QScriptContextPrivate *ctx); - void notifyPositionChange_helper(QScriptContextPrivate *ctx); - inline void notifyContextPush(); - void notifyContextPush_helper(); - inline void notifyContextPop(); - void notifyContextPop_helper(); - inline void notifyFunctionEntry(QScriptContextPrivate *ctx); - void notifyFunctionEntry_helper(QScriptContextPrivate *ctx); - inline void notifyFunctionExit(QScriptContextPrivate *ctx); - void notifyFunctionExit_helper(QScriptContextPrivate *ctx); - inline void notifyException(QScriptContextPrivate *ctx); - void notifyException_helper(QScriptContextPrivate *ctx); - inline void notifyExceptionCatch(QScriptContextPrivate *ctx); - void notifyExceptionCatch_helper(QScriptContextPrivate *ctx); - void notifyDebugger(QScriptContextPrivate *ctx); -#endif // Q_SCRIPT_NO_EVENT_NOTIFY - -public: // attributes - bool m_evaluating; - bool m_abort; - int m_callDepth; - int m_maxCallDepth; - int m_gc_depth; - QList<QScriptValueImpl> m_markStack; - QScriptValueImpl m_globalObject; - int m_oldStringRepositorySize; - int m_oldTempStringRepositorySize; - QVector<QScriptNameIdImpl*> m_stringRepository; - int m_newAllocatedStringRepositoryChars; - QVector<QScriptNameIdImpl*> m_tempStringRepository; - int m_newAllocatedTempStringRepositoryChars; - QScriptNameIdImpl **m_string_hash_base; - int m_string_hash_size; - QScript::GCAlloc<QScriptObject> objectAllocator; - int m_objectGeneration; - QScript::Repository<QScriptContext, QScriptContextPrivate> m_frameRepository; - QScriptContextPrivate *m_context; - QScriptValueImpl *tempStackBegin; - QScriptValueImpl *tempStackEnd; - QScript::AST::Node *m_abstractSyntaxTree; - QScript::Lexer *m_lexer; - QScript::MemoryPool *m_pool; - QStringList m_exceptionBacktrace; - qint64 m_scriptCounter; - - QScriptValueImpl m_undefinedValue; - QScriptValueImpl m_nullValue; - - QScript::Ecma::Object *objectConstructor; - QScript::Ecma::Number *numberConstructor; - QScript::Ecma::Boolean *booleanConstructor; - QScript::Ecma::String *stringConstructor; - QScript::Ecma::Date *dateConstructor; - QScript::Ecma::Function *functionConstructor; - QScript::Ecma::Array *arrayConstructor; - QScript::Ecma::RegExp *regexpConstructor; - QScript::Ecma::Error *errorConstructor; - QScript::Ext::Enumeration *enumerationConstructor; - QScript::Ext::Variant *variantConstructor; - QScript::ExtQObject *qobjectConstructor; - QScript::ExtQMetaObject *qmetaObjectConstructor; - - QHash<int, QScriptCustomTypeInfo> m_customTypes; - - QScriptFunction *m_evalFunction; - - QList<QScriptClassInfo*> m_allocated_classes; - QScriptClassInfo *m_class_object; - QScriptClassInfo *m_class_function; - QScriptClassInfo *m_class_with; - QScriptClassInfo *m_class_arguments; - QScriptClassInfo *m_class_activation; - - int m_class_prev_id; - qint64 m_next_object_id; - - QScript::Repository<QScriptValuePrivate, QScriptValuePrivate> m_handleRepository; - QHash<QScriptObject*, QScriptValuePrivate*> m_objectHandles; - QHash<QScriptNameIdImpl*, QScriptValuePrivate*> m_stringHandles; - QVector<QScriptValuePrivate*> m_otherHandles; - - QScript::Repository<QScriptStringPrivate, - QScriptStringPrivate> m_internedStringRepository; - QHash<QScriptNameIdImpl*, QScriptStringPrivate*> m_internedStrings; - - QSet<QScriptObject*> visitedArrayElements; - -#ifndef QT_NO_REGEXP - QHash<QString, QRegExp> m_regExpLiterals; -#endif - - QScript::IdTable m_id_table; - - QSet<QString> m_importedExtensions; - QSet<QString> m_extensionsBeingImported; - - int m_processEventsInterval; - int m_nextProcessEvents; - int m_processEventIncr; - QTime m_processEventTracker; - - QList<QScriptEngineAgent*> m_agents; - QScriptEngineAgent *m_agent; - -#ifndef QT_NO_QOBJECT - QList<QObject*> m_qobjectsToBeDeleted; - QHash<QObject*, QScriptQObjectData*> m_qobjectData; - -# ifndef Q_SCRIPT_NO_QMETAOBJECT_CACHE - QHash<const QMetaObject*, QScriptMetaObject*> m_cachedMetaObjects; -# endif -#endif - -#ifdef QT_NO_QOBJECT - QScriptEngine *q_ptr; -#endif -}; - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT - -#endif diff --git a/src/script/qscriptextenumeration.cpp b/src/script/qscriptextenumeration.cpp deleted file mode 100644 index 718e27b..0000000 --- a/src/script/qscriptextenumeration.cpp +++ /dev/null @@ -1,209 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qscriptextenumeration_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptengine_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" -#include "qscriptvalueiteratorimpl_p.h" - -#include <QtCore/QtDebug> - -QT_BEGIN_NAMESPACE - -namespace QScript { namespace Ext { - -EnumerationClassData::EnumerationClassData(QScriptClassInfo *classInfo): - m_classInfo(classInfo) -{ -} - -EnumerationClassData::~EnumerationClassData() -{ -} - -void EnumerationClassData::mark(const QScriptValueImpl &object, int generation) -{ - Q_ASSERT(object.isValid()); - - QScriptEnginePrivate *eng = object.engine(); - - if (Enumeration::Instance *instance = Enumeration::Instance::get(object, classInfo())) { - eng->markObject(instance->object, generation); - if (instance->it) - eng->markObject(instance->it->object(), generation); - } -} - -Enumeration::Enumeration(QScriptEnginePrivate *eng): - Ecma::Core(eng, QLatin1String("Enumeration"), QScriptClassInfo::EnumerationType) -{ - classInfo()->setData(new EnumerationClassData(classInfo())); - - newEnumeration(&publicPrototype, eng->newArray()); - - eng->newConstructor(&ctor, this, publicPrototype); - - addPrototypeFunction(QLatin1String("toFront"), method_toFront, 0); - addPrototypeFunction(QLatin1String("hasNext"), method_hasNext, 0); - addPrototypeFunction(QLatin1String("next"), method_next, 0); -} - -Enumeration::~Enumeration() -{ -} - -Enumeration::Instance *Enumeration::Instance::get(const QScriptValueImpl &object, QScriptClassInfo *klass) -{ - if (! klass || klass == object.classInfo()) - return static_cast<Instance*> (object.objectData()); - - return 0; -} - -void Enumeration::execute(QScriptContextPrivate *context) -{ - if (context->argumentCount() > 0) { - newEnumeration(&context->m_result, context->argument(0)); - } else { - context->throwError(QScriptContext::TypeError, - QLatin1String("Enumeration.execute")); - } -} - -void Enumeration::newEnumeration(QScriptValueImpl *result, const QScriptValueImpl &object) -{ - Instance *instance = new Instance(); - instance->object = object; - if (object.isObject()) { - instance->it = new QScriptValueIteratorImpl(object); - instance->it->setIgnoresDontEnum(false); - instance->it->setEnumeratePrototype(true); - } else { - instance->it = 0; - } - engine()->newObject(result, publicPrototype, classInfo()); - result->setObjectData(instance); -} - -QScriptValueImpl Enumeration::method_toFront(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) -{ - if (Instance *instance = Instance::get(context->thisObject(), classInfo)) { - if (instance->it) - instance->it->toFront(); - return eng->undefinedValue(); - } else { - return context->throwError(QScriptContext::TypeError, - QLatin1String("Enumeration.toFront")); - } -} - -QScriptValueImpl Enumeration::method_hasNext(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - Instance *instance = Instance::get(context->thisObject(), classInfo); - if (!instance) { - return context->throwError(QScriptContext::TypeError, - QLatin1String("Enumeration.hasNext")); - } - - QScriptValueImpl v; - instance->hasNext(context, &v); - return v; -} - -QScriptValueImpl Enumeration::method_next(QScriptContextPrivate *context, QScriptEnginePrivate *, QScriptClassInfo *classInfo) -{ - Instance *instance = Instance::get(context->thisObject(), classInfo); - if (!instance) { - return context->throwError(QScriptContext::TypeError, - QLatin1String("Enumeration.next")); - } - - QScriptValueImpl v; - instance->next(context, &v); - return v; -} - -Enumeration::Instance::~Instance() -{ - if (it) { - delete it; - it = 0; - } -} - -void Enumeration::Instance::toFront() -{ - if (it) - it->toFront(); -} - -void Enumeration::Instance::hasNext(QScriptContextPrivate *, QScriptValueImpl *result) -{ - *result = QScriptValueImpl(it && it->hasNext()); -} - -void Enumeration::Instance::next(QScriptContextPrivate *context, QScriptValueImpl *result) -{ - QScriptEnginePrivate *eng = context->engine(); - Q_ASSERT(it != 0); - it->next(); - QScript::Member *member = it->member(); - if (member->isObjectProperty() || member->nameId()) - eng->newNameId(result, member->nameId()); - - else if (member->isNativeProperty() && !member->nameId()) - *result = QScriptValueImpl(uint(member->id())); - - else - *result = eng->undefinedValue(); -} - -} } // namespace QScript::Ext - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptextenumeration_p.h b/src/script/qscriptextenumeration_p.h deleted file mode 100644 index f97e15b..0000000 --- a/src/script/qscriptextenumeration_p.h +++ /dev/null @@ -1,126 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTEXTENUMERATION_P_H -#define QSCRIPTEXTENUMERATION_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 "qscriptecmacore_p.h" - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_SCRIPT - -class QScriptValueIteratorImpl; - -namespace QScript { namespace Ext { - -class EnumerationClassData: public QScriptClassData -{ - QScriptClassInfo *m_classInfo; - -public: - EnumerationClassData(QScriptClassInfo *classInfo); - virtual ~EnumerationClassData(); - - inline QScriptClassInfo *classInfo() const - { return m_classInfo; } - - virtual void mark(const QScriptValueImpl &object, int generation); -}; - -class Enumeration: public QScript::Ecma::Core -{ -public: - Enumeration(QScriptEnginePrivate *engine); - virtual ~Enumeration(); - - virtual void execute(QScriptContextPrivate *context); - - class Instance: public QScriptObjectData { - public: - Instance() : it(0) {} - virtual ~Instance(); - - static Instance *get(const QScriptValueImpl &object, - QScriptClassInfo *klass); - - void toFront(); - void hasNext(QScriptContextPrivate *context, QScriptValueImpl *result); - void next(QScriptContextPrivate *context, QScriptValueImpl *result); - - public: // attributes - QScriptValueIteratorImpl *it; - QScriptValueImpl object; - }; - - void newEnumeration(QScriptValueImpl *result, const QScriptValueImpl &value); - - inline Instance *get(const QScriptValueImpl &object) const - { - return Instance::get(object, classInfo()); - } - -protected: - static QScriptValueImpl method_toFront(QScriptContextPrivate *context, QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_hasNext(QScriptContextPrivate *context, QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_next(QScriptContextPrivate *context, QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); -}; - -} } // namespace QScript::Ext - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT -#endif diff --git a/src/script/qscriptextqobject.cpp b/src/script/qscriptextqobject.cpp deleted file mode 100644 index 8746cc1..0000000 --- a/src/script/qscriptextqobject.cpp +++ /dev/null @@ -1,2244 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtCore/qglobal.h> - -#ifndef QT_NO_SCRIPT - -#include "qscriptengine_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" -#include "qscriptable.h" -#include "qscriptable_p.h" -#include "qscriptextqobject_p.h" - -#include <QtCore/QtDebug> -#include <QtCore/QMetaMethod> -#include <QtCore/QRegExp> -#include <QtCore/QVarLengthArray> -#include <QtCore/QPointer> - -QT_BEGIN_NAMESPACE - -// we use bits 15..12 of property flags -enum { - PROPERTY_ID = 0 << 12, - DYNAPROPERTY_ID = 1 << 12, - METHOD_ID = 2 << 12, - CHILD_ID = 3 << 12, - ID_MASK = 7 << 12, - MAYBE_OVERLOADED = 8 << 12 -}; - -static const bool GeneratePropertyFunctions = true; - -int QScriptMetaType::typeId() const -{ - if (isVariant()) - return QMetaType::type("QVariant"); - return isMetaEnum() ? 2/*int*/ : m_typeId; -} - -QByteArray QScriptMetaType::name() const -{ - if (!m_name.isEmpty()) - return m_name; - else if (m_kind == Variant) - return "QVariant"; - return QMetaType::typeName(typeId()); -} - -namespace QScript { - -class QObjectNotifyCaller : public QObject -{ -public: - void callConnectNotify(const char *signal) - { connectNotify(signal); } - void callDisconnectNotify(const char *signal) - { disconnectNotify(signal); } -}; - -class QtPropertyFunction: public QScriptFunction -{ -public: - QtPropertyFunction(const QMetaObject *meta, int index) - : m_meta(meta), m_index(index) - { } - - ~QtPropertyFunction() { } - - virtual void execute(QScriptContextPrivate *context); - - virtual Type type() const { return QScriptFunction::QtProperty; } - - virtual QString functionName() const; - -private: - const QMetaObject *m_meta; - int m_index; -}; - -class QObjectPrototype : public QObject -{ - Q_OBJECT -public: - QObjectPrototype(QObject *parent = 0) - : QObject(parent) { } - ~QObjectPrototype() { } -}; - -static inline QByteArray methodName(const QMetaMethod &method) -{ - QByteArray signature = method.signature(); - return signature.left(signature.indexOf('(')); -} - -static inline QVariant variantFromValue(QScriptEnginePrivate *eng, - int targetType, const QScriptValueImpl &value) -{ - QVariant v(targetType, (void *)0); - Q_ASSERT(eng); - if (QScriptEnginePrivate::convert(value, targetType, v.data(), eng)) - return v; - if (uint(targetType) == QVariant::LastType) - return value.toVariant(); - if (value.isVariant()) { - v = value.toVariant(); - if (v.canConvert(QVariant::Type(targetType))) { - v.convert(QVariant::Type(targetType)); - return v; - } - QByteArray typeName = v.typeName(); - if (typeName.endsWith('*') - && (QMetaType::type(typeName.left(typeName.size()-1)) == targetType)) { - return QVariant(targetType, *reinterpret_cast<void* *>(v.data())); - } - } - - return QVariant(); -} - -void ExtQObject::Instance::finalize(QScriptEnginePrivate *eng) -{ - switch (ownership) { - case QScriptEngine::QtOwnership: - break; - case QScriptEngine::ScriptOwnership: - if (value) - eng->disposeQObject(value); - break; - case QScriptEngine::AutoOwnership: - if (value && !value->parent()) - eng->disposeQObject(value); - break; - } -} - -ExtQObject::Instance *ExtQObject::Instance::get(const QScriptValueImpl &object, QScriptClassInfo *klass) -{ - if (! klass || klass == object.classInfo()) - return static_cast<Instance*> (object.objectData()); - - return 0; -} - - -static inline QScriptable *scriptableFromQObject(QObject *qobj) -{ - void *ptr = qobj->qt_metacast("QScriptable"); - return reinterpret_cast<QScriptable*>(ptr); -} - -static bool isObjectProperty(const QScriptValueImpl &object, const char *name) -{ - QScriptEnginePrivate *eng = object.engine(); - QScriptNameIdImpl *nameId = eng->nameId(QLatin1String(name)); - QScript::Member member; - QScriptValueImpl base; - return object.resolve(nameId, &member, &base, QScriptValue::ResolveLocal, QScript::Read) - && member.testFlags(QScript::Member::ObjectProperty); -} - -static bool hasMethodAccess(const QMetaMethod &method, int index, const QScriptEngine::QObjectWrapOptions &opt) -{ - return (method.access() != QMetaMethod::Private) - && ((index != 2) || !(opt & QScriptEngine::ExcludeDeleteLater)); -} - -static bool isEnumerableMetaProperty(const QMetaProperty &prop, - const QMetaObject *mo, int index) -{ - return prop.isScriptable() && prop.isValid() - // the following lookup is to ensure that we have the - // "most derived" occurrence of the property with this name - && (mo->indexOfProperty(prop.name()) == index); -} - -static uint flagsForMetaProperty(const QMetaProperty &prop) -{ - return (QScriptValue::Undeletable - | (!prop.isWritable() - ? QScriptValue::ReadOnly - : QScriptValue::PropertyFlag(0)) - | (GeneratePropertyFunctions - ? (QScriptValue::PropertyGetter - | QScriptValue::PropertySetter) - : QScriptValue::PropertyFlag(0)) - | QScriptValue::QObjectMember - | PROPERTY_ID); -} - - -static int indexOfMetaEnum(const QMetaObject *meta, const QByteArray &str) -{ - QByteArray scope; - QByteArray name; - int scopeIdx = str.lastIndexOf("::"); - if (scopeIdx != -1) { - scope = str.left(scopeIdx); - name = str.mid(scopeIdx + 2); - } else { - name = str; - } - for (int i = meta->enumeratorCount() - 1; i >= 0; --i) { - QMetaEnum m = meta->enumerator(i); - if ((m.name() == name) && (scope.isEmpty() || (m.scope() == scope))) - return i; - } - return -1; -} - -static QMetaMethod metaMethod(const QMetaObject *meta, - QMetaMethod::MethodType type, - int index) -{ - if (type != QMetaMethod::Constructor) - return meta->method(index); - else - return meta->constructor(index); -} - -static void callQtMethod(QScriptContextPrivate *context, QMetaMethod::MethodType callType, - QObject *thisQObject, const QMetaObject *meta, int initialIndex, - bool maybeOverloaded) -{ - QScriptValueImpl result; - QScriptEnginePrivate *engine = context->engine(); - - int limit; -#ifndef Q_SCRIPT_NO_QMETAOBJECT_CACHE - int lastFoundIndex = initialIndex; - QScriptMetaObject *metaCache = engine->cachedMetaObject(meta); - if (callType != QMetaMethod::Constructor) - limit = metaCache->methodLowerBound(initialIndex); - else - limit = 0; -#else - limit = 0; -#endif - - QByteArray funName; - QScriptMetaMethod chosenMethod; - int chosenIndex = -1; - QVarLengthArray<QVariant, 9> args; - QVector<QScriptMetaArguments> candidates; - QVector<QScriptMetaArguments> unresolved; - QVector<int> tooFewArgs; - QVector<int> conversionFailed; - int index; - for (index = initialIndex; index >= limit; --index) { - QScriptMetaMethod mtd; -#ifndef Q_SCRIPT_NO_QMETAOBJECT_CACHE - if (callType != QMetaMethod::Constructor) - mtd = metaCache->findMethod(index); - if (!mtd.isValid()) -#endif - { - QMetaMethod method = metaMethod(meta, callType, index); - - QVector<QScriptMetaType> types; - // resolve return type - QByteArray returnTypeName = method.typeName(); - int rtype = QMetaType::type(returnTypeName); - if ((rtype == 0) && !returnTypeName.isEmpty()) { - if (returnTypeName == "QVariant") { - types.append(QScriptMetaType::variant()); - } else { - int enumIndex = indexOfMetaEnum(meta, returnTypeName); - if (enumIndex != -1) - types.append(QScriptMetaType::metaEnum(enumIndex, returnTypeName)); - else - types.append(QScriptMetaType::unresolved(returnTypeName)); - } - } else { - if (callType == QMetaMethod::Constructor) - types.append(QScriptMetaType::metaType(QMetaType::QObjectStar, "QObject*")); - else if (returnTypeName == "QVariant") - types.append(QScriptMetaType::variant()); - else - types.append(QScriptMetaType::metaType(rtype, returnTypeName)); - } - // resolve argument types - QList<QByteArray> parameterTypeNames = method.parameterTypes(); - for (int i = 0; i < parameterTypeNames.count(); ++i) { - QByteArray argTypeName = parameterTypeNames.at(i); - int atype = QMetaType::type(argTypeName); - if (atype == 0) { - if (argTypeName == "QVariant") { - types.append(QScriptMetaType::variant()); - } else { - int enumIndex = indexOfMetaEnum(meta, argTypeName); - if (enumIndex != -1) - types.append(QScriptMetaType::metaEnum(enumIndex, argTypeName)); - else - types.append(QScriptMetaType::unresolved(argTypeName)); - } - } else { - if (argTypeName == "QVariant") - types.append(QScriptMetaType::variant()); - else - types.append(QScriptMetaType::metaType(atype, argTypeName)); - } - } - - mtd = QScriptMetaMethod(methodName(method), types); - -#ifndef Q_SCRIPT_NO_QMETAOBJECT_CACHE - if (mtd.fullyResolved() && (callType != QMetaMethod::Constructor)) - metaCache->registerMethod(index, mtd); -#endif - } - - if (index == initialIndex) - funName = mtd.name(); - else { - if (mtd.name() != funName) - continue; -#ifndef Q_SCRIPT_NO_QMETAOBJECT_CACHE - lastFoundIndex = index; -#endif - } - - if (context->argumentCount() < mtd.argumentCount()) { - tooFewArgs.append(index); - continue; - } - - if (!mtd.fullyResolved()) { - // remember it so we can give an error message later, if necessary - unresolved.append(QScriptMetaArguments(/*matchDistance=*/INT_MAX, index, - mtd, QVarLengthArray<QVariant, 9>())); - if (mtd.hasUnresolvedReturnType()) - continue; - } - - if (args.count() != mtd.count()) - args.resize(mtd.count()); - - QScriptMetaType retType = mtd.returnType(); - args[0] = QVariant(retType.typeId(), (void *)0); // the result - - // try to convert arguments - bool converted = true; - int matchDistance = 0; - for (int i = 0; converted && i < mtd.argumentCount(); ++i) { - QScriptValueImpl actual = context->argument(i); - QScriptMetaType argType = mtd.argumentType(i); - int tid = -1; - QVariant v; - if (argType.isUnresolved()) { - v = QVariant(QMetaType::QObjectStar, (void *)0); - converted = engine->convertToNativeQObject( - actual, argType.name(), reinterpret_cast<void* *>(v.data())); - } else if (argType.isVariant()) { - if (actual.isVariant()) { - v = actual.variantValue(); - } else { - v = actual.toVariant(); - converted = v.isValid() || actual.isUndefined() || actual.isNull(); - } - } else { - tid = argType.typeId(); - v = QVariant(tid, (void *)0); - converted = QScriptEnginePrivate::convert(actual, tid, v.data(), engine); - if (engine->hasUncaughtException()) - return; - } - - if (!converted) { - if (actual.isVariant()) { - if (tid == -1) - tid = argType.typeId(); - QVariant &vv = actual.variantValue(); - if (vv.canConvert(QVariant::Type(tid))) { - v = vv; - converted = v.convert(QVariant::Type(tid)); - if (converted && (vv.userType() != tid)) - matchDistance += 10; - } else { - QByteArray vvTypeName = vv.typeName(); - if (vvTypeName.endsWith('*') - && (vvTypeName.left(vvTypeName.size()-1) == argType.name())) { - v = QVariant(tid, *reinterpret_cast<void* *>(vv.data())); - converted = true; - matchDistance += 10; - } - } - } else if (actual.isNumber() || actual.isString()) { - // see if it's an enum value - QMetaEnum m; - if (argType.isMetaEnum()) { - m = meta->enumerator(argType.enumeratorIndex()); - } else { - int mi = indexOfMetaEnum(meta, argType.name()); - if (mi != -1) - m = meta->enumerator(mi); - } - if (m.isValid()) { - if (actual.isNumber()) { - int ival = actual.toInt32(); - if (m.valueToKey(ival) != 0) { - qVariantSetValue(v, ival); - converted = true; - matchDistance += 10; - } - } else { - QString sval = actual.toString(); - int ival = m.keyToValue(sval.toLatin1()); - if (ival != -1) { - qVariantSetValue(v, ival); - converted = true; - matchDistance += 10; - } - } - } - } - } else { - // determine how well the conversion matched - if (actual.isNumber()) { - switch (tid) { - case QMetaType::Double: - // perfect - break; - case QMetaType::Float: - matchDistance += 1; - break; - case QMetaType::LongLong: - case QMetaType::ULongLong: - matchDistance += 2; - break; - case QMetaType::Long: - case QMetaType::ULong: - matchDistance += 3; - break; - case QMetaType::Int: - case QMetaType::UInt: - matchDistance += 4; - break; - case QMetaType::Short: - case QMetaType::UShort: - matchDistance += 5; - break; - case QMetaType::Char: - case QMetaType::UChar: - matchDistance += 6; - break; - default: - matchDistance += 10; - break; - } - } else if (actual.isString()) { - switch (tid) { - case QMetaType::QString: - // perfect - break; - default: - matchDistance += 10; - break; - } - } else if (actual.isBoolean()) { - switch (tid) { - case QMetaType::Bool: - // perfect - break; - default: - matchDistance += 10; - break; - } - } else if (actual.isDate()) { - switch (tid) { - case QMetaType::QDateTime: - // perfect - break; - case QMetaType::QDate: - matchDistance += 1; - break; - case QMetaType::QTime: - matchDistance += 2; - break; - default: - matchDistance += 10; - break; - } - } else if (actual.isRegExp()) { - switch (tid) { - case QMetaType::QRegExp: - // perfect - break; - default: - matchDistance += 10; - break; - } - } else if (actual.isVariant()) { - if (argType.isVariant() - || (actual.variantValue().userType() == tid)) { - // perfect - } else { - matchDistance += 10; - } - } else if (actual.isArray()) { - switch (tid) { - case QMetaType::QStringList: - case QMetaType::QVariantList: - matchDistance += 5; - break; - default: - matchDistance += 10; - break; - } - } else if (actual.isQObject()) { - switch (tid) { - case QMetaType::QObjectStar: - case QMetaType::QWidgetStar: - // perfect - break; - default: - matchDistance += 10; - break; - } - } else if (actual.isNull()) { - switch (tid) { - case QMetaType::VoidStar: - case QMetaType::QObjectStar: - case QMetaType::QWidgetStar: - // perfect - break; - default: - if (!argType.name().endsWith('*')) - matchDistance += 10; - break; - } - } else { - matchDistance += 10; - } - } - - if (converted) - args[i+1] = v; - } - - if (converted) { - if ((context->argumentCount() == mtd.argumentCount()) - && (matchDistance == 0)) { - // perfect match, use this one - chosenMethod = mtd; - chosenIndex = index; - break; - } else { - bool redundant = false; - if ((callType != QMetaMethod::Constructor) - && (index < meta->methodOffset())) { - // it is possible that a virtual method is redeclared in a subclass, - // in which case we want to ignore the superclass declaration - for (int i = 0; i < candidates.size(); ++i) { - const QScriptMetaArguments &other = candidates.at(i); - if (mtd.types() == other.method.types()) { - redundant = true; - break; - } - } - } - if (!redundant) { - QScriptMetaArguments metaArgs(matchDistance, index, mtd, args); - if (candidates.isEmpty()) { - candidates.append(metaArgs); - } else { - const QScriptMetaArguments &otherArgs = candidates.at(0); - if ((args.count() > otherArgs.args.count()) - || ((args.count() == otherArgs.args.count()) - && (matchDistance <= otherArgs.matchDistance))) { - candidates.prepend(metaArgs); - } else { - candidates.append(metaArgs); - } - } - } - } - } else if (mtd.fullyResolved()) { - conversionFailed.append(index); - } - - if (!maybeOverloaded) - break; - } - -#ifndef Q_SCRIPT_NO_QMETAOBJECT_CACHE - if ((index == -1) && (lastFoundIndex != limit) && maybeOverloaded - && (callType != QMetaMethod::Constructor)) { - metaCache->setMethodLowerBound(initialIndex, lastFoundIndex); - } -#endif - - if ((chosenIndex == -1) && candidates.isEmpty()) { - context->calleeMetaIndex = initialIndex; -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - engine->notifyFunctionEntry(context); -#endif - if (!conversionFailed.isEmpty()) { - QString message = QString::fromLatin1("incompatible type of argument(s) in call to %0(); candidates were\n") - .arg(QLatin1String(funName)); - for (int i = 0; i < conversionFailed.size(); ++i) { - if (i > 0) - message += QLatin1String("\n"); - QMetaMethod mtd = metaMethod(meta, callType, conversionFailed.at(i)); - message += QString::fromLatin1(" %0").arg(QString::fromLatin1(mtd.signature())); - } - result = context->throwError(QScriptContext::TypeError, message); - } else if (!unresolved.isEmpty()) { - QScriptMetaArguments argsInstance = unresolved.first(); - int unresolvedIndex = argsInstance.method.firstUnresolvedIndex(); - Q_ASSERT(unresolvedIndex != -1); - QScriptMetaType unresolvedType = argsInstance.method.type(unresolvedIndex); - QString unresolvedTypeName = QString::fromLatin1(unresolvedType.name()); - QString message = QString::fromLatin1("cannot call %0(): ") - .arg(QString::fromLatin1(funName)); - if (unresolvedIndex > 0) { - message.append(QString::fromLatin1("argument %0 has unknown type `%1'"). - arg(unresolvedIndex).arg(unresolvedTypeName)); - } else { - message.append(QString::fromLatin1("unknown return type `%0'") - .arg(unresolvedTypeName)); - } - message.append(QString::fromLatin1(" (register the type with qScriptRegisterMetaType())")); - result = context->throwError(QScriptContext::TypeError, message); - } else { - QString message = QString::fromLatin1("too few arguments in call to %0(); candidates are\n") - .arg(QLatin1String(funName)); - for (int i = 0; i < tooFewArgs.size(); ++i) { - if (i > 0) - message += QLatin1String("\n"); - QMetaMethod mtd = metaMethod(meta, callType, tooFewArgs.at(i)); - message += QString::fromLatin1(" %0").arg(QString::fromLatin1(mtd.signature())); - } - result = context->throwError(QScriptContext::SyntaxError, message); - } - } else { - if (chosenIndex == -1) { - QScriptMetaArguments metaArgs = candidates.at(0); - if ((candidates.size() > 1) - && (metaArgs.args.count() == candidates.at(1).args.count()) - && (metaArgs.matchDistance == candidates.at(1).matchDistance)) { - // ambiguous call - QString message = QString::fromLatin1("ambiguous call of overloaded function %0(); candidates were\n") - .arg(QLatin1String(funName)); - for (int i = 0; i < candidates.size(); ++i) { - if (i > 0) - message += QLatin1String("\n"); - QMetaMethod mtd = metaMethod(meta, callType, candidates.at(i).index); - message += QString::fromLatin1(" %0").arg(QString::fromLatin1(mtd.signature())); - } - result = context->throwError(QScriptContext::TypeError, message); - } else { - chosenMethod = metaArgs.method; - chosenIndex = metaArgs.index; - args = metaArgs.args; - } - } - - if (chosenIndex != -1) { - // call it - context->calleeMetaIndex = chosenIndex; - - QVarLengthArray<void*, 9> array(args.count()); - void **params = array.data(); - for (int i = 0; i < args.count(); ++i) { - const QVariant &v = args[i]; - switch (chosenMethod.type(i).kind()) { - case QScriptMetaType::Variant: - params[i] = const_cast<QVariant*>(&v); - break; - case QScriptMetaType::MetaType: - case QScriptMetaType::MetaEnum: - case QScriptMetaType::Unresolved: - params[i] = const_cast<void*>(v.constData()); - break; - default: - Q_ASSERT(0); - } - } - - QScriptable *scriptable = 0; - if (thisQObject) - scriptable = scriptableFromQObject(thisQObject); - QScriptEngine *oldEngine = 0; - if (scriptable) { - oldEngine = QScriptablePrivate::get(scriptable)->engine; - QScriptablePrivate::get(scriptable)->engine = QScriptEnginePrivate::get(engine); - } - -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - engine->notifyFunctionEntry(context); -#endif - - if (callType == QMetaMethod::Constructor) { - Q_ASSERT(meta != 0); - meta->static_metacall(QMetaObject::CreateInstance, chosenIndex, params); - } else { - Q_ASSERT(thisQObject != 0); - QMetaObject::metacall(thisQObject, QMetaObject::InvokeMetaMethod, chosenIndex, params); - } - - if (scriptable) - QScriptablePrivate::get(scriptable)->engine = oldEngine; - - if (context->state() == QScriptContext::ExceptionState) { - result = context->returnValue(); // propagate - } else { - QScriptMetaType retType = chosenMethod.returnType(); - if (retType.isVariant()) { - result = engine->valueFromVariant(*(QVariant *)params[0]); - } else if (retType.typeId() != 0) { - result = engine->create(retType.typeId(), params[0]); - if (!result.isValid()) - engine->newVariant(&result, QVariant(retType.typeId(), params[0])); - } else { - result = engine->undefinedValue(); - } - } - } - } - - context->m_result = result; -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - engine->notifyFunctionExit(context); -#endif -} - - -class ExtQObjectDataIterator: public QScriptClassDataIterator -{ -public: - ExtQObjectDataIterator(const QScriptValueImpl &object); - virtual ~ExtQObjectDataIterator(); - - virtual bool hasNext() const; - virtual void next(QScript::Member *member); - - virtual bool hasPrevious() const; - virtual void previous(QScript::Member *member); - - virtual void toFront(); - virtual void toBack(); - -private: - enum State { - MetaProperties, - DynamicProperties, - MetaMethods - }; - - QScriptValueImpl m_object; - int m_index; - State m_state; -}; - -ExtQObjectDataIterator::ExtQObjectDataIterator(const QScriptValueImpl &object) -{ - m_object = object; - toFront(); -} - -ExtQObjectDataIterator::~ExtQObjectDataIterator() -{ -} - -bool ExtQObjectDataIterator::hasNext() const -{ - ExtQObject::Instance *inst = ExtQObject::Instance::get(m_object); - if (!inst->value) - return false; - const QMetaObject *meta = inst->value->metaObject(); - int i = m_index; - - switch (m_state) { - case MetaProperties: { - for ( ; i < meta->propertyCount(); ++i) { - QMetaProperty prop = meta->property(i); - if (isEnumerableMetaProperty(prop, meta, i) - && !isObjectProperty(m_object, prop.name())) { - return true; - } - } - i = 0; - // fall-through - } - - case DynamicProperties: { - QList<QByteArray> dpNames = inst->value->dynamicPropertyNames(); - for ( ; i < dpNames.count(); ++i) { - if (!isObjectProperty(m_object, dpNames.at(i))) { - return true; - } - } - if (inst->options & QScriptEngine::SkipMethodsInEnumeration) - return false; - i = (inst->options & QScriptEngine::ExcludeSuperClassMethods) - ? meta->methodOffset() : 0; - // fall-through - } - - case MetaMethods: { - for ( ; i < meta->methodCount(); ++i) { - QMetaMethod method = meta->method(i); - if (hasMethodAccess(method, i, inst->options) - && !isObjectProperty(m_object, method.signature())) { - return true; - } - } - } - - } // switch - - return false; -} - -void ExtQObjectDataIterator::next(QScript::Member *member) -{ - QScriptEnginePrivate *eng = m_object.engine(); - ExtQObject::Instance *inst = ExtQObject::Instance::get(m_object); - if (!inst->value) - return; - const QMetaObject *meta = inst->value->metaObject(); - int i = m_index; - - switch (m_state) { - case MetaProperties: { - for ( ; i < meta->propertyCount(); ++i) { - QMetaProperty prop = meta->property(i); - if (isEnumerableMetaProperty(prop, meta, i) - && !isObjectProperty(m_object, prop.name())) { - QScriptNameIdImpl *nameId = eng->nameId(QLatin1String(prop.name())); - member->native(nameId, i, flagsForMetaProperty(prop)); - m_index = i + 1; - return; - } - } - m_state = DynamicProperties; - m_index = 0; - i = m_index; - // fall-through - } - - case DynamicProperties: { - QList<QByteArray> dpNames = inst->value->dynamicPropertyNames(); - for ( ; i < dpNames.count(); ++i) { - if (!isObjectProperty(m_object, dpNames.at(i))) { - QByteArray name = dpNames.at(i); - QScriptNameIdImpl *nameId = eng->nameId(QLatin1String(name)); - member->native(nameId, i, - QScriptValue::QObjectMember - | DYNAPROPERTY_ID); - m_index = i + 1; - return; - } - } - m_state = MetaMethods; - m_index = (inst->options & QScriptEngine::ExcludeSuperClassMethods) - ? meta->methodOffset() : 0; - i = m_index; - // fall-through - } - - case MetaMethods: { - for ( ; i < meta->methodCount(); ++i) { - QMetaMethod method = meta->method(i); - if (hasMethodAccess(method, i, inst->options) - && !isObjectProperty(m_object, method.signature())) { - QMetaMethod method = meta->method(i); - QScriptNameIdImpl *nameId = eng->nameId(QLatin1String(method.signature())); - member->native(nameId, i, - QScriptValue::QObjectMember - | METHOD_ID); - m_index = i + 1; - return; - } - } - } - - } // switch - - member->invalidate(); -} - -bool ExtQObjectDataIterator::hasPrevious() const -{ - ExtQObject::Instance *inst = ExtQObject::Instance::get(m_object); - if (!inst->value) - return false; - const QMetaObject *meta = inst->value->metaObject(); - int i = m_index - 1; - - switch (m_state) { - case MetaMethods: { - int limit = (inst->options & QScriptEngine::ExcludeSuperClassMethods) - ? meta->methodOffset() : 0; - for ( ; i >= limit; --i) { - QMetaMethod method = meta->method(i); - if (hasMethodAccess(method, i, inst->options) - && !isObjectProperty(m_object, method.signature())) { - return true; - } - } - i = inst->value->dynamicPropertyNames().count() - 1; - // fall-through - } - - case DynamicProperties: { - QList<QByteArray> dpNames = inst->value->dynamicPropertyNames(); - for ( ; i >= 0; --i) { - if (!isObjectProperty(m_object, dpNames.at(i))) { - return true; - } - } - i = meta->propertyCount() - 1; - // fall-through - } - - case MetaProperties: { - int limit = (inst->options & QScriptEngine::ExcludeSuperClassProperties) - ? meta->propertyOffset() : 0; - for ( ; i >= limit; --i) { - QMetaProperty prop = meta->property(i); - if (isEnumerableMetaProperty(prop, meta, i) - && !isObjectProperty(m_object, prop.name())) { - return true; - } - } - } - - } // switch - - return false; -} - -void ExtQObjectDataIterator::previous(QScript::Member *member) -{ - QScriptEnginePrivate *eng = m_object.engine(); - ExtQObject::Instance *inst = ExtQObject::Instance::get(m_object); - if (!inst->value) - return; - const QMetaObject *meta = inst->value->metaObject(); - int i = m_index - 1; - - switch (m_state) { - case MetaMethods: { - int limit = (inst->options & QScriptEngine::ExcludeSuperClassMethods) - ? meta->methodOffset() : 0; - for ( ; i >= limit; --i) { - QMetaMethod method = meta->method(i); - if (hasMethodAccess(method, i, inst->options) - && !isObjectProperty(m_object, method.signature())) { - QMetaMethod method = meta->method(i); - QScriptNameIdImpl *nameId = eng->nameId(QLatin1String(method.signature())); - member->native(nameId, i, - QScriptValue::QObjectMember - | METHOD_ID); - m_index = i; - return; - } - } - m_state = DynamicProperties; - m_index = inst->value->dynamicPropertyNames().count() - 1; - i = m_index; - // fall-through - } - - case DynamicProperties: { - QList<QByteArray> dpNames = inst->value->dynamicPropertyNames(); - for ( ; i >= 0; --i) { - if (!isObjectProperty(m_object, dpNames.at(i))) { - QByteArray name = dpNames.at(i); - QScriptNameIdImpl *nameId = eng->nameId(QLatin1String(name)); - member->native(nameId, i, - QScriptValue::QObjectMember - | DYNAPROPERTY_ID); - m_index = i; - return; - } - } - m_state = MetaProperties; - m_index = meta->propertyCount() - 1; - i = m_index; - // fall-through - } - - case MetaProperties: { - int limit = (inst->options & QScriptEngine::ExcludeSuperClassProperties) - ? meta->propertyOffset() : 0; - for ( ; i >= limit; --i) { - QMetaProperty prop = meta->property(i); - if (isEnumerableMetaProperty(prop, meta, i) - && !isObjectProperty(m_object, prop.name())) { - QScriptNameIdImpl *nameId = eng->nameId(QLatin1String(prop.name())); - member->native(nameId, i, flagsForMetaProperty(prop)); - m_index = i; - return; - } - } - } - - } // switch - - member->invalidate(); -} - -void ExtQObjectDataIterator::toFront() -{ - ExtQObject::Instance *inst = ExtQObject::Instance::get(m_object); - if (!inst->value) - return; - m_state = MetaProperties; - const QMetaObject *meta = inst->value->metaObject(); - m_index = (inst->options & QScriptEngine::ExcludeSuperClassProperties) - ? meta->propertyOffset() : 0; -} - -void ExtQObjectDataIterator::toBack() -{ - ExtQObject::Instance *inst = ExtQObject::Instance::get(m_object); - if (!inst->value) - return; - if (inst->options & QScriptEngine::SkipMethodsInEnumeration) { - m_state = DynamicProperties; - m_index = inst->value->dynamicPropertyNames().count(); - } else { - m_state = MetaMethods; - const QMetaObject *meta = inst->value->metaObject(); - m_index = meta->methodCount(); - } -} - -class ExtQObjectData: public QScriptClassData -{ -public: - ExtQObjectData(QScriptClassInfo *classInfo) - : m_classInfo(classInfo) - { - } - - virtual bool resolve(const QScriptValueImpl &object, QScriptNameIdImpl *nameId, - QScript::Member *member, QScriptValueImpl *, - QScript::AccessMode access) - { - ExtQObject::Instance *inst = ExtQObject::Instance::get(object, m_classInfo); - QObject *qobject = inst->value; - if (! qobject) { - // the object was deleted. We return true so we can - // throw an error in get()/put() - member->native(nameId, /*id=*/-1, /*flags=*/0); - return true; - } - - const QScriptEngine::QObjectWrapOptions &opt = inst->options; - const QMetaObject *meta = qobject->metaObject(); - - QScriptEnginePrivate *eng = object.engine(); - -#ifndef Q_SCRIPT_NO_QMETAOBJECT_CACHE - QScriptMetaObject *metaCache = eng->cachedMetaObject(meta); - if (metaCache->findMember(nameId, member)) { - bool ignore = false; - switch (member->flags() & ID_MASK) { - case PROPERTY_ID: - ignore = (opt & QScriptEngine::ExcludeSuperClassProperties) - && (member->id() < meta->propertyOffset()); - break; - case METHOD_ID: - ignore = ((opt & QScriptEngine::ExcludeSuperClassMethods) - && (member->id() < meta->methodOffset())) - || ((opt & QScriptEngine::ExcludeDeleteLater) - && (member->id() == 2)); - break; - // we don't cache dynamic properties nor children, - // so no need to handle DYNAPROPERTY_ID and CHILD_ID - default: - break; - } - if (!ignore) - return true; - } -#endif - - QString memberName = eng->toString(nameId); - QByteArray name = memberName.toLatin1(); - - int index = -1; - - if (name.contains('(')) { - QByteArray normalized = QMetaObject::normalizedSignature(name); - if (-1 != (index = meta->indexOfMethod(normalized))) { - QMetaMethod method = meta->method(index); - if (hasMethodAccess(method, index, opt)) { - member->native(nameId, index, - QScriptValue::QObjectMember - | METHOD_ID); -#ifndef Q_SCRIPT_NO_QMETAOBJECT_CACHE - metaCache->registerMember(nameId, *member); -#endif - if (!(opt & QScriptEngine::ExcludeSuperClassMethods) - || (index >= meta->methodOffset())) { - return true; - } - } - } - } - - index = meta->indexOfProperty(name); - if (index != -1) { - QMetaProperty prop = meta->property(index); - if (prop.isScriptable()) { - member->native(nameId, index, flagsForMetaProperty(prop)); -#ifndef Q_SCRIPT_NO_QMETAOBJECT_CACHE - metaCache->registerMember(nameId, *member); -#endif - if (!(opt & QScriptEngine::ExcludeSuperClassProperties) - || (index >= meta->propertyOffset())) { - return true; - } - } - } - - index = qobject->dynamicPropertyNames().indexOf(name); - if (index != -1) { - member->native(nameId, index, - QScriptValue::QObjectMember - | DYNAPROPERTY_ID); - // not cached because it can be removed - return true; - } - - const int offset = (opt & QScriptEngine::ExcludeSuperClassMethods) - ? meta->methodOffset() : 0; - for (index = meta->methodCount() - 1; index >= offset; --index) { - QMetaMethod method = meta->method(index); - if (hasMethodAccess(method, index, opt) - && (methodName(method) == name)) { - member->native(nameId, index, - QScriptValue::QObjectMember - | METHOD_ID - | MAYBE_OVERLOADED); -#ifndef Q_SCRIPT_NO_QMETAOBJECT_CACHE - metaCache->registerMember(nameId, *member); -#endif - return true; - } - } - - if (!(opt & QScriptEngine::ExcludeChildObjects)) { - QList<QObject*> children = qobject->children(); - for (index = 0; index < children.count(); ++index) { - QObject *child = children.at(index); - if (child->objectName() == memberName) { - member->native(nameId, index, - QScriptValue::ReadOnly - | QScriptValue::Undeletable - | QScriptValue::SkipInEnumeration - | CHILD_ID); - // not cached because it can be removed or change name - return true; - } - } - } - - if ((access & QScript::Write) && (opt & QScriptEngine::AutoCreateDynamicProperties)) { - member->native(nameId, -1, DYNAPROPERTY_ID); - return true; - } - - return false; - } - - virtual bool get(const QScriptValueImpl &obj, const QScript::Member &member, QScriptValueImpl *result) - { - if (! member.isNativeProperty()) - return false; - - QScriptEnginePrivate *eng = obj.engine(); - - ExtQObject::Instance *inst = ExtQObject::Instance::get(obj, m_classInfo); - QObject *qobject = inst->value; - if (!qobject) { - QScriptContextPrivate *ctx = eng->currentContext(); - *result = ctx->throwError( - QString::fromLatin1("cannot access member `%0' of deleted QObject") - .arg(member.nameId()->s)); - return true; - } - - switch (member.flags() & ID_MASK) { - case PROPERTY_ID: { - const QMetaObject *meta = qobject->metaObject(); - const int propertyIndex = member.id(); - QMetaProperty prop = meta->property(propertyIndex); - Q_ASSERT(prop.isScriptable()); - if (GeneratePropertyFunctions) { - QScriptValueImpl accessor; -#ifndef Q_SCRIPT_NO_QMETAOBJECT_CACHE - QScriptMetaObject *metaCache = eng->cachedMetaObject(meta); - accessor = metaCache->findPropertyAccessor(propertyIndex); - if (!accessor.isValid()) { -#endif - accessor = eng->createFunction(new QtPropertyFunction(meta, propertyIndex)); -#ifndef Q_SCRIPT_NO_QMETAOBJECT_CACHE - metaCache->registerPropertyAccessor(propertyIndex, accessor); - } -#endif - *result = accessor; - } else { - QVariant v = prop.read(qobject); - *result = eng->valueFromVariant(v); - } - } break; - - case DYNAPROPERTY_ID: { - if (member.id() != -1) { - QVariant v = qobject->property(member.nameId()->s.toLatin1()); - *result = eng->valueFromVariant(v); - } else { - *result = eng->undefinedValue(); - } - } break; - - case METHOD_ID: { - QScript::Member m; - bool maybeOverloaded = (member.flags() & MAYBE_OVERLOADED) != 0; - *result = eng->createFunction(new QtFunction(obj, member.id(), - maybeOverloaded)); - // make it persist (otherwise Function.prototype.disconnect() would fail) - uint flags = QScriptValue::QObjectMember; - if (inst->options & QScriptEngine::SkipMethodsInEnumeration) - flags |= QScriptValue::SkipInEnumeration; - QScriptObject *instance = obj.objectValue(); - if (!instance->findMember(member.nameId(), &m)) - instance->createMember(member.nameId(), &m, flags); - instance->put(m, *result); - } break; - - case CHILD_ID: { - QObject *child = qobject->children().at(member.id()); - result->invalidate(); - QScriptEngine::QObjectWrapOptions opt = QScriptEngine::PreferExistingWrapperObject; - eng->newQObject(result, child, QScriptEngine::QtOwnership, opt); - } break; - - } // switch - - return true; - } - - virtual bool put(QScriptValueImpl *object, const QScript::Member &member, const QScriptValueImpl &value) - { - if (! member.isNativeProperty() || ! member.isWritable()) - return false; - - ExtQObject::Instance *inst = ExtQObject::Instance::get(*object, m_classInfo); - QObject *qobject = inst->value; - if (!qobject) { - QScriptEnginePrivate *eng = object->engine(); - QScriptContextPrivate *ctx = eng->currentContext(); - ctx->throwError(QString::fromLatin1("cannot access member `%0' of deleted QObject") - .arg(member.nameId()->s)); - return true; - } - - switch (member.flags() & ID_MASK) { - case CHILD_ID: - return false; - - case METHOD_ID: { - QScript::Member m; - QScriptObject *instance = object->objectValue(); - if (!instance->findMember(member.nameId(), &m)) { - instance->createMember(member.nameId(), &m, - /*flags=*/0); - } - instance->put(m, value); - return true; - } - - case PROPERTY_ID: - if (GeneratePropertyFunctions) { - // we shouldn't get here, QScriptValueImpl::setProperty() messed up - Q_ASSERT_X(0, "put", "Q_PROPERTY access cannot be overridden"); - return false; - } else { - const QMetaObject *meta = qobject->metaObject(); - QMetaProperty prop = meta->property(member.id()); - Q_ASSERT(prop.isScriptable()); - QVariant v = variantFromValue(object->engine(), prop.userType(), value); - bool ok = prop.write(qobject, v); - return ok; - } - - case DYNAPROPERTY_ID: { - QVariant v = value.toVariant(); - return ! qobject->setProperty(member.nameId()->s.toLatin1(), v); - } - - } // switch - return false; - } - - virtual bool removeMember(const QScriptValueImpl &object, - const QScript::Member &member) - { - QObject *qobject = object.toQObject(); - if (!qobject || !member.isNativeProperty() || !member.isDeletable()) - return false; - - if ((member.flags() & ID_MASK) == DYNAPROPERTY_ID) { - qobject->setProperty(member.nameId()->s.toLatin1(), QVariant()); - return true; - } - - return false; - } - - virtual void mark(const QScriptValueImpl &, int) - { - } - - virtual QScriptClassDataIterator *newIterator(const QScriptValueImpl &object) - { - return new ExtQObjectDataIterator(object); - } - -private: - QScriptClassInfo *m_classInfo; -}; - -struct QObjectConnection -{ - int slotIndex; - QScriptValueImpl receiver; - QScriptValueImpl slot; - QScriptValueImpl senderWrapper; - - QObjectConnection(int i, const QScriptValueImpl &r, const QScriptValueImpl &s, - const QScriptValueImpl &sw) - : slotIndex(i), receiver(r), slot(s), senderWrapper(sw) {} - QObjectConnection() : slotIndex(-1) {} - - bool hasTarget(const QScriptValueImpl &r, const QScriptValueImpl &s) const - { - if (r.isObject() != receiver.isObject()) - return false; - if ((r.isObject() && receiver.isObject()) - && (r.objectValue() != receiver.objectValue())) { - return false; - } - return (s.objectValue() == slot.objectValue()); - } - - void mark(int generation) - { - if (senderWrapper.isValid() && !senderWrapper.isMarked(generation)) { - // see if the sender should be marked or not - ExtQObject::Instance *inst = ExtQObject::Instance::get(senderWrapper); - if ((inst->ownership == QScriptEngine::ScriptOwnership) - || ((inst->ownership == QScriptEngine::AutoOwnership) - && inst->value && !inst->value->parent())) { - senderWrapper.invalidate(); - } else { - senderWrapper.mark(generation); - } - } - if (receiver.isValid()) - receiver.mark(generation); - if (slot.isValid()) - slot.mark(generation); - } -}; - -class QObjectConnectionManager: public QObject -{ -public: - QObjectConnectionManager(); - ~QObjectConnectionManager(); - - bool addSignalHandler(QObject *sender, int signalIndex, - const QScriptValueImpl &receiver, - const QScriptValueImpl &slot, - const QScriptValueImpl &senderWrapper, - Qt::ConnectionType type); - bool removeSignalHandler( - QObject *sender, int signalIndex, - const QScriptValueImpl &receiver, - const QScriptValueImpl &slot); - - static const QMetaObject staticMetaObject; - virtual const QMetaObject *metaObject() const; - virtual void *qt_metacast(const char *); - virtual int qt_metacall(QMetaObject::Call, int, void **argv); - - void execute(int slotIndex, void **argv); - - void mark(int generation); - -private: - int m_slotCounter; - QVector<QVector<QObjectConnection> > connections; -}; - -} // ::QScript - - - -QScript::ExtQObject::ExtQObject(QScriptEnginePrivate *eng): - Ecma::Core(eng, QLatin1String("QObject"), QScriptClassInfo::QObjectType) -{ - newQObject(&publicPrototype, new QScript::QObjectPrototype(), - QScriptEngine::AutoOwnership, - QScriptEngine::ExcludeSuperClassMethods - | QScriptEngine::ExcludeSuperClassProperties - | QScriptEngine::ExcludeChildObjects); - - eng->newConstructor(&ctor, this, publicPrototype); - addPrototypeFunction(QLatin1String("toString"), method_toString, 0); - addPrototypeFunction(QLatin1String("findChild"), method_findChild, 1); - addPrototypeFunction(QLatin1String("findChildren"), method_findChildren, 1); - - classInfo()->setData(new QScript::ExtQObjectData(classInfo())); -} - -QScript::ExtQObject::~ExtQObject() -{ -} - -void QScript::ExtQObject::execute(QScriptContextPrivate *context) -{ - QScriptValueImpl tmp; - newQObject(&tmp, 0); - context->setReturnValue(tmp); -} - -void QScript::ExtQObject::newQObject(QScriptValueImpl *result, QObject *value, - QScriptEngine::ValueOwnership ownership, - const QScriptEngine::QObjectWrapOptions &options) -{ - Instance *instance; - if (!result->isValid()) { - engine()->newObject(result, publicPrototype, classInfo()); - instance = new Instance(); - result->setObjectData(instance); - } else { - Q_ASSERT(result->isObject()); - if (result->classInfo() != classInfo()) { - result->destroyObjectData(); - result->setClassInfo(classInfo()); - instance = new Instance(); - result->setObjectData(instance); - } else { - instance = Instance::get(*result); - } - } - instance->value = value; - instance->ownership = ownership; - instance->options = options; -} - -QScriptValueImpl QScript::ExtQObject::method_findChild(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) -{ - if (Instance *instance = Instance::get(context->thisObject(), classInfo)) { - QObject *obj = instance->value; - QString name = context->argument(0).toString(); - QObject *child = qFindChild<QObject*>(obj, name); - QScriptEngine::QObjectWrapOptions opt = QScriptEngine::PreferExistingWrapperObject; - QScriptValueImpl result; - eng->newQObject(&result, child, QScriptEngine::QtOwnership, opt); - return result; - } - return eng->undefinedValue(); -} - -QScriptValueImpl QScript::ExtQObject::method_findChildren(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) -{ - if (Instance *instance = Instance::get(context->thisObject(), classInfo)) { - QObject *obj = instance->value; - QList<QObject*> found; - QScriptValueImpl arg = context->argument(0); -#ifndef QT_NO_REGEXP - if (arg.isRegExp()) { - QRegExp re = arg.toRegExp(); - found = qFindChildren<QObject*>(obj, re); - } else -#endif - { - QString name = arg.isUndefined() ? QString() : arg.toString(); - found = qFindChildren<QObject*>(obj, name); - } - QScriptValueImpl result = eng->newArray(found.size()); - QScriptEngine::QObjectWrapOptions opt = QScriptEngine::PreferExistingWrapperObject; - for (int i = 0; i < found.size(); ++i) { - QScriptValueImpl value; - eng->newQObject(&value, found.at(i), QScriptEngine::QtOwnership, opt); - result.setProperty(i, value); - } - return result; - } - return eng->undefinedValue(); -} - -QScriptValueImpl QScript::ExtQObject::method_toString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) -{ - if (Instance *instance = Instance::get(context->thisObject(), classInfo)) { - QObject *obj = instance->value; - const QMetaObject *meta = obj ? obj->metaObject() : &QObject::staticMetaObject; - QString name = obj ? obj->objectName() : QString::fromUtf8("unnamed"); - - QString str = QString::fromUtf8("%0(name = \"%1\")") - .arg(QLatin1String(meta->className())).arg(name); - return QScriptValueImpl(eng, str); - } - return eng->undefinedValue(); -} - - - -static const uint qt_meta_data_QObjectConnectionManager[] = { - - // content: - 1, // revision - 0, // classname - 0, 0, // classinfo - 1, 10, // methods - 0, 0, // properties - 0, 0, // enums/sets - - // slots: signature, parameters, type, tag, flags - 35, 34, 34, 34, 0x0a, - - 0 // eod -}; - -static const char qt_meta_stringdata_QObjectConnectionManager[] = { - "QScript::QObjectConnectionManager\0\0execute()\0" -}; - -const QMetaObject QScript::QObjectConnectionManager::staticMetaObject = { - { &QObject::staticMetaObject, qt_meta_stringdata_QObjectConnectionManager, - qt_meta_data_QObjectConnectionManager, 0 } -}; - -const QMetaObject *QScript::QObjectConnectionManager::metaObject() const -{ - return &staticMetaObject; -} - -void *QScript::QObjectConnectionManager::qt_metacast(const char *_clname) -{ - if (!_clname) return 0; - if (!strcmp(_clname, qt_meta_stringdata_QObjectConnectionManager)) - return static_cast<void*>(const_cast<QObjectConnectionManager*>(this)); - return QObject::qt_metacast(_clname); -} - -int QScript::QObjectConnectionManager::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ - _id = QObject::qt_metacall(_c, _id, _a); - if (_id < 0) - return _id; - if (_c == QMetaObject::InvokeMetaMethod) { - execute(_id, _a); - _id -= m_slotCounter; - } - return _id; -} - -void QScript::QObjectConnectionManager::execute(int slotIndex, void **argv) -{ - QScriptValueImpl receiver; - QScriptValueImpl slot; - QScriptValueImpl senderWrapper; - int signalIndex = -1; - for (int i = 0; i < connections.size(); ++i) { - const QVector<QObjectConnection> &cs = connections.at(i); - for (int j = 0; j < cs.size(); ++j) { - const QObjectConnection &c = cs.at(j); - if (c.slotIndex == slotIndex) { - receiver = c.receiver; - slot = c.slot; - senderWrapper = c.senderWrapper; - signalIndex = i; - break; - } - } - } - Q_ASSERT(slot.isValid()); - - QScriptEnginePrivate *eng = slot.engine(); - - if (eng->isCollecting()) { - // we can't do a script function call during GC, - // so we're forced to ignore this signal - return; - } - - QScriptFunction *fun = eng->convertToNativeFunction(slot); - if (fun == 0) { - // the signal handler has been GC'ed. This can only happen when - // a QObject is owned by the engine, the engine is destroyed, and - // there is a script function connected to the destroyed() signal - Q_ASSERT(signalIndex <= 1); // destroyed(QObject*) - return; - } - - const QMetaObject *meta = sender()->metaObject(); - const QMetaMethod method = meta->method(signalIndex); - - QList<QByteArray> parameterTypes = method.parameterTypes(); - int argc = parameterTypes.count(); - - QScriptValueImpl activation; - eng->newActivation(&activation); - QScriptObject *activation_data = activation.objectValue(); - activation_data->m_scope = slot.scope(); - - int formalCount = fun->formals.count(); - int mx = qMax(formalCount, argc); - activation_data->m_members.resize(mx + 1); - activation_data->m_values.resize(mx + 1); - for (int i = 0; i < mx; ++i) { - QScriptNameIdImpl *nameId; - if (i < formalCount) - nameId = fun->formals.at(i); - else - nameId = 0; - activation_data->m_members[i].object(nameId, i, - QScriptValue::Undeletable - | QScriptValue::SkipInEnumeration); - QScriptValueImpl actual; - if (i < argc) { - void *arg = argv[i + 1]; - QByteArray typeName = parameterTypes.at(i); - int argType = QMetaType::type(typeName); - if (!argType) { - if (typeName == "QVariant") { - actual = eng->valueFromVariant(*reinterpret_cast<QVariant*>(arg)); - } else { - qWarning("QScriptEngine: Unable to handle unregistered datatype '%s' " - "when invoking handler of signal %s::%s", - typeName.constData(), meta->className(), method.signature()); - actual = eng->undefinedValue(); - } - } else { - actual = eng->create(argType, arg); - } - } else { - actual = eng->undefinedValue(); - } - activation_data->m_values[i] = actual; - } - - QScriptValueImpl senderObject; - if (senderWrapper.isQObject()) { - senderObject = senderWrapper; - } else { - QScriptEngine::QObjectWrapOptions opt = QScriptEngine::PreferExistingWrapperObject; - eng->newQObject(&senderObject, sender(), QScriptEngine::QtOwnership, opt); - } - activation_data->m_members[mx].object(eng->idTable()->id___qt_sender__, mx, - QScriptValue::SkipInEnumeration); - activation_data->m_values[mx] = senderObject; - - QScriptValueImpl thisObject; - if (receiver.isObject()) - thisObject = receiver; - else - thisObject = eng->globalObject(); - - QScriptContextPrivate *context_data = eng->pushContext(); - context_data->m_activation = activation; - context_data->m_callee = slot; - context_data->m_thisObject = thisObject; - context_data->argc = argc; - context_data->args = const_cast<QScriptValueImpl*> (activation_data->m_values.constData()); - - fun->execute(context_data); - - eng->popContext(); - if (eng->hasUncaughtException()) - eng->emitSignalHandlerException(); -} - -QScript::QObjectConnectionManager::QObjectConnectionManager() - : m_slotCounter(0) -{ -} - -QScript::QObjectConnectionManager::~QObjectConnectionManager() -{ -} - -void QScript::QObjectConnectionManager::mark(int generation) -{ - for (int i = 0; i < connections.size(); ++i) { - QVector<QObjectConnection> &cs = connections[i]; - for (int j = 0; j < cs.size(); ++j) - cs[j].mark(generation); - } -} - -bool QScript::QObjectConnectionManager::addSignalHandler( - QObject *sender, int signalIndex, const QScriptValueImpl &receiver, - const QScriptValueImpl &function, const QScriptValueImpl &senderWrapper, - Qt::ConnectionType type) -{ - if (connections.size() <= signalIndex) - connections.resize(signalIndex+1); - QVector<QObjectConnection> &cs = connections[signalIndex]; - int absSlotIndex = m_slotCounter + metaObject()->methodOffset(); - bool ok = QMetaObject::connect(sender, signalIndex, this, absSlotIndex, type); - if (ok) { - cs.append(QScript::QObjectConnection(m_slotCounter++, receiver, function, senderWrapper)); - QMetaMethod signal = sender->metaObject()->method(signalIndex); - QByteArray signalString; - signalString.append('2'); // signal code - signalString.append(signal.signature()); - static_cast<QScript::QObjectNotifyCaller*>(sender)->callConnectNotify(signalString); - } - return ok; -} - -bool QScript::QObjectConnectionManager::removeSignalHandler( - QObject *sender, int signalIndex, - const QScriptValueImpl &receiver, - const QScriptValueImpl &slot) -{ - if (connections.size() <= signalIndex) - return false; - QVector<QObjectConnection> &cs = connections[signalIndex]; - for (int i = 0; i < cs.size(); ++i) { - const QObjectConnection &c = cs.at(i); - if (c.hasTarget(receiver, slot)) { - int absSlotIndex = c.slotIndex + metaObject()->methodOffset(); - bool ok = QMetaObject::disconnect(sender, signalIndex, this, absSlotIndex); - if (ok) { - cs.remove(i); - QMetaMethod signal = sender->metaObject()->method(signalIndex); - QByteArray signalString; - signalString.append('2'); // signal code - signalString.append(signal.signature()); - static_cast<QScript::QObjectNotifyCaller*>(sender)->callDisconnectNotify(signalString); - } - return ok; - } - } - return false; -} - - - -QString QScript::QtPropertyFunction::functionName() const -{ - QMetaProperty prop = m_meta->property(m_index); - return QLatin1String(prop.name()); -} - -void QScript::QtPropertyFunction::execute(QScriptContextPrivate *context) -{ - context->calleeMetaIndex = m_index; - - QScriptEnginePrivate *eng_p = context->engine(); -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - eng_p->notifyFunctionEntry(context); -#endif - QScriptValueImpl result = eng_p->undefinedValue(); - - QScriptValueImpl object = context->thisObject(); - QObject *qobject = object.toQObject(); - while ((!qobject || (qobject->metaObject() != m_meta)) - && object.prototype().isObject()) { - object = object.prototype(); - qobject = object.toQObject(); - } - Q_ASSERT(qobject); - - QMetaProperty prop = m_meta->property(m_index); - Q_ASSERT(prop.isScriptable()); - if (context->argumentCount() == 0) { - // get - if (prop.isValid()) { - QScriptable *scriptable = scriptableFromQObject(qobject); - QScriptEngine *oldEngine = 0; - if (scriptable) { - oldEngine = QScriptablePrivate::get(scriptable)->engine; - QScriptablePrivate::get(scriptable)->engine = QScriptEnginePrivate::get(eng_p); - } - - QVariant v = prop.read(qobject); - - if (scriptable) - QScriptablePrivate::get(scriptable)->engine = oldEngine; - - result = eng_p->valueFromVariant(v); - } - } else { - // set - QScriptValueImpl arg = context->argument(0); - QVariant v; - if (prop.isEnumType() && arg.isString() - && !eng_p->demarshalFunction(prop.userType())) { - // give QMetaProperty::write() a chance to convert from - // string to enum value - v = arg.toString(); - } else { - v = variantFromValue(eng_p, prop.userType(), arg); - } - - QScriptable *scriptable = scriptableFromQObject(qobject); - QScriptEngine *oldEngine = 0; - if (scriptable) { - oldEngine = QScriptablePrivate::get(scriptable)->engine; - QScriptablePrivate::get(scriptable)->engine = QScriptEnginePrivate::get(eng_p); - } - - prop.write(qobject, v); - - if (scriptable) - QScriptablePrivate::get(scriptable)->engine = oldEngine; - - result = context->argument(0); - } - if (!eng_p->hasUncaughtException()) - context->m_result = result; -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - eng_p->notifyFunctionExit(context); -#endif -} - -QString QScript::QtFunction::functionName() const -{ - const QMetaObject *meta = metaObject(); - if (!meta) - return QString(); - QMetaMethod method = meta->method(m_initialIndex); - return QLatin1String(methodName(method)); -} - -void QScript::QtFunction::mark(QScriptEnginePrivate *engine, int generation) -{ - if (m_object.isValid()) - engine->markObject(m_object, generation); - QScriptFunction::mark(engine, generation); -} - -void QScript::QtFunction::execute(QScriptContextPrivate *context) -{ - QScriptEnginePrivate *eng_p = context->engine(); - QObject *qobj = qobject(); - if (!qobj) { - context->calleeMetaIndex = m_initialIndex; -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - eng_p->notifyFunctionEntry(context); -#endif - context->throwError(QLatin1String("cannot call function of deleted QObject")); -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - eng_p->notifyFunctionExit(context); -#endif - return; - } - - const QMetaObject *meta = qobj->metaObject(); - - QObject *thisQObject = context->thisObject().toQObject(); - if (!thisQObject) // ### TypeError - thisQObject = qobj; - - if (!meta->cast(thisQObject)) { -#if 0 - // ### find common superclass, see if initialIndex is - // in that class (or a superclass of that class), - // then it's still safe to execute it - funName = methodName(meta->method(m_initialIndex)); - context->throwError( - QString::fromUtf8("cannot execute %0: %1 does not inherit %2") - .arg(QLatin1String(funName)) - .arg(QLatin1String(thisQObject->metaObject()->className())) - .arg(QLatin1String(meta->className()))); - return; -#endif - // invoking a function in the prototype - thisQObject = qobj; - } - - callQtMethod(context, QMetaMethod::Method, thisQObject, - meta, m_initialIndex, m_maybeOverloaded); -} - -int QScript::QtFunction::mostGeneralMethod(QMetaMethod *out) const -{ - const QMetaObject *meta = metaObject(); - if (!meta) - return -1; - int index = m_initialIndex; - QMetaMethod method = meta->method(index); - if (maybeOverloaded() && (method.attributes() & QMetaMethod::Cloned)) { - // find the most general method - do { - method = meta->method(--index); - } while (method.attributes() & QMetaMethod::Cloned); - } - if (out) - *out = method; - return index; -} - -QList<int> QScript::QtFunction::overloadedIndexes() const -{ - if (!maybeOverloaded()) - return QList<int>(); - QList<int> result; - QString name = functionName(); - const QMetaObject *meta = metaObject(); - for (int index = mostGeneralMethod() - 1; index >= 0; --index) { - QString otherName = QString::fromLatin1(methodName(meta->method(index))); - if (otherName == name) - result.append(index); - } - return result; -} - -///////////////////////////////////////////////////////// - -namespace QScript -{ - -ExtQMetaObject::Instance *ExtQMetaObject::Instance::get(const QScriptValueImpl &object, - QScriptClassInfo *klass) -{ - if (! klass || klass == object.classInfo()) - return static_cast<Instance*> (object.objectData()); - - return 0; -} - -void ExtQMetaObject::Instance::execute(QScriptContextPrivate *context) -{ - if (ctor.isFunction()) { - QScriptValueImplList args; - for (int i = 0; i < context->argumentCount(); ++i) - args << context->argument(i); - QScriptEnginePrivate *eng = context->engine(); - context->m_result = eng->call(ctor, context->thisObject(), args, - context->isCalledAsConstructor()); - } else { - if (value->constructorCount() > 0) { - callQtMethod(context, QMetaMethod::Constructor, /*thisQObject=*/0, - value, value->constructorCount()-1, /*maybeOverloaded=*/true); - if (context->state() == QScriptContext::NormalState) { - ExtQObject::Instance *inst = ExtQObject::Instance::get(context->m_result); - Q_ASSERT(inst != 0); - inst->ownership = QScriptEngine::AutoOwnership; - context->m_result.setPrototype(prototype); - } - } else { - context->m_result = context->throwError( - QScriptContext::TypeError, - QString::fromUtf8("no constructor for %0") - .arg(QLatin1String(value->className()))); - } - } -} - -struct StaticQtMetaObject : public QObject -{ - static const QMetaObject *get() - { return &static_cast<StaticQtMetaObject*> (0)->staticQtMetaObject; } -}; - -class ExtQMetaObjectData: public QScriptClassData -{ -public: - ExtQMetaObjectData(QScriptEnginePrivate *, QScriptClassInfo *classInfo); - - virtual bool resolve(const QScriptValueImpl &object, QScriptNameIdImpl *nameId, - QScript::Member *member, QScriptValueImpl *base, - QScript::AccessMode access); - virtual bool get(const QScriptValueImpl &object, const QScript::Member &member, - QScriptValueImpl *result); - virtual bool put(QScriptValueImpl *object, const QScript::Member &member, - const QScriptValueImpl &value); - virtual void mark(const QScriptValueImpl &object, int generation); - -private: - QScriptClassInfo *m_classInfo; -}; - -ExtQMetaObjectData::ExtQMetaObjectData(QScriptEnginePrivate *, - QScriptClassInfo *classInfo) - : m_classInfo(classInfo) -{ -} - -bool ExtQMetaObjectData::resolve(const QScriptValueImpl &object, - QScriptNameIdImpl *nameId, - QScript::Member *member, - QScriptValueImpl *base, - QScript::AccessMode /*access*/) -{ - const QMetaObject *meta = object.toQMetaObject(); - if (!meta) - return false; - - QScriptEnginePrivate *eng_p = object.engine(); - if (eng_p->idTable()->id_prototype == nameId) { - // prototype property is a proxy to constructor's prototype property - member->native(nameId, /*id=*/0, QScriptValue::Undeletable); - return true; - } - - QByteArray name = eng_p->toString(nameId).toLatin1(); - - for (int i = 0; i < meta->enumeratorCount(); ++i) { - QMetaEnum e = meta->enumerator(i); - for (int j = 0; j < e.keyCount(); ++j) { - const char *key = e.key(j); - if (! qstrcmp (key, name.constData())) { - member->native(nameId, e.value(j), - QScriptValue::ReadOnly - | QScriptValue::Undeletable); - *base = object; - return true; - } - } - } - - return false; -} - -bool ExtQMetaObjectData::get(const QScriptValueImpl &object, - const QScript::Member &member, - QScriptValueImpl *result) -{ - if (! member.isNativeProperty()) - return false; - - QScriptEnginePrivate *eng_p = object.engine(); - if (eng_p->idTable()->id_prototype == member.nameId()) { - ExtQMetaObject::Instance *inst = ExtQMetaObject::Instance::get(object, m_classInfo); - if (inst->ctor.isFunction()) - *result = inst->ctor.property(eng_p->idTable()->id_prototype); - else - *result = inst->prototype; - } else { - *result = QScriptValueImpl(member.id()); - } - return true; -} - -bool ExtQMetaObjectData::put(QScriptValueImpl *object, const Member &member, - const QScriptValueImpl &value) -{ - if (! member.isNativeProperty()) - return false; - - QScriptEnginePrivate *eng_p = object->engine(); - if (eng_p->idTable()->id_prototype == member.nameId()) { - ExtQMetaObject::Instance *inst = ExtQMetaObject::Instance::get(*object, m_classInfo); - if (inst->ctor.isFunction()) - inst->ctor.setProperty(eng_p->idTable()->id_prototype, value); - else - inst->prototype = value; - } - - return true; -} - -void ExtQMetaObjectData::mark(const QScriptValueImpl &object, int generation) -{ - ExtQMetaObject::Instance *inst = ExtQMetaObject::Instance::get(object, m_classInfo); - if (inst->ctor.isObject() || inst->ctor.isString()) - inst->ctor.mark(generation); -} - -} // namespace QScript - -QScript::ExtQMetaObject::ExtQMetaObject(QScriptEnginePrivate *eng) - : Ecma::Core(eng, QLatin1String("QMetaObject"), QScriptClassInfo::QMetaObjectType) -{ - newQMetaObject(&publicPrototype, QScript::StaticQtMetaObject::get()); - - eng->newConstructor(&ctor, this, publicPrototype); - addPrototypeFunction(QLatin1String("className"), method_className, 0); - - classInfo()->setData(new QScript::ExtQMetaObjectData(eng, classInfo())); -} - -QScript::ExtQMetaObject::~ExtQMetaObject() -{ -} - -void QScript::ExtQMetaObject::execute(QScriptContextPrivate *context) -{ - QScriptValueImpl tmp; - newQMetaObject(&tmp, 0); - context->setReturnValue(tmp); -} - -void QScript::ExtQMetaObject::newQMetaObject(QScriptValueImpl *result, const QMetaObject *value, - const QScriptValueImpl &ctor) -{ - Instance *instance = new Instance(); - instance->value = value; - if (ctor.isFunction()) { - instance->ctor = ctor; - } else { - instance->prototype = engine()->newObject(); - instance->prototype.setPrototype(engine()->qobjectConstructor->publicPrototype); - } - - engine()->newObject(result, publicPrototype, classInfo()); - result->setObjectData(instance); -} - -QScriptValueImpl QScript::ExtQMetaObject::method_className(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) -{ - if (Instance *instance = Instance::get(context->thisObject(), classInfo)) { - return QScriptValueImpl(eng, QString::fromLatin1(instance->value->className())); - } - return eng->undefinedValue(); -} - -QScriptQObjectData::QScriptQObjectData() - : m_connectionManager(0) -{ -} - -QScriptQObjectData::~QScriptQObjectData() -{ - if (m_connectionManager) { - delete m_connectionManager; - m_connectionManager = 0; - } -} - -bool QScriptQObjectData::addSignalHandler(QObject *sender, - int signalIndex, - const QScriptValueImpl &receiver, - const QScriptValueImpl &slot, - const QScriptValueImpl &senderWrapper, - Qt::ConnectionType type) -{ - if (!m_connectionManager) - m_connectionManager = new QScript::QObjectConnectionManager(); - return m_connectionManager->addSignalHandler( - sender, signalIndex, receiver, slot, senderWrapper, type); -} - -bool QScriptQObjectData::removeSignalHandler(QObject *sender, - int signalIndex, - const QScriptValueImpl &receiver, - const QScriptValueImpl &slot) -{ - if (!m_connectionManager) - return false; - return m_connectionManager->removeSignalHandler( - sender, signalIndex, receiver, slot); -} - -bool QScriptQObjectData::findWrapper(QScriptEngine::ValueOwnership ownership, - const QScriptEngine::QObjectWrapOptions &options, - QScriptValueImpl *out) -{ - for (int i = 0; i < wrappers.size(); ++i) { - const QScriptQObjectWrapperInfo &info = wrappers.at(i); - if ((info.ownership == ownership) && (info.options == options)) { - *out = info.object; - return true; - } - } - return false; -} - -void QScriptQObjectData::registerWrapper(const QScriptValueImpl &wrapper, - QScriptEngine::ValueOwnership ownership, - const QScriptEngine::QObjectWrapOptions &options) -{ - wrappers.append(QScriptQObjectWrapperInfo(wrapper, ownership, options)); -} - -void QScriptQObjectData::mark(int generation) -{ - if (m_connectionManager) - m_connectionManager->mark(generation); - - { - QList<QScriptQObjectWrapperInfo>::iterator it; - for (it = wrappers.begin(); it != wrappers.end(); ) { - const QScriptQObjectWrapperInfo &info = *it; - if (info.object.isMarked(generation)) { - ++it; - } else { - it = wrappers.erase(it); - } - } - } -} - -QT_END_NAMESPACE - -#include "qscriptextqobject.moc" - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptextqobject_p.h b/src/script/qscriptextqobject_p.h deleted file mode 100644 index 212f96f..0000000 --- a/src/script/qscriptextqobject_p.h +++ /dev/null @@ -1,448 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTEXTQOBJECT_P_H -#define QSCRIPTEXTQOBJECT_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. -// - -#ifndef QT_NO_QOBJECT - -#include "qscriptecmacore_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptclassdata_p.h" -#include "qscriptfunction_p.h" -#include "qscriptengine.h" -#include "qscriptmemberfwd_p.h" - -#include <QtCore/QHash> -#include <QtCore/QPointer> -#include <QtCore/QObject> -#include <QtCore/QVariant> -#include <QtCore/QVarLengthArray> -#include <QtCore/QVector> - -QT_BEGIN_NAMESPACE - -namespace QScript { - -class QObjectConnectionManager; - -class ExtQObject: public Ecma::Core -{ -public: - ExtQObject(QScriptEnginePrivate *engine); - virtual ~ExtQObject(); - - virtual void execute(QScriptContextPrivate *context); - - class Instance: public QScriptObjectData { - public: - Instance() : ownership(QScriptEngine::QtOwnership) { } - virtual void finalize(QScriptEnginePrivate *engine); - virtual ~Instance() {} - - static Instance *get(const QScriptValueImpl &object, QScriptClassInfo *klass = 0); - - public: - QPointer<QObject> value; - QScriptEngine::ValueOwnership ownership; - QScriptEngine::QObjectWrapOptions options; - }; - - inline Instance *get(const QScriptValueImpl &object) const - { return Instance::get(object, classInfo()); } - - void newQObject(QScriptValueImpl *result, QObject *value, - QScriptEngine::ValueOwnership ownership = QScriptEngine::QtOwnership, - const QScriptEngine::QObjectWrapOptions &options = 0); - -protected: - static QScriptValueImpl method_findChild(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo); - static QScriptValueImpl method_findChildren(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo); - static QScriptValueImpl method_toString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo); -}; - -class QtFunction: public QScriptFunction -{ -public: - QtFunction(const QScriptValueImpl &object, int initialIndex, bool maybeOverloaded) - : m_object(object), m_initialIndex(initialIndex), - m_maybeOverloaded(maybeOverloaded) - { } - - virtual ~QtFunction() { } - - virtual void execute(QScriptContextPrivate *context); - - virtual Type type() const { return QScriptFunction::Qt; } - - virtual QString functionName() const; - - virtual void mark(QScriptEnginePrivate *engine, int generation); - - inline QScriptValueImpl object() const { return m_object; } - - inline QObject *qobject() const { - if (!m_object.isQObject()) - return 0; - return m_object.toQObject(); - } - - inline const QMetaObject *metaObject() const { - if (!m_object.isQObject()) - return 0; - QObject *qobj = m_object.toQObject(); - if (!qobj) - return 0; - return qobj->metaObject(); - } - - int mostGeneralMethod(QMetaMethod *out = 0) const; - QList<int> overloadedIndexes() const; - - inline int initialIndex() const { return m_initialIndex; } - inline bool maybeOverloaded() const { return m_maybeOverloaded; } - -private: - QScriptValueImpl m_object; - int m_initialIndex; - bool m_maybeOverloaded; -}; - -class ExtQMetaObject: public Ecma::Core -{ -public: - ExtQMetaObject(QScriptEnginePrivate *engine); - virtual ~ExtQMetaObject(); - - virtual void execute(QScriptContextPrivate *context); - - class Instance: public QScriptFunction { - public: - Instance() : value(0) { } - virtual ~Instance() { } - - static Instance *get(const QScriptValueImpl &object, QScriptClassInfo *klass); - - virtual void execute(QScriptContextPrivate *context); - - public: - const QMetaObject *value; - QScriptValueImpl ctor; - QScriptValueImpl prototype; - }; - - inline Instance *get(const QScriptValueImpl &object) const - { return Instance::get(object, classInfo()); } - - void newQMetaObject(QScriptValueImpl *result, const QMetaObject *value, - const QScriptValueImpl &ctor = QScriptValueImpl()); - -protected: - static QScriptValueImpl method_className(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo); -}; - -} // namespace QScript - -struct QScriptQObjectWrapperInfo -{ - QScriptQObjectWrapperInfo(const QScriptValueImpl &obj, - QScriptEngine::ValueOwnership own, - const QScriptEngine::QObjectWrapOptions &opt) - : object(obj), ownership(own), options(opt) {} - - QScriptValueImpl object; - QScriptEngine::ValueOwnership ownership; - QScriptEngine::QObjectWrapOptions options; -}; - -class QScriptQObjectData // : public QObjectUserData -{ -public: - QScriptQObjectData(); - ~QScriptQObjectData(); - - bool addSignalHandler(QObject *sender, - int signalIndex, - const QScriptValueImpl &receiver, - const QScriptValueImpl &slot, - const QScriptValueImpl &senderWrapper, - Qt::ConnectionType type); - bool removeSignalHandler(QObject *sender, - int signalIndex, - const QScriptValueImpl &receiver, - const QScriptValueImpl &slot); - - bool findWrapper(QScriptEngine::ValueOwnership ownership, - const QScriptEngine::QObjectWrapOptions &options, - QScriptValueImpl *out); - void registerWrapper(const QScriptValueImpl &wrapper, - QScriptEngine::ValueOwnership ownership, - const QScriptEngine::QObjectWrapOptions &options); - - void mark(int generation); - -private: - QScript::QObjectConnectionManager *m_connectionManager; - QList<QScriptQObjectWrapperInfo> wrappers; -}; - -class QScriptMetaType -{ -public: - enum Kind { - Invalid, - Variant, - MetaType, - Unresolved, - MetaEnum - }; - - inline QScriptMetaType() - : m_kind(Invalid), m_typeId(0) { } - - inline Kind kind() const - { return m_kind; } - - int typeId() const; - - inline bool isValid() const - { return (m_kind != Invalid); } - - inline bool isVariant() const - { return (m_kind == Variant); } - - inline bool isMetaType() const - { return (m_kind == MetaType); } - - inline bool isUnresolved() const - { return (m_kind == Unresolved); } - - inline bool isMetaEnum() const - { return (m_kind == MetaEnum); } - - QByteArray name() const; - - inline int enumeratorIndex() const - { Q_ASSERT(isMetaEnum()); return m_typeId; } - - inline bool operator==(const QScriptMetaType &other) const - { - return (m_kind == other.m_kind) && (m_typeId == other.m_typeId); - } - - static inline QScriptMetaType variant() - { return QScriptMetaType(Variant); } - - static inline QScriptMetaType metaType(int typeId, const QByteArray &name) - { return QScriptMetaType(MetaType, typeId, name); } - - static inline QScriptMetaType metaEnum(int enumIndex, const QByteArray &name) - { return QScriptMetaType(MetaEnum, enumIndex, name); } - - static inline QScriptMetaType unresolved(const QByteArray &name) - { return QScriptMetaType(Unresolved, /*typeId=*/0, name); } - -private: - inline QScriptMetaType(Kind kind, int typeId = 0, const QByteArray &name = QByteArray()) - : m_kind(kind), m_typeId(typeId), m_name(name) { } - - Kind m_kind; - int m_typeId; - QByteArray m_name; -}; - -class QScriptMetaMethod -{ -public: - inline QScriptMetaMethod() - : m_firstUnresolvedIndex(-1) - { } - inline QScriptMetaMethod(const QByteArray &name, const QVector<QScriptMetaType> &types) - : m_name(name), m_types(types), m_firstUnresolvedIndex(-1) - { - QVector<QScriptMetaType>::const_iterator it; - for (it = m_types.constBegin(); it != m_types.constEnd(); ++it) { - if ((*it).kind() == QScriptMetaType::Unresolved) { - m_firstUnresolvedIndex = it - m_types.constBegin(); - break; - } - } - } - inline bool isValid() const - { return !m_types.isEmpty(); } - - QByteArray name() const - { return m_name; } - - inline QScriptMetaType returnType() const - { return m_types.at(0); } - - inline int argumentCount() const - { return m_types.count() - 1; } - - inline QScriptMetaType argumentType(int arg) const - { return m_types.at(arg + 1); } - - inline bool fullyResolved() const - { return m_firstUnresolvedIndex == -1; } - - inline bool hasUnresolvedReturnType() const - { return (m_firstUnresolvedIndex == 0); } - - inline int firstUnresolvedIndex() const - { return m_firstUnresolvedIndex; } - - inline int count() const - { return m_types.count(); } - - inline QScriptMetaType type(int index) const - { return m_types.at(index); } - - inline QVector<QScriptMetaType> types() const - { return m_types; } - -private: - QByteArray m_name; - QVector<QScriptMetaType> m_types; - int m_firstUnresolvedIndex; -}; - -struct QScriptMetaArguments -{ - int matchDistance; - int index; - QScriptMetaMethod method; - QVarLengthArray<QVariant, 9> args; - - inline QScriptMetaArguments(int dist, int idx, const QScriptMetaMethod &mtd, - const QVarLengthArray<QVariant, 9> &as) - : matchDistance(dist), index(idx), method(mtd), args(as) { } - inline QScriptMetaArguments() - : matchDistance(0), index(-1) { } - - inline bool isValid() const - { return (index != -1); } -}; - -class QScriptMetaObject -{ -public: - inline QScriptMetaMethod findMethod(int index) const - { - return m_methods.value(index); - } - - inline void registerMethod(int index, const QScriptMetaMethod &method) - { - m_methods.insert(index, method); - } - - inline bool findMember(QScriptNameIdImpl *nameId, QScript::Member *member) const - { - QHash<QScriptNameIdImpl*, QScript::Member>::const_iterator it; - it = m_members.constFind(nameId); - if (it == m_members.constEnd()) - return false; - *member = it.value(); - return true; - } - - inline void registerMember(QScriptNameIdImpl *nameId, const QScript::Member &member) - { - m_members.insert(nameId, member); - } - - inline QList<QScriptNameIdImpl*> registeredMemberNames() const - { - return m_members.keys(); - } - - inline QScriptValueImpl findPropertyAccessor(int index) const - { - return m_propertyAccessors.value(index); - } - - inline void registerPropertyAccessor(int index, const QScriptValueImpl &accessor) - { - m_propertyAccessors.insert(index, accessor); - } - - inline QList<QScriptValueImpl> registeredPropertyAccessors() const - { - return m_propertyAccessors.values(); - } - - inline int methodLowerBound(int index) const - { - return m_methodBounds.value(index, 0); - } - - inline void setMethodLowerBound(int index, int bound) - { - m_methodBounds.insert(index, bound); - } - -private: - QHash<int, QScriptValueImpl> m_propertyAccessors; - QHash<int, QScriptMetaMethod> m_methods; - QHash<int, int> m_methodBounds; - QHash<QScriptNameIdImpl*, QScript::Member> m_members; -}; - -#endif // QT_NO_QOBJECT - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT -#endif // QSCRIPTEXTQOBJECT_P_H diff --git a/src/script/qscriptextvariant.cpp b/src/script/qscriptextvariant.cpp deleted file mode 100644 index 4ac2a4a..0000000 --- a/src/script/qscriptextvariant.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qscriptextvariant_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptengine_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" - -#include <QtCore/QtDebug> - -#include <QtCore/QStringList> - -#include <limits.h> - -QT_BEGIN_NAMESPACE - -namespace QScript { namespace Ext { - -Variant::Variant(QScriptEnginePrivate *eng): - Ecma::Core(eng, QLatin1String("QVariant"), QScriptClassInfo::VariantType) -{ - newVariant(&publicPrototype, QVariant()); - - eng->newConstructor(&ctor, this, publicPrototype); - - addPrototypeFunction(QLatin1String("toString"), method_toString, 0); - addPrototypeFunction(QLatin1String("valueOf"), method_valueOf, 0); -} - -Variant::~Variant() -{ -} - -Variant::Instance *Variant::Instance::get(const QScriptValueImpl &object, QScriptClassInfo *klass) -{ - if (! klass || klass == object.classInfo()) - return static_cast<Instance*> (object.objectData()); - - return 0; -} - -void Variant::execute(QScriptContextPrivate *context) -{ - QScriptValueImpl tmp; - newVariant(&tmp, QVariant()); - context->setReturnValue(tmp); -} - -void Variant::newVariant(QScriptValueImpl *result, const QVariant &value) -{ - Instance *instance; - if (!result->isValid()) { - engine()->newObject(result, publicPrototype, classInfo()); - instance = new Instance(); - result->setObjectData(instance); - } else { - Q_ASSERT(result->isObject()); - if (result->classInfo() != classInfo()) { - result->destroyObjectData(); - result->setClassInfo(classInfo()); - instance = new Instance(); - result->setObjectData(instance); - } else { - instance = Instance::get(*result, classInfo()); - } - } - instance->value = value; -} - -QScriptValueImpl Variant::method_toString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) -{ - if (Instance *instance = Instance::get(context->thisObject(), classInfo)) { - QString result; - QScriptValueImpl value = method_valueOf(context, eng, classInfo); - if (value.isObject()) { - result = instance->value.toString(); - if (result.isEmpty()) { - result = QString::fromLatin1("QVariant(%0)") - .arg(QLatin1String(instance->value.typeName())); - } - } else { - result = value.toString(); - } - return QScriptValueImpl(eng, result); - } - return context->throwError(QScriptContext::TypeError, - QLatin1String("QVariant.prototype.toString")); -} - -QScriptValueImpl Variant::method_valueOf(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) -{ - if (Instance *instance = Instance::get(context->thisObject(), classInfo)) { - QVariant v = instance->value; - switch (v.type ()) { - case QVariant::Invalid: - return eng->undefinedValue(); - case QVariant::String: - return (QScriptValueImpl(eng, v.toString())); - - case QVariant::Int: - return (QScriptValueImpl(v.toInt())); - - case QVariant::Bool: - return (QScriptValueImpl(v.toBool())); - - case QVariant::Double: - return (QScriptValueImpl(v.toDouble())); // ### hmmm - - case QVariant::Char: - return (QScriptValueImpl(v.toChar().unicode())); - - case QVariant::UInt: - return (QScriptValueImpl(v.toUInt())); - - default: - return context->thisObject(); - } // switch - } - return context->thisObject(); -} - -} } // namespace QScript::Ecma - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptextvariant_p.h b/src/script/qscriptextvariant_p.h deleted file mode 100644 index 070577f..0000000 --- a/src/script/qscriptextvariant_p.h +++ /dev/null @@ -1,106 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTEXTVARIANT_P_H -#define QSCRIPTEXTVARIANT_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/QVariant> - -#include "qscriptecmacore_p.h" - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_SCRIPT - -namespace QScript { namespace Ext { - -class Instance; - -class Variant: public Ecma::Core -{ -public: - Variant(QScriptEnginePrivate *engine); - virtual ~Variant(); - - virtual void execute(QScriptContextPrivate *context); - - class Instance: public QScriptObjectData { - public: - Instance() {} - virtual ~Instance() {} - - static Instance *get(const QScriptValueImpl &object, - QScriptClassInfo *klass); - - public: - QVariant value; - }; - - inline Instance *get(const QScriptValueImpl &object) const - { return Instance::get(object, classInfo()); } - - void newVariant(QScriptValueImpl *result, const QVariant &value); - -protected: - static QScriptValueImpl method_toString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); - static QScriptValueImpl method_valueOf(QScriptContextPrivate *context, QScriptEnginePrivate *eng, - QScriptClassInfo *classInfo); -}; - -} } // namespace QScript::Ext - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT - -#endif // QSCRIPTEXTVARIANT_P_H diff --git a/src/script/qscriptfunction.cpp b/src/script/qscriptfunction.cpp deleted file mode 100644 index 4d2cc07..0000000 --- a/src/script/qscriptfunction.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qscriptfunction_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptengine_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" - -QT_BEGIN_NAMESPACE - -QScriptFunction::~QScriptFunction() -{ -} - -QString QScriptFunction::toString(QScriptContextPrivate *) const -{ - QString result; - result += QLatin1String("function () { [native] }"); - return result; -} - -QString QScriptFunction::fileName() const -{ - return QString(); -} - -QString QScriptFunction::functionName() const -{ - return QString(); -} - -int QScriptFunction::startLineNumber() const -{ - return -1; -} - -int QScriptFunction::endLineNumber() const -{ - return -1; -} - -void QScriptFunction::mark(QScriptEnginePrivate *engine, int generation) -{ - for (int i = 0; i < formals.count(); ++i) - engine->markString(formals.at(i), generation); -} - -// public API function -void QScript::CFunction::execute(QScriptContextPrivate *context) -{ - QScriptEnginePrivate *eng_p = context->engine(); - - context->m_result = eng_p->undefinedValue(); - -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - eng_p->notifyFunctionEntry(context); -#endif - - QScriptContext *publicContext = QScriptContextPrivate::get(eng_p->currentContext()); - QScriptEngine *publicEngine = QScriptEnginePrivate::get(eng_p); - QScriptValueImpl result = eng_p->toImpl((*m_funPtr)(publicContext, publicEngine)); - if (result.isValid() && !eng_p->shouldAbort() - && (context->state() == QScriptContext::NormalState)) { - context->m_result = result; - } - -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - eng_p->notifyFunctionExit(context); -#endif -} - -QString QScript::CFunction::functionName() const -{ - return QString(); -} - -// internal API function -void QScript::C2Function::execute(QScriptContextPrivate *context) -{ - QScriptEnginePrivate *eng_p = context->engine(); - - bool blocked = eng_p->blockGC(true); - -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - eng_p->notifyFunctionEntry(context); -#endif - - context->m_result = (*m_funPtr)(context, eng_p, m_classInfo); - Q_ASSERT(context->m_result.isValid()); - -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - eng_p->notifyFunctionExit(context); -#endif - - eng_p->blockGC(blocked); -} - -QString QScript::C2Function::functionName() const -{ - if (!m_name.isEmpty()) - return m_name; - return QString(); -} - -void QScript::C3Function::execute(QScriptContextPrivate *context) -{ - QScriptEnginePrivate *eng_p = context->engine(); - - context->m_result = eng_p->undefinedValue(); - -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - eng_p->notifyFunctionEntry(context); -#endif - - QScriptContext *publicContext = QScriptContextPrivate::get(eng_p->currentContext()); - QScriptEngine *publicEngine = QScriptEnginePrivate::get(eng_p); - QScriptValueImpl result = eng_p->toImpl((*m_funPtr)(publicContext, publicEngine, m_arg)); - if (result.isValid() && !eng_p->shouldAbort()) - context->m_result = result; - -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - eng_p->notifyFunctionExit(context); -#endif -} - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptfunction_p.h b/src/script/qscriptfunction_p.h deleted file mode 100644 index 09710c1..0000000 --- a/src/script/qscriptfunction_p.h +++ /dev/null @@ -1,219 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTFUNCTION_P_H -#define QSCRIPTFUNCTION_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 "qscriptobjectdata_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptglobals_p.h" -#include "qscriptnodepool_p.h" - -#include <QtCore/QList> - -#ifndef QT_NO_QOBJECT -# include <QtCore/QPointer> -# include <QtCore/QMetaMethod> -#endif - -QT_BEGIN_NAMESPACE - -class QScriptContext; -class QScriptContextPrivate; -class QScriptNameIdImpl; - -class QScriptFunction: public QScriptObjectData -{ -public: - enum Type { - Unknown, - Script, - C, - C2, - C3, - Qt, - QtProperty - }; - - QScriptFunction(int len = 0) - : length(len) - { } - virtual ~QScriptFunction(); - - virtual void execute(QScriptContextPrivate *context) = 0; - virtual QString toString(QScriptContextPrivate *context) const; - - virtual Type type() const { return Unknown; } - - // name of the file the function is defined in - virtual QString fileName() const; - - virtual QString functionName() const; - - virtual int startLineNumber() const; - - virtual int endLineNumber() const; - - virtual void mark(QScriptEnginePrivate *engine, int generation); - -public: // ### private - int length; - QList<QScriptNameIdImpl*> formals; -}; - -namespace QScript { - -// public API function -class CFunction: public QScriptFunction -{ -public: - CFunction(QScriptFunctionSignature funPtr, int length) - : QScriptFunction(length), m_funPtr(funPtr) - { } - - virtual ~CFunction() { } - - virtual void execute(QScriptContextPrivate *context); - - virtual Type type() const { return QScriptFunction::C; } - - virtual QString functionName() const; - -private: - QScriptFunctionSignature m_funPtr; -}; - -// internal API function -class C2Function: public QScriptFunction -{ -public: - C2Function(QScriptInternalFunctionSignature funPtr, int length, - QScriptClassInfo *classInfo, const QString &name) - : QScriptFunction(length), m_funPtr(funPtr), - m_classInfo(classInfo), m_name(name) - { } - - virtual ~C2Function() {} - - virtual void execute(QScriptContextPrivate *context); - - virtual Type type() const { return QScriptFunction::C2; } - - virtual QString functionName() const; - -private: - QScriptInternalFunctionSignature m_funPtr; - QScriptClassInfo *m_classInfo; - QString m_name; -}; - -class C3Function: public QScriptFunction -{ -public: - C3Function(QScriptFunctionWithArgSignature funPtr, void *arg, int length) - : QScriptFunction(length), m_funPtr(funPtr), m_arg(arg) - { } - - virtual ~C3Function() { } - - virtual void execute(QScriptContextPrivate *context); - - virtual Type type() const { return QScriptFunction::C3; } - -private: - QScriptFunctionWithArgSignature m_funPtr; - void *m_arg; -}; - -namespace AST { - class FunctionExpression; -} - -// implemented in qscriptcontext_p.cpp -class ScriptFunction: public QScriptFunction -{ -public: - ScriptFunction(AST::FunctionExpression *definition, NodePool *astPool): - m_definition(definition), m_astPool(astPool), m_compiledCode(0) {} - - virtual ~ScriptFunction() {} - - virtual void execute(QScriptContextPrivate *context); - - virtual QString toString(QScriptContextPrivate *context) const; - - virtual Type type() const - { return QScriptFunction::Script; } - - virtual QString fileName() const; - - virtual QString functionName() const; - - virtual int startLineNumber() const; - - virtual int endLineNumber() const; - -private: - AST::FunctionExpression *m_definition; - QExplicitlySharedDataPointer<NodePool> m_astPool; - Code *m_compiledCode; -}; - -} // namespace QScript - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT - -#endif // QSCRIPTFUNCTION_P_H diff --git a/src/script/qscriptgc_p.h b/src/script/qscriptgc_p.h deleted file mode 100644 index a1bf8c5..0000000 --- a/src/script/qscriptgc_p.h +++ /dev/null @@ -1,321 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTGC_P_H -#define QSCRIPTGC_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. -// - -#if defined(Q_OS_VXWORKS) && defined(m_free) -# undef m_free -#endif - -#include <QtCore/qglobal.h> - -#ifndef QT_NO_SCRIPT - -#include <QtCore/QtDebug> -#include <new> - -#include "qscriptmemorypool_p.h" - -QT_BEGIN_NAMESPACE - -namespace QScript { - -class GCBlock -{ -public: - GCBlock *next; - - union { - int generation; - uint flags; - }; - -public: - inline GCBlock(GCBlock *n): - next(n), flags(0) {} - - inline void *data() - { return reinterpret_cast<char *>(this) + sizeof(GCBlock); } - - inline static GCBlock *get(void *ptr) - { - char *where = reinterpret_cast<char *>(ptr); - return reinterpret_cast<GCBlock *>(where - sizeof(GCBlock)); - } -}; - -template <typename _Tp> -class GCAlloc -{ -private: - int m_new_allocated_blocks; - int m_free_blocks; - int m_new_allocated_extra_bytes; - GCBlock *m_head; - GCBlock *m_current; - GCBlock *m_free; - bool m_blocked_gc; - bool m_force_gc; - bool m_sweeping; - MemoryPool pool; - _Tp trivial; - -public: - enum { MaxNumberOfBlocks = 1 << 14 }; - enum { MaxNumberOfExtraBytes = 0x800000 }; - -public: - inline GCAlloc(): - m_new_allocated_blocks(0), - m_free_blocks(0), - m_new_allocated_extra_bytes(0), - m_head(0), - m_current(0), - m_free(0), - m_blocked_gc(false), - m_force_gc(false), - m_sweeping(false) { - trivial.reset(); - } - - inline ~GCAlloc() { - } - - inline void destruct() { - m_sweeping = true; - GCBlock *blk = m_free; - - if (! blk) { - blk = m_head; - m_head = 0; - } - - while (blk) { - GCBlock *was = blk; - blk = blk->next; - - Q_ASSERT(was->data()); - _Tp *data = reinterpret_cast<_Tp*>(was->data()); - data->~_Tp(); - blk->~GCBlock(); - - if (! blk && m_head) { - blk = m_head; - m_head = 0; - } - } - m_sweeping = false; - } - - inline int newAllocatedBlocks() const { return m_new_allocated_blocks; } - inline int freeBlocks() const { return m_free_blocks; } - - inline _Tp *operator()(int generation) - { - GCBlock *previous = m_current; - void *where = 0; - - if (! m_free) { - Q_ASSERT (m_free_blocks == 0); - where = pool.allocate(sizeof(GCBlock) + sizeof(_Tp)); - ++m_new_allocated_blocks; - (void) new (reinterpret_cast<char*>(where) + sizeof(GCBlock)) _Tp(); - } else { - --m_free_blocks; - where = m_free; - m_free = m_free->next; - - if (! m_free) - m_force_gc = true; - } - - m_current = new (where) GCBlock(0); - - if (! previous) { - Q_ASSERT(! m_head); - m_head = m_current; - } else { - previous->next = m_current; - } - m_current->generation = generation; - - return reinterpret_cast<_Tp*> (m_current->data()); - } - - inline bool blocked() const - { - return m_blocked_gc; - } - - inline bool sweeping() const - { - return m_sweeping; - } - - inline bool blockGC(bool block) - { - bool was = m_blocked_gc; - m_blocked_gc = block; - return was; - } - - inline void requestGC() - { - m_force_gc = true; - } - - inline void adjustBytesAllocated(int bytes) - { m_new_allocated_extra_bytes += bytes; } - - inline bool poll() - { - if (m_blocked_gc || ! m_head) - return false; - - else if (m_force_gc) { - m_force_gc = false; - return true; - } - - else if (m_free && ! m_free->next) - return true; - - return (m_new_allocated_blocks >= MaxNumberOfBlocks) - || ((m_new_allocated_extra_bytes >= MaxNumberOfExtraBytes) - && (m_new_allocated_blocks > 0)); - } - - inline int generation(_Tp *ptr) const - { return GCBlock::get(ptr)->generation; } - - inline GCBlock *head() const - { return m_head; } - - void sweep(int generation) - { - m_sweeping = true; - GCBlock *blk = m_head; - m_current = 0; - - m_new_allocated_blocks = 0; - m_new_allocated_extra_bytes = 0; - - while (blk != 0) { - if (blk->generation != generation) { - if (m_current) - m_current->next = blk->next; - - GCBlock *tmp = blk; - blk = blk->next; // advance the pointer - - tmp->next = m_free; // prepend the node to the free list... - m_free = tmp; - ++m_free_blocks; - - if (m_free == m_head) - m_head = blk; - - _Tp *data = reinterpret_cast<_Tp *>(tmp->data()); - data->finalize(); - tmp->~GCBlock(); - } else { - m_current = blk; - blk = blk->next; - } - } - - if (! m_current) - m_head = m_current; - m_sweeping = false; - } - - class const_iterator - { - public: - typedef _Tp value_type; - typedef const _Tp *pointer; - typedef const _Tp &reference; - inline const_iterator() : i(0) { } - inline const_iterator(GCBlock *block) : i(block) { } - inline const_iterator(const const_iterator &o) - { i = reinterpret_cast<const const_iterator &>(o).i; } - - inline const _Tp *data() const { return reinterpret_cast<_Tp*>(i->data()); } - inline const _Tp &value() const { return *reinterpret_cast<_Tp*>(i->data()); } - inline const _Tp &operator*() const { return *reinterpret_cast<_Tp*>(i->data()); } - inline const _Tp *operator->() const { return reinterpret_cast<_Tp*>(i->data()); } - inline bool operator==(const const_iterator &o) const { return i == o.i; } - inline bool operator!=(const const_iterator &o) const { return i != o.i; } - - inline const_iterator &operator++() { - i = i->next; - return *this; - } - private: - GCBlock *i; - }; - friend class const_iterator; - - inline const_iterator constBegin() const { return const_iterator(m_head); } - inline const_iterator constEnd() const { return const_iterator(0); } - -private: - Q_DISABLE_COPY(GCAlloc) -}; - -} // namespace QScript - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT -#endif // QSCRIPT_GC_H diff --git a/src/script/qscriptglobals_p.h b/src/script/qscriptglobals_p.h deleted file mode 100644 index 8fdd18e..0000000 --- a/src/script/qscriptglobals_p.h +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTGLOBALS_P_H -#define QSCRIPTGLOBALS_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/qglobal.h> - -#ifndef QT_NO_SCRIPT - -QT_BEGIN_NAMESPACE - -class QScriptValue; -class QScriptValueImpl; -class QScriptClassInfo; -class QScriptEngine; -class QScriptEnginePrivate; -class QScriptContext; -class QScriptContextPrivate; - -typedef QScriptValueImpl (*QScriptInternalFunctionSignature)(QScriptContextPrivate *, QScriptEnginePrivate *, QScriptClassInfo *); -typedef QScriptValue (*QScriptFunctionSignature)(QScriptContext *, QScriptEngine *); -typedef QScriptValue (*QScriptFunctionWithArgSignature)(QScriptContext *, QScriptEngine *, void *); - -namespace QScript { - -enum Type { - InvalidType, - // standard types - UndefinedType, - NullType, - BooleanType, - StringType, - NumberType, - ObjectType, - // internal types - IntegerType, - ReferenceType, - PointerType, - LazyStringType -}; - -enum AccessMode { - Read = 0x01, - Write = 0x02, - ReadWrite = 0x03 -}; - -} // namespace QScript - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT - -#endif // QSCRIPTGLOBALS_P_H diff --git a/src/script/qscriptmember_p.h b/src/script/qscriptmember_p.h deleted file mode 100644 index 67a6eae..0000000 --- a/src/script/qscriptmember_p.h +++ /dev/null @@ -1,191 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTMEMBER_P_H -#define QSCRIPTMEMBER_P_H - -#include "qscriptmemberfwd_p.h" - -#ifndef QT_NO_SCRIPT - -QT_BEGIN_NAMESPACE - -// -// 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. -// - -inline void QScript::Member::resetFlags(uint flags) -{ - m_flags = flags; -} - -inline void QScript::Member::setFlags(uint flags) -{ - m_flags |= flags; -} - -inline void QScript::Member::unsetFlags(uint flags) -{ - m_flags &= ~flags; -} - -inline uint QScript::Member::flags() const -{ - return m_flags; -} - -inline bool QScript::Member::testFlags(uint mask) const -{ - return m_flags & mask; -} - -inline bool QScript::Member::isValid() const -{ - return m_flags & 0x00000300; -} - -inline bool QScript::Member::isWritable() const -{ - return !(m_flags & QScriptValue::ReadOnly); -} - -inline bool QScript::Member::isDeletable() const -{ - return !(m_flags & QScriptValue::Undeletable); -} - -inline bool QScript::Member::dontEnum() const -{ - return m_flags & QScriptValue::SkipInEnumeration; -} - -inline bool QScript::Member::isObjectProperty() const -{ - return m_flags & ObjectProperty; -} - -inline bool QScript::Member::isNativeProperty() const -{ - return m_flags & NativeProperty; -} - -inline bool QScript::Member::isUninitializedConst() const -{ - return m_flags & UninitializedConst; -} - -inline bool QScript::Member::isGetter() const -{ - return m_flags & QScriptValue::PropertyGetter; -} - -inline bool QScript::Member::isSetter() const -{ - return m_flags & QScriptValue::PropertySetter; -} - -inline bool QScript::Member::isGetterOrSetter() const -{ - return m_flags & (QScriptValue::PropertyGetter | QScriptValue::PropertySetter); -} - -inline int QScript::Member::id() const -{ - return m_id; -} - -inline QScriptNameIdImpl *QScript::Member::nameId() const -{ - return m_nameId; -} - -inline QScript::Member QScript::Member::invalid() -{ - Member m; - m.m_flags = 0; - return m; -} - -inline void QScript::Member::invalidate() -{ - m_flags = 0; -} - -inline void QScript::Member::native(QScriptNameIdImpl *nameId, int id, uint flags) -{ - Q_ASSERT(! (flags & ObjectProperty)); - - m_nameId = nameId; - m_id = id; - m_flags = flags | NativeProperty; -} - -inline void QScript::Member::object(QScriptNameIdImpl *nameId, int id, uint flags) -{ - Q_ASSERT(! (flags & NativeProperty)); - - m_nameId = nameId; - m_id = id; - m_flags = flags | ObjectProperty; -} - -inline bool QScript::Member::operator==(const QScript::Member &other) const -{ - return m_nameId == other.m_nameId; -} - -inline bool QScript::Member::operator!=(const QScript::Member &other) const -{ - return m_nameId != other.m_nameId; -} - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT - -#endif diff --git a/src/script/qscriptmemberfwd_p.h b/src/script/qscriptmemberfwd_p.h deleted file mode 100644 index cdf4602..0000000 --- a/src/script/qscriptmemberfwd_p.h +++ /dev/null @@ -1,130 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTMEMBERFWD_P_H -#define QSCRIPTMEMBERFWD_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. -// - -#if defined(Q_OS_VXWORKS) && defined(m_flags) -# undef m_flags -#endif - -#include <QtCore/qglobal.h> - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_SCRIPT - -class QScriptNameIdImpl; - -namespace QScript { - - class Member - { - public: - enum PropertyFlag { - ObjectProperty = 0x00000100, // Stored in the member table - NativeProperty = 0x00000200, - - UninitializedConst = 0x00000800, // NB: shared with QScriptValue::KeepExistingFlags - - InternalRange = 0x0000ff00 // Not user-accessible (read as 0, don't change on write) - }; - - inline Member() : m_nameId(0), m_id(0), m_flags(0) {} - - inline void resetFlags(uint flags); - inline void setFlags(uint flags); - inline void unsetFlags(uint flags); - inline uint flags() const; - inline bool testFlags(uint mask) const; - - inline bool isValid() const; - - inline bool isWritable() const; - inline bool isDeletable() const; - - inline bool dontEnum() const; - - inline bool isObjectProperty() const; - inline bool isNativeProperty() const; - - inline bool isUninitializedConst() const; - - inline bool isGetter() const; - inline bool isSetter() const; - inline bool isGetterOrSetter() const; - - inline int id() const; - inline QScriptNameIdImpl *nameId() const; - - inline bool operator==(const Member &other) const; - inline bool operator!=(const Member &other) const; - - inline static Member invalid(); - inline void invalidate(); - - inline void native(QScriptNameIdImpl *nameId, int id, uint flags); - inline void object(QScriptNameIdImpl *nameId, int id, uint flags); - - private: - QScriptNameIdImpl *m_nameId; - int m_id; - uint m_flags; - }; - -} // namespace QScript - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT - -#endif diff --git a/src/script/qscriptnameid_p.h b/src/script/qscriptnameid_p.h deleted file mode 100644 index 1babc5f..0000000 --- a/src/script/qscriptnameid_p.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTNAMEID_P_H -#define QSCRIPTNAMEID_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/qglobal.h> - -QT_BEGIN_NAMESPACE - -class QScriptNameIdImpl -{ -public: - QString s; - uint h; - QScriptNameIdImpl *next; - uint used: 1; - uint persistent: 1; - uint unique: 1; - uint pad: 29; - - inline QScriptNameIdImpl(const QString &_s): - s(_s), h(0), next(0), used(0), persistent(0), unique(0), pad(0) { } -}; - -QT_END_NAMESPACE - -#endif // QSCRIPTNAMEID_P_H diff --git a/src/script/qscriptnodepool_p.h b/src/script/qscriptnodepool_p.h deleted file mode 100644 index d41e314..0000000 --- a/src/script/qscriptnodepool_p.h +++ /dev/null @@ -1,139 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTNODEPOOL_P_H -#define QSCRIPTNODEPOOL_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/QHash> -#include <QtCore/QString> - -#include "qscriptmemorypool_p.h" - -QT_BEGIN_NAMESPACE - -class QScriptEnginePrivate; - -namespace QScript { - -namespace AST { -class Node; -} // namespace AST - -class Code; -class CompilationUnit; - -template <typename NodeType> -inline NodeType *makeAstNode(MemoryPool *storage) -{ - NodeType *node = new (storage->allocate(sizeof(NodeType))) NodeType(); - return node; -} - -template <typename NodeType, typename Arg1> -inline NodeType *makeAstNode(MemoryPool *storage, Arg1 arg1) -{ - NodeType *node = new (storage->allocate(sizeof(NodeType))) NodeType(arg1); - return node; -} - -template <typename NodeType, typename Arg1, typename Arg2> -inline NodeType *makeAstNode(MemoryPool *storage, Arg1 arg1, Arg2 arg2) -{ - NodeType *node = new (storage->allocate(sizeof(NodeType))) NodeType(arg1, arg2); - return node; -} - -template <typename NodeType, typename Arg1, typename Arg2, typename Arg3> -inline NodeType *makeAstNode(MemoryPool *storage, Arg1 arg1, Arg2 arg2, Arg3 arg3) -{ - NodeType *node = new (storage->allocate(sizeof(NodeType))) NodeType(arg1, arg2, arg3); - return node; -} - -template <typename NodeType, typename Arg1, typename Arg2, typename Arg3, typename Arg4> -inline NodeType *makeAstNode(MemoryPool *storage, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) -{ - NodeType *node = new (storage->allocate(sizeof(NodeType))) NodeType(arg1, arg2, arg3, arg4); - return node; -} - -class NodePool : public MemoryPool -{ -public: - NodePool(const QString &fileName, QScriptEnginePrivate *engine); - virtual ~NodePool(); - - Code *createCompiledCode(AST::Node *node, CompilationUnit &compilation); - - inline QString fileName() const { return m_fileName; } - inline QScriptEnginePrivate *engine() const { return m_engine; } -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - inline qint64 id() const { return m_id; } -#endif - -private: - QHash<AST::Node*, Code*> m_codeCache; - QString m_fileName; - QScriptEnginePrivate *m_engine; -#ifndef Q_SCRIPT_NO_EVENT_NOTIFY - qint64 m_id; -#endif - -private: - Q_DISABLE_COPY(NodePool) -}; - -} // namespace QScript - -QT_END_NAMESPACE - -#endif diff --git a/src/script/qscriptobject_p.h b/src/script/qscriptobject_p.h deleted file mode 100644 index a599e1f..0000000 --- a/src/script/qscriptobject_p.h +++ /dev/null @@ -1,188 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTOBJECT_P_H -#define QSCRIPTOBJECT_P_H - -#include "qscriptobjectfwd_p.h" - -#ifndef QT_NO_SCRIPT - -QT_BEGIN_NAMESPACE - -// -// 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. -// - -inline bool QScriptObject::findMember(QScriptNameIdImpl *nameId, - QScript::Member *m) const -{ - const QScript::Member *members = m_members.constData(); - const int size = m_members.size(); - - const QScript::Member *first = &members[-1]; - const QScript::Member *last = &members[size - 1]; - - for (const QScript::Member *it = last; it != first; --it) { - if (it->nameId() == nameId && it->isValid()) { - *m = *it; - return true; - } - } - - return false; -} - -// assumes that m already points to the setter -inline bool QScriptObject::findGetter(QScript::Member *m) const -{ - const QScript::Member *members = m_members.constData(); - const QScript::Member *first = &members[-1]; - const QScript::Member *last = &members[m->id() - 1]; - - for (const QScript::Member *it = last; it != first; --it) { - if (it->nameId() == m->nameId() && it->isValid() && it->isGetter()) { - *m = *it; - return true; - } - } - - return false; -} - -// assumes that m already points to the getter -inline bool QScriptObject::findSetter(QScript::Member *m) const -{ - const QScript::Member *members = m_members.constData(); - const QScript::Member *first = &members[-1]; - const QScript::Member *last = &members[m->id() - 1]; - - for (const QScript::Member *it = last; it != first; --it) { - if (it->nameId() == m->nameId() && it->isValid() && it->isSetter()) { - *m = *it; - return true; - } - } - - return false; -} - -inline int QScriptObject::memberCount() const -{ - return m_members.size(); -} - -inline void QScriptObject::createMember(QScriptNameIdImpl *nameId, - QScript::Member *member, uint flags) -{ - member->object(nameId, m_values.size(), flags); - m_members.append(*member); - m_values.append(QScriptValueImpl()); -} - -inline void QScriptObject::member(int index, QScript::Member *member) -{ - *member = m_members[index]; -} - -inline void QScriptObject::put(const QScript::Member &m, const QScriptValueImpl &v) -{ - m_values[m.id()] = v; -} - -inline QScriptValueImpl &QScriptObject::reference(const QScript::Member &m) -{ - return m_values[m.id()]; -} - -inline void QScriptObject::get(const QScript::Member &m, QScriptValueImpl *v) -{ - Q_ASSERT(m.isObjectProperty()); - *v = m_values[m.id()]; -} - -inline void QScriptObject::removeMember(const QScript::Member &member) -{ - m_members[member.id()].invalidate(); - m_values[member.id()].invalidate(); -} - -inline QScriptObject::~QScriptObject() -{ - finalize(); -} - -inline void QScriptObject::finalize() -{ - finalizeData(); -} - -inline void QScriptObject::finalizeData() -{ - if (m_data) { - m_data->finalize(m_class->engine()); - delete m_data; - m_data = 0; - } -} - -inline void QScriptObject::reset() -{ - m_prototype.invalidate(); - m_scope.invalidate(); - m_internalValue.invalidate(); - m_members.resize(0); - m_values.resize(0); - m_data = 0; -} - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT - -#endif diff --git a/src/script/qscriptobjectfwd_p.h b/src/script/qscriptobjectfwd_p.h deleted file mode 100644 index 10d7b27..0000000 --- a/src/script/qscriptobjectfwd_p.h +++ /dev/null @@ -1,112 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTOBJECTFWD_P_H -#define QSCRIPTOBJECTFWD_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/qglobal.h> - -#ifndef QT_NO_SCRIPT - -#include "qscriptbuffer_p.h" -#include "qscriptmemberfwd_p.h" -#include "qscriptvalueimplfwd_p.h" - -QT_BEGIN_NAMESPACE - -class QScriptObjectData; - -class QScriptObject -{ -public: - inline void reset(); - inline ~QScriptObject(); - inline void finalize(); - inline void finalizeData(); - - inline bool findMember(QScriptNameIdImpl *nameId, - QScript::Member *m) const; - - inline bool findGetter(QScript::Member *m) const; - - inline bool findSetter(QScript::Member *m) const; - - inline int memberCount() const; - - inline void createMember(QScriptNameIdImpl *nameId, - QScript::Member *member, uint flags); - - inline void member(int index, QScript::Member *member); - - inline void put(const QScript::Member &m, const QScriptValueImpl &v); - - inline QScriptValueImpl &reference(const QScript::Member &m); - - inline void get(const QScript::Member &m, QScriptValueImpl *v); - - inline void removeMember(const QScript::Member &member); - - QScriptValueImpl m_prototype; - QScriptValueImpl m_scope; - QScriptValueImpl m_internalValue; // [[value]] - QScriptObjectData *m_data; - QScript::Buffer<QScript::Member> m_members; - QScript::Buffer<QScriptValueImpl> m_values; - qint64 m_id; - QScriptClassInfo *m_class; -}; - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT - -#endif diff --git a/src/script/qscriptprettypretty.cpp b/src/script/qscriptprettypretty.cpp deleted file mode 100644 index c186be7..0000000 --- a/src/script/qscriptprettypretty.cpp +++ /dev/null @@ -1,1334 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qscriptprettypretty_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptengine_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" -#include "qscriptast_p.h" - -#include <QtCore/QString> -#include <QtCore/QTextStream> -#include <QtCore/QtDebug> - -QT_BEGIN_NAMESPACE - -namespace QScript { -QString numberToString(qsreal value); -} - -using namespace QScript; - -PrettyPretty::PrettyPretty(QTextStream &o): - out(o), m_indentLevel(0) -{ -} - -PrettyPretty::~PrettyPretty() -{ -} - -void PrettyPretty::acceptAsBlock(AST::Node *node) -{ - out << '{'; - pushIndentLevel(); - newlineAndIndent(); - accept(node); - popIndentLevel(); - newlineAndIndent(); - out << '}'; -} - -int PrettyPretty::operatorPrecedenceLevel(int op) -{ - switch (op) { - case QSOperator::Div: - case QSOperator::Mod: - case QSOperator::Mul: - return 5; - case QSOperator::Add: - case QSOperator::Sub: - return 6; - case QSOperator::LShift: - case QSOperator::RShift: - case QSOperator::URShift: - return 7; - case QSOperator::Ge: - case QSOperator::Gt: - case QSOperator::In: - case QSOperator::InstanceOf: - case QSOperator::Le: - case QSOperator::Lt: - return 8; - case QSOperator::Equal: - case QSOperator::NotEqual: - case QSOperator::StrictEqual: - case QSOperator::StrictNotEqual: - return 9; - case QSOperator::BitAnd: - return 10; - case QSOperator::BitXor: - return 11; - case QSOperator::BitOr: - return 12; - case QSOperator::And: - return 13; - case QSOperator::Or: - return 14; - case QSOperator::InplaceAnd: - case QSOperator::InplaceSub: - case QSOperator::InplaceDiv: - case QSOperator::InplaceAdd: - case QSOperator::InplaceLeftShift: - case QSOperator::InplaceMod: - case QSOperator::InplaceMul: - case QSOperator::InplaceOr: - case QSOperator::InplaceRightShift: - case QSOperator::InplaceURightShift: - case QSOperator::InplaceXor: - case QSOperator::Assign: - return 16; - default: - Q_ASSERT_X(false, "PrettyPretty::operatorPrecedenceLevel()", "bad operator"); - } - return 0; -} - -int PrettyPretty::compareOperatorPrecedence(int op1, int op2) -{ - int prec1 = operatorPrecedenceLevel(op1); - int prec2 = operatorPrecedenceLevel(op2); - if (prec1 == prec2) - return 0; - if (prec1 > prec2) - return -1; - return 1; -} - -QTextStream &PrettyPretty::operator () (AST::Node *node, int level) -{ - int was = indentLevel(level); - accept(node); - indentLevel(was); - return out; -} - -QTextStream &PrettyPretty::newlineAndIndent() -{ - enum { IND = 4 }; - out << endl << QString().fill(QLatin1Char(' '), m_indentLevel * IND); - return out; -} - -void PrettyPretty::accept(AST::Node *node) -{ - AST::Node::acceptChild(node, this); -} - -bool PrettyPretty::visit(AST::ThisExpression *node) -{ - Q_UNUSED(node); - out << "this"; - return true; -} - -void PrettyPretty::endVisit(AST::ThisExpression *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::IdentifierExpression *node) -{ - out << QScriptEnginePrivate::toString(node->name); - return true; -} - -void PrettyPretty::endVisit(AST::IdentifierExpression *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::NullExpression *node) -{ - Q_UNUSED(node); - out << "null"; - return false; -} - -void PrettyPretty::endVisit(AST::NullExpression *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::TrueLiteral *node) -{ - Q_UNUSED(node); - out << "true"; - return false; -} - -void PrettyPretty::endVisit(AST::TrueLiteral *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::FalseLiteral *node) -{ - Q_UNUSED(node); - out << "false"; - return false; -} - -void PrettyPretty::endVisit(AST::FalseLiteral *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::StringLiteral *node) -{ - QString lit = QScriptEnginePrivate::toString(node->value); - lit.replace(QLatin1Char('\\'), QLatin1String("\\\\")); - out << '\"' << lit << '\"'; - return false; -} - -void PrettyPretty::endVisit(AST::StringLiteral *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::NumericLiteral *node) -{ - out << QScript::numberToString(node->value); - return true; -} - -void PrettyPretty::endVisit(AST::NumericLiteral *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::RegExpLiteral *node) -{ - out << '/' << QScriptEnginePrivate::toString(node->pattern) << '/'; - if (node->flags) - out << QScript::Ecma::RegExp::flagsToString(node->flags); - - return true; -} - -void PrettyPretty::endVisit(AST::RegExpLiteral *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::ArrayLiteral *node) -{ - out << '['; - accept(node->elements); - accept(node->elision); - out << ']'; - return false; -} - -void PrettyPretty::endVisit(AST::ArrayLiteral *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::ObjectLiteral *node) -{ - out << '{'; - if (node->properties) { - pushIndentLevel(); - AST::PropertyNameAndValueList *prop; - for (prop = node->properties; prop != 0; prop = prop->next) { - newlineAndIndent(); - accept(prop); - if (prop->next) - out << ','; - } - popIndentLevel(); - newlineAndIndent(); - } - out << '}'; - return false; -} - -void PrettyPretty::endVisit(AST::ObjectLiteral *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::ElementList *node) -{ - accept(node->elision); - accept(node->expression); - for (node = node->next; node != 0; node = node->next) { - out << ", "; - accept(node->elision); - accept(node->expression); - } - return false; -} - -void PrettyPretty::endVisit(AST::ElementList *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::Elision *node) -{ - out << ", "; - for (AST::Elision *eit = node->next; eit != 0; eit = eit->next) - out << ", "; - return false; -} - -void PrettyPretty::endVisit(AST::Elision *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::PropertyNameAndValueList *node) -{ - accept(node->name); - out << ": "; - accept(node->value); - return false; -} - -void PrettyPretty::endVisit(AST::PropertyNameAndValueList *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::IdentifierPropertyName *node) -{ - out << QScriptEnginePrivate::toString(node->id); - return false; -} - -void PrettyPretty::endVisit(AST::IdentifierPropertyName *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::StringLiteralPropertyName *node) -{ - QString lit = QScriptEnginePrivate::toString(node->id); - lit.replace(QLatin1String("\\"), QLatin1String("\\\\")); - out << lit; - return false; -} - -void PrettyPretty::endVisit(AST::StringLiteralPropertyName *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::NumericLiteralPropertyName *node) -{ - out << node->id; - return false; -} - -void PrettyPretty::endVisit(AST::NumericLiteralPropertyName *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::ArrayMemberExpression *node) -{ - accept(node->base); - out << '['; - accept(node->expression); - out << ']'; - return false; -} - -void PrettyPretty::endVisit(AST::ArrayMemberExpression *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::FieldMemberExpression *node) -{ - accept(node->base); - out << '.' << QScriptEnginePrivate::toString(node->name); - return false; -} - -void PrettyPretty::endVisit(AST::FieldMemberExpression *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::NewMemberExpression *node) -{ - out << "new "; - accept(node->base); - out << '('; - accept(node->arguments); - out << ')'; - return false; -} - -void PrettyPretty::endVisit(AST::NewMemberExpression *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::NewExpression *node) -{ - Q_UNUSED(node); - out << "new "; - return true; -} - -void PrettyPretty::endVisit(AST::NewExpression *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::CallExpression *node) -{ - accept(node->base); - out << '('; - accept(node->arguments); - out << ')'; - return false; -} - -void PrettyPretty::endVisit(AST::CallExpression *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::ArgumentList *node) -{ - accept(node->expression); - for (node = node->next; node != 0; node = node->next) { - out << ", "; - accept(node->expression); - } - return false; -} - -void PrettyPretty::endVisit(AST::ArgumentList *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::PostIncrementExpression *node) -{ - Q_UNUSED(node); - return true; -} - -void PrettyPretty::endVisit(AST::PostIncrementExpression *node) -{ - Q_UNUSED(node); - out << "++"; -} - -bool PrettyPretty::visit(AST::PostDecrementExpression *node) -{ - Q_UNUSED(node); - return true; -} - -void PrettyPretty::endVisit(AST::PostDecrementExpression *node) -{ - Q_UNUSED(node); - out << "--"; -} - -bool PrettyPretty::visit(AST::DeleteExpression *node) -{ - Q_UNUSED(node); - out << "delete "; - return true; -} - -void PrettyPretty::endVisit(AST::DeleteExpression *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::VoidExpression *node) -{ - Q_UNUSED(node); - out << "void "; - return true; -} - -void PrettyPretty::endVisit(AST::VoidExpression *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::TypeOfExpression *node) -{ - Q_UNUSED(node); - out << "typeof "; - return true; -} - -void PrettyPretty::endVisit(AST::TypeOfExpression *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::PreIncrementExpression *node) -{ - Q_UNUSED(node); - out << "++"; - return true; -} - -void PrettyPretty::endVisit(AST::PreIncrementExpression *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::PreDecrementExpression *node) -{ - Q_UNUSED(node); - out << "--"; - return true; -} - -void PrettyPretty::endVisit(AST::PreDecrementExpression *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::UnaryPlusExpression *node) -{ - out << '+'; - bool needParens = (node->expression->binaryExpressionCast() != 0); - if (needParens) - out << '('; - accept(node->expression); - if (needParens) - out << ')'; - return false; -} - -void PrettyPretty::endVisit(AST::UnaryPlusExpression *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::UnaryMinusExpression *node) -{ - out << '-'; - bool needParens = (node->expression->binaryExpressionCast() != 0); - if (needParens) - out << '('; - accept(node->expression); - if (needParens) - out << ')'; - return false; -} - -void PrettyPretty::endVisit(AST::UnaryMinusExpression *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::TildeExpression *node) -{ - out << '~'; - bool needParens = (node->expression->binaryExpressionCast() != 0); - if (needParens) - out << '('; - accept(node->expression); - if (needParens) - out << ')'; - return false; -} - -void PrettyPretty::endVisit(AST::TildeExpression *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::NotExpression *node) -{ - out << '!'; - bool needParens = (node->expression->binaryExpressionCast() != 0); - if (needParens) - out << '('; - accept(node->expression); - if (needParens) - out << ')'; - return false; -} - -void PrettyPretty::endVisit(AST::NotExpression *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::BinaryExpression *node) -{ - bool needParens = node->left->binaryExpressionCast() - && (compareOperatorPrecedence(node->left->binaryExpressionCast()->op, node->op) < 0); - if (needParens) - out << '('; - accept(node->left); - if (needParens) - out << ')'; - QString s; - switch (node->op) { - case QSOperator::Add: - s = QLatin1String("+"); break; - case QSOperator::And: - s = QLatin1String("&&"); break; - case QSOperator::InplaceAnd: - s = QLatin1String("&="); break; - case QSOperator::Assign: - s = QLatin1String("="); break; - case QSOperator::BitAnd: - s = QLatin1String("&"); break; - case QSOperator::BitOr: - s = QLatin1String("|"); break; - case QSOperator::BitXor: - s = QLatin1String("^"); break; - case QSOperator::InplaceSub: - s = QLatin1String("-="); break; - case QSOperator::Div: - s = QLatin1String("/"); break; - case QSOperator::InplaceDiv: - s = QLatin1String("/="); break; - case QSOperator::Equal: - s = QLatin1String("=="); break; - case QSOperator::Ge: - s = QLatin1String(">="); break; - case QSOperator::Gt: - s = QLatin1String(">"); break; - case QSOperator::In: - s = QLatin1String("in"); break; - case QSOperator::InplaceAdd: - s = QLatin1String("+="); break; - case QSOperator::InstanceOf: - s = QLatin1String("instanceof"); break; - case QSOperator::Le: - s = QLatin1String("<="); break; - case QSOperator::LShift: - s = QLatin1String("<<"); break; - case QSOperator::InplaceLeftShift: - s = QLatin1String("<<="); break; - case QSOperator::Lt: - s = QLatin1String("<"); break; - case QSOperator::Mod: - s = QLatin1String("%"); break; - case QSOperator::InplaceMod: - s = QLatin1String("%="); break; - case QSOperator::Mul: - s = QLatin1String("*"); break; - case QSOperator::InplaceMul: - s = QLatin1String("*="); break; - case QSOperator::NotEqual: - s = QLatin1String("!="); break; - case QSOperator::Or: - s = QLatin1String("||"); break; - case QSOperator::InplaceOr: - s = QLatin1String("|="); break; - case QSOperator::RShift: - s = QLatin1String(">>"); break; - case QSOperator::InplaceRightShift: - s = QLatin1String(">>="); break; - case QSOperator::StrictEqual: - s = QLatin1String("==="); break; - case QSOperator::StrictNotEqual: - s = QLatin1String("!=="); break; - case QSOperator::Sub: - s = QLatin1String("-"); break; - case QSOperator::URShift: - s = QLatin1String(">>>"); break; - case QSOperator::InplaceURightShift: - s = QLatin1String(">>>="); break; - case QSOperator::InplaceXor: - s = QLatin1String("^="); break; - default: - Q_ASSERT (0); - } - out << ' ' << s << ' '; - needParens = node->right->binaryExpressionCast() - && (compareOperatorPrecedence(node->right->binaryExpressionCast()->op, node->op) <= 0); - if (needParens) - out << '('; - accept(node->right); - if (needParens) - out << ')'; - return false; -} - -void PrettyPretty::endVisit(AST::BinaryExpression *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::ConditionalExpression *node) -{ - accept(node->expression); - out << " ? "; - accept(node->ok); - out << " : "; - accept(node->ko); - return false; -} - -void PrettyPretty::endVisit(AST::ConditionalExpression *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::Expression *node) -{ - accept(node->left); - out << ", "; - accept(node->right); - return false; -} - -void PrettyPretty::endVisit(AST::Expression *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::Block *node) -{ - Q_UNUSED(node); - return true; -} - -void PrettyPretty::endVisit(AST::Block *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::StatementList *node) -{ - accept(node->statement); - for (node = node->next; node != 0; node = node->next) { - newlineAndIndent(); - accept(node->statement); - } - return false; -} - -void PrettyPretty::endVisit(AST::StatementList *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::VariableDeclarationList *node) -{ - AST::VariableDeclarationList *it = node; - - do { - it->declaration->accept(this); - it = it->next; - if (it) - out << ", "; - } while (it); - - return false; -} - -void PrettyPretty::endVisit(AST::VariableDeclarationList *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::VariableStatement *node) -{ - out << "var "; - Q_UNUSED(node); - return true; -} - -void PrettyPretty::endVisit(AST::VariableStatement *node) -{ - Q_UNUSED(node); - out << ';'; -} - -bool PrettyPretty::visit(AST::VariableDeclaration *node) -{ - out << QScriptEnginePrivate::toString(node->name); - if (node->expression) { - out << " = "; - accept(node->expression); - } - return false; -} - -void PrettyPretty::endVisit(AST::VariableDeclaration *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::EmptyStatement *node) -{ - Q_UNUSED(node); - out << ';'; - return true; -} - -void PrettyPretty::endVisit(AST::EmptyStatement *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::ExpressionStatement *node) -{ - accept(node->expression); - out << ';'; - return false; -} - -void PrettyPretty::endVisit(AST::ExpressionStatement *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::IfStatement *node) -{ - out << "if ("; - accept(node->expression); - out << ") "; - acceptAsBlock(node->ok); - if (node->ko) { - out << " else "; - acceptAsBlock(node->ko); - } - return false; -} - -void PrettyPretty::endVisit(AST::IfStatement *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::DoWhileStatement *node) -{ - out << "do "; - acceptAsBlock(node->statement); - out << " while ("; - accept(node->expression); - out << ");"; - return false; -} - -void PrettyPretty::endVisit(AST::DoWhileStatement *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::WhileStatement *node) -{ - out << "while ("; - accept(node->expression); - out << ") "; - acceptAsBlock(node->statement); - return false; -} - -void PrettyPretty::endVisit(AST::WhileStatement *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::ForStatement *node) -{ - out << "for ("; - accept(node->initialiser); - out << "; "; - accept(node->condition); - out << "; "; - accept(node->expression); - out << ") "; - acceptAsBlock(node->statement); - return false; -} - -void PrettyPretty::endVisit(AST::ForStatement *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::LocalForStatement *node) -{ - out << "for (var "; - accept(node->declarations); - out << "; "; - accept(node->condition); - out << "; "; - accept(node->expression); - out << ") "; - acceptAsBlock(node->statement); - return false; -} - -void PrettyPretty::endVisit(AST::LocalForStatement *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::ForEachStatement *node) -{ - out << "for ("; - accept(node->initialiser); - out << " in "; - accept(node->expression); - out << ") "; - acceptAsBlock(node->statement); - return false; -} - -void PrettyPretty::endVisit(AST::ForEachStatement *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::LocalForEachStatement *node) -{ - out << "for (var "; - accept(node->declaration); - out << " in "; - accept(node->expression); - out << ") "; - acceptAsBlock(node->statement); - return false; -} - -void PrettyPretty::endVisit(AST::LocalForEachStatement *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::ContinueStatement *node) -{ - out << "continue"; - if (node->label) { - out << ' ' << QScriptEnginePrivate::toString(node->label); - } - out << ';'; - return false; -} - -void PrettyPretty::endVisit(AST::ContinueStatement *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::BreakStatement *node) -{ - out << "break"; - if (node->label) { - out << ' ' << QScriptEnginePrivate::toString(node->label); - } - out << ';'; - return false; -} - -void PrettyPretty::endVisit(AST::BreakStatement *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::ReturnStatement *node) -{ - out << "return"; - if (node->expression) { - out << ' '; - accept(node->expression); - } - out << ';'; - return false; -} - -void PrettyPretty::endVisit(AST::ReturnStatement *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::WithStatement *node) -{ - out << "with ("; - accept(node->expression); - out << ") "; - acceptAsBlock(node->statement); - return false; -} - -void PrettyPretty::endVisit(AST::WithStatement *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::SwitchStatement *node) -{ - out << "switch ("; - accept(node->expression); - out << ") "; - acceptAsBlock(node->block); - return false; -} - -void PrettyPretty::endVisit(AST::SwitchStatement *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::CaseBlock *node) -{ - accept(node->clauses); - if (node->defaultClause) { - newlineAndIndent(); - accept(node->defaultClause); - } - if (node->moreClauses) { - newlineAndIndent(); - accept(node->moreClauses); - } - return false; -} - -void PrettyPretty::endVisit(AST::CaseBlock *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::CaseClauses *node) -{ - accept(node->clause); - for (node = node->next; node != 0; node = node->next) { - newlineAndIndent(); - accept(node->clause); - } - return false; -} - -void PrettyPretty::endVisit(AST::CaseClauses *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::CaseClause *node) -{ - out << "case "; - accept(node->expression); - out << ':'; - if (node->statements) { - newlineAndIndent(); - accept(node->statements); - } - return false; -} - -void PrettyPretty::endVisit(AST::CaseClause *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::DefaultClause *node) -{ - Q_UNUSED(node); - out << "default:"; - newlineAndIndent(); - return true; -} - -void PrettyPretty::endVisit(AST::DefaultClause *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::LabelledStatement *node) -{ - out << QScriptEnginePrivate::toString(node->label) << ": "; - return true; -} - -void PrettyPretty::endVisit(AST::LabelledStatement *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::ThrowStatement *node) -{ - Q_UNUSED(node); - out << "throw "; - accept(node->expression); - out << ';'; - return false; -} - -void PrettyPretty::endVisit(AST::ThrowStatement *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::TryStatement *node) -{ - out << "try "; - acceptAsBlock(node->statement); - if (node->catchExpression) { - out << " catch (" << QScriptEnginePrivate::toString(node->catchExpression->name) << ") "; - acceptAsBlock(node->catchExpression->statement); - } - if (node->finallyExpression) { - out << " finally "; - acceptAsBlock(node->finallyExpression->statement); - } - return false; -} - -void PrettyPretty::endVisit(AST::TryStatement *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::Catch *node) -{ - Q_UNUSED(node); - return true; -} - -void PrettyPretty::endVisit(AST::Catch *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::Finally *node) -{ - Q_UNUSED(node); - out << "finally "; - return true; -} - -void PrettyPretty::endVisit(AST::Finally *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::FunctionDeclaration *node) -{ - out << "function"; - - if (node->name) - out << ' ' << QScriptEnginePrivate::toString(node->name); - - // the arguments - out << '('; - for (AST::FormalParameterList *it = node->formals; it; it = it->next) { - if (it->name) - out << QScriptEnginePrivate::toString(it->name); - - if (it->next) - out << ", "; - } - out << ')'; - - // the function body - out << " {"; - - if (node->body) { - pushIndentLevel(); - newlineAndIndent(); - accept(node->body); - popIndentLevel(); - newlineAndIndent(); - } - - out << '}'; - - return false; -} - -void PrettyPretty::endVisit(AST::FunctionDeclaration *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::FunctionExpression *node) -{ - out << "function"; - - if (node->name) - out << ' ' << QScriptEnginePrivate::toString(node->name); - - // the arguments - out << '('; - for (AST::FormalParameterList *it = node->formals; it; it = it->next) { - if (it->name) - out << QScriptEnginePrivate::toString(it->name); - - if (it->next) - out << ", "; - } - out << ')'; - - // the function body - out << " {"; - - if (node->body) { - pushIndentLevel(); - newlineAndIndent(); - accept(node->body); - popIndentLevel(); - newlineAndIndent(); - } - - out << '}'; - - return false; -} - -void PrettyPretty::endVisit(AST::FunctionExpression *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::FormalParameterList *node) -{ - Q_UNUSED(node); - return true; -} - -void PrettyPretty::endVisit(AST::FormalParameterList *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::FunctionBody *node) -{ - Q_UNUSED(node); - return true; -} - -void PrettyPretty::endVisit(AST::FunctionBody *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::Program *node) -{ - Q_UNUSED(node); - return true; -} - -void PrettyPretty::endVisit(AST::Program *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::SourceElements *node) -{ - Q_UNUSED(node); - accept(node->element); - for (node = node->next; node != 0; node = node->next) { - newlineAndIndent(); - accept(node->element); - } - return false; -} - -void PrettyPretty::endVisit(AST::SourceElements *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::FunctionSourceElement *node) -{ - Q_UNUSED(node); - return true; -} - -void PrettyPretty::endVisit(AST::FunctionSourceElement *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::StatementSourceElement *node) -{ - Q_UNUSED(node); - return true; -} - -void PrettyPretty::endVisit(AST::StatementSourceElement *node) -{ - Q_UNUSED(node); -} - -bool PrettyPretty::visit(AST::DebuggerStatement *node) -{ - Q_UNUSED(node); - out << "debugger"; - return true; -} - -void PrettyPretty::endVisit(AST::DebuggerStatement *node) -{ - Q_UNUSED(node); - out << ';'; -} - -bool PrettyPretty::preVisit(AST::Node *node) -{ - Q_UNUSED(node); - return true; -} - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptprettypretty_p.h b/src/script/qscriptprettypretty_p.h deleted file mode 100644 index 36568d1..0000000 --- a/src/script/qscriptprettypretty_p.h +++ /dev/null @@ -1,329 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTPRETTYPRETTY_P_H -#define QSCRIPTPRETTYPRETTY_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/qglobal.h> - -#include "qscriptastvisitor_p.h" - -QT_BEGIN_NAMESPACE - -class QTextStream; - -namespace QScript { - -class PrettyPretty: protected AST::Visitor -{ -public: - PrettyPretty(QTextStream &out); - virtual ~PrettyPretty(); - - QTextStream &operator () (AST::Node *node, int level = 0); - -protected: - void accept(AST::Node *node); - - virtual bool preVisit(AST::Node *node); - - virtual bool visit(AST::ThisExpression *node); - virtual void endVisit(AST::ThisExpression *node); - - virtual bool visit(AST::IdentifierExpression *node); - virtual void endVisit(AST::IdentifierExpression *node); - - virtual bool visit(AST::NullExpression *node); - virtual void endVisit(AST::NullExpression *node); - - virtual bool visit(AST::TrueLiteral *node); - virtual void endVisit(AST::TrueLiteral *node); - - virtual bool visit(AST::FalseLiteral *node); - virtual void endVisit(AST::FalseLiteral *node); - - virtual bool visit(AST::StringLiteral *node); - virtual void endVisit(AST::StringLiteral *node); - - virtual bool visit(AST::NumericLiteral *node); - virtual void endVisit(AST::NumericLiteral *node); - - virtual bool visit(AST::RegExpLiteral *node); - virtual void endVisit(AST::RegExpLiteral *node); - - virtual bool visit(AST::ArrayLiteral *node); - virtual void endVisit(AST::ArrayLiteral *node); - - virtual bool visit(AST::ObjectLiteral *node); - virtual void endVisit(AST::ObjectLiteral *node); - - virtual bool visit(AST::ElementList *node); - virtual void endVisit(AST::ElementList *node); - - virtual bool visit(AST::Elision *node); - virtual void endVisit(AST::Elision *node); - - virtual bool visit(AST::PropertyNameAndValueList *node); - virtual void endVisit(AST::PropertyNameAndValueList *node); - - virtual bool visit(AST::IdentifierPropertyName *node); - virtual void endVisit(AST::IdentifierPropertyName *node); - - virtual bool visit(AST::StringLiteralPropertyName *node); - virtual void endVisit(AST::StringLiteralPropertyName *node); - - virtual bool visit(AST::NumericLiteralPropertyName *node); - virtual void endVisit(AST::NumericLiteralPropertyName *node); - - virtual bool visit(AST::ArrayMemberExpression *node); - virtual void endVisit(AST::ArrayMemberExpression *node); - - virtual bool visit(AST::FieldMemberExpression *node); - virtual void endVisit(AST::FieldMemberExpression *node); - - virtual bool visit(AST::NewMemberExpression *node); - virtual void endVisit(AST::NewMemberExpression *node); - - virtual bool visit(AST::NewExpression *node); - virtual void endVisit(AST::NewExpression *node); - - virtual bool visit(AST::CallExpression *node); - virtual void endVisit(AST::CallExpression *node); - - virtual bool visit(AST::ArgumentList *node); - virtual void endVisit(AST::ArgumentList *node); - - virtual bool visit(AST::PostIncrementExpression *node); - virtual void endVisit(AST::PostIncrementExpression *node); - - virtual bool visit(AST::PostDecrementExpression *node); - virtual void endVisit(AST::PostDecrementExpression *node); - - virtual bool visit(AST::DeleteExpression *node); - virtual void endVisit(AST::DeleteExpression *node); - - virtual bool visit(AST::VoidExpression *node); - virtual void endVisit(AST::VoidExpression *node); - - virtual bool visit(AST::TypeOfExpression *node); - virtual void endVisit(AST::TypeOfExpression *node); - - virtual bool visit(AST::PreIncrementExpression *node); - virtual void endVisit(AST::PreIncrementExpression *node); - - virtual bool visit(AST::PreDecrementExpression *node); - virtual void endVisit(AST::PreDecrementExpression *node); - - virtual bool visit(AST::UnaryPlusExpression *node); - virtual void endVisit(AST::UnaryPlusExpression *node); - - virtual bool visit(AST::UnaryMinusExpression *node); - virtual void endVisit(AST::UnaryMinusExpression *node); - - virtual bool visit(AST::TildeExpression *node); - virtual void endVisit(AST::TildeExpression *node); - - virtual bool visit(AST::NotExpression *node); - virtual void endVisit(AST::NotExpression *node); - - virtual bool visit(AST::BinaryExpression *node); - virtual void endVisit(AST::BinaryExpression *node); - - virtual bool visit(AST::ConditionalExpression *node); - virtual void endVisit(AST::ConditionalExpression *node); - - virtual bool visit(AST::Expression *node); - virtual void endVisit(AST::Expression *node); - - virtual bool visit(AST::Block *node); - virtual void endVisit(AST::Block *node); - - virtual bool visit(AST::StatementList *node); - virtual void endVisit(AST::StatementList *node); - - virtual bool visit(AST::VariableStatement *node); - virtual void endVisit(AST::VariableStatement *node); - - virtual bool visit(AST::VariableDeclarationList *node); - virtual void endVisit(AST::VariableDeclarationList *node); - - virtual bool visit(AST::VariableDeclaration *node); - virtual void endVisit(AST::VariableDeclaration *node); - - virtual bool visit(AST::EmptyStatement *node); - virtual void endVisit(AST::EmptyStatement *node); - - virtual bool visit(AST::ExpressionStatement *node); - virtual void endVisit(AST::ExpressionStatement *node); - - virtual bool visit(AST::IfStatement *node); - virtual void endVisit(AST::IfStatement *node); - - virtual bool visit(AST::DoWhileStatement *node); - virtual void endVisit(AST::DoWhileStatement *node); - - virtual bool visit(AST::WhileStatement *node); - virtual void endVisit(AST::WhileStatement *node); - - virtual bool visit(AST::ForStatement *node); - virtual void endVisit(AST::ForStatement *node); - - virtual bool visit(AST::LocalForStatement *node); - virtual void endVisit(AST::LocalForStatement *node); - - virtual bool visit(AST::ForEachStatement *node); - virtual void endVisit(AST::ForEachStatement *node); - - virtual bool visit(AST::LocalForEachStatement *node); - virtual void endVisit(AST::LocalForEachStatement *node); - - virtual bool visit(AST::ContinueStatement *node); - virtual void endVisit(AST::ContinueStatement *node); - - virtual bool visit(AST::BreakStatement *node); - virtual void endVisit(AST::BreakStatement *node); - - virtual bool visit(AST::ReturnStatement *node); - virtual void endVisit(AST::ReturnStatement *node); - - virtual bool visit(AST::WithStatement *node); - virtual void endVisit(AST::WithStatement *node); - - virtual bool visit(AST::SwitchStatement *node); - virtual void endVisit(AST::SwitchStatement *node); - - virtual bool visit(AST::CaseBlock *node); - virtual void endVisit(AST::CaseBlock *node); - - virtual bool visit(AST::CaseClauses *node); - virtual void endVisit(AST::CaseClauses *node); - - virtual bool visit(AST::CaseClause *node); - virtual void endVisit(AST::CaseClause *node); - - virtual bool visit(AST::DefaultClause *node); - virtual void endVisit(AST::DefaultClause *node); - - virtual bool visit(AST::LabelledStatement *node); - virtual void endVisit(AST::LabelledStatement *node); - - virtual bool visit(AST::ThrowStatement *node); - virtual void endVisit(AST::ThrowStatement *node); - - virtual bool visit(AST::TryStatement *node); - virtual void endVisit(AST::TryStatement *node); - - virtual bool visit(AST::Catch *node); - virtual void endVisit(AST::Catch *node); - - virtual bool visit(AST::Finally *node); - virtual void endVisit(AST::Finally *node); - - virtual bool visit(AST::FunctionDeclaration *node); - virtual void endVisit(AST::FunctionDeclaration *node); - - virtual bool visit(AST::FunctionExpression *node); - virtual void endVisit(AST::FunctionExpression *node); - - virtual bool visit(AST::FormalParameterList *node); - virtual void endVisit(AST::FormalParameterList *node); - - virtual bool visit(AST::FunctionBody *node); - virtual void endVisit(AST::FunctionBody *node); - - virtual bool visit(AST::Program *node); - virtual void endVisit(AST::Program *node); - - virtual bool visit(AST::SourceElements *node); - virtual void endVisit(AST::SourceElements *node); - - virtual bool visit(AST::FunctionSourceElement *node); - virtual void endVisit(AST::FunctionSourceElement *node); - - virtual bool visit(AST::StatementSourceElement *node); - virtual void endVisit(AST::StatementSourceElement *node); - - virtual bool visit(AST::DebuggerStatement *node); - virtual void endVisit(AST::DebuggerStatement *node); - - int indentLevel(int level) - { - int was = m_indentLevel; - m_indentLevel = level; - return was; - } - - void pushIndentLevel() - { ++m_indentLevel; } - - void popIndentLevel() - { --m_indentLevel; } - - QTextStream &newlineAndIndent(); - - void acceptAsBlock(AST::Node *node); - - static int operatorPrecedenceLevel(int op); - static int compareOperatorPrecedence(int op1, int op2); - -private: - QTextStream &out; - int m_indentLevel; - - Q_DISABLE_COPY(PrettyPretty) -}; - -} // namespace QScript - -QT_END_NAMESPACE - -#endif diff --git a/src/script/qscriptsyntaxcheckresult_p.h b/src/script/qscriptsyntaxcheckresult_p.h deleted file mode 100644 index 3be82ef..0000000 --- a/src/script/qscriptsyntaxcheckresult_p.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTSYNTAXCHECKRESULT_P_H -#define QSCRIPTSYNTAXCHECKRESULT_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. -// - -#if defined(Q_OS_VXWORKS) && defined(m_type) -# undef m_type -#endif - -#ifndef QT_NO_SCRIPT - -#include <QtCore/qatomic.h> -#include <QtCore/qstring.h> - -QT_BEGIN_NAMESPACE - -class QScriptSyntaxCheckResultPrivate -{ -public: - QScriptSyntaxCheckResultPrivate() { ref = 0; } - ~QScriptSyntaxCheckResultPrivate() {} - - QScriptSyntaxCheckResult::State state; - int errorColumnNumber; - int errorLineNumber; - QString errorMessage; - QBasicAtomicInt ref; -}; - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT - -#endif diff --git a/src/script/qscriptvalue.cpp b/src/script/qscriptvalue.cpp deleted file mode 100644 index b70afe5..0000000 --- a/src/script/qscriptvalue.cpp +++ /dev/null @@ -1,1600 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qscriptvalue.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptvalue_p.h" -#include "qscriptengine_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" -#include "qscriptclass.h" -#include "qscriptclass_p.h" - -#include <QtCore/QDateTime> -#include <QtCore/QRegExp> - -QT_BEGIN_NAMESPACE - -/*! - \since 4.3 - \class QScriptValue - - \brief The QScriptValue class acts as a container for the Qt Script data types. - - \ingroup script - - - QScriptValue supports the types defined in the \l{ECMA-262} - standard: The primitive types, which are Undefined, Null, Boolean, - Number, and String; and the Object type. Additionally, Qt Script - has built-in support for QVariant, QObject and QMetaObject. - - For the object-based types (including Date and RegExp), use the - newT() functions in QScriptEngine (e.g. QScriptEngine::newObject()) - to create a QScriptValue of the desired type. For the primitive types, - use one of the QScriptValue constructor overloads. - - The methods named isT() (e.g. isBool(), isUndefined()) can be - used to test if a value is of a certain type. The methods named - toT() (e.g. toBool(), toString()) can be used to convert a - QScriptValue to another type. You can also use the generic - qscriptvalue_cast() function. - - Object values have zero or more properties which are themselves - QScriptValues. Use setProperty() to set a property of an object, and - call property() to retrieve the value of a property. - - \snippet doc/src/snippets/code/src_script_qscriptvalue.cpp 0 - - Each property can have a set of attributes; these are specified as - the third (optional) argument to setProperty(). The attributes of a - property can be queried by calling the propertyFlags() function. The - following code snippet creates a property that cannot be modified by - script code: - - \snippet doc/src/snippets/code/src_script_qscriptvalue.cpp 1 - - If you want to iterate over the properties of a script object, use - the QScriptValueIterator class. - - Object values have an internal \c{prototype} property, which can be - accessed with prototype() and setPrototype(). Properties added to a - prototype are shared by all objects having that prototype; this is - referred to as prototype-based inheritance. In practice, it means - that (by default) the property() function will automatically attempt - to look up look the property in the prototype() (and in the - prototype of the prototype(), and so on), if the object itself does - not have the requested property. Note that this prototype-based - lookup is not performed by setProperty(); setProperty() will always - create the property in the script object itself. For more - information, see the \l{QtScript} documentation. - - Function objects (objects for which isFunction() returns true) can - be invoked by calling call(). Constructor functions can be used to - construct new objects by calling construct(). - - Use equals(), strictlyEquals() and lessThan() to compare a QScriptValue - to another. - - Object values can have custom data associated with them; see the - setData() and data() functions. By default, this data is not - accessible to scripts; it can be used to store any data you want to - associate with the script object. Typically this is used by custom - class objects (see QScriptClass) to store a C++ type that contains - the "native" object data. - - Note that a QScriptValue for which isObject() is true only carries a - reference to an actual object; copying the QScriptValue will only - copy the object reference, not the object itself. If you want to - clone an object (i.e. copy an object's properties to another - object), you can do so with the help of a \c{for-in} statement in - script code, or QScriptValueIterator in C++. - - \sa QScriptEngine, QScriptValueIterator -*/ - -/*! - \enum QScriptValue::SpecialValue - - This enum is used to specify a single-valued type. - - \value UndefinedValue An undefined value. - - \value NullValue A null value. -*/ - -/*! - \enum QScriptValue::PropertyFlag - - This enum describes the attributes of a property. - - \value ReadOnly The property is read-only. Attempts by Qt Script code to write to the property will be ignored. - - \value Undeletable Attempts by Qt Script code to \c{delete} the property will be ignored. - - \value SkipInEnumeration The property is not to be enumerated by a \c{for-in} enumeration. - - \value PropertyGetter The property is defined by a function which will be called to get the property value. - - \value PropertySetter The property is defined by a function which will be called to set the property value. - - \value QObjectMember This flag is used to indicate that an existing property is a QObject member (a property or method). - - \value KeepExistingFlags This value is used to indicate to setProperty() that the property's flags should be left unchanged. If the property doesn't exist, the default flags (0) will be used. - - \value UserRange Flags in this range are not used by Qt Script, and can be used for custom purposes. -*/ - -/*! - \enum QScriptValue::ResolveFlag - - This enum specifies how to look up a property of an object. - - \value ResolveLocal Only check the object's own properties. - - \value ResolvePrototype Check the object's own properties first, then search the prototype chain. This is the default. - - \value ResolveScope Check the object's own properties first, then search the scope chain. - - \value ResolveFull Check the object's own properties first, then search the prototype chain, and finally search the scope chain. -*/ - -/*! - Constructs an invalid QScriptValue. -*/ -QScriptValue::QScriptValue() - : d_ptr(0) -{ -} - -/*! - Destroys this QScriptValue. -*/ -QScriptValue::~QScriptValue() -{ - if (d_ptr && !d_ptr->ref.deref()) { - if (engine()) { - QScriptEnginePrivate::get(engine())->unregisterValue(d_ptr); - } else { - delete d_ptr; - } - d_ptr = 0; - } -} - -/*! - Constructs a new QScriptValue that is a copy of \a other. - - Note that if \a other is an object (i.e., isObject() would return - true), then only a reference to the underlying object is copied into - the new script value (i.e., the object itself is not copied). -*/ -QScriptValue::QScriptValue(const QScriptValue &other) - : d_ptr(other.d_ptr) -{ - if (d_ptr) - d_ptr->ref.ref(); -} - -/*! - \obsolete - - Constructs a new QScriptValue with the special \a value and - registers it with the script \a engine. -*/ -QScriptValue::QScriptValue(QScriptEngine *engine, QScriptValue::SpecialValue value) -{ - if (engine) { - QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(engine); - d_ptr = eng_p->registerValue(QScriptValueImpl(value)); - d_ptr->ref.ref(); - } else { - d_ptr = 0; - } -} - -/*! - \obsolete - - \fn QScriptValue::QScriptValue(QScriptEngine *engine, bool value) - - Constructs a new QScriptValue with the boolean \a value and - registers it with the script \a engine. -*/ -QScriptValue::QScriptValue(QScriptEngine *engine, bool val) -{ - if (engine) { - QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(engine); - d_ptr = eng_p->registerValue(QScriptValueImpl(val)); - d_ptr->ref.ref(); - } else { - d_ptr = 0; - } -} - -/*! - \fn QScriptValue::QScriptValue(QScriptEngine *engine, int value) - \obsolete - - Constructs a new QScriptValue with the integer \a value and - registers it with the script \a engine. -*/ -QScriptValue::QScriptValue(QScriptEngine *engine, int val) -{ - if (engine) { - QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(engine); - d_ptr = eng_p->registerValue(QScriptValueImpl(val)); - d_ptr->ref.ref(); - } else { - d_ptr = 0; - } -} - -/*! - \fn QScriptValue::QScriptValue(QScriptEngine *engine, uint value) - \obsolete - - Constructs a new QScriptValue with the unsigned integer \a value and - registers it with the script \a engine. - */ -QScriptValue::QScriptValue(QScriptEngine *engine, uint val) -{ - if (engine) { - QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(engine); - d_ptr = eng_p->registerValue(QScriptValueImpl(val)); - d_ptr->ref.ref(); - } else { - d_ptr = 0; - } -} - -/*! - \fn QScriptValue::QScriptValue(QScriptEngine *engine, qsreal value) - \obsolete - - Constructs a new QScriptValue with the qsreal \a value and - registers it with the script \a engine. -*/ -QScriptValue::QScriptValue(QScriptEngine *engine, qsreal val) -{ - if (engine) { - QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(engine); - d_ptr = eng_p->registerValue(QScriptValueImpl(val)); - d_ptr->ref.ref(); - } else { - d_ptr = 0; - } -} - -/*! - \fn QScriptValue::QScriptValue(QScriptEngine *engine, const QString &value) - \obsolete - - Constructs a new QScriptValue with the string \a value and - registers it with the script \a engine. -*/ -QScriptValue::QScriptValue(QScriptEngine *engine, const QString &val) -{ - if (engine) { - QScriptValueImpl v; - QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(engine); - eng_p->newString(&v, val); - d_ptr = eng_p->registerValue(v); - d_ptr->ref.ref(); - } else { - d_ptr = 0; - } -} - -/*! - \fn QScriptValue::QScriptValue(QScriptEngine *engine, const char *value) - \obsolete - - Constructs a new QScriptValue with the string \a value and - registers it with the script \a engine. -*/ - -#ifndef QT_NO_CAST_FROM_ASCII -QScriptValue::QScriptValue(QScriptEngine *engine, const char *val) -{ - if (engine) { - QScriptValueImpl v; - QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(engine); - eng_p->newString(&v, QString::fromAscii(val)); - d_ptr = eng_p->registerValue(v); - d_ptr->ref.ref(); - } else { - d_ptr = 0; - } -} -#endif - -/*! - \since 4.5 - - Constructs a new QScriptValue with a special \a value. -*/ -QScriptValue::QScriptValue(SpecialValue value) - : d_ptr(new QScriptValuePrivate) -{ - d_ptr->value = QScriptValueImpl(value); - d_ptr->ref.ref(); -} - -/*! - \since 4.5 - - Constructs a new QScriptValue with a boolean \a value. -*/ -QScriptValue::QScriptValue(bool value) - : d_ptr(new QScriptValuePrivate) -{ - d_ptr->value = QScriptValueImpl(value); - d_ptr->ref.ref(); -} - -/*! - \since 4.5 - - Constructs a new QScriptValue with a number \a value. -*/ -QScriptValue::QScriptValue(int value) - : d_ptr(new QScriptValuePrivate) -{ - d_ptr->value = QScriptValueImpl(value); - d_ptr->ref.ref(); -} - -/*! - \since 4.5 - - Constructs a new QScriptValue with a number \a value. -*/ -QScriptValue::QScriptValue(uint value) - : d_ptr(new QScriptValuePrivate) -{ - d_ptr->value = QScriptValueImpl(value); - d_ptr->ref.ref(); -} - -/*! - \since 4.5 - - Constructs a new QScriptValue with a number \a value. -*/ -QScriptValue::QScriptValue(qsreal value) - : d_ptr(new QScriptValuePrivate) -{ - d_ptr->value = QScriptValueImpl(value); - d_ptr->ref.ref(); -} - -/*! - \since 4.5 - - Constructs a new QScriptValue with a string \a value. -*/ -QScriptValue::QScriptValue(const QString &value) - : d_ptr(new QScriptValuePrivate) -{ - d_ptr->value.m_type = QScript::LazyStringType; - d_ptr->value.m_lazy_string_value = new QString(value); - d_ptr->ref.ref(); -} - -/*! - \since 4.5 - - Constructs a new QScriptValue with a string \a value. -*/ -QScriptValue::QScriptValue(const QLatin1String &value) - : d_ptr(new QScriptValuePrivate) -{ - d_ptr->value.m_type = QScript::LazyStringType; - d_ptr->value.m_lazy_string_value = new QString(value); - d_ptr->ref.ref(); -} - -/*! - \since 4.5 - - Constructs a new QScriptValue with a string \a value. -*/ - -#ifndef QT_NO_CAST_FROM_ASCII -QScriptValue::QScriptValue(const char *value) - : d_ptr(new QScriptValuePrivate) -{ - d_ptr->value.m_type = QScript::LazyStringType; - d_ptr->value.m_lazy_string_value = new QString(QString::fromAscii(value)); - d_ptr->ref.ref(); -} -#endif - -/*! - Assigns the \a other value to this QScriptValue. - - Note that if \a other is an object (isObject() returns true), - only a reference to the underlying object will be assigned; - the object itself will not be copied. -*/ -QScriptValue &QScriptValue::operator=(const QScriptValue &other) -{ - if (d_ptr == other.d_ptr) - return *this; - if (d_ptr && !d_ptr->ref.deref()) { - if (engine()) { - QScriptEnginePrivate::get(engine())->unregisterValue(d_ptr); - } else { - delete d_ptr; - } - } - d_ptr = other.d_ptr; - if (d_ptr) - d_ptr->ref.ref(); - return *this; -} - -/*! - Returns true if this QScriptValue is an object of the Error class; - otherwise returns false. - - \sa QScriptContext::throwError() -*/ -bool QScriptValue::isError() const -{ - Q_D(const QScriptValue); - return d && d->value.isError(); -} - -/*! - Returns true if this QScriptValue is an object of the Array class; - otherwise returns false. - - \sa QScriptEngine::newArray() -*/ -bool QScriptValue::isArray() const -{ - Q_D(const QScriptValue); - return d && d->value.isArray(); -} - -/*! - Returns true if this QScriptValue is an object of the Date class; - otherwise returns false. - - \sa QScriptEngine::newDate() -*/ -bool QScriptValue::isDate() const -{ - Q_D(const QScriptValue); - return d && d->value.isDate(); -} - -/*! - Returns true if this QScriptValue is an object of the RegExp class; - otherwise returns false. - - \sa QScriptEngine::newRegExp() -*/ -bool QScriptValue::isRegExp() const -{ - Q_D(const QScriptValue); - return d && d->value.isRegExp(); -} - -/*! - If this QScriptValue is an object, returns the internal prototype - (\c{__proto__} property) of this object; otherwise returns an - invalid QScriptValue. - - \sa setPrototype(), isObject() -*/ -QScriptValue QScriptValue::prototype() const -{ - Q_D(const QScriptValue); - if (!d || !d->value.isObject()) - return QScriptValue(); - QScriptEnginePrivate *eng = QScriptEnginePrivate::get(engine()); - return eng->toPublic(d->value.prototype()); -} - -/*! - If this QScriptValue is an object, sets the internal prototype - (\c{__proto__} property) of this object to be \a prototype; - otherwise does nothing. - - The internal prototype should not be confused with the public - property with name "prototype"; the public prototype is usually - only set on functions that act as constructors. - - \sa prototype(), isObject() -*/ -void QScriptValue::setPrototype(const QScriptValue &prototype) -{ - Q_D(QScriptValue); - if (!d || !d->value.isObject()) - return; - if (prototype.isValid() && prototype.engine() - && (prototype.engine() != engine())) { - qWarning("QScriptValue::setPrototype() failed: " - "cannot set a prototype created in " - "a different engine"); - return; - } - QScriptValueImpl was = d->value.prototype(); - d->value.setPrototype(d->value.engine()->toImpl(prototype)); - if (d->value.detectedCycle()) { - qWarning("QScriptValue::setPrototype() failed: " - "cyclic prototype value"); - d->value.setPrototype(was); - } -} - -/*! - \since 4.6 - - Returns the scope object of this QScriptValue. This function is only - relevant for function objects. The scope determines how variables are - resolved when the function is invoked. -*/ -QScriptValue QScriptValue::scope() const -{ - Q_D(const QScriptValue); - if (!d || !d->value.isObject()) - return QScriptValue(); - QScriptEnginePrivate *eng = QScriptEnginePrivate::get(engine()); - return eng->toPublic(d->value.scope()); -} - -/*! - \since 4.6 - - Sets the \a scope object of this QScriptValue. This function is only - relevant for function objects. Changing the scope is useful when creating - closures; see \l{Nested Functions and the Scope Chain}. -*/ -void QScriptValue::setScope(const QScriptValue &scope) -{ - Q_D(QScriptValue); - if (!d || !d->value.isObject()) - return; - if (scope.isValid() && scope.engine() - && (scope.engine() != engine())) { - qWarning("QScriptValue::setScope() failed: " - "cannot set a scope object created in " - "a different engine"); - return; - } - d->value.setScope(d->value.engine()->toImpl(scope)); -} - -/*! - Returns true if this QScriptValue is an instance of - \a other; otherwise returns false. - - This QScriptValue is considered to be an instance of \a other if - \a other is a function and the value of the \c{prototype} - property of \a other is in the prototype chain of this - QScriptValue. -*/ -bool QScriptValue::instanceOf(const QScriptValue &other) const -{ - Q_D(const QScriptValue); - if (!isObject() || !other.isObject()) - return false; - if (other.engine() != engine()) { - qWarning("QScriptValue::instanceof: " - "cannot perform operation on a value created in " - "a different engine"); - return false; - } - return d->value.engine()->toImpl(*this) - .instanceOf(d->value.engine()->toImpl(other)); -} - -/*! - Returns true if this QScriptValue is less than \a other, otherwise - returns false. The comparison follows the behavior described in - \l{ECMA-262} section 11.8.5, "The Abstract Relational Comparison - Algorithm". - - Note that if this QScriptValue or the \a other value are objects, - calling this function has side effects on the script engine, since - the engine will call the object's valueOf() function (and possibly - toString()) in an attempt to convert the object to a primitive value - (possibly resulting in an uncaught script exception). - - \sa equals() -*/ -bool QScriptValue::lessThan(const QScriptValue &other) const -{ - if (!isValid() || !other.isValid()) - return false; - if (other.engine() && engine() && (other.engine() != engine())) { - qWarning("QScriptValue::lessThan: " - "cannot compare to a value created in " - "a different engine"); - return false; - } - return QScriptEnginePrivate::lessThan(QScriptValuePrivate::valueOf(*this), - QScriptValuePrivate::valueOf(other)); -} - -/*! - Returns true if this QScriptValue is equal to \a other, otherwise - returns false. The comparison follows the behavior described in - \l{ECMA-262} section 11.9.3, "The Abstract Equality Comparison - Algorithm". - - This function can return true even if the type of this QScriptValue - is different from the type of the \a other value; i.e. the - comparison is not strict. For example, comparing the number 9 to - the string "9" returns true; comparing an undefined value to a null - value returns true; comparing a \c{Number} object whose primitive - value is 6 to a \c{String} object whose primitive value is "6" - returns true; and comparing the number 1 to the boolean value - \c{true} returns true. If you want to perform a comparison - without such implicit value conversion, use strictlyEquals(). - - Note that if this QScriptValue or the \a other value are objects, - calling this function has side effects on the script engine, since - the engine will call the object's valueOf() function (and possibly - toString()) in an attempt to convert the object to a primitive value - (possibly resulting in an uncaught script exception). - - \sa strictlyEquals(), lessThan() -*/ -bool QScriptValue::equals(const QScriptValue &other) const -{ - if (!isValid() || !other.isValid()) - return isValid() == other.isValid(); - if (other.engine() && engine() && (other.engine() != engine())) { - qWarning("QScriptValue::equals: " - "cannot compare to a value created in " - "a different engine"); - return false; - } - return QScriptEnginePrivate::equals(QScriptValuePrivate::valueOf(*this), - QScriptValuePrivate::valueOf(other)); -} - -/*! - Returns true if this QScriptValue is equal to \a other using strict - comparison (no conversion), otherwise returns false. The comparison - follows the behavior described in \l{ECMA-262} section 11.9.6, "The - Strict Equality Comparison Algorithm". - - If the type of this QScriptValue is different from the type of the - \a other value, this function returns false. If the types are equal, - the result depends on the type, as shown in the following table: - - \table - \header \o Type \o Result - \row \o Undefined \o true - \row \o Null \o true - \row \o Boolean \o true if both values are true, false otherwise - \row \o Number \o false if either value is NaN (Not-a-Number); true if values are equal, false otherwise - \row \o String \o true if both values are exactly the same sequence of characters, false otherwise - \row \o Object \o true if both values refer to the same object, false otherwise - \endtable - - \sa equals() -*/ -bool QScriptValue::strictlyEquals(const QScriptValue &other) const -{ - if (!isValid() || !other.isValid()) - return isValid() == other.isValid(); - if (other.engine() && engine() && (other.engine() != engine())) { - qWarning("QScriptValue::strictlyEquals: " - "cannot compare to a value created in " - "a different engine"); - return false; - } - return QScriptEnginePrivate::strictlyEquals(QScriptValuePrivate::valueOf(*this), - QScriptValuePrivate::valueOf(other)); -} - -/*! - Returns the string value of this QScriptValue, as defined in - \l{ECMA-262} section 9.8, "ToString". - - Note that if this QScriptValue is an object, calling this function - has side effects on the script engine, since the engine will call - the object's toString() function (and possibly valueOf()) in an - attempt to convert the object to a primitive value (possibly - resulting in an uncaught script exception). - - \sa isString() -*/ -QString QScriptValue::toString() const -{ - Q_D(const QScriptValue); - if (!d) - return QString(); - return d->value.toString(); -} - -/*! - Returns the number value of this QScriptValue, as defined in - \l{ECMA-262} section 9.3, "ToNumber". - - Note that if this QScriptValue is an object, calling this function - has side effects on the script engine, since the engine will call - the object's valueOf() function (and possibly toString()) in an - attempt to convert the object to a primitive value (possibly - resulting in an uncaught script exception). - - \sa isNumber(), toInteger(), toInt32(), toUInt32(), toUInt16() -*/ -qsreal QScriptValue::toNumber() const -{ - Q_D(const QScriptValue); - if (!d) - return 0; - return d->value.toNumber(); -} - -/*! - \obsolete - - Use toBool() instead. -*/ -bool QScriptValue::toBoolean() const -{ - Q_D(const QScriptValue); - if (!d) - return false; - return d->value.toBoolean(); -} - -/*! - \since 4.5 - - Returns the boolean value of this QScriptValue, using the conversion - rules described in \l{ECMA-262} section 9.2, "ToBoolean". - - Note that if this QScriptValue is an object, calling this function - has side effects on the script engine, since the engine will call - the object's valueOf() function (and possibly toString()) in an - attempt to convert the object to a primitive value (possibly - resulting in an uncaught script exception). - - \sa isBool() -*/ -bool QScriptValue::toBool() const -{ - Q_D(const QScriptValue); - if (!d) - return false; - return d->value.toBoolean(); -} - -/*! - Returns the signed 32-bit integer value of this QScriptValue, using - the conversion rules described in \l{ECMA-262} section 9.5, "ToInt32". - - Note that if this QScriptValue is an object, calling this function - has side effects on the script engine, since the engine will call - the object's valueOf() function (and possibly toString()) in an - attempt to convert the object to a primitive value (possibly - resulting in an uncaught script exception). - - \sa toNumber(), toUInt32() -*/ -qint32 QScriptValue::toInt32() const -{ - Q_D(const QScriptValue); - if (!d) - return 0; - return d->value.toInt32(); -} - -/*! - Returns the unsigned 32-bit integer value of this QScriptValue, using - the conversion rules described in \l{ECMA-262} section 9.6, "ToUint32". - - Note that if this QScriptValue is an object, calling this function - has side effects on the script engine, since the engine will call - the object's valueOf() function (and possibly toString()) in an - attempt to convert the object to a primitive value (possibly - resulting in an uncaught script exception). - - \sa toNumber(), toInt32() -*/ -quint32 QScriptValue::toUInt32() const -{ - Q_D(const QScriptValue); - if (!d) - return 0; - return d->value.toUInt32(); -} - -/*! - Returns the unsigned 16-bit integer value of this QScriptValue, using - the conversion rules described in \l{ECMA-262} section 9.7, "ToUint16". - - Note that if this QScriptValue is an object, calling this function - has side effects on the script engine, since the engine will call - the object's valueOf() function (and possibly toString()) in an - attempt to convert the object to a primitive value (possibly - resulting in an uncaught script exception). - - \sa toNumber() -*/ -quint16 QScriptValue::toUInt16() const -{ - Q_D(const QScriptValue); - if (!d) - return 0; - return d->value.toUInt16(); -} - -/*! - Returns the integer value of this QScriptValue, using the conversion - rules described in \l{ECMA-262} section 9.4, "ToInteger". - - Note that if this QScriptValue is an object, calling this function - has side effects on the script engine, since the engine will call - the object's valueOf() function (and possibly toString()) in an - attempt to convert the object to a primitive value (possibly - resulting in an uncaught script exception). - - \sa toNumber() -*/ -qsreal QScriptValue::toInteger() const -{ - Q_D(const QScriptValue); - if (!d) - return 0; - return d->value.toInteger(); -} - -/*! - Returns the QVariant value of this QScriptValue, if it can be - converted to a QVariant; otherwise returns an invalid QVariant. - The conversion is performed according to the following table: - - \table - \header \o Input Type \o Result - \row \o Undefined \o An invalid QVariant. - \row \o Null \o An invalid QVariant. - \row \o Boolean \o A QVariant containing the value of the boolean. - \row \o Number \o A QVariant containing the value of the number. - \row \o String \o A QVariant containing the value of the string. - \row \o QVariant Object \o The result is the QVariant value of the object (no conversion). - \row \o QObject Object \o A QVariant containing a pointer to the QObject. - \row \o Date Object \o A QVariant containing the date value (toDateTime()). - \row \o RegExp Object \o A QVariant containing the regular expression value (toRegExp()). - \row \o Array Object \o The array is converted to a QVariantList. - \row \o Object \o If the value is primitive, then the result is converted to a QVariant according to the above rules; otherwise, an invalid QVariant is returned. - \endtable - - \sa isVariant() -*/ -QVariant QScriptValue::toVariant() const -{ - Q_D(const QScriptValue); - if (!d) - return QVariant(); - return d->value.toVariant(); -} - -/*! - \obsolete - - This function is obsolete; use QScriptEngine::toObject() instead. -*/ -QScriptValue QScriptValue::toObject() const -{ - Q_D(const QScriptValue); - if (!d) - return QScriptValue(); - QScriptEnginePrivate *eng = QScriptEnginePrivate::get(engine()); - if (!eng) - return QScriptValue(); - return eng->toPublic(eng->toObject(d->value)); -} - -/*! - Returns a QDateTime representation of this value, in local time. - If this QScriptValue is not a date, or the value of the date is NaN - (Not-a-Number), an invalid QDateTime is returned. - - \sa isDate() -*/ -QDateTime QScriptValue::toDateTime() const -{ - Q_D(const QScriptValue); - if (!d) - return QDateTime(); - return d->value.toDateTime(); -} - -#ifndef QT_NO_REGEXP -/*! - Returns the QRegExp representation of this value. - If this QScriptValue is not a regular expression, an empty - QRegExp is returned. - - \sa isRegExp() -*/ -QRegExp QScriptValue::toRegExp() const -{ - Q_D(const QScriptValue); - if (!d) - return QRegExp(); - return d->value.toRegExp(); -} -#endif // QT_NO_REGEXP - -/*! - If this QScriptValue is a QObject, returns the QObject pointer - that the QScriptValue represents; otherwise, returns 0. - - If the QObject that this QScriptValue wraps has been deleted, - this function returns 0 (i.e. it is possible for toQObject() - to return 0 even when isQObject() returns true). - - \sa isQObject() -*/ -QObject *QScriptValue::toQObject() const -{ - Q_D(const QScriptValue); - if (!d) - return 0; - return d->value.toQObject(); -} - -/*! - If this QScriptValue is a QMetaObject, returns the QMetaObject pointer - that the QScriptValue represents; otherwise, returns 0. - - \sa isQMetaObject() -*/ -const QMetaObject *QScriptValue::toQMetaObject() const -{ - Q_D(const QScriptValue); - if (!d) - return 0; - return d->value.toQMetaObject(); -} - -/*! - Sets the value of this QScriptValue's property with the given \a name to - the given \a value. - - If this QScriptValue is not an object, this function does nothing. - - If this QScriptValue does not already have a property with name \a name, - a new property is created; the given \a flags then specify how this - property may be accessed by script code. - - If \a value is invalid, the property is removed. - - If the property is implemented using a setter function (i.e. has the - PropertySetter flag set), calling setProperty() has side-effects on - the script engine, since the setter function will be called with the - given \a value as argument (possibly resulting in an uncaught script - exception). - - Note that you cannot specify custom getter or setter functions for - built-in properties, such as the \c{length} property of Array objects - or meta properties of QObject objects. - - \sa property() -*/ -void QScriptValue::setProperty(const QString &name, const QScriptValue &value, - const PropertyFlags &flags) -{ - Q_D(QScriptValue); - if (!d || !d->value.isObject()) - return; - if (value.engine() && (value.engine() != engine())) { - qWarning("QScriptValue::setProperty(%s) failed: " - "cannot set value created in a different engine", - qPrintable(name)); - return; - } - d->value.setProperty(name, d->value.engine()->toImpl(value), flags); -} - -/*! - Returns the value of this QScriptValue's property with the given \a name, - using the given \a mode to resolve the property. - - If no such property exists, an invalid QScriptValue is returned. - - If the property is implemented using a getter function (i.e. has the - PropertyGetter flag set), calling property() has side-effects on the - script engine, since the getter function will be called (possibly - resulting in an uncaught script exception). If an exception - occurred, property() returns the value that was thrown (typically - an \c{Error} object). - - \sa setProperty(), propertyFlags(), QScriptValueIterator -*/ -QScriptValue QScriptValue::property(const QString &name, - const ResolveFlags &mode) const -{ - Q_D(const QScriptValue); - if (!d || !d->value.isObject()) - return QScriptValue(); - QScriptEnginePrivate *eng = QScriptEnginePrivate::get(engine()); - return eng->toPublic(d->value.property(name, mode)); -} - -/*! - \overload - - Returns the property at the given \a arrayIndex, using the given \a - mode to resolve the property. - - This function is provided for convenience and performance when - working with array objects. - - If this QScriptValue is not an Array object, this function behaves - as if property() was called with the string representation of \a - arrayIndex. -*/ -QScriptValue QScriptValue::property(quint32 arrayIndex, - const ResolveFlags &mode) const -{ - Q_D(const QScriptValue); - if (!d || !d->value.isObject()) - return QScriptValue(); - QScriptEnginePrivate *eng = QScriptEnginePrivate::get(engine()); - return eng->toPublic(d->value.property(arrayIndex, mode)); -} - -/*! - \overload - - Sets the property at the given \a arrayIndex to the given \a value. - - This function is provided for convenience and performance when - working with array objects. - - If this QScriptValue is not an Array object, this function behaves - as if setProperty() was called with the string representation of \a - arrayIndex. -*/ -void QScriptValue::setProperty(quint32 arrayIndex, const QScriptValue &value, - const PropertyFlags &flags) -{ - Q_D(QScriptValue); - if (!d || !d->value.isObject()) - return; - if (value.engine() && (value.engine() != engine())) { - qWarning("QScriptValue::setProperty() failed: " - "cannot set value created in a different engine"); - return; - } - d->value.setProperty(arrayIndex, d->value.engine()->toImpl(value), flags); -} - -/*! - \since 4.4 - - Returns the value of this QScriptValue's property with the given \a name, - using the given \a mode to resolve the property. - - This overload of property() is useful when you need to look up the - same property repeatedly, since the lookup can be performed faster - when the name is represented as an interned string. - - \sa QScriptEngine::toStringHandle(), setProperty() -*/ -QScriptValue QScriptValue::property(const QScriptString &name, - const ResolveFlags &mode) const -{ - Q_D(const QScriptValue); - if (!d || !d->value.isObject()) - return QScriptValue(); - if (!name.isValid()) - return QScriptValue(); - QScriptStringPrivate *s = QScriptStringPrivate::get(name); - QScriptEnginePrivate *eng = QScriptEnginePrivate::get(engine()); - return eng->toPublic(d->value.property(s->nameId, mode)); -} - -/*! - \since 4.4 - - Sets the value of this QScriptValue's property with the given \a - name to the given \a value. The given \a flags specify how this - property may be accessed by script code. - - This overload of setProperty() is useful when you need to set the - same property repeatedly, since the operation can be performed - faster when the name is represented as an interned string. - - \sa QScriptEngine::toStringHandle() -*/ -void QScriptValue::setProperty(const QScriptString &name, - const QScriptValue &value, - const PropertyFlags &flags) -{ - Q_D(QScriptValue); - if (!d || !d->value.isObject() || !name.isValid()) - return; - if (value.engine() && (value.engine() != engine())) { - qWarning("QScriptValue::setProperty() failed: " - "cannot set value created in a different engine"); - return; - } - QScriptStringPrivate *s = QScriptStringPrivate::get(name); - d->value.setProperty(s->nameId, d->value.engine()->toImpl(value), flags); -} - -/*! - Returns the flags of the property with the given \a name, using the - given \a mode to resolve the property. - - \sa property() -*/ -QScriptValue::PropertyFlags QScriptValue::propertyFlags(const QString &name, - const ResolveFlags &mode) const -{ - Q_D(const QScriptValue); - if (!d) - return 0; - return d->value.propertyFlags(name, mode); -} - -/*! - \since 4.4 - - Returns the flags of the property with the given \a name, using the - given \a mode to resolve the property. - - \sa property() -*/ -QScriptValue::PropertyFlags QScriptValue::propertyFlags(const QScriptString &name, - const ResolveFlags &mode) const -{ - Q_D(const QScriptValue); - if (!d) - return 0; - if (!name.isValid()) - return 0; - QScriptStringPrivate *s = QScriptStringPrivate::get(name); - return d->value.propertyFlags(s->nameId, mode); -} - -/*! - Calls this QScriptValue as a function, using \a thisObject as - the `this' object in the function call, and passing \a args - as arguments to the function. Returns the value returned from - the function. - - If this QScriptValue is not a function, call() does nothing - and returns an invalid QScriptValue. - - Note that if \a thisObject is not an object, the global object - (see \l{QScriptEngine::globalObject()}) will be used as the - `this' object. - - Calling call() can cause an exception to occur in the script engine; - in that case, call() returns the value that was thrown (typically an - \c{Error} object). You can call - QScriptEngine::hasUncaughtException() to determine if an exception - occurred. - - \snippet doc/src/snippets/code/src_script_qscriptvalue.cpp 2 - - \sa construct() -*/ -QScriptValue QScriptValue::call(const QScriptValue &thisObject, - const QScriptValueList &args) -{ - Q_D(QScriptValue); - if (!d || !d->value.isObject()) - return QScriptValue(); - if (isFunction() && thisObject.isValid() && thisObject.engine() && - engine() && (thisObject.engine() != engine())) { - qWarning("QScriptValue::call() failed: " - "cannot call function with thisObject created in " - "a different engine"); - return QScriptValue(); - } - QScriptEnginePrivate *eng = QScriptEnginePrivate::get(engine()); - return eng->toPublic(d->value.call(eng->toImpl(thisObject), - eng->toImplList(args))); -} - -/*! - Calls this QScriptValue as a function, using \a thisObject as - the `this' object in the function call, and passing \a arguments - as arguments to the function. Returns the value returned from - the function. - - If this QScriptValue is not a function, call() does nothing - and returns an invalid QScriptValue. - - \a arguments can be an arguments object, an array, null or - undefined; any other type will cause a TypeError to be thrown. - - Note that if \a thisObject is not an object, the global object - (see \l{QScriptEngine::globalObject()}) will be used as the - `this' object. - - One common usage of this function is to forward native function - calls to another function: - - \snippet doc/src/snippets/code/src_script_qscriptvalue.cpp 3 - - \sa construct(), QScriptContext::argumentsObject() -*/ -QScriptValue QScriptValue::call(const QScriptValue &thisObject, - const QScriptValue &arguments) -{ - Q_D(QScriptValue); - if (!d || !d->value.isObject()) - return QScriptValue(); - if (isFunction() && thisObject.isValid() && thisObject.engine() - && (thisObject.engine() != engine())) { - qWarning("QScriptValue::call() failed: " - "cannot call function with thisObject created in " - "a different engine"); - return QScriptValue(); - } - QScriptEnginePrivate *eng = QScriptEnginePrivate::get(engine()); - return eng->toPublic(d->value.call(eng->toImpl(thisObject), - eng->toImpl(arguments))); -} - -/*! - Creates a new \c{Object} and calls this QScriptValue as a - constructor, using the created object as the `this' object and - passing \a args as arguments. If the return value from the - constructor call is an object, then that object is returned; - otherwise the default constructed object is returned. - - If this QScriptValue is not a function, construct() does nothing - and returns an invalid QScriptValue. - - Calling construct() can cause an exception to occur in the script - engine; in that case, construct() returns the value that was thrown - (typically an \c{Error} object). You can call - QScriptEngine::hasUncaughtException() to determine if an exception - occurred. - - \sa call(), QScriptEngine::newObject() -*/ -QScriptValue QScriptValue::construct(const QScriptValueList &args) -{ - Q_D(QScriptValue); - if (!d || !d->value.isObject()) - return QScriptValue(); - QScriptEnginePrivate *eng = QScriptEnginePrivate::get(engine()); - return eng->toPublic(d->value.construct(eng->toImplList(args))); -} - -/*! - Creates a new \c{Object} and calls this QScriptValue as a - constructor, using the created object as the `this' object and - passing \a arguments as arguments. If the return value from the - constructor call is an object, then that object is returned; - otherwise the default constructed object is returned. - - If this QScriptValue is not a function, construct() does nothing - and returns an invalid QScriptValue. - - \a arguments can be an arguments object, an array, null or - undefined. Any other type will cause a TypeError to be thrown. - - \sa call(), QScriptEngine::newObject(), QScriptContext::argumentsObject() -*/ -QScriptValue QScriptValue::construct(const QScriptValue &arguments) -{ - Q_D(QScriptValue); - if (!d || !d->value.isObject()) - return QScriptValue(); - QScriptEnginePrivate *eng = QScriptEnginePrivate::get(engine()); - return eng->toPublic(d->value.construct(eng->toImpl(arguments))); -} - -/*! - Returns the QScriptEngine that created this QScriptValue, - or 0 if this QScriptValue is invalid or the value is not - associated with a particular engine. -*/ -QScriptEngine *QScriptValue::engine() const -{ - Q_D(const QScriptValue); - if (!d) - return 0; - return d->engine; -} - -/*! - \obsolete - - Use isBool() instead. -*/ -bool QScriptValue::isBoolean() const -{ - Q_D(const QScriptValue); - return d && d->value.isBoolean(); -} - -/*! - \since 4.5 - - Returns true if this QScriptValue is of the primitive type Boolean; - otherwise returns false. - - \sa toBool() -*/ -bool QScriptValue::isBool() const -{ - Q_D(const QScriptValue); - return d && d->value.isBoolean(); -} - -/*! - Returns true if this QScriptValue is of the primitive type Number; - otherwise returns false. - - \sa toNumber() -*/ -bool QScriptValue::isNumber() const -{ - Q_D(const QScriptValue); - return d && d->value.isNumber(); -} - -/*! - Returns true if this QScriptValue is of the primitive type String; - otherwise returns false. - - \sa toString() -*/ -bool QScriptValue::isString() const -{ - Q_D(const QScriptValue); - return d && d->value.isString(); -} - -/*! - Returns true if this QScriptValue is a function; otherwise returns - false. - - \sa call() -*/ -bool QScriptValue::isFunction() const -{ - Q_D(const QScriptValue); - return d && d->value.isFunction(); -} - -/*! - Returns true if this QScriptValue is of the primitive type Null; - otherwise returns false. - - \sa QScriptEngine::nullValue() -*/ -bool QScriptValue::isNull() const -{ - Q_D(const QScriptValue); - return d && d->value.isNull(); -} - -/*! - Returns true if this QScriptValue is of the primitive type Undefined; - otherwise returns false. - - \sa QScriptEngine::undefinedValue() -*/ -bool QScriptValue::isUndefined() const -{ - Q_D(const QScriptValue); - return d && d->value.isUndefined(); -} - -/*! - Returns true if this QScriptValue is of the Object type; otherwise - returns false. - - Note that function values, variant values, and QObject values are - objects, so this function returns true for such values. - - \sa QScriptEngine::toObject(), QScriptEngine::newObject() -*/ -bool QScriptValue::isObject() const -{ - Q_D(const QScriptValue); - return d && d->value.isObject(); -} - -/*! - Returns true if this QScriptValue is a variant value; - otherwise returns false. - - \sa toVariant(), QScriptEngine::newVariant() -*/ -bool QScriptValue::isVariant() const -{ - Q_D(const QScriptValue); - return d && d->value.isVariant(); -} - -/*! - Returns true if this QScriptValue is a QObject; otherwise returns - false. - - Note: This function returns true even if the QObject that this - QScriptValue wraps has been deleted. - - \sa toQObject(), QScriptEngine::newQObject() -*/ -bool QScriptValue::isQObject() const -{ - Q_D(const QScriptValue); - return d && d->value.isQObject(); -} - -/*! - Returns true if this QScriptValue is a QMetaObject; otherwise returns - false. - - \sa toQMetaObject(), QScriptEngine::newQMetaObject() -*/ -bool QScriptValue::isQMetaObject() const -{ - Q_D(const QScriptValue); - return d && d->value.isQMetaObject(); -} - -/*! - Returns true if this QScriptValue is valid; otherwise returns - false. -*/ -bool QScriptValue::isValid() const -{ - Q_D(const QScriptValue); - return d && d->value.isValid(); -} - -/*! - \since 4.4 - - Returns the internal data of this QScriptValue object. QtScript uses - this property to store the primitive value of Date, String, Number - and Boolean objects. For other types of object, custom data may be - stored using setData(). -*/ -QScriptValue QScriptValue::data() const -{ - Q_D(const QScriptValue); - if (!d || !d->value.isObject()) - return QScriptValue(); - QScriptEnginePrivate *eng = QScriptEnginePrivate::get(engine()); - return eng->toPublic(d->value.internalValue()); -} - -/*! - \since 4.4 - - Sets the internal \a data of this QScriptValue object. You can use - this function to set object-specific data that won't be directly - accessible to scripts, but may be retrieved in C++ using the data() - function. -*/ -void QScriptValue::setData(const QScriptValue &data) -{ - Q_D(QScriptValue); - if (!d || !d->value.isObject()) - return; - QScriptEnginePrivate *eng = QScriptEnginePrivate::get(engine()); - d->value.setInternalValue(eng->toImpl(data)); -} - -/*! - \since 4.4 - - Returns the custom script class that this script object is an - instance of, or 0 if the object is not of a custom class. - - \sa setScriptClass() -*/ -QScriptClass *QScriptValue::scriptClass() const -{ - Q_D(const QScriptValue); - if (!d || !d->value.isObject()) - return 0; - QScriptClassInfo *info = d->value.classInfo(); - if ((info->type() & QScriptClassInfo::TypeMask) < QScriptClassInfo::CustomType) - return 0; - return QScriptClassPrivate::classFromInfo(info); -} - -/*! - \since 4.4 - - Sets the custom script class of this script object to \a scriptClass. - This can be used to "promote" a plain script object (e.g. created - by the "new" operator in a script, or by QScriptEngine::newObject() in C++) - to an object of a custom type. - - If \a scriptClass is 0, the object will be demoted to a plain - script object. - - \sa scriptClass(), setData() -*/ -void QScriptValue::setScriptClass(QScriptClass *scriptClass) -{ - Q_D(QScriptValue); - if (!d || !d->value.isObject()) - return; - if (!scriptClass) { - QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(engine()); - d->value.setClassInfo(eng_p->m_class_object); - } else { - QScriptClassPrivate *cls_p = QScriptClassPrivate::get(scriptClass); - d->value.setClassInfo(cls_p->classInfo()); - } -} - -/*! - \internal - - Returns the ID of this object, or -1 if this QScriptValue is not an - object. - - \sa QScriptEngine::objectById() -*/ -qint64 QScriptValue::objectId() const -{ - Q_D(const QScriptValue); - if (!d || !d->value.isObject()) - return -1; - return d->value.m_object_value->m_id; -} - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptvalue_p.h b/src/script/qscriptvalue_p.h deleted file mode 100644 index 629d86c..0000000 --- a/src/script/qscriptvalue_p.h +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTVALUE_P_H -#define QSCRIPTVALUE_P_H - -#include "qscriptvaluefwd_p.h" - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_SCRIPT - -// -// 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. -// - -inline QScriptValuePrivate::QScriptValuePrivate() -{ - engine = 0; - ref = 0; -} - -inline QScriptValuePrivate::~QScriptValuePrivate() -{ - if (value.type() == QScript::LazyStringType) - delete value.m_lazy_string_value; -} - -inline QScriptValuePrivate *QScriptValuePrivate::create() -{ - return new QScriptValuePrivate(); -} - -inline QScriptValuePrivate *QScriptValuePrivate::get(const QScriptValue &value) -{ - return const_cast<QScriptValuePrivate*>(value.d_func()); -} - -inline QScriptValueImpl QScriptValuePrivate::valueOf(const QScriptValue &value) -{ - QScriptValuePrivate *p = const_cast<QScriptValuePrivate*>(value.d_func()); - if (!p) - return QScriptValueImpl(); - return p->value; -} - -inline void QScriptValuePrivate::init(QScriptValue &value, QScriptValuePrivate *p) -{ - value.d_ptr = p; - value.d_ptr->ref.ref(); -} - -inline void QScriptValuePrivate::invalidate() -{ - engine = 0; - value.invalidate(); -} - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT - -#endif diff --git a/src/script/qscriptvalueimpl.cpp b/src/script/qscriptvalueimpl.cpp deleted file mode 100644 index 58fb363..0000000 --- a/src/script/qscriptvalueimpl.cpp +++ /dev/null @@ -1,450 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qscriptvalueimpl_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptengine_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" - -QT_BEGIN_NAMESPACE - -static void dfs(QScriptObject *instance, QHash<QScriptObject*, int> &dfn, int n) -{ - bool found = dfn.contains(instance); - dfn[instance] = n; - - if (found) - return; - - if (instance->m_prototype.isObject()) - dfs (instance->m_prototype.m_object_value, dfn, n + 1); - - if (instance->m_scope.isObject()) - dfs (instance->m_scope.m_object_value, dfn, n + 1); -} - - -static bool checkCycle(QScriptObject *instance, const QHash<QScriptObject*, int> &dfn) -{ - int n = dfn.value(instance); - - if (instance->m_prototype.isObject()) { - if (n >= dfn.value(instance->m_prototype.m_object_value)) - return true; - } - - if (instance->m_scope.isObject()) { - if (n >= dfn.value(instance->m_scope.m_object_value)) - return true; - } - - return false; -} - -bool QScriptValueImpl::detectedCycle() const -{ - QHash<QScriptObject*, int> dfn; - dfs(m_object_value, dfn, 0); - return checkCycle(m_object_value, dfn); -} - -bool QScriptValueImpl::instanceOf(const QScriptValueImpl &value) const -{ - if (! isObject() || ! value.isObject() || !value.implementsHasInstance()) - return false; - return value.hasInstance(*this); -} - -bool QScriptValueImpl::implementsHasInstance() const -{ - Q_ASSERT(isObject()); - if (isFunction()) - return true; - if (QScriptClassData *odata = classInfo()->data()) { - return odata->implementsHasInstance(*this); - } - return false; -} - -bool QScriptValueImpl::hasInstance(const QScriptValueImpl &value) const -{ - Q_ASSERT(isObject()); - - if (QScriptClassData *odata = classInfo()->data()) { - if (odata->implementsHasInstance(*this)) - return odata->hasInstance(*this, value); - } - if (!isFunction()) - return false; - - // [[HasInstance] for function objects - - if (!value.isObject()) - return false; - - QScriptEnginePrivate *eng = engine(); - QScriptValueImpl proto = property(eng->idTable()->id_prototype); - if (!proto.isObject()) { - QScriptContextPrivate *ctx = eng->currentContext(); - ctx->throwTypeError(QLatin1String("instanceof: 'prototype' property is not an object")); - return false; - } - - QScriptObject *target = proto.m_object_value; - QScriptValueImpl v = value; - while (true) { - v = v.prototype(); - if (!v.isObject()) - break; - if (target == v.m_object_value) - return true; - } - return false; -} - -bool QScriptValueImpl::resolve_helper(QScriptNameIdImpl *nameId, QScript::Member *member, - QScriptValueImpl *object, QScriptValue::ResolveFlags mode, - QScript::AccessMode access) const -{ - QScriptObject *object_data = m_object_value; - - QScriptEnginePrivate *eng_p = engine(); - - if (nameId == eng_p->idTable()->id___proto__) { - member->native(nameId, /*id=*/0, QScriptValue::Undeletable); - *object = *this; - return true; - } - - // If not found anywhere else, search in the extra members. - if (QScriptClassData *odata = classInfo()->data()) { - *object = *this; - - if (odata->resolve(*this, nameId, member, object, access)) - return true; - } - - if (mode & QScriptValue::ResolvePrototype) { - // For values and other non object based types, search in class's prototype - const QScriptValueImpl &proto = object_data->m_prototype; - - if (proto.isObject() - && proto.resolve(nameId, member, object, mode, access)) { - return true; - } - } - - if ((mode & QScriptValue::ResolveScope) && object_data->m_scope.isValid()) - return object_data->m_scope.resolve(nameId, member, object, mode, access); - - return false; -} - -void QScriptValueImpl::setProperty(QScriptNameIdImpl *nameId, - const QScriptValueImpl &value, - const QScriptValue::PropertyFlags &flags) -{ - if (!isObject()) - return; - - QScriptValueImpl base; - QScript::Member member; - - QScriptValue::ResolveFlags mode = QScriptValue::ResolveLocal; - // if we are not setting a setter or getter, look in prototype too - if (!(flags & (QScriptValue::PropertyGetter | QScriptValue::PropertySetter))) - mode |= QScriptValue::ResolvePrototype; - - if (resolve(nameId, &member, &base, mode, QScript::ReadWrite)) { - // we resolved an existing property with that name - if (flags & (QScriptValue::PropertyGetter | QScriptValue::PropertySetter)) { - // setting the getter or setter of a property in this object - if (member.isNativeProperty()) { - if (value.isValid()) { - qWarning("QScriptValue::setProperty() failed: " - "cannot set getter or setter of native property `%s'", - qPrintable(nameId->s)); - } - return; - } - if (member.isSetter()) { - // the property we resolved is a setter - if (!(flags & QScriptValue::PropertySetter) && !member.isGetter()) { - // find the getter, if not, create one - if (!m_object_value->findGetter(&member)) { - if (!value.isValid()) - return; // don't create property for invalid value - createMember(nameId, &member, flags); - } - } - } else if (member.isGetter()) { - // the property we resolved is a getter - if (!(flags & QScriptValue::PropertyGetter)) { - // find the setter, if not, create one - if (!m_object_value->findSetter(&member)) { - if (!value.isValid()) - return; // don't create property for invalid value - createMember(nameId, &member, flags); - } - } - } else { - // the property is a normal property -- change the flags - uint newFlags = flags & ~QScript::Member::InternalRange; - newFlags |= QScript::Member::ObjectProperty; - member.resetFlags(newFlags); - base.m_object_value->m_members[member.id()].resetFlags(newFlags); - } - Q_ASSERT(member.isValid()); - if (!value.isValid()) { - // remove the property - removeMember(member); - return; - } - } else { - // setting the value - if (member.isGetterOrSetter()) { - // call the setter - QScriptValueImpl setter; - if (member.isObjectProperty() && !member.isSetter()) { - if (!base.m_object_value->findSetter(&member)) { - qWarning("QScriptValue::setProperty() failed: " - "property '%s' has a getter but no setter", - qPrintable(nameId->s)); - return; - } - } - base.get(member, &setter); - setter.call(*this, QScriptValueImplList() << value); - return; - } else { - if (base.m_object_value != m_object_value) { - if (!value.isValid()) - return; // don't create property for invalid value - createMember(nameId, &member, flags); - base = *this; - } else { - if (!value.isValid()) { - // remove the property - removeMember(member); - return; - } - } - if (flags != QScriptValue::KeepExistingFlags) { - // change flags - if (member.isNativeProperty()) { - qWarning("QScriptValue::setProperty(%s): " - "cannot change flags of a native property", - qPrintable(nameId->s)); - } else { - uint newFlags = member.flags() & QScript::Member::InternalRange; - newFlags |= flags & ~QScript::Member::InternalRange; - base.m_object_value->m_members[member.id()].resetFlags(newFlags); - } - } - } - } - } else { - // property does not exist - if (!value.isValid()) - return; // don't create property for invalid value - createMember(nameId, &member, flags & ~QScript::Member::InternalRange); - base = *this; - } - - base.put(member, value); -} - -QVariant QScriptValueImpl::toVariant() const -{ - switch (m_type) { - case QScript::InvalidType: - return QVariant(); - - case QScript::UndefinedType: - case QScript::NullType: - case QScript::PointerType: - case QScript::ReferenceType: - break; - - case QScript::BooleanType: - return QVariant(m_bool_value); - - case QScript::IntegerType: - return QVariant(m_int_value); - - case QScript::NumberType: - return QVariant(m_number_value); - - case QScript::StringType: - return QVariant(m_string_value->s); - - case QScript::LazyStringType: - return QVariant(*m_lazy_string_value); - - case QScript::ObjectType: - if (isDate()) - return QVariant(toDateTime()); - -#ifndef QT_NO_REGEXP - if (isRegExp()) - return QVariant(toRegExp()); -#endif - if (isVariant()) - return variantValue(); - -#ifndef QT_NO_QOBJECT - if (isQObject()) - return qVariantFromValue(toQObject()); -#endif - if (isArray()) - return QScriptEnginePrivate::variantListFromArray(*this); - - QScriptValueImpl v = engine()->toPrimitive(*this); - if (!v.isObject()) - return v.toVariant(); - break; - } // switch - return QVariant(); -} - -QDebug &operator<<(QDebug &d, const QScriptValueImpl &object) -{ - d.nospace() << "QScriptValue("; - - switch (object.type()) { - case QScript::InvalidType: - d.nospace() << "Invalid)"; - return d; - - case QScript::BooleanType: - d.nospace() << "bool=" << object.toBoolean(); - break; - - case QScript::IntegerType: - d.nospace() << "int=" << object.toInt32(); - break; - - case QScript::NumberType: - d.nospace() << "qsreal=" << object.toNumber(); - break; - - case QScript::LazyStringType: - case QScript::StringType: - d.nospace() << "string=" << object.toString(); - break; - - case QScript::ReferenceType: - d.nospace() << "reference"; - break; - - case QScript::NullType: - d.nospace() << "null"; - break; - - case QScript::UndefinedType: - d.nospace() << "undefined"; - break; - - case QScript::PointerType: - d.nospace() << "pointer"; - break; - - case QScript::ObjectType: - d.nospace() << object.classInfo()->name() << ",{"; - QScriptObject *od = object.objectValue(); - for (int i=0; i<od->memberCount(); ++i) { - if (i != 0) - d << ','; - - QScript::Member m; - od->member(i, &m); - - if (m.isValid() && m.isObjectProperty()) { - d << object.engine()->toString(m.nameId()); - QScriptValueImpl o; - od->get(m, &o); - d.nospace() << QLatin1Char(':') - << (o.classInfo() - ? o.classInfo()->name() - : QLatin1String("?")); - } - } - - d.nospace() << "} scope={"; - QScriptValueImpl scope = object.scope(); - while (scope.isValid()) { - Q_ASSERT(scope.isObject()); - d.nospace() << ' ' << scope.objectValue(); - scope = scope.scope(); - } - d.nospace() << '}'; - break; - } - - d << ')'; - return d; -} - -void QScriptValueImpl::destroyObjectData() -{ - Q_ASSERT(isObject()); - m_object_value->finalizeData(); -} - -bool QScriptValueImpl::isMarked(int generation) const -{ - if (isString()) - return (m_string_value->used != 0); - else if (isObject()) { - QScript::GCBlock *block = QScript::GCBlock::get(m_object_value); - return (block->generation == generation); - } - return false; -} - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptvalueimpl_p.h b/src/script/qscriptvalueimpl_p.h deleted file mode 100644 index d1fdf43..0000000 --- a/src/script/qscriptvalueimpl_p.h +++ /dev/null @@ -1,786 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTVALUEIMPL_P_H -#define QSCRIPTVALUEIMPL_P_H - -#include "qscriptvalueimplfwd_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptclassinfo_p.h" -#include "qscriptecmaarray_p.h" -#include "qscriptecmadate_p.h" -#include "qscriptecmaerror_p.h" -#include "qscriptecmaregexp_p.h" -#include "qscriptextqobject_p.h" -#include "qscriptextvariant_p.h" -#include "qscriptvaluefwd_p.h" -#include "qscriptnameid_p.h" -#include "qscriptenginefwd_p.h" -#include "qscriptcontextfwd_p.h" - -#include <QtCore/QDateTime> - -QT_BEGIN_NAMESPACE - -// -// 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. -// - -inline QScriptValueImpl::QScriptValueImpl() - : m_type(QScript::InvalidType) {} - -inline QScriptValueImpl::QScriptValueImpl(QScriptValue::SpecialValue val) -{ - if (val == QScriptValue::NullValue) - m_type = QScript::NullType; - else if (val == QScriptValue::UndefinedValue) - m_type = QScript::UndefinedType; - else - m_type = QScript::InvalidType; -} - -inline QScriptValueImpl::QScriptValueImpl(bool val) - : m_type(QScript::BooleanType), m_bool_value(val) -{ -} - -inline QScriptValueImpl::QScriptValueImpl(int val) - : m_type(QScript::NumberType), m_number_value(val) -{ -} - -inline QScriptValueImpl::QScriptValueImpl(uint val) - : m_type(QScript::NumberType), m_number_value(val) -{ -} - -inline QScriptValueImpl::QScriptValueImpl(qsreal val) - : m_type(QScript::NumberType), m_number_value(val) -{ -} - -inline QScriptValueImpl::QScriptValueImpl(QScriptEnginePrivate *engine, const QString &val) -{ - engine->newString(this, val); -} - -inline QScriptValueImpl::QScriptValueImpl(QScriptNameIdImpl *val) - : m_type(QScript::StringType), m_string_value(val) -{ -} - -inline QScript::Type QScriptValueImpl::type() const -{ - return m_type; -} - -inline QScriptEnginePrivate *QScriptValueImpl::engine() const -{ - if (!isObject()) - return 0; - return m_object_value->m_class->engine(); -} - -inline QScriptClassInfo *QScriptValueImpl::classInfo() const -{ - if (!isObject()) - return 0; - return m_object_value->m_class; -} - -inline void QScriptValueImpl::setClassInfo(QScriptClassInfo *cls) -{ - Q_ASSERT(isObject()); - m_object_value->m_class = cls; -} - -inline QScriptNameIdImpl *QScriptValueImpl::stringValue() const -{ - Q_ASSERT(isString()); - return m_string_value; -} - -inline QScriptObject *QScriptValueImpl::objectValue() const -{ - Q_ASSERT(isObject()); - return m_object_value; -} - -inline void QScriptValueImpl::incr() -{ - ++m_number_value; -} - -inline void QScriptValueImpl::decr() -{ - --m_number_value; -} - -inline void QScriptValueImpl::invalidate() -{ - m_type = QScript::InvalidType; -} - -inline bool QScriptValueImpl::isValid() const -{ - return m_type != QScript::InvalidType; -} - -inline bool QScriptValueImpl::isUndefined() const -{ - return (m_type == QScript::UndefinedType); -} - -inline bool QScriptValueImpl::isNull() const -{ - return (m_type == QScript::NullType); -} - -inline bool QScriptValueImpl::isBoolean() const -{ - return (m_type == QScript::BooleanType); -} - -inline bool QScriptValueImpl::isNumber() const -{ - return (m_type == QScript::NumberType); -} - -inline bool QScriptValueImpl::isString() const -{ - return (m_type == QScript::StringType) - || (m_type == QScript::LazyStringType); -} - -inline bool QScriptValueImpl::isReference() const -{ - return (m_type == QScript::ReferenceType); -} - -inline bool QScriptValueImpl::isObject() const -{ - return (m_type == QScript::ObjectType); -} - -inline bool QScriptValueImpl::isFunction() const -{ - return (m_type == QScript::ObjectType) - && (classInfo()->type() & QScriptClassInfo::FunctionBased); -} - -inline bool QScriptValueImpl::isVariant() const -{ - return (m_type == QScript::ObjectType) - && (classInfo()->type() == QScriptClassInfo::VariantType); -} - -inline bool QScriptValueImpl::isQObject() const -{ - return (m_type == QScript::ObjectType) - && (classInfo()->type() == QScriptClassInfo::QObjectType); -} - -inline bool QScriptValueImpl::isQMetaObject() const -{ - return (m_type == QScript::ObjectType) - && (classInfo()->type() == QScriptClassInfo::QMetaObjectType); -} - -inline bool QScriptValueImpl::isArray() const -{ - if (!isObject()) - return false; - return classInfo() == engine()->arrayConstructor->classInfo(); -} - -inline bool QScriptValueImpl::isDate() const -{ - if (!isObject()) - return false; - return classInfo() == engine()->dateConstructor->classInfo(); -} - -inline bool QScriptValueImpl::isError() const -{ - if (!isObject()) - return false; - return classInfo() == engine()->errorConstructor->classInfo(); -} - -inline bool QScriptValueImpl::isRegExp() const -{ - if (!isObject()) - return false; - return classInfo() == engine()->regexpConstructor->classInfo(); -} - -inline qsreal QScriptValueImpl::toNumber() const -{ - if (!isValid()) - return 0; - return QScriptEnginePrivate::convertToNativeDouble(*this); -} - -inline bool QScriptValueImpl::toBoolean() const -{ - if (!isValid()) - return false; - return QScriptEnginePrivate::convertToNativeBoolean(*this); -} - -inline QString QScriptValueImpl::toString() const -{ - if (!isValid()) - return QString(); - return QScriptEnginePrivate::convertToNativeString(*this); -} - -inline qint32 QScriptValueImpl::toInt32() const -{ - if (!isValid()) - return 0; - double d = QScriptEnginePrivate::convertToNativeDouble(*this); - return QScriptEnginePrivate::toInt32(d); -} - -inline quint32 QScriptValueImpl::toUInt32() const -{ - if (!isValid()) - return 0; - double d = QScriptEnginePrivate::convertToNativeDouble(*this); - return QScriptEnginePrivate::toUint32(d); -} - -inline quint16 QScriptValueImpl::toUInt16() const -{ - if (!isValid()) - return 0; - double d = QScriptEnginePrivate::convertToNativeDouble(*this); - return QScriptEnginePrivate::toUint16(d); -} - -inline qsreal QScriptValueImpl::toInteger() const -{ - if (!isValid()) - return 0; - double d = QScriptEnginePrivate::convertToNativeDouble(*this); - return QScriptEnginePrivate::toInteger(d); -} - -inline QDateTime QScriptValueImpl::toDateTime() const -{ - if (!isDate()) - return QDateTime(); - return engine()->toDateTime(*this); -} - -#ifndef QT_NO_REGEXP -inline QRegExp QScriptValueImpl::toRegExp() const -{ - if (!isRegExp()) - return QRegExp(); - return engine()->regexpConstructor->toRegExp(*this); -} -#endif // QT_NO_REGEXP - -inline QObject *QScriptValueImpl::toQObject() const -{ -#ifndef QT_NO_QOBJECT - if (isQObject()) { - QScript::ExtQObject *ctor = engine()->qobjectConstructor; - Q_ASSERT(ctor != 0); - - QScript::ExtQObject::Instance *data = ctor->get(*this); - Q_ASSERT(data != 0); - - return data->value; - } else if (isVariant()) { - int type = variantValue().userType(); - if ((type == QMetaType::QObjectStar) || (type == QMetaType::QWidgetStar)) - return *reinterpret_cast<QObject* const *>(variantValue().constData()); - } -#endif - return 0; -} - -inline const QMetaObject *QScriptValueImpl::toQMetaObject() const -{ -#ifndef QT_NO_QOBJECT - if (isQMetaObject()) { - QScript::ExtQMetaObject *ctor = engine()->qmetaObjectConstructor; - Q_ASSERT(ctor != 0); - - QScript::ExtQMetaObject::Instance *data = ctor->get(*this); - Q_ASSERT(data != 0); - - return data->value; - } -#endif - return 0; -} - -inline QScriptValueImpl QScriptValueImpl::prototype() const -{ - if (!isObject()) - return QScriptValueImpl(); - return m_object_value->m_prototype; -} - -inline void QScriptValueImpl::setPrototype(const QScriptValueImpl &prototype) -{ - if (isObject()) - m_object_value->m_prototype = prototype; -} - -inline QScriptObjectData *QScriptValueImpl::objectData() const -{ - Q_ASSERT(isObject()); - return m_object_value->m_data; -} - -inline void QScriptValueImpl::setObjectData(QScriptObjectData *data) -{ - Q_ASSERT(isObject()); - m_object_value->m_data = data; -} - -inline bool QScriptValueImpl::resolve(QScriptNameIdImpl *nameId, QScript::Member *member, - QScriptValueImpl *object, QScriptValue::ResolveFlags mode, - QScript::AccessMode access) const -{ - Q_ASSERT(isValid()); - Q_ASSERT(isObject()); - Q_ASSERT(member); - Q_ASSERT(object); - - Q_ASSERT(nameId->unique); - - QScriptObject *object_data = m_object_value; - - // Search in properties... - if (object_data->findMember(nameId, member)) { - *object = *this; - return true; - } - - return resolve_helper(nameId, member, object, mode, access); -} - -inline void QScriptValueImpl::get(const QScript::Member &member, QScriptValueImpl *out) const -{ - Q_ASSERT(out); - Q_ASSERT(isObject()); - Q_ASSERT(member.isValid()); - - if (! member.isObjectProperty()) { - get_helper(member, out); - return; - } - - Q_ASSERT(member.id() >= 0); - Q_ASSERT(member.id() < m_object_value->memberCount()); - - m_object_value->get(member, out); -} - -inline void QScriptValueImpl::get(QScriptNameIdImpl *nameId, QScriptValueImpl *out) -{ - QScript::Member m; - QScriptValueImpl o; - if (resolve(nameId, &m, &o, QScriptValue::ResolvePrototype, QScript::Read)) - o.get(m, out); - else - *out = QScriptValueImpl(QScriptValue::UndefinedValue); -} - -inline void QScriptValueImpl::get_helper(const QScript::Member &member, QScriptValueImpl *out) const -{ - if (member.nameId() == engine()->idTable()->id___proto__) { - *out = prototype(); - - if (!out->isValid()) - *out = QScriptValueImpl(QScriptValue::UndefinedValue); - - return; - } - - if (QScriptClassData *data = classInfo()->data()) { - if (data->get(*this, member, out)) - return; - } - - out->invalidate(); -} - -inline void QScriptValueImpl::put(const QScript::Member &member, const QScriptValueImpl &value) -{ - Q_ASSERT(isObject()); - Q_ASSERT(member.isValid()); - // Q_ASSERT(member.isWritable()); - - QScriptEnginePrivate *eng_p = engine(); - - if (member.isObjectProperty()) { - Q_ASSERT(member.nameId()->unique); - Q_ASSERT(member.id() >= 0); - Q_ASSERT(member.id() < m_object_value->memberCount()); - m_object_value->put(member, value); - } - - else if (member.nameId() == eng_p->idTable()->id___proto__) { - if (value.isNull()) // only Object.prototype.__proto__ can be null - setPrototype(eng_p->undefinedValue()); - else { - QScriptValueImpl was = prototype(); - setPrototype(value); - if (detectedCycle()) { - eng_p->currentContext()->throwError(QLatin1String("cycle in prototype chain")); - setPrototype(was); - } - } - } - - else { - Q_ASSERT(classInfo()->data()); - classInfo()->data()->put(this, member, value); - } -} - -inline void QScriptValueImpl::setQObjectValue(QObject *object) -{ -#ifndef QT_NO_QOBJECT - Q_ASSERT(isQObject()); - - QScript::ExtQObject *ctor = engine()->qobjectConstructor; - Q_ASSERT(ctor != 0); - - QScript::ExtQObject::Instance *data = ctor->get(*this); - Q_ASSERT(data != 0); - - data->value = object; -#else - Q_UNUSED(object); -#endif -} - -inline QVariant &QScriptValueImpl::variantValue() const -{ - Q_ASSERT(isVariant()); - - QScript::Ext::Variant *ctor = engine()->variantConstructor; - Q_ASSERT(ctor != 0); - - QScript::Ext::Variant::Instance *data = ctor->get(*this); - Q_ASSERT(data != 0); - - return data->value; -} - -inline void QScriptValueImpl::setVariantValue(const QVariant &value) -{ - if (!isVariant()) - return; - - QScript::Ext::Variant *ctor = engine()->variantConstructor; - Q_ASSERT(ctor != 0); - - QScript::Ext::Variant::Instance *data = ctor->get(*this); - Q_ASSERT(data != 0); - - data->value = value; -} - -inline QScriptValueImpl QScriptValueImpl::internalValue() const -{ - Q_ASSERT(isObject()); - return m_object_value->m_internalValue; -} - -inline void QScriptValueImpl::setInternalValue(const QScriptValueImpl &internalValue) -{ - Q_ASSERT(isObject()); - m_object_value->m_internalValue = internalValue; -} - -inline void QScriptValueImpl::removeMember(const QScript::Member &member) -{ - if (member.isObjectProperty()) - m_object_value->removeMember(member); - - else if (QScriptClassData *data = classInfo()->data()) - data->removeMember(*this, member); -} - -inline void QScriptValueImpl::createMember(QScriptNameIdImpl *nameId, - QScript::Member *member, uint flags) -{ - Q_ASSERT(isObject()); - - QScriptObject *object_data = m_object_value; - object_data->createMember(nameId, member, flags); - Q_ASSERT(member->isObjectProperty()); -} - -inline QScriptValueImpl QScriptValueImpl::scope() const -{ - Q_ASSERT(isObject()); - return m_object_value->m_scope; -} - -inline void QScriptValueImpl::setScope(const QScriptValueImpl &scope) -{ - Q_ASSERT(isObject()); - m_object_value->m_scope = scope; -} - -inline int QScriptValueImpl::memberCount() const -{ - Q_ASSERT(isObject()); - return m_object_value->memberCount(); -} - -inline void QScriptValueImpl::member(int index, QScript::Member *member) const -{ - Q_ASSERT(isObject()); - Q_ASSERT(index >= 0); - Q_ASSERT(index < m_object_value->memberCount()); - m_object_value->member(index, member); -} - -inline QScriptFunction *QScriptValueImpl::toFunction() const -{ - if (!isFunction()) - return 0; - return engine()->convertToNativeFunction(*this); -} - -inline QScriptValueImpl QScriptValueImpl::property(QScriptNameIdImpl *nameId, - const QScriptValue::ResolveFlags &mode) const -{ - if (!isObject()) - return QScriptValueImpl(); - - QScriptValueImpl base; - QScript::Member member; - - if (! resolve(nameId, &member, &base, mode, QScript::Read)) - return QScriptValueImpl(); - - QScriptValueImpl value; - base.get(member, &value); - if (member.isGetterOrSetter()) { - QScriptValueImpl getter; - if (member.isObjectProperty() && !member.isGetter()) { - if (!base.m_object_value->findGetter(&member)) - return QScriptValueImpl(); - } - base.get(member, &getter); - value = getter.call(*this); - } - return value; -} - -inline void QScriptValueImpl::setProperty(const QString &name, const QScriptValueImpl &value, - const QScriptValue::PropertyFlags &flags) -{ - if (!isObject()) - return; - QScriptNameIdImpl *nameId = engine()->nameId(name); - setProperty(nameId, value, flags); -} - -inline QScriptValueImpl QScriptValueImpl::property(const QString &name, - const QScriptValue::ResolveFlags &mode) const -{ - if (!isObject()) - return QScriptValueImpl(); - QScriptNameIdImpl *nameId = engine()->nameId(name); - return property(nameId, mode); -} - -inline QScriptValueImpl QScriptValueImpl::property(quint32 arrayIndex, - const QScriptValue::ResolveFlags &mode) const -{ - if (!isObject()) - return QScriptValueImpl(); - - QScriptEnginePrivate *eng_p = engine(); - QScript::Ecma::Array::Instance *instance = eng_p->arrayConstructor->get(*this); - if (instance && (arrayIndex != 0xFFFFFFFF)) - return instance->value.at(arrayIndex); - - return property(QScriptValueImpl(arrayIndex).toString(), mode); -} - -inline void QScriptValueImpl::setProperty(quint32 arrayIndex, const QScriptValueImpl &value, - const QScriptValue::PropertyFlags &flags) -{ - if (!isObject()) - return; - - QScriptEnginePrivate *eng_p = engine(); - QScript::Ecma::Array::Instance *instance = eng_p->arrayConstructor->get(*this); - if (instance && (arrayIndex != 0xFFFFFFFF)) { - instance->value.assign(arrayIndex, value); - return; - } - - setProperty(QScriptValueImpl(arrayIndex).toString(), value, flags); -} - -inline QScriptValue::PropertyFlags QScriptValueImpl::propertyFlags(const QString &name, - const QScriptValue::ResolveFlags &mode) const -{ - QScriptNameIdImpl *nameId = engine()->nameId(name); - return propertyFlags(nameId, mode); -} - -inline QScriptValue::PropertyFlags QScriptValueImpl::propertyFlags(QScriptNameIdImpl *nameId, - const QScriptValue::ResolveFlags &mode) const -{ - if (!isObject()) - return 0; - - QScriptValueImpl base; - QScript::Member member; - if (! resolve(nameId, &member, &base, mode, QScript::ReadWrite)) - return 0; - - return QScriptValue::PropertyFlags(member.flags() & ~QScript::Member::InternalRange); -} - -inline bool QScriptValueImpl::deleteProperty(QScriptNameIdImpl *nameId, - const QScriptValue::ResolveFlags &mode) -{ - if (!isObject()) - return true; - QScript::Member member; - QScriptValueImpl base; - if (resolve(nameId, &member, &base, mode, QScript::Write)) { - if (!member.isDeletable()) - return false; - base.removeMember(member); - if (member.isGetterOrSetter() && (member.isGetter() != member.isSetter())) { - // delete the "other half" of the property too (getter or setter) - return deleteProperty(nameId, mode); - } - } - return true; -} - -inline QScriptValueImpl QScriptValueImpl::call(const QScriptValueImpl &thisObject, - const QScriptValueImplList &args) -{ - if (!isFunction()) - return QScriptValueImpl(); - - return engine()->call(*this, thisObject, args, /*asConstructor=*/false); -} - -inline QScriptValueImpl QScriptValueImpl::call(const QScriptValueImpl &thisObject, - const QScriptValueImpl &args) -{ - if (!isFunction()) - return QScriptValueImpl(); - - return engine()->call(*this, thisObject, args, /*asConstructor=*/false); -} - -inline QScriptValueImpl QScriptValueImpl::construct(const QScriptValueImplList &args) -{ - if (!isFunction()) - return QScriptValueImpl(); - - QScriptEnginePrivate *eng_p = engine(); - - QScriptValueImpl proto = property(QLatin1String("prototype"), QScriptValue::ResolveLocal); - QScriptValueImpl object; - eng_p->newObject(&object, proto); - - QScriptValueImpl result = eng_p->call(*this, object, args, /*asConstructor=*/true); - if (result.isObject()) - return result; - return object; -} - -inline QScriptValueImpl QScriptValueImpl::construct(const QScriptValueImpl &args) -{ - if (!isFunction()) - return QScriptValueImpl(); - - QScriptEnginePrivate *eng_p = engine(); - - QScriptValueImpl proto = property(QLatin1String("prototype"), QScriptValue::ResolveLocal); - QScriptValueImpl object; - eng_p->newObject(&object, proto); - - QScriptValueImpl result = eng_p->call(*this, object, args, /*asConstructor=*/true); - if (result.isObject()) - return result; - return object; -} - -inline void QScriptValueImpl::mark(int generation) const -{ - if (! isValid()) - return; - - else if (isString()) - engine()->markString(m_string_value, generation); - - else if (isObject()) - engine()->markObject(*this, generation); -} - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT - -#endif diff --git a/src/script/qscriptvalueimplfwd_p.h b/src/script/qscriptvalueimplfwd_p.h deleted file mode 100644 index 5baaa99..0000000 --- a/src/script/qscriptvalueimplfwd_p.h +++ /dev/null @@ -1,241 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTVALUEIMPLFWD_P_H -#define QSCRIPTVALUEIMPLFWD_P_H - -#include "qscriptglobals_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptvalue.h" - -#include <QtCore/qstring.h> -#include <QtCore/qlist.h> - -QT_BEGIN_NAMESPACE - -// -// 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. -// - -#if defined(Q_OS_VXWORKS) && defined(m_type) -# undef m_type -#endif - -class QScriptValueImpl; -typedef QList<QScriptValueImpl> QScriptValueImplList; - -class QScriptClassInfo; -class QScriptObject; -class QScriptObjectData; -class QScriptNameIdImpl; -class QScriptFunction; -class QScriptEnginePrivate; - -namespace QScript -{ - class Member; -} - -class QScriptValueImpl -{ -public: - enum TypeHint { - NoTypeHint, - NumberTypeHint, - StringTypeHint - }; - - inline QScriptValueImpl(); - inline QScriptValueImpl(QScriptValue::SpecialValue val); - inline QScriptValueImpl(bool val); - inline QScriptValueImpl(int val); - inline QScriptValueImpl(uint val); - inline QScriptValueImpl(qsreal val); - inline QScriptValueImpl(QScriptEnginePrivate *engine, const QString &val); - inline QScriptValueImpl(QScriptNameIdImpl *val); - - inline QScript::Type type() const; - inline QScriptEnginePrivate *engine() const; - inline QScriptClassInfo *classInfo() const; - inline void setClassInfo(QScriptClassInfo *cls); - inline QScriptNameIdImpl *stringValue() const; - inline QScriptObject *objectValue() const; - inline void incr(); - inline void decr(); - - inline void invalidate(); - inline bool isValid() const; - inline bool isBoolean() const; - inline bool isNumber() const; - inline bool isString() const; - inline bool isFunction() const; - inline bool isObject() const; - inline bool isUndefined() const; - inline bool isNull() const; - inline bool isVariant() const; - inline bool isQObject() const; - inline bool isQMetaObject() const; - inline bool isReference() const; - - inline bool isError() const; - inline bool isArray() const; - inline bool isDate() const; - inline bool isRegExp() const; - - inline QString toString() const; - inline qsreal toNumber() const; - inline bool toBoolean() const; - inline qsreal toInteger() const; - inline qint32 toInt32() const; - inline quint32 toUInt32() const; - inline quint16 toUInt16() const; - QVariant toVariant() const; - inline QObject *toQObject() const; - inline const QMetaObject *toQMetaObject() const; - inline QDateTime toDateTime() const; -#ifndef QT_NO_REGEXP - inline QRegExp toRegExp() const; -#endif - - inline QVariant &variantValue() const; - inline void setVariantValue(const QVariant &v); - - bool instanceOf(const QScriptValueImpl &value) const; - bool instanceOf_helper(const QScriptValueImpl &value) const; - - bool implementsHasInstance() const; - bool hasInstance(const QScriptValueImpl &value) const; - - inline QScriptValueImpl prototype() const; - inline void setPrototype(const QScriptValueImpl &prototype); - - inline QScriptValueImpl property(QScriptNameIdImpl *nameId, - const QScriptValue::ResolveFlags &mode = QScriptValue::ResolvePrototype) const; - void setProperty(QScriptNameIdImpl *nameId, const QScriptValueImpl &value, - const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags); - - inline QScriptValueImpl property(const QString &name, - const QScriptValue::ResolveFlags &mode = QScriptValue::ResolvePrototype) const; - inline void setProperty(const QString &name, const QScriptValueImpl &value, - const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags); - - inline QScriptValueImpl property(quint32 arrayIndex, - const QScriptValue::ResolveFlags &mode = QScriptValue::ResolvePrototype) const; - inline void setProperty(quint32 arrayIndex, const QScriptValueImpl &value, - const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags); - - inline QScriptValue::PropertyFlags propertyFlags(const QString &name, - const QScriptValue::ResolveFlags &mode = QScriptValue::ResolvePrototype) const; - inline QScriptValue::PropertyFlags propertyFlags(QScriptNameIdImpl *nameId, - const QScriptValue::ResolveFlags &mode = QScriptValue::ResolvePrototype) const; - - inline bool deleteProperty(QScriptNameIdImpl *nameId, - const QScriptValue::ResolveFlags &mode = QScriptValue::ResolveLocal); - - inline QScriptValueImpl call(const QScriptValueImpl &thisObject = QScriptValueImpl(), - const QScriptValueImplList &args = QScriptValueImplList()); - inline QScriptValueImpl call(const QScriptValueImpl &thisObject, - const QScriptValueImpl &arguments); - inline QScriptValueImpl construct(const QScriptValueImplList &args = QScriptValueImplList()); - inline QScriptValueImpl construct(const QScriptValueImpl &arguments); - - inline void mark(int) const; - bool isMarked(int) const; - - inline QScriptValueImpl internalValue() const; - inline void setInternalValue(const QScriptValueImpl &internalValue); - - inline void setQObjectValue(QObject *object); - - inline QScriptObjectData *objectData() const; - inline void setObjectData(QScriptObjectData *data); - void destroyObjectData(); - - inline void createMember(QScriptNameIdImpl *nameId, - QScript::Member *member, uint flags); // ### remove me - inline int memberCount() const; - inline void member(int index, QScript::Member *member) const; - - inline bool resolve(QScriptNameIdImpl *nameId, QScript::Member *member, - QScriptValueImpl *object, QScriptValue::ResolveFlags mode, - QScript::AccessMode access) const; - bool resolve_helper(QScriptNameIdImpl *nameId, QScript::Member *member, - QScriptValueImpl *object, QScriptValue::ResolveFlags mode, - QScript::AccessMode access) const; - inline void get(const QScript::Member &member, QScriptValueImpl *out) const; - inline void get_helper(const QScript::Member &member, QScriptValueImpl *out) const; - inline void get(QScriptNameIdImpl *nameId, QScriptValueImpl *out); - inline void put(const QScript::Member &member, const QScriptValueImpl &value); - inline void removeMember(const QScript::Member &member); - - inline QScriptValueImpl scope() const; - inline void setScope(const QScriptValueImpl &scope); - - inline QScriptFunction *toFunction() const; - - bool detectedCycle() const; - - QScript::Type m_type; - union { - bool m_bool_value; - int m_int_value; - qsreal m_number_value; - void *m_ptr_value; - QScriptObject *m_object_value; - QScriptNameIdImpl *m_string_value; - QString *m_lazy_string_value; - }; -}; - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT - -#endif // QSCRIPTVALUEIMPLFWD_P_H diff --git a/src/script/qscriptvalueiteratorimpl.cpp b/src/script/qscriptvalueiteratorimpl.cpp deleted file mode 100644 index 35b5241..0000000 --- a/src/script/qscriptvalueiteratorimpl.cpp +++ /dev/null @@ -1,415 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qscriptvalueiteratorimpl_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptengine_p.h" -#include "qscriptcontext_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" - -QT_BEGIN_NAMESPACE - -namespace QScript { - -extern QString numberToString(qsreal value); - -} // namespace - -QScriptValueIteratorImpl::QScriptValueIteratorImpl(const QScriptValueImpl &obj) -{ - Q_ASSERT(obj.isObject()); - m_frontObject = obj; - m_member.invalidate(); - m_foundMember.invalidate(); - m_foundForward = false; - m_object = obj; - m_searchIndex = 0; - m_searchClassDataIterator = false; - m_classDataIterator = 0; - m_ignoresDontEnum = true; - m_enumerateProto = false; -} - -QScriptValueIteratorImpl::~QScriptValueIteratorImpl() -{ - if (m_classDataIterator) { - delete m_classDataIterator; - m_classDataIterator = 0; - } -} - -bool QScriptValueIteratorImpl::ignoresDontEnum() const -{ - return m_ignoresDontEnum; -} - -void QScriptValueIteratorImpl::setIgnoresDontEnum(bool ignore) -{ - m_ignoresDontEnum = ignore; -} - -bool QScriptValueIteratorImpl::enumeratePrototype() const -{ - return m_enumerateProto; -} - -void QScriptValueIteratorImpl::setEnumeratePrototype(bool enable) -{ - m_enumerateProto = enable; -} - -bool QScriptValueIteratorImpl::acceptsMember(const QScriptValueImpl &o, - const QScript::Member &m) const -{ - if (!m.isValid() || (!m_ignoresDontEnum && m.dontEnum()) - || (m.isSetter() && !m.isGetter())) { - return false; - } - - if (!m_enumerateProto || QScriptEnginePrivate::strictlyEquals(o, m_frontObject)) - return true; - - // make sure it's not a shadowed property - QScript::Member dummy; - QScriptValueImpl base; - QScriptNameIdImpl *id; - if (m.nameId()) { - id = m.nameId(); - } else { - QScriptEnginePrivate *eng_p = m_frontObject.engine(); - id = eng_p->nameId(QScript::numberToString(m.id())); - } - m_frontObject.resolve(id, &dummy, &base, QScriptValue::ResolvePrototype, QScript::Read); - return QScriptEnginePrivate::strictlyEquals(base, o); -} - -bool QScriptValueIteratorImpl::hasNext() -{ - if (m_foundMember.isValid() && m_foundForward) { - // we have the information about the next element already - return true; - } - - int idx, count; - QScriptValueImpl obj = m_object; - - if (m_searchClassDataIterator) { - Q_ASSERT(m_classDataIterator != 0); - if (m_foundMember.isValid()) { - // undo effect of hasPrevious() - m_foundMember.invalidate(); - QScript::Member dummy; - m_classDataIterator->next(&dummy); - } - goto LSearchClassData; - } - - idx = m_searchIndex; - if (m_foundMember.isValid()) { - // undo effect of hasPrevious() - m_foundMember.invalidate(); - ++idx; - } - - LSearchObjectData: - count = obj.memberCount(); - for (int i = idx; i < count; ++i) { - QScript::Member m; - obj.member(i, &m); - if (acceptsMember(obj, m)) { - m_foundObject = obj; - m_foundMember = m; - m_foundForward = true; - m_searchIndex = i + 1; - return true; - } - } - - if (!m_classDataIterator) { - QScriptClassData *data = obj.classInfo()->data(); - if (!data) - goto LNext; - m_classDataIterator = data->newIterator(obj); - if (!m_classDataIterator) - goto LNext; - } - m_searchClassDataIterator = true; - - LSearchClassData: - Q_ASSERT(m_classDataIterator != 0); - while (m_classDataIterator->hasNext()) { - QScript::Member m; - m_classDataIterator->next(&m); - if (acceptsMember(obj, m)) { - m_foundObject = obj; - m_foundMember = m; - m_foundForward = true; - return true; - } - } - - LNext: - if (!m_enumerateProto || !obj.prototype().isObject()) - return false; - - // look in prototype - obj = obj.prototype(); - idx = 0; - if (m_classDataIterator) { - delete m_classDataIterator; - m_classDataIterator = 0; - m_searchClassDataIterator = false; - } - goto LSearchObjectData; -} - -void QScriptValueIteratorImpl::next() -{ - (void)hasNext(); // sync the next-element info - m_object = m_foundObject; - m_member = m_foundMember; - m_foundObject = QScriptValueImpl(); - m_foundMember.invalidate(); -} - -bool QScriptValueIteratorImpl::hasPrevious() -{ - if (m_foundMember.isValid() && !m_foundForward) { - // we have the information about the previous element already - return true; - } - - QScriptValueImpl obj = m_object; - - if (m_searchClassDataIterator) { - Q_ASSERT(m_classDataIterator != 0); - if (m_foundMember.isValid()) { - // undo effect of hasNext() - m_foundMember.invalidate(); - QScript::Member dummy; - m_classDataIterator->previous(&dummy); - } - while (m_classDataIterator->hasPrevious()) { - QScript::Member m; - m_classDataIterator->previous(&m); - if (acceptsMember(obj, m)) { - m_foundObject = obj; - m_foundMember = m; - m_foundForward = false; - return true; - } - } - m_searchClassDataIterator = false; - m_searchIndex = obj.memberCount(); - m_foundMember.invalidate(); - } - - // search object members - int i = m_searchIndex - 1; - if (m_foundMember.isValid()) { - // undo effect of hasPrevious() - m_foundMember.invalidate(); - --i; - } - for ( ; i >= 0; --i) { - QScript::Member m; - obj.member(i, &m); - if (acceptsMember(obj, m)) { - m_foundObject = obj; - m_foundMember = m; - m_foundForward = false; - m_searchIndex = i; - return true; - } - } - - return false; -} - -void QScriptValueIteratorImpl::previous() -{ - (void)hasPrevious(); // sync the previous-element info - m_object = m_foundObject; - m_member = m_foundMember; - m_foundObject = QScriptValueImpl(); - m_foundMember.invalidate(); -} - -QScript::Member *QScriptValueIteratorImpl::member() -{ - return &m_member; -} - -QScriptNameIdImpl *QScriptValueIteratorImpl::nameId() const -{ - return m_member.nameId(); -} - -QString QScriptValueIteratorImpl::name() const -{ - if (!m_member.isValid()) - return QString(); - if (m_member.nameId()) - return m_member.nameId()->s; - else - return QScript::numberToString(m_member.id()); -} - -QScriptValueImpl QScriptValueIteratorImpl::value() const -{ - if (!m_member.isValid()) - return QScriptValueImpl(); - QScriptValueImpl result; - m_object.get(m_member, &result); - if (m_member.isGetterOrSetter()) { - // find and call the getter - QScriptValueImpl getter; - if (m_member.isObjectProperty() && !m_member.isGetter()) { - QScript::Member mb; - QScriptObject *obj = m_object.m_object_value; - mb.object(m_member.nameId(), obj->memberCount(), 0); - if (!obj->findGetter(&mb)) - return QScriptValueImpl(); - m_object.get(mb, &getter); - } else { - getter = result; - } - result = getter.call(m_object); - } - return result; -} - -void QScriptValueIteratorImpl::setValue(const QScriptValueImpl &value) -{ - if (!m_member.isValid()) - return; - if (m_member.isGetterOrSetter()) { - // find and call the setter - QScriptValueImpl setter; - if (m_member.isObjectProperty() && !m_member.isSetter()) { - QScript::Member mb; - QScriptObject *obj = m_object.m_object_value; - mb.object(m_member.nameId(), obj->memberCount(), 0); - if (!obj->findSetter(&mb)) - return; - m_object.get(mb, &setter); - } else { - m_object.get(m_member, &setter); - } - setter.call(m_object, QScriptValueImplList() << value); - } else { - m_object.put(m_member, value); - } -} - -uint QScriptValueIteratorImpl::flags() const -{ - return m_member.flags(); -} - -QScriptValueImpl QScriptValueIteratorImpl::object() const -{ - return m_object; -} - -void QScriptValueIteratorImpl::setObject(const QScriptValueImpl &obj) -{ - Q_ASSERT(obj.isObject()); - m_object = obj; - if (m_classDataIterator) { - delete m_classDataIterator; - m_classDataIterator = 0; - } - toFront(); -} - -void QScriptValueIteratorImpl::remove() -{ - if (m_member.isValid()) - m_object.removeMember(m_member); -} - -void QScriptValueIteratorImpl::toFront() -{ - if (m_classDataIterator) { - if (!m_enumerateProto || QScriptEnginePrivate::strictlyEquals(m_object, m_frontObject)) { - m_classDataIterator->toFront(); - } else { - delete m_classDataIterator; - m_classDataIterator = 0; - } - } - - m_member.invalidate(); - m_object = m_frontObject; - - m_foundObject = QScriptValueImpl(); - m_foundMember.invalidate(); - m_searchIndex = 0; - m_searchClassDataIterator = false; -} - -void QScriptValueIteratorImpl::toBack() -{ - m_member.invalidate(); - - m_foundObject = QScriptValueImpl(); - m_foundMember.invalidate(); - - if (!m_classDataIterator) { - QScriptClassData *data = m_object.classInfo()->data(); - if (data) - m_classDataIterator = data->newIterator(m_object); - } - if (m_classDataIterator) - m_classDataIterator->toBack(); - else - m_searchIndex = m_object.memberCount(); - m_searchClassDataIterator = (m_classDataIterator != 0); -} - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptvalueiteratorimpl_p.h b/src/script/qscriptvalueiteratorimpl_p.h deleted file mode 100644 index d72295e..0000000 --- a/src/script/qscriptvalueiteratorimpl_p.h +++ /dev/null @@ -1,127 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTVALUEITERATORIMPL_P_H -#define QSCRIPTVALUEITERATORIMPL_P_H - -#include "qscriptvalueimplfwd_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptmemberfwd_p.h" - -QT_BEGIN_NAMESPACE - -// -// 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. -// - -class QScriptClassDataIterator; -class QScriptNameIdImpl; - -class QScriptValueIteratorImpl -{ -public: - QScriptValueIteratorImpl(const QScriptValueImpl &obj); - ~QScriptValueIteratorImpl(); - - bool ignoresDontEnum() const; - void setIgnoresDontEnum(bool ignore); - - bool enumeratePrototype() const; - void setEnumeratePrototype(bool enable); - - bool hasNext(); - void next(); - - bool hasPrevious(); - void previous(); - - QScript::Member *member(); - - QScriptNameIdImpl *nameId() const; - QString name() const; - - QScriptValueImpl value() const; - void setValue(const QScriptValueImpl &value); - - uint flags() const; - - void remove(); - - void toFront(); - void toBack(); - - QScriptValueImpl object() const; - void setObject(const QScriptValueImpl &obj); - -private: - bool acceptsMember(const QScriptValueImpl &o, const QScript::Member &m) const; - QScriptClassDataIterator *getClassDataIterator(); - - QScriptValueImpl m_frontObject; - - bool m_ignoresDontEnum; - bool m_enumerateProto; - - QScriptValueImpl m_object; - QScript::Member m_member; - - int m_searchIndex; - QScriptValueImpl m_foundObject; - QScript::Member m_foundMember; - bool m_foundForward; - QScriptClassDataIterator *m_classDataIterator; - bool m_searchClassDataIterator; -}; - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT - -#endif diff --git a/src/script/qscriptxmlgenerator.cpp b/src/script/qscriptxmlgenerator.cpp deleted file mode 100644 index 254bfcd..0000000 --- a/src/script/qscriptxmlgenerator.cpp +++ /dev/null @@ -1,1118 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qscriptxmlgenerator_p.h" - -#ifndef QT_NO_SCRIPT - -#include "qscriptast_p.h" -#include "qscriptengine_p.h" -#include "qscriptvalueimpl_p.h" -#include "qscriptcontext_p.h" -#include "qscriptmember_p.h" -#include "qscriptobject_p.h" -#include "qscriptlexer_p.h" -#include "qscriptparser_p.h" - -#include <QtCore/qstring.h> -#include <QtCore/qtextstream.h> - -QT_BEGIN_NAMESPACE - -namespace QScript { - -extern QString numberToString(qsreal value); - -// copy of Qt::escape() (it's in QtGui :-( ) - -static QString escape(const QString& plain) -{ - QString rich; - rich.reserve(int(plain.length() * 1.1)); - for (int i = 0; i < plain.length(); ++i) { - if (plain.at(i) == QLatin1Char('<')) - rich += QLatin1String("<"); - else if (plain.at(i) == QLatin1Char('>')) - rich += QLatin1String(">"); - else if (plain.at(i) == QLatin1Char('&')) - rich += QLatin1String("&"); - else - rich += plain.at(i); - } - return rich; -} - -XmlGenerator::XmlGenerator(QTextStream &o): - out(o), m_indentLevel(-1), m_formatOutput(false) -{ -} - -XmlGenerator::~XmlGenerator() -{ -} - -QTextStream &XmlGenerator::operator()(const QString &program, int lineNumber) -{ - QScriptEnginePrivate priv; - NodePool *pool = new NodePool(/*fileName=*/QString(), &priv); - priv.setNodePool(pool); - - Lexer lex(&priv); - priv.setLexer(&lex); - lex.setCode(program, lineNumber); - - QScriptParser parser; - if (parser.parse(&priv)) { - accept(priv.abstractSyntaxTree()); - } - - delete pool; - - return out; -} - -QTextStream &XmlGenerator::newlineAndIndent() -{ - enum { IND = 2 }; - if (m_formatOutput) - out << endl << QString().fill(QLatin1Char(' '), m_indentLevel * IND); - return out; -} - -QTextStream &XmlGenerator::startTag(const QString &name, AST::Node *locationNode) -{ - pushIndentLevel(); - newlineAndIndent(); - out << QLatin1Char('<') << name; - if (locationNode) - out << QLatin1String(" line=\"") << locationNode->startLine << QLatin1Char('\"'); - out << QLatin1Char('>'); - return out; -} - -QTextStream &XmlGenerator::endTag(const QString &name) -{ - newlineAndIndent(); - popIndentLevel(); - out << QLatin1String("</") << escape(name) << QLatin1Char('>'); - return out; -} - -void XmlGenerator::accept(AST::Node *node) -{ - AST::Node::acceptChild(node, this); -} - -bool XmlGenerator::visit(AST::ThisExpression *) -{ - pushIndentLevel(); - newlineAndIndent(); - out << QLatin1String("<this/>"); - popIndentLevel(); - return true; -} - -void XmlGenerator::endVisit(AST::ThisExpression *) -{ -} - -bool XmlGenerator::visit(AST::IdentifierExpression *node) -{ - startTag(QLatin1String("identifier")); - out << escape(QScriptEnginePrivate::toString(node->name)); - out << QLatin1String("</identifier>"); - popIndentLevel(); - return false; -} - -void XmlGenerator::endVisit(AST::IdentifierExpression *) -{ -} - -bool XmlGenerator::visit(AST::NullExpression *) -{ - pushIndentLevel(); - newlineAndIndent(); - out << QLatin1String("<null/>"); - popIndentLevel(); - return false; -} - -void XmlGenerator::endVisit(AST::NullExpression *) -{ -} - -bool XmlGenerator::visit(AST::TrueLiteral *) -{ - pushIndentLevel(); - newlineAndIndent(); - out << QLatin1String("<true/>"); - popIndentLevel(); - return false; -} - -void XmlGenerator::endVisit(AST::TrueLiteral *) -{ -} - -bool XmlGenerator::visit(AST::FalseLiteral *) -{ - pushIndentLevel(); - newlineAndIndent(); - out << QLatin1String("<false/>"); - popIndentLevel(); - return false; -} - -void XmlGenerator::endVisit(AST::FalseLiteral *) -{ -} - -bool XmlGenerator::visit(AST::StringLiteral *node) -{ - startTag(QLatin1String("string")); - out << escape(QScriptEnginePrivate::toString(node->value)) << QLatin1String("</string>"); - popIndentLevel(); - return false; -} - -void XmlGenerator::endVisit(AST::StringLiteral *) -{ -} - -bool XmlGenerator::visit(AST::NumericLiteral *node) -{ - startTag(QLatin1String("number")); - out << QString::number(node->value) << QLatin1String("</number>"); - popIndentLevel(); - return false; -} - -void XmlGenerator::endVisit(AST::NumericLiteral *) -{ -} - -bool XmlGenerator::visit(AST::RegExpLiteral *node) -{ - startTag(QLatin1String("regexp")); - out << QLatin1Char('/') << escape(QScriptEnginePrivate::toString(node->pattern)) << QLatin1Char('/'); - if (node->flags) - out << QScript::Ecma::RegExp::flagsToString(node->flags); - out << QLatin1String("</regexp>"); - popIndentLevel(); - return false; -} - -void XmlGenerator::endVisit(AST::RegExpLiteral *) -{ -} - -bool XmlGenerator::visit(AST::ArrayLiteral *) -{ - startTag(QLatin1String("array-literal")); - return true; -} - -void XmlGenerator::endVisit(AST::ArrayLiteral *) -{ - endTag(QLatin1String("array-literal")); -} - -bool XmlGenerator::visit(AST::ObjectLiteral *) -{ - startTag(QLatin1String("object-literal")); - return true; -} - -void XmlGenerator::endVisit(AST::ObjectLiteral *) -{ - endTag(QLatin1String("object-literal")); -} - -bool XmlGenerator::visit(AST::ElementList *) -{ - startTag(QLatin1String("element-list")); - return true; -} - -void XmlGenerator::endVisit(AST::ElementList *) -{ - endTag(QLatin1String("element-list")); -} - -bool XmlGenerator::visit(AST::Elision *) -{ - startTag(QLatin1String("elision")); // ### count - return true; -} - -void XmlGenerator::endVisit(AST::Elision *) -{ - endTag(QLatin1String("elision")); -} - -bool XmlGenerator::visit(AST::PropertyNameAndValueList *) -{ - startTag(QLatin1String("property-name-and-value-list")); - return true; -} - -void XmlGenerator::endVisit(AST::PropertyNameAndValueList *) -{ - endTag(QLatin1String("property-name-and-value-list")); -} - -bool XmlGenerator::visit(AST::IdentifierPropertyName *node) -{ - startTag(QLatin1String("identifier")); - out << escape(QScriptEnginePrivate::toString(node->id)) << QLatin1String("</identifier>"); - popIndentLevel(); - return false; -} - -void XmlGenerator::endVisit(AST::IdentifierPropertyName *) -{ -} - -bool XmlGenerator::visit(AST::StringLiteralPropertyName *node) -{ - startTag(QLatin1String("string")); - out << escape(QScriptEnginePrivate::toString(node->id)) << QLatin1String("</string>"); - popIndentLevel(); - return false; -} - -void XmlGenerator::endVisit(AST::StringLiteralPropertyName *) -{ -} - -bool XmlGenerator::visit(AST::NumericLiteralPropertyName *node) -{ - startTag(QLatin1String("number")); - out << escape(QScript::numberToString(node->id)) << QLatin1String("</number>"); - popIndentLevel(); - return false; -} - -void XmlGenerator::endVisit(AST::NumericLiteralPropertyName *) -{ -} - -bool XmlGenerator::visit(AST::ArrayMemberExpression *) -{ - startTag(QLatin1String("array-member-expression")); - return true; -} - -void XmlGenerator::endVisit(AST::ArrayMemberExpression *) -{ - endTag(QLatin1String("array-member-expression")); -} - -bool XmlGenerator::visit(AST::FieldMemberExpression *) -{ - startTag(QLatin1String("field-member-expression")); - return true; -} - -void XmlGenerator::endVisit(AST::FieldMemberExpression *node) -{ - startTag(QLatin1String("identifier")); - out << escape(QScriptEnginePrivate::toString(node->name)); - out << QLatin1String("</identifier>"); - popIndentLevel(); - endTag(QLatin1String("field-member-expression")); -} - -bool XmlGenerator::visit(AST::NewMemberExpression *) -{ - startTag(QLatin1String("new-member-expression")); - return true; -} - -void XmlGenerator::endVisit(AST::NewMemberExpression *) -{ - endTag(QLatin1String("new-member-expression")); -} - -bool XmlGenerator::visit(AST::NewExpression *) -{ - startTag(QLatin1String("new")); - return true; -} - -void XmlGenerator::endVisit(AST::NewExpression *) -{ - endTag(QLatin1String("new")); -} - -bool XmlGenerator::visit(AST::CallExpression *) -{ - startTag(QLatin1String("call")); - return true; -} - -void XmlGenerator::endVisit(AST::CallExpression *) -{ - endTag(QLatin1String("call")); -} - -bool XmlGenerator::visit(AST::ArgumentList *) -{ - startTag(QLatin1String("argument-list")); - return true; -} - -void XmlGenerator::endVisit(AST::ArgumentList *) -{ - endTag(QLatin1String("argument-list")); -} - -bool XmlGenerator::visit(AST::PostIncrementExpression *) -{ - startTag(QLatin1String("post-increment")); - return true; -} - -void XmlGenerator::endVisit(AST::PostIncrementExpression *) -{ - endTag(QLatin1String("post-increment")); -} - -bool XmlGenerator::visit(AST::PostDecrementExpression *) -{ - startTag(QLatin1String("post-decrement")); - return true; -} - -void XmlGenerator::endVisit(AST::PostDecrementExpression *) -{ - endTag(QLatin1String("post-decrement")); -} - -bool XmlGenerator::visit(AST::DeleteExpression *) -{ - startTag(QLatin1String("delete")); - return true; -} - -void XmlGenerator::endVisit(AST::DeleteExpression *) -{ - endTag(QLatin1String("delete")); -} - -bool XmlGenerator::visit(AST::VoidExpression *) -{ - startTag(QLatin1String("void")); - return true; -} - -void XmlGenerator::endVisit(AST::VoidExpression *) -{ - endTag(QLatin1String("void")); -} - -bool XmlGenerator::visit(AST::TypeOfExpression *) -{ - startTag(QLatin1String("typeof")); - return true; -} - -void XmlGenerator::endVisit(AST::TypeOfExpression *) -{ - endTag(QLatin1String("typeof")); -} - -bool XmlGenerator::visit(AST::PreIncrementExpression *) -{ - startTag(QLatin1String("pre-increment")); - return true; -} - -void XmlGenerator::endVisit(AST::PreIncrementExpression *) -{ - endTag(QLatin1String("pre-increment")); -} - -bool XmlGenerator::visit(AST::PreDecrementExpression *) -{ - startTag(QLatin1String("pre-decrement")); - return true; -} - -void XmlGenerator::endVisit(AST::PreDecrementExpression *) -{ - endTag(QLatin1String("pre-decrement")); -} - -bool XmlGenerator::visit(AST::UnaryPlusExpression *) -{ - startTag(QLatin1String("unary-plus")); - return true; -} - -void XmlGenerator::endVisit(AST::UnaryPlusExpression *) -{ - endTag(QLatin1String("unary-plus")); -} - -bool XmlGenerator::visit(AST::UnaryMinusExpression *) -{ - startTag(QLatin1String("unary-minus")); - return true; -} - -void XmlGenerator::endVisit(AST::UnaryMinusExpression *) -{ - endTag(QLatin1String("unary-minus")); -} - -bool XmlGenerator::visit(AST::TildeExpression *) -{ - startTag(QLatin1String("bitwise-not")); - return true; -} - -void XmlGenerator::endVisit(AST::TildeExpression *) -{ - endTag(QLatin1String("bitwise-not")); -} - -bool XmlGenerator::visit(AST::NotExpression *) -{ - startTag(QLatin1String("logical-not")); - return true; -} - -void XmlGenerator::endVisit(AST::NotExpression *) -{ - endTag(QLatin1String("logical-not")); -} - -bool XmlGenerator::visit(AST::BinaryExpression *node) -{ - QString s; - switch (node->op) { - case QSOperator::Add: - s = QLatin1String("+"); break; - case QSOperator::And: - s = QLatin1String("&&"); break; - case QSOperator::InplaceAnd: - s = QLatin1String("&="); break; - case QSOperator::Assign: - s = QLatin1String("="); break; - case QSOperator::BitAnd: - s = QLatin1String("&"); break; - case QSOperator::BitOr: - s = QLatin1String("|"); break; - case QSOperator::BitXor: - s = QLatin1String("^"); break; - case QSOperator::InplaceSub: - s = QLatin1String("-="); break; - case QSOperator::Div: - s = QLatin1String("/"); break; - case QSOperator::InplaceDiv: - s = QLatin1String("/="); break; - case QSOperator::Equal: - s = QLatin1String("=="); break; - case QSOperator::Ge: - s = QLatin1String(">="); break; - case QSOperator::Gt: - s = QLatin1String(">"); break; - case QSOperator::In: - s = QLatin1String("in"); break; - case QSOperator::InplaceAdd: - s = QLatin1String("+="); break; - case QSOperator::InstanceOf: - s = QLatin1String("instanceof"); break; - case QSOperator::Le: - s = QLatin1String("<="); break; - case QSOperator::LShift: - s = QLatin1String("<<"); break; - case QSOperator::InplaceLeftShift: - s = QLatin1String("<<="); break; - case QSOperator::Lt: - s = QLatin1String("<"); break; - case QSOperator::Mod: - s = QLatin1String("%"); break; - case QSOperator::InplaceMod: - s = QLatin1String("%="); break; - case QSOperator::Mul: - s = QLatin1String("*"); break; - case QSOperator::InplaceMul: - s = QLatin1String("*="); break; - case QSOperator::NotEqual: - s = QLatin1String("!="); break; - case QSOperator::Or: - s = QLatin1String("||"); break; - case QSOperator::InplaceOr: - s = QLatin1String("|="); break; - case QSOperator::RShift: - s = QLatin1String(">>"); break; - case QSOperator::InplaceRightShift: - s = QLatin1String(">>="); break; - case QSOperator::StrictEqual: - s = QLatin1String("==="); break; - case QSOperator::StrictNotEqual: - s = QLatin1String("!=="); break; - case QSOperator::Sub: - s = QLatin1String("-"); break; - case QSOperator::URShift: - s = QLatin1String(">>>"); break; - case QSOperator::InplaceURightShift: - s = QLatin1String(">>>="); break; - case QSOperator::InplaceXor: - s = QLatin1String("^="); break; - default: - Q_ASSERT (0); - } - pushIndentLevel(); - newlineAndIndent(); - out << QLatin1String("<binary-expression op=\"") << s << QLatin1String("\">"); - return true; -} - -void XmlGenerator::endVisit(AST::BinaryExpression *) -{ - endTag(QLatin1String("binary-expression")); -} - -bool XmlGenerator::visit(AST::ConditionalExpression *) -{ - startTag(QLatin1String("conditional")); - return true; -} - -void XmlGenerator::endVisit(AST::ConditionalExpression *) -{ - endTag(QLatin1String("conditional")); -} - -bool XmlGenerator::visit(AST::Expression *) -{ - startTag(QLatin1String("comma-expression")); - return true; -} - -void XmlGenerator::endVisit(AST::Expression *) -{ - endTag(QLatin1String("comma-expression")); -} - -bool XmlGenerator::visit(AST::Block *) -{ - startTag(QLatin1String("block")); - return true; -} - -void XmlGenerator::endVisit(AST::Block *) -{ - endTag(QLatin1String("block")); -} - -bool XmlGenerator::visit(AST::StatementList *) -{ - startTag(QLatin1String("statement-list")); - return true; -} - -void XmlGenerator::endVisit(AST::StatementList *) -{ - endTag(QLatin1String("statement-list")); -} - -bool XmlGenerator::visit(AST::VariableDeclarationList *) -{ - startTag(QLatin1String("variable-declaration-list")); - return true; -} - -void XmlGenerator::endVisit(AST::VariableDeclarationList *) -{ - endTag(QLatin1String("variable-declaration-list")); -} - -bool XmlGenerator::visit(AST::VariableStatement *node) -{ - startTag(QLatin1String("variable-statement"), node); - return true; -} - -void XmlGenerator::endVisit(AST::VariableStatement *) -{ - endTag(QLatin1String("variable-statement")); -} - -bool XmlGenerator::visit(AST::VariableDeclaration *node) -{ - startTag(QLatin1String("variable-declaration"), node); - startTag(QLatin1String("name")); - out << escape(QScriptEnginePrivate::toString(node->name)); - out << QLatin1String("</name>"); - popIndentLevel(); - return true; -} - -void XmlGenerator::endVisit(AST::VariableDeclaration *) -{ - endTag(QLatin1String("variable-declaration")); -} - -bool XmlGenerator::visit(AST::EmptyStatement *node) -{ - startTag(QLatin1String("empty-statement"), node); - return true; -} - -void XmlGenerator::endVisit(AST::EmptyStatement *) -{ - endTag(QLatin1String("empty-statement")); -} - -bool XmlGenerator::visit(AST::ExpressionStatement *node) -{ - startTag(QLatin1String("expression-statement"), node); - return true; -} - -void XmlGenerator::endVisit(AST::ExpressionStatement *) -{ - endTag(QLatin1String("expression-statement")); -} - -bool XmlGenerator::visit(AST::IfStatement *node) -{ - startTag(QLatin1String("if"), node); - return true; -} - -void XmlGenerator::endVisit(AST::IfStatement *) -{ - endTag(QLatin1String("if")); -} - -bool XmlGenerator::visit(AST::DoWhileStatement *node) -{ - startTag(QLatin1String("do-while"), node); - return true; -} - -void XmlGenerator::endVisit(AST::DoWhileStatement *) -{ - endTag(QLatin1String("do-while")); -} - -bool XmlGenerator::visit(AST::WhileStatement *node) -{ - startTag(QLatin1String("while"), node); - return true; -} - -void XmlGenerator::endVisit(AST::WhileStatement *) -{ - endTag(QLatin1String("while")); -} - -bool XmlGenerator::visit(AST::ForStatement *node) -{ - startTag(QLatin1String("for"), node); - return true; -} - -void XmlGenerator::endVisit(AST::ForStatement *) -{ - endTag(QLatin1String("for")); -} - -bool XmlGenerator::visit(AST::LocalForStatement *node) -{ - startTag(QLatin1String("for"), node); - return true; -} - -void XmlGenerator::endVisit(AST::LocalForStatement *) -{ - endTag(QLatin1String("for")); -} - -bool XmlGenerator::visit(AST::ForEachStatement *node) -{ - startTag(QLatin1String("for-in"), node); - return false; -} - -void XmlGenerator::endVisit(AST::ForEachStatement *) -{ - endTag(QLatin1String("for-in")); -} - -bool XmlGenerator::visit(AST::LocalForEachStatement *node) -{ - startTag(QLatin1String("for-in"), node); - return true; -} - -void XmlGenerator::endVisit(AST::LocalForEachStatement *) -{ - endTag(QLatin1String("for-in")); -} - -bool XmlGenerator::visit(AST::ContinueStatement *node) -{ - startTag(QLatin1String("continue"), node); - if (node->label) { - startTag(QLatin1String("label")); - out << escape(QScriptEnginePrivate::toString(node->label)); - out << QLatin1String("</label>"); - popIndentLevel(); - } - return true; -} - -void XmlGenerator::endVisit(AST::ContinueStatement *) -{ - endTag(QLatin1String("continue")); -} - -bool XmlGenerator::visit(AST::BreakStatement *node) -{ - startTag(QLatin1String("break"), node); - if (node->label) { - startTag(QLatin1String("label")); - out << escape(QScriptEnginePrivate::toString(node->label)); - out << QLatin1String("</label>"); - popIndentLevel(); - } - return true; -} - -void XmlGenerator::endVisit(AST::BreakStatement *) -{ - endTag(QLatin1String("break")); -} - -bool XmlGenerator::visit(AST::ReturnStatement *node) -{ - startTag(QLatin1String("return"), node); - return true; -} - -void XmlGenerator::endVisit(AST::ReturnStatement *) -{ - endTag(QLatin1String("return")); -} - -bool XmlGenerator::visit(AST::WithStatement *node) -{ - startTag(QLatin1String("with"), node); - return true; -} - -void XmlGenerator::endVisit(AST::WithStatement *) -{ - endTag(QLatin1String("with")); -} - -bool XmlGenerator::visit(AST::SwitchStatement *node) -{ - startTag(QLatin1String("switch"), node); - return true; -} - -void XmlGenerator::endVisit(AST::SwitchStatement *) -{ - endTag(QLatin1String("switch")); -} - -bool XmlGenerator::visit(AST::CaseBlock *) -{ - startTag(QLatin1String("case-block")); - return true; -} - -void XmlGenerator::endVisit(AST::CaseBlock *) -{ - endTag(QLatin1String("case-block")); -} - -bool XmlGenerator::visit(AST::CaseClauses *) -{ - startTag(QLatin1String("case-clauses")); - return true; -} - -void XmlGenerator::endVisit(AST::CaseClauses *) -{ - endTag(QLatin1String("case-clauses")); -} - -bool XmlGenerator::visit(AST::CaseClause *) -{ - startTag(QLatin1String("case-clause")); - return true; -} - -void XmlGenerator::endVisit(AST::CaseClause *) -{ - endTag(QLatin1String("case-clause")); -} - -bool XmlGenerator::visit(AST::DefaultClause *) -{ - startTag(QLatin1String("default-clause")); - return true; -} - -void XmlGenerator::endVisit(AST::DefaultClause *) -{ - endTag(QLatin1String("default-clause")); -} - -bool XmlGenerator::visit(AST::LabelledStatement *node) -{ - startTag(QLatin1String("labelled-statement"), node); - startTag(QLatin1String("label")); - out << escape(QScriptEnginePrivate::toString(node->label)); - out << QLatin1String("</label>"); - popIndentLevel(); - return true; -} - -void XmlGenerator::endVisit(AST::LabelledStatement *) -{ - endTag(QLatin1String("labelled-statement")); -} - -bool XmlGenerator::visit(AST::ThrowStatement *node) -{ - startTag(QLatin1String("throw"), node); - return true; -} - -void XmlGenerator::endVisit(AST::ThrowStatement *) -{ - endTag(QLatin1String("throw")); -} - -bool XmlGenerator::visit(AST::TryStatement *node) -{ - startTag(QLatin1String("try"), node); - return true; -} - -void XmlGenerator::endVisit(AST::TryStatement *) -{ - endTag(QLatin1String("try")); -} - -bool XmlGenerator::visit(AST::Catch *node) -{ - startTag(QLatin1String("catch")); - startTag(QLatin1String("identifier")); - out << escape(QScriptEnginePrivate::toString(node->name)); - out << QLatin1String("</identifier>"); - popIndentLevel(); - return true; -} - -void XmlGenerator::endVisit(AST::Catch *) -{ - endTag(QLatin1String("catch")); -} - -bool XmlGenerator::visit(AST::Finally *) -{ - startTag(QLatin1String("finally")); - return true; -} - -void XmlGenerator::endVisit(AST::Finally *) -{ - endTag(QLatin1String("finally")); -} - -bool XmlGenerator::visit(AST::FunctionDeclaration *node) -{ - startTag(QLatin1String("function-declaration"), node); - startTag(QLatin1String("name")); - if (node->name) - out << escape(QScriptEnginePrivate::toString(node->name)); - out << QLatin1String("</name>"); - popIndentLevel(); - if (!node->formals) { - startTag(QLatin1String("formal-parameter-list")); - endTag(QLatin1String("formal-parameter-list")); - } - if (!node->body) { - startTag(QLatin1String("function-body")); - endTag(QLatin1String("function-body")); - } - return true; -} - -void XmlGenerator::endVisit(AST::FunctionDeclaration *) -{ - endTag(QLatin1String("function-declaration")); -} - -bool XmlGenerator::visit(AST::FunctionExpression *node) -{ - startTag(QLatin1String("function-expression"), node); - startTag(QLatin1String("name")); - if (node->name) - out << escape(QScriptEnginePrivate::toString(node->name)); - out << QLatin1String("</name>"); - if (!node->formals) { - startTag(QLatin1String("formal-parameter-list")); - endTag(QLatin1String("formal-parameter-list")); - } - if (!node->body) { - startTag(QLatin1String("function-body")); - endTag(QLatin1String("function-body")); - } - return true; -} - -void XmlGenerator::endVisit(AST::FunctionExpression *) -{ - endTag(QLatin1String("function-expression")); -} - -bool XmlGenerator::visit(AST::FormalParameterList *node) -{ - Q_UNUSED(node); - startTag(QLatin1String("formal-parameter-list")); - for (AST::FormalParameterList *it = node; it; it = it->next) { - startTag(QLatin1String("identifier")); - out << escape(QScriptEnginePrivate::toString(it->name)); - out << QLatin1String("</identifier>"); - popIndentLevel(); - } - return true; -} - -void XmlGenerator::endVisit(AST::FormalParameterList *) -{ - endTag(QLatin1String("formal-parameter-list")); -} - -bool XmlGenerator::visit(AST::FunctionBody *) -{ - startTag(QLatin1String("function-body")); - return true; -} - -void XmlGenerator::endVisit(AST::FunctionBody *) -{ - endTag(QLatin1String("function-body")); -} - -bool XmlGenerator::visit(AST::Program *) -{ - startTag(QLatin1String("program")); - return true; -} - -void XmlGenerator::endVisit(AST::Program *) -{ - endTag(QLatin1String("program")); -} - -bool XmlGenerator::visit(AST::SourceElements *) -{ - startTag(QLatin1String("source-elements")); - return true; -} - -void XmlGenerator::endVisit(AST::SourceElements *) -{ - endTag(QLatin1String("source-elements")); -} - -bool XmlGenerator::visit(AST::FunctionSourceElement *) -{ - return true; -} - -void XmlGenerator::endVisit(AST::FunctionSourceElement *) -{ -} - -bool XmlGenerator::visit(AST::StatementSourceElement *) -{ - return true; -} - -void XmlGenerator::endVisit(AST::StatementSourceElement *) -{ -} - -bool XmlGenerator::visit(AST::DebuggerStatement *node) -{ - startTag(QLatin1String("debugger-statement"), node); - return true; -} - -void XmlGenerator::endVisit(AST::DebuggerStatement *) -{ - endTag(QLatin1String("debugger-statement")); -} - -bool XmlGenerator::preVisit(AST::Node *) -{ - return true; -} - -} // namespace QScript - -Q_SCRIPT_EXPORT QString qt_scriptToXml(const QString &program, int lineNumber = 1) -{ - QString result; - QTextStream out(&result, QIODevice::WriteOnly); - QScript::XmlGenerator gen(out); - gen(program, lineNumber); - out.flush(); - return result; -} - -QT_END_NAMESPACE - -#endif // QT_NO_SCRIPT diff --git a/src/script/qscriptxmlgenerator_p.h b/src/script/qscriptxmlgenerator_p.h deleted file mode 100644 index 265bb5f..0000000 --- a/src/script/qscriptxmlgenerator_p.h +++ /dev/null @@ -1,330 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTXMLGENERATOR_P_H -#define QSCRIPTXMLGENERATOR_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> - -#ifndef QT_NO_SCRIPT - -#include "qscriptastvisitor_p.h" - -QT_BEGIN_NAMESPACE - -class QTextStream; - -namespace QScript { - -class XmlGenerator: protected AST::Visitor -{ -public: - XmlGenerator(QTextStream &out); - virtual ~XmlGenerator(); - - QTextStream &operator()(const QString &program, int lineNumber = 1); - -protected: - void accept(AST::Node *node); - - virtual bool preVisit(AST::Node *node); - - virtual bool visit(AST::ThisExpression *node); - virtual void endVisit(AST::ThisExpression *node); - - virtual bool visit(AST::IdentifierExpression *node); - virtual void endVisit(AST::IdentifierExpression *node); - - virtual bool visit(AST::NullExpression *node); - virtual void endVisit(AST::NullExpression *node); - - virtual bool visit(AST::TrueLiteral *node); - virtual void endVisit(AST::TrueLiteral *node); - - virtual bool visit(AST::FalseLiteral *node); - virtual void endVisit(AST::FalseLiteral *node); - - virtual bool visit(AST::StringLiteral *node); - virtual void endVisit(AST::StringLiteral *node); - - virtual bool visit(AST::NumericLiteral *node); - virtual void endVisit(AST::NumericLiteral *node); - - virtual bool visit(AST::RegExpLiteral *node); - virtual void endVisit(AST::RegExpLiteral *node); - - virtual bool visit(AST::ArrayLiteral *node); - virtual void endVisit(AST::ArrayLiteral *node); - - virtual bool visit(AST::ObjectLiteral *node); - virtual void endVisit(AST::ObjectLiteral *node); - - virtual bool visit(AST::ElementList *node); - virtual void endVisit(AST::ElementList *node); - - virtual bool visit(AST::Elision *node); - virtual void endVisit(AST::Elision *node); - - virtual bool visit(AST::PropertyNameAndValueList *node); - virtual void endVisit(AST::PropertyNameAndValueList *node); - - virtual bool visit(AST::IdentifierPropertyName *node); - virtual void endVisit(AST::IdentifierPropertyName *node); - - virtual bool visit(AST::StringLiteralPropertyName *node); - virtual void endVisit(AST::StringLiteralPropertyName *node); - - virtual bool visit(AST::NumericLiteralPropertyName *node); - virtual void endVisit(AST::NumericLiteralPropertyName *node); - - virtual bool visit(AST::ArrayMemberExpression *node); - virtual void endVisit(AST::ArrayMemberExpression *node); - - virtual bool visit(AST::FieldMemberExpression *node); - virtual void endVisit(AST::FieldMemberExpression *node); - - virtual bool visit(AST::NewMemberExpression *node); - virtual void endVisit(AST::NewMemberExpression *node); - - virtual bool visit(AST::NewExpression *node); - virtual void endVisit(AST::NewExpression *node); - - virtual bool visit(AST::CallExpression *node); - virtual void endVisit(AST::CallExpression *node); - - virtual bool visit(AST::ArgumentList *node); - virtual void endVisit(AST::ArgumentList *node); - - virtual bool visit(AST::PostIncrementExpression *node); - virtual void endVisit(AST::PostIncrementExpression *node); - - virtual bool visit(AST::PostDecrementExpression *node); - virtual void endVisit(AST::PostDecrementExpression *node); - - virtual bool visit(AST::DeleteExpression *node); - virtual void endVisit(AST::DeleteExpression *node); - - virtual bool visit(AST::VoidExpression *node); - virtual void endVisit(AST::VoidExpression *node); - - virtual bool visit(AST::TypeOfExpression *node); - virtual void endVisit(AST::TypeOfExpression *node); - - virtual bool visit(AST::PreIncrementExpression *node); - virtual void endVisit(AST::PreIncrementExpression *node); - - virtual bool visit(AST::PreDecrementExpression *node); - virtual void endVisit(AST::PreDecrementExpression *node); - - virtual bool visit(AST::UnaryPlusExpression *node); - virtual void endVisit(AST::UnaryPlusExpression *node); - - virtual bool visit(AST::UnaryMinusExpression *node); - virtual void endVisit(AST::UnaryMinusExpression *node); - - virtual bool visit(AST::TildeExpression *node); - virtual void endVisit(AST::TildeExpression *node); - - virtual bool visit(AST::NotExpression *node); - virtual void endVisit(AST::NotExpression *node); - - virtual bool visit(AST::BinaryExpression *node); - virtual void endVisit(AST::BinaryExpression *node); - - virtual bool visit(AST::ConditionalExpression *node); - virtual void endVisit(AST::ConditionalExpression *node); - - virtual bool visit(AST::Expression *node); - virtual void endVisit(AST::Expression *node); - - virtual bool visit(AST::Block *node); - virtual void endVisit(AST::Block *node); - - virtual bool visit(AST::StatementList *node); - virtual void endVisit(AST::StatementList *node); - - virtual bool visit(AST::VariableStatement *node); - virtual void endVisit(AST::VariableStatement *node); - - virtual bool visit(AST::VariableDeclarationList *node); - virtual void endVisit(AST::VariableDeclarationList *node); - - virtual bool visit(AST::VariableDeclaration *node); - virtual void endVisit(AST::VariableDeclaration *node); - - virtual bool visit(AST::EmptyStatement *node); - virtual void endVisit(AST::EmptyStatement *node); - - virtual bool visit(AST::ExpressionStatement *node); - virtual void endVisit(AST::ExpressionStatement *node); - - virtual bool visit(AST::IfStatement *node); - virtual void endVisit(AST::IfStatement *node); - - virtual bool visit(AST::DoWhileStatement *node); - virtual void endVisit(AST::DoWhileStatement *node); - - virtual bool visit(AST::WhileStatement *node); - virtual void endVisit(AST::WhileStatement *node); - - virtual bool visit(AST::ForStatement *node); - virtual void endVisit(AST::ForStatement *node); - - virtual bool visit(AST::LocalForStatement *node); - virtual void endVisit(AST::LocalForStatement *node); - - virtual bool visit(AST::ForEachStatement *node); - virtual void endVisit(AST::ForEachStatement *node); - - virtual bool visit(AST::LocalForEachStatement *node); - virtual void endVisit(AST::LocalForEachStatement *node); - - virtual bool visit(AST::ContinueStatement *node); - virtual void endVisit(AST::ContinueStatement *node); - - virtual bool visit(AST::BreakStatement *node); - virtual void endVisit(AST::BreakStatement *node); - - virtual bool visit(AST::ReturnStatement *node); - virtual void endVisit(AST::ReturnStatement *node); - - virtual bool visit(AST::WithStatement *node); - virtual void endVisit(AST::WithStatement *node); - - virtual bool visit(AST::SwitchStatement *node); - virtual void endVisit(AST::SwitchStatement *node); - - virtual bool visit(AST::CaseBlock *node); - virtual void endVisit(AST::CaseBlock *node); - - virtual bool visit(AST::CaseClauses *node); - virtual void endVisit(AST::CaseClauses *node); - - virtual bool visit(AST::CaseClause *node); - virtual void endVisit(AST::CaseClause *node); - - virtual bool visit(AST::DefaultClause *node); - virtual void endVisit(AST::DefaultClause *node); - - virtual bool visit(AST::LabelledStatement *node); - virtual void endVisit(AST::LabelledStatement *node); - - virtual bool visit(AST::ThrowStatement *node); - virtual void endVisit(AST::ThrowStatement *node); - - virtual bool visit(AST::TryStatement *node); - virtual void endVisit(AST::TryStatement *node); - - virtual bool visit(AST::Catch *node); - virtual void endVisit(AST::Catch *node); - - virtual bool visit(AST::Finally *node); - virtual void endVisit(AST::Finally *node); - - virtual bool visit(AST::FunctionDeclaration *node); - virtual void endVisit(AST::FunctionDeclaration *node); - - virtual bool visit(AST::FunctionExpression *node); - virtual void endVisit(AST::FunctionExpression *node); - - virtual bool visit(AST::FormalParameterList *node); - virtual void endVisit(AST::FormalParameterList *node); - - virtual bool visit(AST::FunctionBody *node); - virtual void endVisit(AST::FunctionBody *node); - - virtual bool visit(AST::Program *node); - virtual void endVisit(AST::Program *node); - - virtual bool visit(AST::SourceElements *node); - virtual void endVisit(AST::SourceElements *node); - - virtual bool visit(AST::FunctionSourceElement *node); - virtual void endVisit(AST::FunctionSourceElement *node); - - virtual bool visit(AST::StatementSourceElement *node); - virtual void endVisit(AST::StatementSourceElement *node); - - virtual bool visit(AST::DebuggerStatement *node); - virtual void endVisit(AST::DebuggerStatement *node); - -private: - int indentLevel(int level) - { - int was = m_indentLevel; - m_indentLevel = level; - return was; - } - - void pushIndentLevel() - { ++m_indentLevel; } - - void popIndentLevel() - { --m_indentLevel; } - - QTextStream &newlineAndIndent(); - QTextStream &startTag(const QString &name, AST::Node *locationNode = 0); - QTextStream &endTag(const QString &name); - -private: - QTextStream &out; - int m_indentLevel; - bool m_formatOutput; -}; - -} // namespace QScript - -#endif // QT_NO_SCRIPT - -QT_END_NAMESPACE - -#endif diff --git a/src/script/script.pri b/src/script/script.pri index 15e68de..2ee1a82 100644 --- a/src/script/script.pri +++ b/src/script/script.pri @@ -1,124 +1,4 @@ - -*-g++:DEFINES += Q_SCRIPT_DIRECT_CODE - -SOURCES += \ - $$PWD/qscriptasm.cpp \ - $$PWD/qscriptast.cpp \ - $$PWD/qscriptastvisitor.cpp \ - $$PWD/qscriptcompiler.cpp \ - $$PWD/qscriptecmaarray.cpp \ - $$PWD/qscriptecmaboolean.cpp \ - $$PWD/qscriptecmacore.cpp \ - $$PWD/qscriptecmadate.cpp \ - $$PWD/qscriptecmafunction.cpp \ - $$PWD/qscriptecmaglobal.cpp \ - $$PWD/qscriptecmamath.cpp \ - $$PWD/qscriptecmanumber.cpp \ - $$PWD/qscriptecmaobject.cpp \ - $$PWD/qscriptecmaregexp.cpp \ - $$PWD/qscriptecmastring.cpp \ - $$PWD/qscriptecmaerror.cpp \ - $$PWD/qscriptcontext_p.cpp \ - $$PWD/qscriptengine.cpp \ - $$PWD/qscriptengine_p.cpp \ - $$PWD/qscriptengineagent.cpp \ - $$PWD/qscriptextenumeration.cpp \ - $$PWD/qscriptextvariant.cpp \ - $$PWD/qscriptcontext.cpp \ - $$PWD/qscriptcontextinfo.cpp \ - $$PWD/qscriptfunction.cpp \ - $$PWD/qscriptgrammar.cpp \ - $$PWD/qscriptlexer.cpp \ - $$PWD/qscriptclassdata.cpp \ - $$PWD/qscriptparser.cpp \ - $$PWD/qscriptprettypretty.cpp \ - $$PWD/qscriptxmlgenerator.cpp \ - $$PWD/qscriptsyntaxchecker.cpp \ - $$PWD/qscriptstring.cpp \ - $$PWD/qscriptclass.cpp \ - $$PWD/qscriptclasspropertyiterator.cpp \ - $$PWD/qscriptvalueiteratorimpl.cpp \ - $$PWD/qscriptvalueiterator.cpp \ - $$PWD/qscriptvalueimpl.cpp \ - $$PWD/qscriptvalue.cpp - -HEADERS += \ - $$PWD/qscriptarray_p.h \ - $$PWD/qscriptasm_p.h \ - $$PWD/qscriptastfwd_p.h \ - $$PWD/qscriptast_p.h \ - $$PWD/qscriptastvisitor_p.h \ - $$PWD/qscriptbuffer_p.h \ - $$PWD/qscriptcompiler_p.h \ - $$PWD/qscriptcontext.h \ - $$PWD/qscriptcontextfwd_p.h \ - $$PWD/qscriptcontext_p.h \ - $$PWD/qscriptcontextinfo.h \ - $$PWD/qscriptcontextinfo_p.h \ - $$PWD/qscriptecmaarray_p.h \ - $$PWD/qscriptecmaboolean_p.h \ - $$PWD/qscriptecmacore_p.h \ - $$PWD/qscriptecmadate_p.h \ - $$PWD/qscriptecmafunction_p.h \ - $$PWD/qscriptecmaglobal_p.h \ - $$PWD/qscriptecmamath_p.h \ - $$PWD/qscriptecmanumber_p.h \ - $$PWD/qscriptecmaobject_p.h \ - $$PWD/qscriptecmaregexp_p.h \ - $$PWD/qscriptecmastring_p.h \ - $$PWD/qscriptecmaerror_p.h \ - $$PWD/qscriptengine.h \ - $$PWD/qscriptenginefwd_p.h \ - $$PWD/qscriptengine_p.h \ - $$PWD/qscriptengineagent.h \ - $$PWD/qscriptengineagent_p.h \ - $$PWD/qscriptable.h \ - $$PWD/qscriptable_p.h \ - $$PWD/qscriptextenumeration_p.h \ - $$PWD/qscriptextvariant_p.h \ - $$PWD/qscriptfunction_p.h \ - $$PWD/qscriptgc_p.h \ - $$PWD/qscriptglobals_p.h \ - $$PWD/qscriptgrammar_p.h \ - $$PWD/qscriptobjectdata_p.h \ - $$PWD/qscriptobjectfwd_p.h \ - $$PWD/qscriptobject_p.h \ - $$PWD/qscriptlexer_p.h \ - $$PWD/qscriptmemberfwd_p.h \ - $$PWD/qscriptmember_p.h \ - $$PWD/qscriptmemorypool_p.h \ - $$PWD/qscriptnodepool_p.h \ - $$PWD/qscriptclassinfo_p.h \ - $$PWD/qscriptparser_p.h \ - $$PWD/qscriptprettypretty_p.h \ - $$PWD/qscriptsyntaxcheckresult_p.h \ - $$PWD/qscriptxmlgenerator_p.h \ - $$PWD/qscriptrepository_p.h \ - $$PWD/qscriptsyntaxchecker_p.h \ - $$PWD/qscriptstring.h \ - $$PWD/qscriptstring_p.h \ - $$PWD/qscriptclass.h \ - $$PWD/qscriptclass_p.h \ - $$PWD/qscriptclasspropertyiterator.h \ - $$PWD/qscriptclasspropertyiterator_p.h \ - $$PWD/qscriptvalue.h \ - $$PWD/qscriptvaluefwd_p.h \ - $$PWD/qscriptvalue_p.h \ - $$PWD/qscriptvalueimplfwd_p.h \ - $$PWD/qscriptvalueimpl_p.h \ - $$PWD/qscriptvalueiteratorimpl_p.h \ - $$PWD/qscriptvalueiterator.h \ - $$PWD/qscriptvalueiterator_p.h \ - $$PWD/qscriptextensioninterface.h \ - $$PWD/qscriptextensionplugin.h \ - $$PWD/qscriptnameid_p.h \ - $$PWD/qscriptclassdata_p.h - -!contains(DEFINES, QT_NO_QOBJECT) { - HEADERS += $$PWD/qscriptextqobject_p.h - SOURCES += $$PWD/qscriptextqobject.cpp \ - $$PWD/qscriptable.cpp \ - $$PWD/qscriptextensionplugin.cpp -} else { - INCLUDEPATH += $$PWD -} +include($$PWD/api/api.pri) +include($$PWD/bridge/bridge.pri) +include($$PWD/parser/parser.pri) +include($$PWD/utils/utils.pri) diff --git a/src/script/script.pro b/src/script/script.pro index 9aa9bc2..03dc341 100644 --- a/src/script/script.pro +++ b/src/script/script.pro @@ -9,4 +9,68 @@ DEFINES += QLALR_NO_QSCRIPTGRAMMAR_DEBUG_INFO unix:QMAKE_PKGCONFIG_REQUIRES = QtCore include(../qbase.pri) + +# disable JIT for now +DEFINES += ENABLE_JIT=0 +# FIXME: shared the statically built JavaScriptCore + +# Fetch the base WebKit directory from the WEBKITDIR environment variable; +# fall back to src/3rdparty otherwise +WEBKITDIR = $$(WEBKITDIR) +isEmpty(WEBKITDIR) { + WEBKITDIR = $$PWD/../3rdparty/webkit + + # FIXME: not needed once JSCBISON works + # TODO: or leave it like this since the generated file is available anyway? + SOURCES += $$WEBKITDIR/JavaScriptCore/generated/Grammar.cpp +} else { + CONFIG += building-libs + CONFIG -= QTDIR_build + include($$WEBKITDIR/WebKit.pri) +} + +# Windows CE-specific stuff copied from WebCore.pro +# ### Should rather be in JavaScriptCore.pri? +wince* { + INCLUDEPATH += $$WEBKITDIR/JavaScriptCore/os-wince + INCLUDEPATH += $$WEBKITDIR/JavaScriptCore/os-win32 + LIBS += -lmmtimer +} + +# avoid warnings when parsing JavaScriptCore.pri +# (we don't care about generating files, we already have them generated) +defineTest(addExtraCompiler) { + return(true) +} +defineTest(addExtraCompilerWithHeader) { + return(true) +} + +include($$WEBKITDIR/JavaScriptCore/JavaScriptCore.pri) + +INCLUDEPATH += $$WEBKITDIR/JavaScriptCore +INCLUDEPATH += $$WEBKITDIR/JavaScriptCore/parser +INCLUDEPATH += $$WEBKITDIR/JavaScriptCore/bytecompiler +INCLUDEPATH += $$WEBKITDIR/JavaScriptCore/debugger +INCLUDEPATH += $$WEBKITDIR/JavaScriptCore/runtime +INCLUDEPATH += $$WEBKITDIR/JavaScriptCore/wtf +INCLUDEPATH += $$WEBKITDIR/JavaScriptCore/unicode +INCLUDEPATH += $$WEBKITDIR/JavaScriptCore/interpreter +INCLUDEPATH += $$WEBKITDIR/JavaScriptCore/jit +INCLUDEPATH += $$WEBKITDIR/JavaScriptCore/profiler +INCLUDEPATH += $$WEBKITDIR/JavaScriptCore/wrec +INCLUDEPATH += $$WEBKITDIR/JavaScriptCore/API +INCLUDEPATH += $$WEBKITDIR/JavaScriptCore/bytecode +INCLUDEPATH += $$WEBKITDIR/JavaScriptCore/assembler +INCLUDEPATH += $$WEBKITDIR/JavaScriptCore/generated + +DEFINES += BUILDING_QT__=1 +DEFINES += USE_SYSTEM_MALLOC +DEFINES += WTF_USE_JAVASCRIPTCORE_BINDINGS=1 +DEFINES += WTF_CHANGES=1 +DEFINES += NDEBUG + +INCLUDEPATH += $$PWD + include(script.pri) + diff --git a/src/script/utils/qscriptdate.cpp b/src/script/utils/qscriptdate.cpp new file mode 100644 index 0000000..4f235f6 --- /dev/null +++ b/src/script/utils/qscriptdate.cpp @@ -0,0 +1,383 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptdate_p.h" + +#include <QtCore/qnumeric.h> +#include <QtCore/qstringlist.h> + +#include <math.h> + +#ifndef Q_WS_WIN +# include <time.h> +# include <sys/time.h> +#else +# include <windows.h> +#endif + +QT_BEGIN_NAMESPACE + +namespace QScript { + +qsreal ToInteger(qsreal n); + +static const qsreal HoursPerDay = 24.0; +static const qsreal MinutesPerHour = 60.0; +static const qsreal SecondsPerMinute = 60.0; +static const qsreal msPerSecond = 1000.0; +static const qsreal msPerMinute = 60000.0; +static const qsreal msPerHour = 3600000.0; +static const qsreal msPerDay = 86400000.0; + +static qsreal LocalTZA = 0.0; // initialized at startup + +static inline qsreal TimeWithinDay(qsreal t) +{ + qsreal r = ::fmod(t, msPerDay); + return (r >= 0) ? r : r + msPerDay; +} + +static inline int HourFromTime(qsreal t) +{ + int r = int(::fmod(::floor(t / msPerHour), HoursPerDay)); + return (r >= 0) ? r : r + int(HoursPerDay); +} + +static inline int MinFromTime(qsreal t) +{ + int r = int(::fmod(::floor(t / msPerMinute), MinutesPerHour)); + return (r >= 0) ? r : r + int(MinutesPerHour); +} + +static inline int SecFromTime(qsreal t) +{ + int r = int(::fmod(::floor(t / msPerSecond), SecondsPerMinute)); + return (r >= 0) ? r : r + int(SecondsPerMinute); +} + +static inline int msFromTime(qsreal t) +{ + int r = int(::fmod(t, msPerSecond)); + return (r >= 0) ? r : r + int(msPerSecond); +} + +static inline qsreal Day(qsreal t) +{ + return ::floor(t / msPerDay); +} + +static inline qsreal DaysInYear(qsreal y) +{ + if (::fmod(y, 4)) + return 365; + + else if (::fmod(y, 100)) + return 366; + + else if (::fmod(y, 400)) + return 365; + + return 366; +} + +static inline qsreal DayFromYear(qsreal y) +{ + return 365 * (y - 1970) + + ::floor((y - 1969) / 4) + - ::floor((y - 1901) / 100) + + ::floor((y - 1601) / 400); +} + +static inline qsreal TimeFromYear(qsreal y) +{ + return msPerDay * DayFromYear(y); +} + +static inline qsreal YearFromTime(qsreal t) +{ + int y = 1970; + y += (int) ::floor(t / (msPerDay * 365.2425)); + + qsreal t2 = TimeFromYear(y); + return (t2 > t) ? y - 1 : ((t2 + msPerDay * DaysInYear(y)) <= t) ? y + 1 : y; +} + +static inline bool InLeapYear(qsreal t) +{ + qsreal x = DaysInYear(YearFromTime(t)); + if (x == 365) + return 0; + + Q_ASSERT (x == 366); + return 1; +} + +static inline qsreal DayWithinYear(qsreal t) +{ + return Day(t) - DayFromYear(YearFromTime(t)); +} + +static inline qsreal MonthFromTime(qsreal t) +{ + qsreal d = DayWithinYear(t); + qsreal l = InLeapYear(t); + + if (d < 31.0) + return 0; + + else if (d < 59.0 + l) + return 1; + + else if (d < 90.0 + l) + return 2; + + else if (d < 120.0 + l) + return 3; + + else if (d < 151.0 + l) + return 4; + + else if (d < 181.0 + l) + return 5; + + else if (d < 212.0 + l) + return 6; + + else if (d < 243.0 + l) + return 7; + + else if (d < 273.0 + l) + return 8; + + else if (d < 304.0 + l) + return 9; + + else if (d < 334.0 + l) + return 10; + + else if (d < 365.0 + l) + return 11; + + return qSNaN(); // ### assert? +} + +static inline qsreal DateFromTime(qsreal t) +{ + int m = (int) ToInteger(MonthFromTime(t)); + qsreal d = DayWithinYear(t); + qsreal l = InLeapYear(t); + + switch (m) { + case 0: return d + 1.0; + case 1: return d - 30.0; + case 2: return d - 58.0 - l; + case 3: return d - 89.0 - l; + case 4: return d - 119.0 - l; + case 5: return d - 150.0 - l; + case 6: return d - 180.0 - l; + case 7: return d - 211.0 - l; + case 8: return d - 242.0 - l; + case 9: return d - 272.0 - l; + case 10: return d - 303.0 - l; + case 11: return d - 333.0 - l; + } + + return qSNaN(); // ### assert +} + +static inline qsreal WeekDay(qsreal t) +{ + qsreal r = ::fmod (Day(t) + 4.0, 7.0); + return (r >= 0) ? r : r + 7.0; +} + + +static inline qsreal MakeTime(qsreal hour, qsreal min, qsreal sec, qsreal ms) +{ + return ((hour * MinutesPerHour + min) * SecondsPerMinute + sec) * msPerSecond + ms; +} + +static inline qsreal DayFromMonth(qsreal month, qsreal leap) +{ + switch ((int) month) { + case 0: return 0; + case 1: return 31.0; + case 2: return 59.0 + leap; + case 3: return 90.0 + leap; + case 4: return 120.0 + leap; + case 5: return 151.0 + leap; + case 6: return 181.0 + leap; + case 7: return 212.0 + leap; + case 8: return 243.0 + leap; + case 9: return 273.0 + leap; + case 10: return 304.0 + leap; + case 11: return 334.0 + leap; + } + + return qSNaN(); // ### assert? +} + +static qsreal MakeDay(qsreal year, qsreal month, qsreal day) +{ + year += ::floor(month / 12.0); + + month = ::fmod(month, 12.0); + if (month < 0) + month += 12.0; + + qsreal t = TimeFromYear(year); + qsreal leap = InLeapYear(t); + + day += ::floor(t / msPerDay); + day += DayFromMonth(month, leap); + + return day - 1; +} + +static inline qsreal MakeDate(qsreal day, qsreal time) +{ + return day * msPerDay + time; +} + +static inline qsreal DaylightSavingTA(double t) +{ +#ifndef Q_WS_WIN + long int tt = (long int)(t / msPerSecond); + struct tm *tmtm = localtime((const time_t*)&tt); + if (! tmtm) + return 0; + return (tmtm->tm_isdst > 0) ? msPerHour : 0; +#else + Q_UNUSED(t); + /// ### implement me + return 0; +#endif +} + +static inline qsreal LocalTime(qsreal t) +{ + return t + LocalTZA + DaylightSavingTA(t); +} + +static inline qsreal UTC(qsreal t) +{ + return t - LocalTZA - DaylightSavingTA(t - LocalTZA); +} + +static inline qsreal TimeClip(qsreal t) +{ + if (! qIsFinite(t) || fabs(t) > 8.64e15) + return qSNaN(); + return ToInteger(t); +} + +static qsreal getLocalTZA() +{ +#ifndef Q_WS_WIN + struct tm* t; + time_t curr; + time(&curr); + t = localtime(&curr); + time_t locl = mktime(t); + t = gmtime(&curr); + time_t globl = mktime(t); + return double(locl - globl) * 1000.0; +#else + TIME_ZONE_INFORMATION tzInfo; + GetTimeZoneInformation(&tzInfo); + return -tzInfo.Bias * 60.0 * 1000.0; +#endif +} + +/*! + \internal + + Converts the QDateTime \dt to an ECMA Date value (in UTC form). +*/ +qsreal FromDateTime(const QDateTime &dt) +{ + if (!dt.isValid()) + return qSNaN(); + if (!LocalTZA) // ### move + LocalTZA = getLocalTZA(); + QDate date = dt.date(); + QTime taim = dt.time(); + int year = date.year(); + int month = date.month() - 1; + int day = date.day(); + int hours = taim.hour(); + int mins = taim.minute(); + int secs = taim.second(); + int ms = taim.msec(); + double t = MakeDate(MakeDay(year, month, day), + MakeTime(hours, mins, secs, ms)); + if (dt.timeSpec() == Qt::LocalTime) + t = UTC(t); + return TimeClip(t); +} + +/*! + \internal + + Converts the ECMA Date value \tt (in UTC form) to QDateTime + according to \a spec. +*/ +QDateTime ToDateTime(qsreal t, Qt::TimeSpec spec) +{ + if (qIsNaN(t)) + return QDateTime(); + if (!LocalTZA) // ### move + LocalTZA = getLocalTZA(); + if (spec == Qt::LocalTime) + t = LocalTime(t); + int year = int(YearFromTime(t)); + int month = int(MonthFromTime(t) + 1); + int day = int(DateFromTime(t)); + int hours = HourFromTime(t); + int mins = MinFromTime(t); + int secs = SecFromTime(t); + int ms = msFromTime(t); + return QDateTime(QDate(year, month, day), QTime(hours, mins, secs, ms), spec); +} + +} // namespace QScript + +QT_END_NAMESPACE diff --git a/src/script/qscriptvalueiterator_p.h b/src/script/utils/qscriptdate_p.h index 3c0e3b6..218650d 100644 --- a/src/script/qscriptvalueiterator_p.h +++ b/src/script/utils/qscriptdate_p.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef QSCRIPTVALUEITERATOR_P_H -#define QSCRIPTVALUEITERATOR_P_H +#ifndef QSCRIPTDATE_P_H +#define QSCRIPTDATE_P_H // // W A R N I N G @@ -53,23 +53,18 @@ // We mean it. // +#include <QtCore/qdatetime.h> + QT_BEGIN_NAMESPACE -class QScriptValueIteratorImpl; +typedef double qsreal; -class QScriptValueIterator; -class QScriptValueIteratorPrivate +namespace QScript { - Q_DECLARE_PUBLIC(QScriptValueIterator) -public: - QScriptValueIteratorPrivate(); - ~QScriptValueIteratorPrivate(); - - QScriptValueIterator *q_ptr; - - QScriptValueIteratorImpl *it; -}; + qsreal FromDateTime(const QDateTime &dt); + QDateTime ToDateTime(qsreal t, Qt::TimeSpec spec); +} QT_END_NAMESPACE -#endif // QSCRIPTVALUEITERATOR_P_H +#endif diff --git a/src/script/utils/utils.pri b/src/script/utils/utils.pri new file mode 100644 index 0000000..d8302d5 --- /dev/null +++ b/src/script/utils/utils.pri @@ -0,0 +1,5 @@ +SOURCES += \ + $$PWD/qscriptdate.cpp + +HEADERS += \ + $$PWD/qscriptdate_p.h |