diff options
-rw-r--r-- | src/qml/qml/qqmlboundsignal.cpp | 97 | ||||
-rw-r--r-- | src/qml/qml/qqmlboundsignal_p.h | 40 |
2 files changed, 96 insertions, 41 deletions
diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp index e5a0df8c32..8c3e1c7384 100644 --- a/src/qml/qml/qqmlboundsignal.cpp +++ b/src/qml/qml/qqmlboundsignal.cpp @@ -66,36 +66,44 @@ static QQmlJavaScriptExpression::VTable QQmlBoundSignalExpression_jsvtable = { QQmlBoundSignalExpression::expressionChanged }; +QQmlBoundSignalExpression::ExtraData::ExtraData(const QString &handlerName, const QString ¶meterString, + const QString &expression, const QString &fileName, + quint16 line, quint16 column) + : m_handlerName(handlerName), + m_parameterString(parameterString), + m_expression(expression), + m_fileName(fileName), + m_line(line), + m_column(column) +{ +} + QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index, QQmlContextData *ctxt, QObject *scope, const QString &expression, const QString &fileName, quint16 line, quint16 column, const QString &handlerName, const QString ¶meterString) : QQmlJavaScriptExpression(&QQmlBoundSignalExpression_jsvtable), - m_fileName(fileName), - m_line(line), - m_column(column), m_target(target), m_index(index), - m_expressionFunctionValid(false), - m_invalidParameterName(false) + m_extra(new ExtraData(handlerName, parameterString, expression, fileName, line, column)) { + setExpressionFunctionValid(false); + setInvalidParameterName(false); + init(ctxt, scope); - m_handlerName = handlerName; - m_parameterString = parameterString; - m_expression = expression; } QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index, QQmlContextData *ctxt, QObject *scope, const QV4::ValueRef &function) : QQmlJavaScriptExpression(&QQmlBoundSignalExpression_jsvtable), m_v8function(function), - m_line(USHRT_MAX), - m_column(USHRT_MAX), m_target(target), m_index(index), - m_expressionFunctionValid(true), - m_invalidParameterName(false) + m_extra(0) { + setExpressionFunctionValid(true); + setInvalidParameterName(false); + init(ctxt, scope); } @@ -124,21 +132,55 @@ void QQmlBoundSignalExpression::expressionChanged(QQmlJavaScriptExpression *) // bound signals do not notify on change. } +QString QQmlBoundSignalExpression::sourceFile() const +{ + if (expressionFunctionValid()) { + QV4::Function *f = function(); + Q_ASSERT(f); + return f->sourceFile(); + } + Q_ASSERT(!m_extra.isNull()); + return m_extra->m_fileName; +} + +quint16 QQmlBoundSignalExpression::lineNumber() const +{ + if (expressionFunctionValid()) { + QV4::Function *f = function(); + Q_ASSERT(f); + return f->compiledFunction->location.line; + } + Q_ASSERT(!m_extra.isNull()); + return m_extra->m_line; +} + +quint16 QQmlBoundSignalExpression::columnNumber() const +{ + if (expressionFunctionValid()) { + QV4::Function *f = function(); + Q_ASSERT(f); + return f->compiledFunction->location.column; + } + Q_ASSERT(!m_extra.isNull()); + return m_extra->m_column; +} + QString QQmlBoundSignalExpression::expression() const { - if (m_expressionFunctionValid) { + if (expressionFunctionValid()) { Q_ASSERT (context() && engine()); QV4::Scope scope(QQmlEnginePrivate::get(engine())->v4engine()); QV4::ScopedValue v(scope, m_v8function.value()); return v->toQStringNoThrow(); } else { - return m_expression; + Q_ASSERT(!m_extra.isNull()); + return m_extra->m_expression; } } QV4::Function *QQmlBoundSignalExpression::function() const { - if (m_expressionFunctionValid) { + if (expressionFunctionValid()) { Q_ASSERT (context() && engine()); QV4::Scope scope(QQmlEnginePrivate::get(engine())->v4engine()); QV4::Scoped<QV4::FunctionObject> v(scope, m_v8function.value()); @@ -153,7 +195,7 @@ void QQmlBoundSignalExpression::evaluate(void **a) { Q_ASSERT (context() && engine()); - if (m_invalidParameterName) + if (invalidParameterName()) return; QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine()); @@ -161,14 +203,15 @@ void QQmlBoundSignalExpression::evaluate(void **a) ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation. { - if (!m_expressionFunctionValid) { + if (!expressionFunctionValid()) { + Q_ASSERT(!m_extra.isNull()); QString expression; expression = QStringLiteral("(function "); - expression += m_handlerName; + expression += m_extra->m_handlerName; expression += QLatin1Char('('); - if (m_parameterString.isEmpty()) { + if (m_extra->m_parameterString.isEmpty()) { QString error; //TODO: look at using the property cache here (as in the compiler) // for further optimization @@ -177,30 +220,30 @@ void QQmlBoundSignalExpression::evaluate(void **a) if (!error.isEmpty()) { qmlInfo(scopeObject()) << error; - m_invalidParameterName = true; + setInvalidParameterName(true); ep->dereferenceScarceResources(); return; } } else - expression += m_parameterString; + expression += m_extra->m_parameterString; expression += QStringLiteral(") { "); - expression += m_expression; + expression += m_extra->m_expression; expression += QStringLiteral(" })"); - m_expression.clear(); - m_handlerName.clear(); - m_parameterString.clear(); + m_extra->m_expression.clear(); + m_extra->m_handlerName.clear(); + m_extra->m_parameterString.clear(); m_v8function = evalFunction(context(), scopeObject(), expression, - m_fileName, m_line, &m_v8qmlscope); + m_extra->m_fileName, m_extra->m_line, &m_v8qmlscope); if (m_v8function.isNullOrUndefined()) { ep->dereferenceScarceResources(); return; // could not evaluate function. Not valid. } - m_expressionFunctionValid = true; + setExpressionFunctionValid(true); } QV8Engine *engine = ep->v8engine(); diff --git a/src/qml/qml/qqmlboundsignal_p.h b/src/qml/qml/qqmlboundsignal_p.h index fe0dbd380e..93cff745e2 100644 --- a/src/qml/qml/qqmlboundsignal_p.h +++ b/src/qml/qml/qqmlboundsignal_p.h @@ -86,9 +86,9 @@ public: // evaluation of a bound signal expression doesn't return any value void evaluate(void **a); - QString sourceFile() const { return m_fileName; } - quint16 lineNumber() const { return m_line; } - quint16 columnNumber() const { return m_column; } + QString sourceFile() const; + quint16 lineNumber() const; + quint16 columnNumber() const; QString expression() const; QV4::Function *function() const; QObject *target() const { return m_target; } @@ -100,23 +100,35 @@ private: void init(QQmlContextData *ctxt, QObject *scope); + bool expressionFunctionValid() const { return m_extra.flag(); } + void setExpressionFunctionValid(bool v) { m_extra.setFlagValue(v); } + + bool invalidParameterName() const { return m_extra.flag2(); } + void setInvalidParameterName(bool v) { m_extra.setFlag2Value(v); } + QV4::PersistentValue m_v8qmlscope; QV4::PersistentValue m_v8function; - QString m_handlerName; - QString m_parameterString; - //once m_v8function is valid, we clear expression and - //extract it from m_v8function if needed. - QString m_expression; //only used when expression needs to be rewritten - QString m_fileName; - quint16 m_line; - quint16 m_column; - QObject *m_target; int m_index; - bool m_expressionFunctionValid:1; - bool m_invalidParameterName:1; + // only needed when !expressionFunctionValid() + struct ExtraData { + ExtraData(const QString &handlerName, const QString ¶meterString, + const QString &expression, const QString &fileName, + quint16 line, quint16 column); + QString m_handlerName; + QString m_parameterString; + QString m_expression; + QString m_fileName; + quint16 m_line; + quint16 m_column; + }; + + // We store some flag bits in the following flag pointers. + // flag - expressionFunctionValid + // flag2 - invalidParameterName + QFlagPointer<ExtraData> m_extra; }; class Q_QML_PRIVATE_EXPORT QQmlAbstractBoundSignal |