diff options
Diffstat (limited to 'src/declarative/qml/v4/qv4bindings.cpp')
-rw-r--r-- | src/declarative/qml/v4/qv4bindings.cpp | 1538 |
1 files changed, 0 insertions, 1538 deletions
diff --git a/src/declarative/qml/v4/qv4bindings.cpp b/src/declarative/qml/v4/qv4bindings.cpp deleted file mode 100644 index 2c26fff3d8..0000000000 --- a/src/declarative/qml/v4/qv4bindings.cpp +++ /dev/null @@ -1,1538 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// #define REGISTER_CLEANUP_DEBUG - -#include "qv4bindings_p.h" -#include "qv4program_p.h" -#include "qv4compiler_p.h" -#include "qv4compiler_p_p.h" - -#include <private/qdeclarativeaccessors_p.h> -#include <private/qdeclarativeprofilerservice_p.h> -#include <private/qdeclarativemetatype_p.h> -#include <private/qdeclarativetrace_p.h> - -#include <QtDeclarative/qdeclarativeinfo.h> -#include <QtCore/qnumeric.h> -#include <QtCore/qmath.h> -#include <math.h> // ::fmod - -QT_BEGIN_NAMESPACE - -using namespace QDeclarativeJS; - -namespace { -struct Register { - typedef QDeclarativeRegisterType Type; - - void setUndefined() { dataType = UndefinedType; } - void setNaN() { setqreal(qSNaN()); } - bool isUndefined() const { return dataType == UndefinedType; } - - void setQObject(QObject *o) { qobjectValue = o; dataType = QObjectStarType; } - QObject *getQObject() const { return qobjectValue; } - - void setqreal(qreal v) { qrealValue = v; dataType = QRealType; } - qreal getqreal() const { return qrealValue; } - qreal &getqrealref() { return qrealValue; } - - void setint(int v) { intValue = v; dataType = IntType; } - int getint() const { return intValue; } - int &getintref() { return intValue; } - - void setbool(bool v) { boolValue = v; dataType = BoolType; } - bool getbool() const { return boolValue; } - bool &getboolref() { return boolValue; } - - QVariant *getvariantptr() { return (QVariant *)typeDataPtr(); } - QString *getstringptr() { return (QString *)typeDataPtr(); } - QUrl *geturlptr() { return (QUrl *)typeDataPtr(); } - const QVariant *getvariantptr() const { return (QVariant *)typeDataPtr(); } - const QString *getstringptr() const { return (QString *)typeDataPtr(); } - const QUrl *geturlptr() const { return (QUrl *)typeDataPtr(); } - - void *typeDataPtr() { return (void *)&data; } - void *typeMemory() { return (void *)data; } - const void *typeDataPtr() const { return (void *)&data; } - const void *typeMemory() const { return (void *)data; } - - Type gettype() const { return dataType; } - void settype(Type t) { dataType = t; } - - Type dataType; // Type of data - union { - QObject *qobjectValue; - qreal qrealValue; - int intValue; - bool boolValue; - void *data[sizeof(QVariant)]; - qint64 q_for_alignment_1; - double q_for_alignment_2; - }; - - inline void cleanup(); - inline void cleanupString(); - inline void cleanupUrl(); - inline void cleanupVariant(); - - inline void copy(const Register &other); - inline void init(Type type); -#ifdef REGISTER_CLEANUP_DEBUG - Register() { - type = 0; - } - - ~Register() { - if (dataType >= FirstCleanupType) - qWarning("Register leaked of type %d", dataType); - } -#endif -}; - -void Register::cleanup() -{ - if (dataType >= FirstCleanupType) { - if (dataType == QStringType) { - getstringptr()->~QString(); - } else if (dataType == QUrlType) { - geturlptr()->~QUrl(); - } else if (dataType == QVariantType) { - getvariantptr()->~QVariant(); - } - } - setUndefined(); -} - -void Register::cleanupString() -{ - getstringptr()->~QString(); - setUndefined(); -} - -void Register::cleanupUrl() -{ - geturlptr()->~QUrl(); - setUndefined(); -} - -void Register::cleanupVariant() -{ - getvariantptr()->~QVariant(); - setUndefined(); -} - -void Register::copy(const Register &other) -{ - *this = other; - if (other.dataType >= FirstCleanupType) { - if (other.dataType == QStringType) - new (getstringptr()) QString(*other.getstringptr()); - else if (other.dataType == QUrlType) - new (geturlptr()) QUrl(*other.geturlptr()); - else if (other.dataType == QVariantType) - new (getvariantptr()) QVariant(*other.getvariantptr()); - } -} - -void Register::init(Type type) -{ - dataType = type; - if (dataType >= FirstCleanupType) { - if (dataType == QStringType) - new (getstringptr()) QString(); - else if (dataType == QUrlType) - new (geturlptr()) QUrl(); - else if (dataType == QVariantType) - new (getvariantptr()) QVariant(); - } -} - -} // end of anonymous namespace - -QV4Bindings::QV4Bindings(const char *programData, - QDeclarativeContextData *context, - QDeclarativeRefCount *ref) -: subscriptions(0), program(0), dataRef(0), bindings(0) -{ - program = (QV4Program *)programData; - dataRef = ref; - if (dataRef) dataRef->addref(); - - if (program) { - subscriptions = new Subscription[program->subscriptions]; - bindings = new Binding[program->bindings]; - - QDeclarativeAbstractExpression::setContext(context); - } -} - -QV4Bindings::~QV4Bindings() -{ - delete [] bindings; - delete [] subscriptions; subscriptions = 0; - if (dataRef) dataRef->release(); -} - -QDeclarativeAbstractBinding *QV4Bindings::configBinding(int index, QObject *target, - QObject *scope, int property, - int line, int column) -{ - Binding *rv = bindings + index; - - rv->index = index; - rv->property = property; - rv->target = target; - rv->scope = scope; - rv->line = line; - rv->column = column; - rv->parent = this; - - addref(); // This is decremented in Binding::destroy() - - return rv; -} - -void QV4Bindings::Binding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteFlags flags) -{ - if (enabled != e) { - enabled = e; - - if (e) update(flags); - } -} - -void QV4Bindings::Binding::update(QDeclarativePropertyPrivate::WriteFlags flags) -{ - parent->run(this, flags); -} - -void QV4Bindings::Binding::destroy() -{ - enabled = false; - removeFromObject(); - clear(); - removeError(); - parent->release(); -} - -int QV4Bindings::Binding::propertyIndex() const -{ - return property; -} - -QObject *QV4Bindings::Binding::object() const -{ - return target; -} - -void QV4Bindings::Subscription::subscriptionCallback(QDeclarativeNotifierEndpoint *e) -{ - Subscription *s = static_cast<Subscription *>(e); - s->bindings->subscriptionNotify(s->method); -} - -void QV4Bindings::subscriptionNotify(int id) -{ - QV4Program::BindingReferenceList *list = program->signalTable(id); - - for (quint32 ii = 0; ii < list->count; ++ii) { - QV4Program::BindingReference *bindingRef = list->bindings + ii; - - Binding *binding = bindings + bindingRef->binding; - - if (binding->executedBlocks & bindingRef->blockMask) { - run(binding, QDeclarativePropertyPrivate::DontRemoveBinding); - } - } -} - -void QV4Bindings::run(Binding *binding, QDeclarativePropertyPrivate::WriteFlags flags) -{ - if (!binding->enabled) - return; - - QDeclarativeContextData *context = QDeclarativeAbstractExpression::context(); - if (!context || !context->isValid()) - return; - - QDeclarativeTrace trace("V4 Binding Update"); - trace.addDetail("URL", context->url); - trace.addDetail("Line", binding->line); - trace.addDetail("Column", binding->column); - - QDeclarativeBindingProfiler prof(context->urlString, binding->line, binding->column); - - if (binding->updating) { - QString name; - if (binding->property & 0xFFFF0000) { - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine); - - QDeclarativeValueType *vt = ep->valueTypes[(binding->property >> 16) & 0xFF]; - Q_ASSERT(vt); - - name = QLatin1String(binding->target->metaObject()->property(binding->property & 0xFFFF).name()); - name.append(QLatin1String(".")); - name.append(QLatin1String(vt->metaObject()->property(binding->property >> 24).name())); - } else { - name = QLatin1String(binding->target->metaObject()->property(binding->property).name()); - } - qmlInfo(binding->target) << tr("Binding loop detected for property \"%1\"").arg(name); - return; - } - - binding->updating = true; - if (binding->property & 0xFFFF0000) { - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine); - - QDeclarativeValueType *vt = ep->valueTypes[(binding->property >> 16) & 0xFF]; - Q_ASSERT(vt); - vt->read(binding->target, binding->property & 0xFFFF); - - QObject *target = vt; - run(binding->index, binding->executedBlocks, context, binding, binding->scope, target, flags); - - vt->write(binding->target, binding->property & 0xFFFF, flags); - } else { - run(binding->index, binding->executedBlocks, context, binding, binding->scope, binding->target, flags); - } - binding->updating = false; -} - - -void QV4Bindings::unsubscribe(int subIndex) -{ - Subscription *sub = (subscriptions + subIndex); - sub->disconnect(); -} - -void QV4Bindings::subscribeId(QDeclarativeContextData *p, int idIndex, int subIndex) -{ - unsubscribe(subIndex); - - if (p->idValues[idIndex]) { - Subscription *sub = (subscriptions + subIndex); - sub->bindings = this; - sub->method = subIndex; - sub->connect(&p->idValues[idIndex].bindings); - } -} - -void QV4Bindings::subscribe(QObject *o, int notifyIndex, int subIndex) -{ - Subscription *sub = (subscriptions + subIndex); - if (sub->isConnected(o, notifyIndex)) - return; - sub->bindings = this; - sub->method = subIndex; - if (o) - sub->connect(o, notifyIndex); - else - sub->disconnect(); -} - -// Conversion functions - these MUST match the QtScript expression path -inline static qreal toReal(Register *reg, int type, bool *ok = 0) -{ - if (ok) *ok = true; - - if (type == QMetaType::QReal) { - return reg->getqreal(); - } else if (type == qMetaTypeId<QVariant>()) { - return reg->getvariantptr()->toReal(); - } else { - if (ok) *ok = false; - return 0; - } -} - -inline static QString toString(Register *reg, int type, bool *ok = 0) -{ - if (ok) *ok = true; - - if (type == QMetaType::QReal) { - return QString::number(reg->getqreal()); - } else if (type == QMetaType::Int) { - return QString::number(reg->getint()); - } else if (type == qMetaTypeId<QVariant>()) { - return reg->getvariantptr()->toString(); - } else if (type == QMetaType::QString) { - return *reg->getstringptr(); - } else { - if (ok) *ok = false; - return QString(); - } -} - -inline static bool toBool(Register *reg, int type, bool *ok = 0) -{ - if (ok) *ok = true; - - if (type == QMetaType::Bool) { - return reg->getbool(); - } else if (type == qMetaTypeId<QVariant>()) { - return reg->getvariantptr()->toBool(); - } else { - if (ok) *ok = false; - return false; - } -} - -inline static QUrl toUrl(Register *reg, int type, QDeclarativeContextData *context, bool *ok = 0) -{ - if (ok) *ok = true; - - QUrl base; - if (type == qMetaTypeId<QVariant>()) { - QVariant *var = reg->getvariantptr(); - int vt = var->type(); - if (vt == QVariant::Url) { - base = var->toUrl(); - } else if (vt == QVariant::ByteArray) { - // Preserve any valid percent-encoded octets supplied by the source - base.setEncodedUrl(var->toByteArray(), QUrl::TolerantMode); - } else if (vt == QVariant::String) { - base.setEncodedUrl(var->toString().toUtf8(), QUrl::TolerantMode); - } else { - if (ok) *ok = false; - return QUrl(); - } - } else if (type == QMetaType::QString) { - base.setEncodedUrl(reg->getstringptr()->toUtf8(), QUrl::TolerantMode); - } else { - if (ok) *ok = false; - return QUrl(); - } - - if (!base.isEmpty() && base.isRelative()) - return context->url.resolved(base); - else - return base; -} - -static bool testCompareVariants(const QVariant &qtscriptRaw, const QVariant &v4) -{ - QVariant qtscript = qtscriptRaw; - - if (qtscript.userType() == v4.userType()) { - } else if (qtscript.canConvert((QVariant::Type)v4.userType())) { - qtscript.convert((QVariant::Type)v4.userType()); - } else if (qtscript.userType() == QVariant::Invalid && v4.userType() == QMetaType::QObjectStar) { - qtscript = qVariantFromValue<QObject *>(0); - } else { - return false; - } - - int type = qtscript.userType(); - - if (type == QDeclarativeMetaType::QQuickAnchorLineMetaTypeId()) { - return QDeclarativeMetaType::QQuickAnchorLineCompare(qtscript.constData(), v4.constData()); - } else if (type == QMetaType::Double) { - - double la = qvariant_cast<double>(qtscript); - double lr = qvariant_cast<double>(v4); - - return la == lr || (qIsNaN(la) && qIsNaN(lr)); - - } else if (type == QMetaType::Float) { - - float la = qvariant_cast<float>(qtscript); - float lr = qvariant_cast<float>(v4); - - return la == lr || (qIsNaN(la) && qIsNaN(lr)); - - } else { - return qtscript == v4; - } -} - -QByteArray testResultToString(const QVariant &result, bool undefined) -{ - if (undefined) { - return "undefined"; - } else { - QString rv; - QDebug d(&rv); - d << result; - return rv.toUtf8(); - } -} - -static void testBindingResult(const QString &binding, int line, int column, - QDeclarativeContextData *context, QObject *scope, - const Register &result, int resultType) -{ - QDeclarativeExpression expression(context->asQDeclarativeContext(), scope, binding); - bool isUndefined = false; - QVariant value = expression.evaluate(&isUndefined); - - bool iserror = false; - QByteArray qtscriptResult; - QByteArray v4Result; - - if (expression.hasError()) { - iserror = true; - qtscriptResult = "exception"; - } else { - qtscriptResult = testResultToString(value, isUndefined); - } - - if (isUndefined && result.isUndefined()) { - return; - } else if(isUndefined != result.isUndefined()) { - iserror = true; - } - - QVariant v4value; - if (!result.isUndefined()) { - switch (resultType) { - case QMetaType::QString: - v4value = *result.getstringptr(); - break; - case QMetaType::QUrl: - v4value = *result.geturlptr(); - break; - case QMetaType::QObjectStar: - v4value = qVariantFromValue<QObject *>(result.getQObject()); - break; - case QMetaType::Bool: - v4value = result.getbool(); - break; - case QMetaType::Int: - v4value = result.getint(); - break; - case QMetaType::QReal: - v4value = result.getqreal(); - break; - default: - if (resultType == QDeclarativeMetaType::QQuickAnchorLineMetaTypeId()) { - v4value = QVariant(QDeclarativeMetaType::QQuickAnchorLineMetaTypeId(), result.typeDataPtr()); - } else { - iserror = true; - v4Result = "Unknown V4 type"; - } - } - } - if (v4Result.isEmpty()) - v4Result = testResultToString(v4value, result.isUndefined()); - - if (!testCompareVariants(value, v4value)) - iserror = true; - - if (iserror) { - qWarning().nospace() << "QV4: Optimization error @" << context->url.toString().toUtf8().constData() << ":" << line << ":" << column; - - qWarning().nospace() << " Binding: " << binding; - qWarning().nospace() << " QtScript: " << qtscriptResult.constData(); - qWarning().nospace() << " V4: " << v4Result.constData(); - } -} - -static void testBindingException(const QString &binding, int line, int column, - QDeclarativeContextData *context, QObject *scope) -{ - QDeclarativeExpression expression(context->asQDeclarativeContext(), scope, binding); - bool isUndefined = false; - QVariant value = expression.evaluate(&isUndefined); - - if (!expression.hasError()) { - QByteArray qtscriptResult = testResultToString(value, isUndefined); - qWarning().nospace() << "QV4: Optimization error @" << context->url.toString().toUtf8().constData() << ":" << line << ":" << column; - qWarning().nospace() << " Binding: " << binding; - qWarning().nospace() << " QtScript: " << qtscriptResult.constData(); - qWarning().nospace() << " V4: exception"; - } -} - -static void throwException(int id, QDeclarativeDelayedError *error, - QV4Program *program, QDeclarativeContextData *context, - const QString &description = QString()) -{ - error->error.setUrl(context->url); - if (description.isEmpty()) - error->error.setDescription(QLatin1String("TypeError: Result of expression is not an object")); - else - error->error.setDescription(description); - if (id != 0xFF) { - quint64 e = *((quint64 *)(program->data() + program->exceptionDataOffset) + id); - error->error.setLine((e >> 32) & 0xFFFFFFFF); - error->error.setColumn(e & 0xFFFFFFFF); - } else { - error->error.setLine(-1); - error->error.setColumn(-1); - } - if (!context->engine || !error->addError(QDeclarativeEnginePrivate::get(context->engine))) - QDeclarativeEnginePrivate::warning(context->engine, error->error); -} - -const qreal QV4Bindings::D32 = 4294967296.0; - -qint32 QV4Bindings::toInt32(qreal n) -{ - if (qIsNaN(n) || qIsInf(n) || (n == 0)) - return 0; - - double sign = (n < 0) ? -1.0 : 1.0; - qreal 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 QV4Bindings::toUint32(qreal n) -{ - if (qIsNaN(n) || qIsInf(n) || (n == 0)) - return 0; - - double sign = (n < 0) ? -1.0 : 1.0; - qreal abs_n = fabs(n); - - n = ::fmod(sign * ::floor(abs_n), D32); - - if (n < 0) - n += D32; - - return quint32 (n); -} - -#define THROW_EXCEPTION_STR(id, str) { \ - if (testBinding) testBindingException(*testBindingSource, bindingLine, bindingColumn, context, scope); \ - throwException((id), error, program, context, (str)); \ - goto exceptionExit; \ -} - -#define THROW_EXCEPTION(id) THROW_EXCEPTION_STR(id, QString()) - -#define MARK_REGISTER(reg) cleanupRegisterMask |= (1 << (reg)) -#define MARK_CLEAN_REGISTER(reg) cleanupRegisterMask &= ~(1 << (reg)) - -#define STRING_REGISTER(reg) { \ - registers[(reg)].settype(QStringType); \ - MARK_REGISTER(reg); \ -} - -#define URL_REGISTER(reg) { \ - registers[(reg)].settype(QUrlType); \ - MARK_REGISTER(reg); \ -} - -#define VARIANT_REGISTER(reg) { \ - registers[(reg)].settype(QVariantType); \ - MARK_REGISTER(reg); \ -} - -#ifdef QML_THREADED_INTERPRETER -void **QV4Bindings::getDecodeInstrTable() -{ - static void **decode_instr; - if (!decode_instr) { - QV4Bindings *dummy = new QV4Bindings(0, 0, 0); - quint32 executedBlocks = 0; - dummy->run(0, executedBlocks, 0, 0, 0, 0, - QDeclarativePropertyPrivate::BypassInterceptor, - &decode_instr); - dummy->release(); - } - return decode_instr; -} -#endif - -void QV4Bindings::run(int instrIndex, quint32 &executedBlocks, - QDeclarativeContextData *context, QDeclarativeDelayedError *error, - QObject *scope, QObject *output, - QDeclarativePropertyPrivate::WriteFlags storeFlags -#ifdef QML_THREADED_INTERPRETER - ,void ***table -#endif - ) -{ -#ifdef QML_THREADED_INTERPRETER - if (table) { - static void *decode_instr[] = { - FOR_EACH_V4_INSTR(QML_V4_INSTR_ADDR) - }; - - *table = decode_instr; - return; - } -#endif - - - error->removeError(); - - Register registers[32]; - quint32 cleanupRegisterMask = 0; - - executedBlocks = 0; - - const char *code = program->instructions(); - code += instrIndex * QML_V4_INSTR_SIZE(Jump, jump); - const V4Instr *instr = reinterpret_cast<const V4Instr *>(code); - - const char *data = program->data(); - - QString *testBindingSource = 0; - bool testBinding = false; - int bindingLine = 0; - int bindingColumn = 0; - -#ifdef QML_THREADED_INTERPRETER - goto *instr->common.code; -#else - for (;;) { - switch (instr->common.type) { -#endif - - QML_V4_BEGIN_INSTR(Noop, common) - QML_V4_END_INSTR(Noop, common) - - QML_V4_BEGIN_INSTR(BindingId, id) - bindingLine = instr->id.line; - bindingColumn = instr->id.column; - QML_V4_END_INSTR(BindingId, id) - - QML_V4_BEGIN_INSTR(SubscribeId, subscribeop) - subscribeId(context, instr->subscribeop.index, instr->subscribeop.offset); - QML_V4_END_INSTR(SubscribeId, subscribeop) - - QML_V4_BEGIN_INSTR(Subscribe, subscribeop) - { - QObject *o = 0; - const Register &object = registers[instr->subscribeop.reg]; - if (!object.isUndefined()) o = object.getQObject(); - subscribe(o, instr->subscribeop.index, instr->subscribeop.offset); - } - QML_V4_END_INSTR(Subscribe, subscribeop) - - QML_V4_BEGIN_INSTR(FetchAndSubscribe, fetchAndSubscribe) - { - Register ® = registers[instr->fetchAndSubscribe.reg]; - - if (reg.isUndefined()) - THROW_EXCEPTION(instr->fetchAndSubscribe.exceptionId); - - QObject *object = reg.getQObject(); - if (!object) { - reg.setUndefined(); - } else { - int subIdx = instr->fetchAndSubscribe.subscription; - Subscription *sub = 0; - if (subIdx != -1) { - sub = (subscriptions + subIdx); - sub->bindings = this; - sub->method = subIdx; - } - reg.init((Register::Type)instr->fetchAndSubscribe.valueType); - if (instr->fetchAndSubscribe.valueType >= FirstCleanupType) - MARK_REGISTER(instr->fetchAndSubscribe.reg); - QDeclarativeAccessors *accessors = instr->fetchAndSubscribe.property.accessors; - accessors->read(object, instr->fetchAndSubscribe.property.accessorData, - reg.typeDataPtr()); - - if (accessors->notifier) { - QDeclarativeNotifier *notifier = 0; - accessors->notifier(object, instr->fetchAndSubscribe.property.accessorData, ¬ifier); - if (notifier) sub->connect(notifier); - } else if (instr->fetchAndSubscribe.property.notifyIndex != -1) { - sub->connect(object, instr->fetchAndSubscribe.property.notifyIndex); - } - } - } - QML_V4_END_INSTR(FetchAndSubscribe, fetchAndSubscribe) - - QML_V4_BEGIN_INSTR(LoadId, load) - registers[instr->load.reg].setQObject(context->idValues[instr->load.index].data()); - QML_V4_END_INSTR(LoadId, load) - - QML_V4_BEGIN_INSTR(LoadScope, load) - registers[instr->load.reg].setQObject(scope); - QML_V4_END_INSTR(LoadScope, load) - - QML_V4_BEGIN_INSTR(LoadRoot, load) - registers[instr->load.reg].setQObject(context->contextObject); - QML_V4_END_INSTR(LoadRoot, load) - - QML_V4_BEGIN_INSTR(LoadAttached, attached) - { - const Register &input = registers[instr->attached.reg]; - Register &output = registers[instr->attached.output]; - if (input.isUndefined()) - THROW_EXCEPTION(instr->attached.exceptionId); - - QObject *object = registers[instr->attached.reg].getQObject(); - if (!object) { - output.setUndefined(); - } else { - QObject *attached = qmlAttachedPropertiesObjectById(instr->attached.id, input.getQObject(), true); - Q_ASSERT(attached); - output.setQObject(attached); - } - } - QML_V4_END_INSTR(LoadAttached, attached) - - QML_V4_BEGIN_INSTR(UnaryNot, unaryop) - { - registers[instr->unaryop.output].setbool(!registers[instr->unaryop.src].getbool()); - } - QML_V4_END_INSTR(UnaryNot, unaryop) - - QML_V4_BEGIN_INSTR(UnaryMinusReal, unaryop) - { - registers[instr->unaryop.output].setqreal(-registers[instr->unaryop.src].getqreal()); - } - QML_V4_END_INSTR(UnaryMinusReal, unaryop) - - QML_V4_BEGIN_INSTR(UnaryMinusInt, unaryop) - { - registers[instr->unaryop.output].setint(-registers[instr->unaryop.src].getint()); - } - QML_V4_END_INSTR(UnaryMinusInt, unaryop) - - QML_V4_BEGIN_INSTR(UnaryPlusReal, unaryop) - { - registers[instr->unaryop.output].setqreal(+registers[instr->unaryop.src].getqreal()); - } - QML_V4_END_INSTR(UnaryPlusReal, unaryop) - - QML_V4_BEGIN_INSTR(UnaryPlusInt, unaryop) - { - registers[instr->unaryop.output].setint(+registers[instr->unaryop.src].getint()); - } - QML_V4_END_INSTR(UnaryPlusInt, unaryop) - - QML_V4_BEGIN_INSTR(ConvertBoolToInt, unaryop) - { - const Register &src = registers[instr->unaryop.src]; - Register &output = registers[instr->unaryop.output]; - if (src.isUndefined()) output.setUndefined(); - else output.setint(src.getbool()); - } - QML_V4_END_INSTR(ConvertBoolToInt, unaryop) - - QML_V4_BEGIN_INSTR(ConvertBoolToReal, unaryop) - { - const Register &src = registers[instr->unaryop.src]; - Register &output = registers[instr->unaryop.output]; - if (src.isUndefined()) output.setUndefined(); - else output.setqreal(src.getbool()); - } - QML_V4_END_INSTR(ConvertBoolToReal, unaryop) - - QML_V4_BEGIN_INSTR(ConvertBoolToString, unaryop) - { - const Register &src = registers[instr->unaryop.src]; - Register &output = registers[instr->unaryop.output]; - if (src.isUndefined()) { - output.setUndefined(); - } else { - new (output.getstringptr()) QString(QLatin1String(src.getbool() ? "true" : "false")); - STRING_REGISTER(instr->unaryop.output); - } - } - QML_V4_END_INSTR(ConvertBoolToString, unaryop) - - QML_V4_BEGIN_INSTR(ConvertIntToBool, unaryop) - { - const Register &src = registers[instr->unaryop.src]; - Register &output = registers[instr->unaryop.output]; - if (src.isUndefined()) output.setUndefined(); - else output.setbool(src.getint()); - } - QML_V4_END_INSTR(ConvertIntToBool, unaryop) - - QML_V4_BEGIN_INSTR(ConvertIntToReal, unaryop) - { - const Register &src = registers[instr->unaryop.src]; - Register &output = registers[instr->unaryop.output]; - if (src.isUndefined()) output.setUndefined(); - else output.setqreal(qreal(src.getint())); - } - QML_V4_END_INSTR(ConvertIntToReal, unaryop) - - QML_V4_BEGIN_INSTR(ConvertIntToString, unaryop) - { - const Register &src = registers[instr->unaryop.src]; - Register &output = registers[instr->unaryop.output]; - if (src.isUndefined()) { - output.setUndefined(); - } else { - new (output.getstringptr()) QString(QString::number(src.getint())); - STRING_REGISTER(instr->unaryop.output); - } - } - QML_V4_END_INSTR(ConvertIntToString, unaryop) - - QML_V4_BEGIN_INSTR(ConvertRealToBool, unaryop) - { - const Register &src = registers[instr->unaryop.src]; - Register &output = registers[instr->unaryop.output]; - if (src.isUndefined()) output.setUndefined(); - else output.setbool(src.getqreal() != 0); - } - QML_V4_END_INSTR(ConvertRealToBool, unaryop) - - QML_V4_BEGIN_INSTR(ConvertRealToInt, unaryop) - { - const Register &src = registers[instr->unaryop.src]; - Register &output = registers[instr->unaryop.output]; - if (src.isUndefined()) output.setUndefined(); - else output.setint(toInt32(src.getqreal())); - } - QML_V4_END_INSTR(ConvertRealToInt, unaryop) - - QML_V4_BEGIN_INSTR(ConvertRealToString, unaryop) - { - const Register &src = registers[instr->unaryop.src]; - Register &output = registers[instr->unaryop.output]; - // ### NaN - if (src.isUndefined()) { - output.setUndefined(); - } else { - new (output.getstringptr()) QString(QString::number(src.getqreal())); - STRING_REGISTER(instr->unaryop.output); - } - } - QML_V4_END_INSTR(ConvertRealToString, unaryop) - - QML_V4_BEGIN_INSTR(ConvertStringToBool, unaryop) - { - const Register &src = registers[instr->unaryop.src]; - Register &output = registers[instr->unaryop.output]; - // ### NaN - if (src.isUndefined()) { - output.setUndefined(); - } else { - // Delegate the conversion. This is pretty fast and it doesn't require a QScriptEngine. - // Ideally we should just call the methods in the QScript namespace directly. - QJSValue tmp(*src.getstringptr()); - if (instr->unaryop.src == instr->unaryop.output) { - output.cleanupString(); - MARK_CLEAN_REGISTER(instr->unaryop.output); - } - output.setbool(tmp.toBool()); - } - } - QML_V4_END_INSTR(ConvertStringToBool, unaryop) - - QML_V4_BEGIN_INSTR(ConvertStringToInt, unaryop) - { - const Register &src = registers[instr->unaryop.src]; - Register &output = registers[instr->unaryop.output]; - // ### NaN - if (src.isUndefined()) { - output.setUndefined(); - } else { - // Delegate the conversion. This is pretty fast and it doesn't require a QScriptEngine. - // Ideally we should just call the methods in the QScript namespace directly. - QJSValue tmp(*src.getstringptr()); - if (instr->unaryop.src == instr->unaryop.output) { - output.cleanupString(); - MARK_CLEAN_REGISTER(instr->unaryop.output); - } - output.setint(tmp.toInt()); - } - } - QML_V4_END_INSTR(ConvertStringToInt, unaryop) - - QML_V4_BEGIN_INSTR(ConvertStringToReal, unaryop) - { - const Register &src = registers[instr->unaryop.src]; - Register &output = registers[instr->unaryop.output]; - // ### NaN - if (src.isUndefined()) { - output.setUndefined(); - } else { - // Delegate the conversion. This is pretty fast and it doesn't require a QScriptEngine. - // Ideally we should just call the methods in the QScript namespace directly. - QJSValue tmp(*src.getstringptr()); - if (instr->unaryop.src == instr->unaryop.output) { - output.cleanupString(); - MARK_CLEAN_REGISTER(instr->unaryop.output); - } - output.setqreal(tmp.toNumber()); - } - } - QML_V4_END_INSTR(ConvertStringToReal, unaryop) - - QML_V4_BEGIN_INSTR(ConvertStringToUrl, unaryop) - { - const Register &src = registers[instr->unaryop.src]; - Register &output = registers[instr->unaryop.output]; - // ### NaN - if (src.isUndefined()) { - output.setUndefined(); - } else { - const QString tmp(*src.getstringptr()); - if (instr->unaryop.src == instr->unaryop.output) { - output.cleanupString(); - MARK_CLEAN_REGISTER(instr->unaryop.output); - } - QUrl *urlPtr = output.geturlptr(); - new (urlPtr) QUrl(); - urlPtr->setEncodedUrl(tmp.toUtf8(), QUrl::TolerantMode); - - URL_REGISTER(instr->unaryop.output); - } - } - QML_V4_END_INSTR(ConvertStringToUrl, unaryop) - - QML_V4_BEGIN_INSTR(ConvertUrlToBool, unaryop) - { - const Register &src = registers[instr->unaryop.src]; - Register &output = registers[instr->unaryop.output]; - // ### NaN - if (src.isUndefined()) { - output.setUndefined(); - } else { - const QUrl tmp(*src.geturlptr()); - if (instr->unaryop.src == instr->unaryop.output) { - output.cleanupUrl(); - MARK_CLEAN_REGISTER(instr->unaryop.output); - } - output.setbool(!tmp.isEmpty()); - } - } - QML_V4_END_INSTR(ConvertUrlToBool, unaryop) - - QML_V4_BEGIN_INSTR(ConvertUrlToString, unaryop) - { - const Register &src = registers[instr->unaryop.src]; - Register &output = registers[instr->unaryop.output]; - // ### NaN - if (src.isUndefined()) { - output.setUndefined(); - } else { - const QUrl tmp(*src.geturlptr()); - if (instr->unaryop.src == instr->unaryop.output) { - output.cleanupUrl(); - MARK_CLEAN_REGISTER(instr->unaryop.output); - } - new (output.getstringptr()) QString(tmp.toString()); - STRING_REGISTER(instr->unaryop.output); - } - } - QML_V4_END_INSTR(ConvertUrlToString, unaryop) - - QML_V4_BEGIN_INSTR(ResolveUrl, unaryop) - { - const Register &src = registers[instr->unaryop.src]; - Register &output = registers[instr->unaryop.output]; - if (src.isUndefined()) { - output.setUndefined(); - } else { - const QUrl tmp(*src.geturlptr()); - if (instr->unaryop.src == instr->unaryop.output) { - *output.geturlptr() = context->resolvedUrl(tmp); - } else { - new (output.geturlptr()) QUrl(context->resolvedUrl(tmp)); - URL_REGISTER(instr->unaryop.output); - } - } - } - QML_V4_END_INSTR(ResolveUrl, unaryop) - - QML_V4_BEGIN_INSTR(MathSinReal, unaryop) - { - const Register &src = registers[instr->unaryop.src]; - Register &output = registers[instr->unaryop.output]; - if (src.isUndefined()) output.setUndefined(); - else output.setqreal(qSin(src.getqreal())); - } - QML_V4_END_INSTR(MathSinReal, unaryop) - - QML_V4_BEGIN_INSTR(MathCosReal, unaryop) - { - const Register &src = registers[instr->unaryop.src]; - Register &output = registers[instr->unaryop.output]; - if (src.isUndefined()) output.setUndefined(); - else output.setqreal(qCos(src.getqreal())); - } - QML_V4_END_INSTR(MathCosReal, unaryop) - - QML_V4_BEGIN_INSTR(MathRoundReal, unaryop) - { - const Register &src = registers[instr->unaryop.src]; - Register &output = registers[instr->unaryop.output]; - if (src.isUndefined()) output.setUndefined(); - else output.setint(qRound(src.getqreal())); - } - QML_V4_END_INSTR(MathRoundReal, unaryop) - - QML_V4_BEGIN_INSTR(MathFloorReal, unaryop) - { - const Register &src = registers[instr->unaryop.src]; - Register &output = registers[instr->unaryop.output]; - if (src.isUndefined()) output.setUndefined(); - else output.setint(qFloor(src.getqreal())); - } - QML_V4_END_INSTR(MathFloorReal, unaryop) - - QML_V4_BEGIN_INSTR(MathPIReal, unaryop) - { - static const qreal qmlPI = 2.0 * qAsin(1.0); - Register &output = registers[instr->unaryop.output]; - output.setqreal(qmlPI); - } - QML_V4_END_INSTR(MathPIReal, unaryop) - - QML_V4_BEGIN_INSTR(LoadReal, real_value) - registers[instr->real_value.reg].setqreal(instr->real_value.value); - QML_V4_END_INSTR(LoadReal, real_value) - - QML_V4_BEGIN_INSTR(LoadInt, int_value) - registers[instr->int_value.reg].setint(instr->int_value.value); - QML_V4_END_INSTR(LoadInt, int_value) - - QML_V4_BEGIN_INSTR(LoadBool, bool_value) - registers[instr->bool_value.reg].setbool(instr->bool_value.value); - QML_V4_END_INSTR(LoadBool, bool_value) - - QML_V4_BEGIN_INSTR(LoadString, string_value) - { - Register &output = registers[instr->string_value.reg]; - QChar *string = (QChar *)(data + instr->string_value.offset); - new (output.getstringptr()) QString(string, instr->string_value.length); - STRING_REGISTER(instr->string_value.reg); - } - QML_V4_END_INSTR(LoadString, string_value) - - QML_V4_BEGIN_INSTR(EnableV4Test, string_value) - { - testBindingSource = new QString((QChar *)(data + instr->string_value.offset), instr->string_value.length); - testBinding = true; - } - QML_V4_END_INSTR(String, string_value) - - QML_V4_BEGIN_INSTR(BitAndInt, binaryop) - { - registers[instr->binaryop.output].setint(registers[instr->binaryop.left].getint() & - registers[instr->binaryop.right].getint()); - } - QML_V4_END_INSTR(BitAndInt, binaryop) - - QML_V4_BEGIN_INSTR(BitOrInt, binaryop) - { - registers[instr->binaryop.output].setint(registers[instr->binaryop.left].getint() | - registers[instr->binaryop.right].getint()); - } - QML_V4_END_INSTR(BitAndInt, binaryop) - - QML_V4_BEGIN_INSTR(BitXorInt, binaryop) - { - registers[instr->binaryop.output].setint(registers[instr->binaryop.left].getint() ^ - registers[instr->binaryop.right].getint()); - } - QML_V4_END_INSTR(BitXorInt, binaryop) - - QML_V4_BEGIN_INSTR(AddReal, binaryop) - { - registers[instr->binaryop.output].setqreal(registers[instr->binaryop.left].getqreal() + - registers[instr->binaryop.right].getqreal()); - } - QML_V4_END_INSTR(AddReal, binaryop) - - QML_V4_BEGIN_INSTR(AddString, binaryop) - { - QString &string = *registers[instr->binaryop.output].getstringptr(); - if (instr->binaryop.output == instr->binaryop.left) { - string += registers[instr->binaryop.right].getstringptr(); - } else { - string = *registers[instr->binaryop.left].getstringptr() + - *registers[instr->binaryop.right].getstringptr(); - } - } - QML_V4_END_INSTR(AddString, binaryop) - - QML_V4_BEGIN_INSTR(SubReal, binaryop) - { - registers[instr->binaryop.output].setqreal(registers[instr->binaryop.left].getqreal() - - registers[instr->binaryop.right].getqreal()); - } - QML_V4_END_INSTR(SubReal, binaryop) - - QML_V4_BEGIN_INSTR(MulReal, binaryop) - { - registers[instr->binaryop.output].setqreal(registers[instr->binaryop.left].getqreal() * - registers[instr->binaryop.right].getqreal()); - } - QML_V4_END_INSTR(MulReal, binaryop) - - QML_V4_BEGIN_INSTR(DivReal, binaryop) - { - registers[instr->binaryop.output].setqreal(registers[instr->binaryop.left].getqreal() / - registers[instr->binaryop.right].getqreal()); - } - QML_V4_END_INSTR(DivReal, binaryop) - - QML_V4_BEGIN_INSTR(ModReal, binaryop) - { - Register &target = registers[instr->binaryop.output]; - const Register &left = registers[instr->binaryop.left]; - const Register &right = registers[instr->binaryop.right]; - if (QMetaType::QReal == QMetaType::Float) - target.setqreal(::fmodf(left.getqreal(), right.getqreal())); - else - target.setqreal(::fmod(left.getqreal(), right.getqreal())); - } - QML_V4_END_INSTR(ModInt, binaryop) - - QML_V4_BEGIN_INSTR(LShiftInt, binaryop) - { - registers[instr->binaryop.output].setint(registers[instr->binaryop.left].getint() << - registers[instr->binaryop.right].getint()); - } - QML_V4_END_INSTR(LShiftInt, binaryop) - - QML_V4_BEGIN_INSTR(RShiftInt, binaryop) - { - registers[instr->binaryop.output].setint(registers[instr->binaryop.left].getint() >> - registers[instr->binaryop.right].getint()); - } - QML_V4_END_INSTR(RShiftInt, binaryop) - - QML_V4_BEGIN_INSTR(URShiftInt, binaryop) - { - registers[instr->binaryop.output].setint((unsigned)registers[instr->binaryop.left].getint() >> - registers[instr->binaryop.right].getint()); - } - QML_V4_END_INSTR(URShiftInt, binaryop) - - QML_V4_BEGIN_INSTR(GtReal, binaryop) - { - registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getqreal() > - registers[instr->binaryop.right].getqreal()); - } - QML_V4_END_INSTR(GtReal, binaryop) - - QML_V4_BEGIN_INSTR(LtReal, binaryop) - { - registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getqreal() < - registers[instr->binaryop.right].getqreal()); - } - QML_V4_END_INSTR(LtReal, binaryop) - - QML_V4_BEGIN_INSTR(GeReal, binaryop) - { - registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getqreal() >= - registers[instr->binaryop.right].getqreal()); - } - QML_V4_END_INSTR(GeReal, binaryop) - - QML_V4_BEGIN_INSTR(LeReal, binaryop) - { - registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getqreal() <= - registers[instr->binaryop.right].getqreal()); - } - QML_V4_END_INSTR(LeReal, binaryop) - - QML_V4_BEGIN_INSTR(EqualReal, binaryop) - { - registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getqreal() == - registers[instr->binaryop.right].getqreal()); - } - QML_V4_END_INSTR(EqualReal, binaryop) - - QML_V4_BEGIN_INSTR(NotEqualReal, binaryop) - { - registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getqreal() != - registers[instr->binaryop.right].getqreal()); - } - QML_V4_END_INSTR(NotEqualReal, binaryop) - - QML_V4_BEGIN_INSTR(StrictEqualReal, binaryop) - { - registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getqreal() == - registers[instr->binaryop.right].getqreal()); - } - QML_V4_END_INSTR(StrictEqualReal, binaryop) - - QML_V4_BEGIN_INSTR(StrictNotEqualReal, binaryop) - { - registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getqreal() != - registers[instr->binaryop.right].getqreal()); - } - QML_V4_END_INSTR(StrictNotEqualReal, binaryop) - - QML_V4_BEGIN_INSTR(GtString, binaryop) - { - const QString &a = *registers[instr->binaryop.left].getstringptr(); - const QString &b = *registers[instr->binaryop.right].getstringptr(); - bool result = a > b; - if (instr->binaryop.left == instr->binaryop.output) { - registers[instr->binaryop.output].cleanupString(); - MARK_CLEAN_REGISTER(instr->binaryop.output); - } - registers[instr->binaryop.output].setbool(result); - } - QML_V4_END_INSTR(GtString, binaryop) - - QML_V4_BEGIN_INSTR(LtString, binaryop) - { - const QString &a = *registers[instr->binaryop.left].getstringptr(); - const QString &b = *registers[instr->binaryop.right].getstringptr(); - bool result = a < b; - if (instr->binaryop.left == instr->binaryop.output) { - registers[instr->binaryop.output].cleanupString(); - MARK_CLEAN_REGISTER(instr->binaryop.output); - } - registers[instr->binaryop.output].setbool(result); - } - QML_V4_END_INSTR(LtString, binaryop) - - QML_V4_BEGIN_INSTR(GeString, binaryop) - { - const QString &a = *registers[instr->binaryop.left].getstringptr(); - const QString &b = *registers[instr->binaryop.right].getstringptr(); - bool result = a >= b; - if (instr->binaryop.left == instr->binaryop.output) { - registers[instr->binaryop.output].cleanupString(); - MARK_CLEAN_REGISTER(instr->binaryop.output); - } - registers[instr->binaryop.output].setbool(result); - } - QML_V4_END_INSTR(GeString, binaryop) - - QML_V4_BEGIN_INSTR(LeString, binaryop) - { - const QString &a = *registers[instr->binaryop.left].getstringptr(); - const QString &b = *registers[instr->binaryop.right].getstringptr(); - bool result = a <= b; - if (instr->binaryop.left == instr->binaryop.output) { - registers[instr->binaryop.output].cleanupString(); - MARK_CLEAN_REGISTER(instr->binaryop.output); - } - registers[instr->binaryop.output].setbool(result); - } - QML_V4_END_INSTR(LeString, binaryop) - - QML_V4_BEGIN_INSTR(EqualString, binaryop) - { - const QString &a = *registers[instr->binaryop.left].getstringptr(); - const QString &b = *registers[instr->binaryop.right].getstringptr(); - bool result = a == b; - if (instr->binaryop.left == instr->binaryop.output) { - registers[instr->binaryop.output].cleanupString(); - MARK_CLEAN_REGISTER(instr->binaryop.output); - } - registers[instr->binaryop.output].setbool(result); - } - QML_V4_END_INSTR(EqualString, binaryop) - - QML_V4_BEGIN_INSTR(NotEqualString, binaryop) - { - const QString &a = *registers[instr->binaryop.left].getstringptr(); - const QString &b = *registers[instr->binaryop.right].getstringptr(); - bool result = a != b; - if (instr->binaryop.left == instr->binaryop.output) { - registers[instr->binaryop.output].cleanupString(); - MARK_CLEAN_REGISTER(instr->binaryop.output); - } - registers[instr->binaryop.output].setbool(result); - } - QML_V4_END_INSTR(NotEqualString, binaryop) - - QML_V4_BEGIN_INSTR(StrictEqualString, binaryop) - { - const QString &a = *registers[instr->binaryop.left].getstringptr(); - const QString &b = *registers[instr->binaryop.right].getstringptr(); - bool result = a == b; - if (instr->binaryop.left == instr->binaryop.output) { - registers[instr->binaryop.output].cleanupString(); - MARK_CLEAN_REGISTER(instr->binaryop.output); - } - registers[instr->binaryop.output].setbool(result); - } - QML_V4_END_INSTR(StrictEqualString, binaryop) - - QML_V4_BEGIN_INSTR(StrictNotEqualString, binaryop) - { - const QString &a = *registers[instr->binaryop.left].getstringptr(); - const QString &b = *registers[instr->binaryop.right].getstringptr(); - bool result = a != b; - if (instr->binaryop.left == instr->binaryop.output) { - registers[instr->binaryop.output].cleanupString(); - MARK_CLEAN_REGISTER(instr->binaryop.output); - } - registers[instr->binaryop.output].setbool(result); - } - QML_V4_END_INSTR(StrictNotEqualString, binaryop) - - QML_V4_BEGIN_INSTR(NewString, construct) - { - Register &output = registers[instr->construct.reg]; - new (output.getstringptr()) QString; - STRING_REGISTER(instr->construct.reg); - } - QML_V4_END_INSTR(NewString, construct) - - QML_V4_BEGIN_INSTR(NewUrl, construct) - { - Register &output = registers[instr->construct.reg]; - new (output.geturlptr()) QUrl; - URL_REGISTER(instr->construct.reg); - } - QML_V4_END_INSTR(NewUrl, construct) - - QML_V4_BEGIN_INSTR(Fetch, fetch) - { - Register ® = registers[instr->fetch.reg]; - - if (reg.isUndefined()) - THROW_EXCEPTION(instr->fetch.exceptionId); - - QObject *object = reg.getQObject(); - if (!object) { - THROW_EXCEPTION(instr->fetch.exceptionId); - } else { - reg.init((Register::Type)instr->fetch.valueType); - if (instr->fetch.valueType >= FirstCleanupType) - MARK_REGISTER(instr->fetch.reg); - void *argv[] = { reg.typeDataPtr(), 0 }; - QMetaObject::metacall(object, QMetaObject::ReadProperty, instr->fetch.index, argv); - } - } - QML_V4_END_INSTR(Fetch, fetch) - - QML_V4_BEGIN_INSTR(TestV4Store, storetest) - { - Register &data = registers[instr->storetest.reg]; - testBindingResult(*testBindingSource, bindingLine, bindingColumn, context, - scope, data, instr->storetest.regType); - } - QML_V4_END_INSTR(TestV4Store, storetest) - - QML_V4_BEGIN_INSTR(Store, store) - { - Register &data = registers[instr->store.reg]; - - if (data.isUndefined()) - THROW_EXCEPTION_STR(instr->store.exceptionId, QLatin1String("Unable to assign undefined value")); - - int status = -1; - void *argv[] = { data.typeDataPtr(), 0, &status, &storeFlags }; - QMetaObject::metacall(output, QMetaObject::WriteProperty, - instr->store.index, argv); - - goto programExit; - } - QML_V4_END_INSTR(Store, store) - - QML_V4_BEGIN_INSTR(Copy, copy) - registers[instr->copy.reg].copy(registers[instr->copy.src]); - if (registers[instr->copy.reg].gettype() >= FirstCleanupType) - MARK_REGISTER(instr->copy.reg); - QML_V4_END_INSTR(Copy, copy) - - QML_V4_BEGIN_INSTR(Jump, jump) - if (instr->jump.reg == -1 || !registers[instr->jump.reg].getbool()) - code += instr->jump.count; - QML_V4_END_INSTR(Jump, jump) - - QML_V4_BEGIN_INSTR(BranchTrue, branchop) - if (registers[instr->branchop.reg].getbool()) - code += instr->branchop.offset; - QML_V4_END_INSTR(BranchTrue, branchop) - - QML_V4_BEGIN_INSTR(BranchFalse, branchop) - if (! registers[instr->branchop.reg].getbool()) - code += instr->branchop.offset; - QML_V4_END_INSTR(BranchFalse, branchop) - - QML_V4_BEGIN_INSTR(Branch, branchop) - code += instr->branchop.offset; - QML_V4_END_INSTR(Branch, branchop) - - QML_V4_BEGIN_INSTR(Block, blockop) - executedBlocks |= instr->blockop.block; - QML_V4_END_INSTR(Block, blockop) - - // XXX not applicable in v8 - QML_V4_BEGIN_INSTR(InitString, initstring) -// if (!identifiers[instr->initstring.offset].identifier) { -// quint32 len = *(quint32 *)(data + instr->initstring.dataIdx); -// QChar *strdata = (QChar *)(data + instr->initstring.dataIdx + sizeof(quint32)); - -// QString str = QString::fromRawData(strdata, len); - -// // identifiers[instr->initstring.offset] = engine->objectClass->createPersistentIdentifier(str); -// } - QML_V4_END_INSTR(InitString, initstring) - - QML_V4_BEGIN_INSTR(CleanupRegister, cleanup) - registers[instr->cleanup.reg].cleanup(); - QML_V4_END_INSTR(CleanupRegister, cleanup) - -#ifdef QML_THREADED_INTERPRETER - // nothing to do -#else - default: - qFatal("QV4: Unknown instruction %d encountered.", instr->common.type); - break; - } // switch - - } // while -#endif - - Q_ASSERT(!"Unreachable code reached"); - -programExit: -exceptionExit: - delete testBindingSource; - - int reg = 0; - while (cleanupRegisterMask) { - if (cleanupRegisterMask & 0x1) - registers[reg].cleanup(); - - reg++; - cleanupRegisterMask >>= 1; - } -} - -QT_END_NAMESPACE |