diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-03-20 12:46:58 +0100 |
---|---|---|
committer | Aapo Keskimolo <aapo.keskimolo@qt.io> | 2018-04-16 17:52:13 +0000 |
commit | 4909773f8162de49830d65e886747c11fff72934 (patch) | |
tree | b5777ddbe5ada52afe3871e90085881e8b03d546 /src/qml/qml/v8 | |
parent | 8e2cfa1d77dd4568a126f5ed5736dfef844a28ef (diff) |
Fix calling Qt.binding() on bound functions
Calling Qt.binding() on a bound function object is a valid use
case and used to work until Qt 5.8.
The problem was that we optimized the code in QQmlBinding and
QQmlJavascriptExpression to directly work on a QV4::Function,
so this wouldn't work anymore.
To fix this make sure recursive calls to Function.bind() are
unrolled (so that the BoundFunction's target is never a bound
function itself), then add the bound function as an optional
member to the QQmlBinding and use it's bound arguments if
present.
Task-number: QTBUG-61927
Change-Id: I472214ddd82fc2a1212efd9b769861fc43d2ddaf
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/qml/v8')
-rw-r--r-- | src/qml/qml/v8/qqmlbuiltinfunctions.cpp | 9 | ||||
-rw-r--r-- | src/qml/qml/v8/qqmlbuiltinfunctions_p.h | 8 |
2 files changed, 11 insertions, 6 deletions
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index 1371f1f041..9e7c84011b 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -1344,11 +1344,12 @@ ReturnedValue QtObject::method_locale(const FunctionObject *b, const Value *, co return QQmlLocale::locale(scope.engine, code); } -void Heap::QQmlBindingFunction::init(const QV4::FunctionObject *originalFunction) +void Heap::QQmlBindingFunction::init(const QV4::FunctionObject *bindingFunction) { - Scope scope(originalFunction->engine()); - ScopedContext context(scope, originalFunction->scope()); - FunctionObject::init(context, originalFunction->function()); + Scope scope(bindingFunction->engine()); + ScopedContext context(scope, bindingFunction->scope()); + FunctionObject::init(context, bindingFunction->function()); + this->bindingFunction.set(internalClass->engine, bindingFunction->d()); } QQmlSourceLocation QQmlBindingFunction::currentLocation() const diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h index 104dae5d79..ee3b5f7d6e 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h +++ b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h @@ -80,8 +80,11 @@ struct ConsoleObject : Object { void init(); }; -struct QQmlBindingFunction : FunctionObject { - void init(const QV4::FunctionObject *originalFunction); +#define QQmlBindingFunctionMembers(class, Member) \ + Member(class, Pointer, FunctionObject *, bindingFunction) +DECLARE_HEAP_OBJECT(QQmlBindingFunction, FunctionObject) { + DECLARE_MARKOBJECTS(QQmlBindingFunction) + void init(const QV4::FunctionObject *bindingFunction); }; } @@ -179,6 +182,7 @@ struct QQmlBindingFunction : public QV4::FunctionObject { V4_OBJECT2(QQmlBindingFunction, FunctionObject) + Heap::FunctionObject *bindingFunction() const { return d()->bindingFunction; } QQmlSourceLocation currentLocation() const; // from caller stack trace }; |