Commit 5ae8caba authored by Aaron Kennedy's avatar Aaron Kennedy Committed by Qt by Nokia

Remove binding dependency on QQmlExpression

This is the first step to creating much lighter weight bindings that
are tuned for the specific scenario in which they're used.

Change-Id: Ib985dcff25679b711b5c634bbc891aa7902bf405
Reviewed-by: default avatarMichael Brasser <michael.brasser@nokia.com>
parent b0610835
......@@ -577,10 +577,8 @@ void QQmlEngineDebugService::setBinding(int objectId,
QQmlPropertyPrivate::setSignalExpression(property, qmlExpression);
qmlExpression->setSourceLocation(filename, line, column);
} else if (property.isProperty()) {
QQmlBinding *binding = new QQmlBinding(expression.toString(), object, context);
QQmlBinding *binding = new QQmlBinding(expression.toString(), false, object, QQmlContextData::get(context), filename, line, column);;
binding->setTarget(property);
binding->setSourceLocation(filename, line, column);
binding->setNotifyOnValueChanged(true);
QQmlAbstractBinding *oldBinding = QQmlPropertyPrivate::setBinding(property, binding);
if (oldBinding)
oldBinding->destroy();
......
......@@ -64,7 +64,6 @@ HEADERS += \
$$PWD/qqml.h \
$$PWD/qquickapplication_p.h \
$$PWD/qqmlbinding_p.h \
$$PWD/qqmlbinding_p_p.h \
$$PWD/qqmlproperty.h \
$$PWD/qqmlcomponent.h \
$$PWD/qqmlcomponent_p.h \
......
......@@ -41,6 +41,7 @@
#include "qqmlabstractbinding_p.h"
#include <QtQml/qqmlinfo.h>
#include <private/qqmlbinding_p.h>
#include <private/qqmlvaluetypeproxybinding_p.h>
......@@ -154,6 +155,12 @@ void QQmlAbstractBinding::removeFromObject()
}
}
void QQmlAbstractBinding::printBindingLoopError(QQmlProperty &prop)
{
qmlInfo(prop.object()) << QString(QLatin1String("Binding loop detected for property \"%1\"")).arg(prop.name());
}
static void bindingDummyDeleter(QQmlAbstractBinding *)
{
}
......
......@@ -92,6 +92,7 @@ public:
void removeFromObject();
static inline Pointer getPointer(QQmlAbstractBinding *p);
static void printBindingLoopError(QQmlProperty &prop);
protected:
virtual ~QQmlAbstractBinding();
......
This diff is collapsed.
......@@ -64,23 +64,26 @@
#include <private/qpointervaluepair_p.h>
#include <private/qqmlabstractbinding_p.h>
#include <private/qqmlabstractexpression_p.h>
#include <private/qqmljavascriptexpression_p.h>
QT_BEGIN_NAMESPACE
class QQmlContext;
class QQmlBindingPrivate;
class Q_QML_PRIVATE_EXPORT QQmlBinding : public QQmlExpression, public QQmlAbstractBinding
class Q_QML_PRIVATE_EXPORT QQmlBinding : public QQmlJavaScriptExpression,
public QQmlAbstractExpression,
public QQmlAbstractBinding
{
Q_OBJECT
public:
enum EvaluateFlag { None = 0x00, RequiresThisObject = 0x01 };
Q_DECLARE_FLAGS(EvaluateFlags, EvaluateFlag)
QQmlBinding(const QString &, QObject *, QQmlContext *, QObject *parent=0);
QQmlBinding(const QString &, QObject *, QQmlContextData *, QObject *parent=0);
QQmlBinding(const QString &, QObject *, QQmlContext *);
QQmlBinding(const QString &, QObject *, QQmlContextData *);
QQmlBinding(const QString &, bool isRewritten, QObject *, QQmlContextData *,
const QString &url, int lineNumber, int columnNumber = 0, QObject *parent=0);
QQmlBinding(void *, QObject *, QQmlContextData *, QObject *parent=0);
const QString &url, int lineNumber, int columnNumber);
QQmlBinding(void *, QObject *, QQmlContextData *,
const QString &url, int lineNumber, int columnNumber);
void setTarget(const QQmlProperty &);
void setTarget(QObject *, const QQmlPropertyData &, QQmlContextData *);
......@@ -89,32 +92,80 @@ public:
void setEvaluateFlags(EvaluateFlags flags);
EvaluateFlags evaluateFlags() const;
bool enabled() const;
void setNotifyOnValueChanged(bool);
// Inherited from QQmlAbstractExpression
virtual void refresh();
// Inherited from QQmlAbstractBinding
virtual void setEnabled(bool, QQmlPropertyPrivate::WriteFlags flags);
virtual void update(QQmlPropertyPrivate::WriteFlags flags);
virtual QString expression() const;
virtual int propertyIndex() const;
virtual QObject *object() const;
virtual int propertyIndex() const;
virtual void retargetBinding(QObject *, int);
typedef int Identifier;
static Identifier Invalid;
static QQmlBinding *createBinding(Identifier, QObject *, QQmlContext *,
const QString &, int, QObject *parent=0);
static QQmlBinding *createBinding(Identifier, QObject *, QQmlContext *, const QString &, int);
public Q_SLOTS:
QVariant evaluate();
void update() { update(QQmlPropertyPrivate::DontRemoveBinding); }
static QString expressionIdentifier(QQmlJavaScriptExpression *);
static void expressionChanged(QQmlJavaScriptExpression *);
protected:
~QQmlBinding();
private:
Q_DECLARE_PRIVATE(QQmlBinding)
v8::Persistent<v8::Function> v8function;
inline bool updatingFlag() const;
inline void setUpdatingFlag(bool);
inline bool enabledFlag() const;
inline void setEnabledFlag(bool);
struct Retarget {
QObject *target;
int targetProperty;
};
QPointerValuePair<QObject, Retarget> m_coreObject;
QQmlPropertyData m_core;
// We store some flag bits in the following flag pointers.
// m_ctxt:flag1 - updatingFlag
// m_ctxt:flag2 - enabledFlag
QFlagPointer<QQmlContextData> m_ctxt;
// XXX It would be good if we could get rid of these in most circumstances
QString m_url;
int m_lineNumber;
int m_columnNumber;
QByteArray m_expression;
};
bool QQmlBinding::updatingFlag() const
{
return m_ctxt.flag();
}
void QQmlBinding::setUpdatingFlag(bool v)
{
m_ctxt.setFlagValue(v);
}
bool QQmlBinding::enabledFlag() const
{
return m_ctxt.flag2();
}
void QQmlBinding::setEnabledFlag(bool v)
{
m_ctxt.setFlag2Value(v);
}
Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlBinding::EvaluateFlags)
QT_END_NAMESPACE
......
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the QtQml 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$
**
****************************************************************************/
#ifndef QQMLBINDING_P_P_H
#define QQMLBINDING_P_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 "qqmlbinding_p.h"
#include "qqmlproperty.h"
#include "qqmlexpression_p.h"
QT_BEGIN_NAMESPACE
class QQmlBindingPrivate : public QQmlExpressionPrivate
{
Q_DECLARE_PUBLIC(QQmlBinding)
public:
QQmlBindingPrivate();
~QQmlBindingPrivate();
virtual void expressionChanged();
static void printBindingLoopError(QQmlProperty &prop);
protected:
virtual void refresh();
private:
bool updating:1;
bool enabled:1;
int columnNumber;
QQmlProperty property;
QObject *target;
int targetProperty;
};
QT_END_NAMESPACE
#endif // QQMLBINDING_P_P_H
......@@ -50,13 +50,13 @@
#include "qqml.h"
#include "qqmlengine.h"
#include "qqmlbinding_p.h"
#include "qqmlbinding_p_p.h"
#include "qqmlglobal_p.h"
#include "qqmlscript_p.h"
#include <private/qqmlprofilerservice_p.h>
#include <private/qqmlenginedebugservice_p.h>
#include "qqmlincubator.h"
#include "qqmlincubator_p.h"
#include <private/qqmljavascriptexpression_p.h>
#include <private/qv8engine_p.h>
#include <private/qv8include_p.h>
......@@ -1337,9 +1337,8 @@ void QV8IncubatorResource::statusChanged(Status s)
f->Call(me, 1, args);
if (tc.HasCaught()) {
QQmlError error;
QQmlExpressionPrivate::exceptionToError(tc.Message(), error);
QQmlEnginePrivate::warning(QQmlEnginePrivate::get(engine->engine()),
error);
QQmlJavaScriptExpression::exceptionToError(tc.Message(), error);
QQmlEnginePrivate::warning(QQmlEnginePrivate::get(engine->engine()), error);
}
}
}
......
......@@ -49,7 +49,6 @@
#include "qqmlcontext.h"
#include "qqmlexpression.h"
#include "qqmlcomponent.h"
#include "qqmlbinding_p_p.h"
#include "qqmlvme_p.h"
#include <private/qqmlenginedebugservice_p.h>
#include "qqmlstringconverters_p.h"
......@@ -176,7 +175,6 @@ void QQmlEnginePrivate::registerBaseTypes(const char *uri, int versionMajor, int
void QQmlEnginePrivate::defineModule()
{
registerBaseTypes("QtQuick", 2, 0);
qmlRegisterType<QQmlBinding>();
qmlRegisterUncreatableType<QQuickApplication>("QtQuick",2,0,"Application", QQuickApplication::tr("Application is an abstract class"));
qmlRegisterUncreatableType<QQmlLocale>("QtQuick",2,0,"Locale",QQmlEngine::tr("Locale cannot be instantiated. Use Qt.locale()"));
}
......
......@@ -72,8 +72,7 @@ QQmlExpressionPrivate::~QQmlExpressionPrivate()
dataRef = 0;
}
void QQmlExpressionPrivate::init(QQmlContextData *ctxt, const QString &expr,
QObject *me)
void QQmlExpressionPrivate::init(QQmlContextData *ctxt, const QString &expr, QObject *me)
{
expression = expr;
......@@ -83,22 +82,9 @@ void QQmlExpressionPrivate::init(QQmlContextData *ctxt, const QString &expr,
expressionFunctionRewritten = false;
}
void QQmlExpressionPrivate::init(QQmlContextData *ctxt, v8::Handle<v8::Function> func,
QObject *me)
{
QQmlAbstractExpression::setContext(ctxt);
setScopeObject(me);
v8function = qPersistentNew<v8::Function>(func);
setUseSharedContext(false);
expressionFunctionValid = true;
expressionFunctionRewritten = false;
extractExpressionFromFunction = true;
}
void QQmlExpressionPrivate::init(QQmlContextData *ctxt, const QString &expr,
bool isRewritten, QObject *me, const QString &srcUrl,
int lineNumber, int columnNumber)
bool isRewritten, QObject *me, const QString &srcUrl,
int lineNumber, int columnNumber)
{
url = srcUrl;
line = lineNumber;
......@@ -114,8 +100,8 @@ void QQmlExpressionPrivate::init(QQmlContextData *ctxt, const QString &expr,
}
void QQmlExpressionPrivate::init(QQmlContextData *ctxt, const QByteArray &expr,
bool isRewritten, QObject *me, const QString &srcUrl,
int lineNumber, int columnNumber)
bool isRewritten, QObject *me, const QString &srcUrl,
int lineNumber, int columnNumber)
{
url = srcUrl;
line = lineNumber;
......@@ -140,97 +126,13 @@ void QQmlExpressionPrivate::init(QQmlContextData *ctxt, const QByteArray &expr,
setScopeObject(me);
}
// Callee owns the persistent handle
v8::Persistent<v8::Function>
QQmlExpressionPrivate::evalFunction(QQmlContextData *ctxt, QObject *scope,
const char *code, int codeLength,
const QString &filename, int line,
v8::Persistent<v8::Object> *qmlscope)
{
QQmlEngine *engine = ctxt->engine;
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
v8::HandleScope handle_scope;
v8::Context::Scope ctxtscope(ep->v8engine()->context());
v8::TryCatch tc;
v8::Local<v8::Object> scopeobject = ep->v8engine()->qmlScope(ctxt, scope);
v8::Local<v8::Script> script = ep->v8engine()->qmlModeCompile(code, codeLength, filename, line);
if (tc.HasCaught()) {
QQmlError error;
error.setDescription(QLatin1String("Exception occurred during function compilation"));
error.setLine(line);
error.setUrl(QUrl::fromLocalFile(filename));
v8::Local<v8::Message> message = tc.Message();
if (!message.IsEmpty())
QQmlExpressionPrivate::exceptionToError(message, error);
ep->warning(error);
return v8::Persistent<v8::Function>();
}
v8::Local<v8::Value> result = script->Run(scopeobject);
if (tc.HasCaught()) {
QQmlError error;
error.setDescription(QLatin1String("Exception occurred during function evaluation"));
error.setLine(line);
error.setUrl(QUrl::fromLocalFile(filename));
v8::Local<v8::Message> message = tc.Message();
if (!message.IsEmpty())
QQmlExpressionPrivate::exceptionToError(message, error);
ep->warning(error);
return v8::Persistent<v8::Function>();
}
if (qmlscope) *qmlscope = qPersistentNew<v8::Object>(scopeobject);
return qPersistentNew<v8::Function>(v8::Local<v8::Function>::Cast(result));
}
// Callee owns the persistent handle
v8::Persistent<v8::Function>
QQmlExpressionPrivate::evalFunction(QQmlContextData *ctxt, QObject *scope,
const QString &code, const QString &filename, int line,
v8::Persistent<v8::Object> *qmlscope)
{
QQmlEngine *engine = ctxt->engine;
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
v8::HandleScope handle_scope;
v8::Context::Scope ctxtscope(ep->v8engine()->context());
v8::TryCatch tc;
v8::Local<v8::Object> scopeobject = ep->v8engine()->qmlScope(ctxt, scope);
v8::Local<v8::Script> script = ep->v8engine()->qmlModeCompile(code, filename, line);
if (tc.HasCaught()) {
QQmlError error;
error.setDescription(QLatin1String("Exception occurred during function compilation"));
error.setLine(line);
error.setUrl(QUrl::fromLocalFile(filename));
v8::Local<v8::Message> message = tc.Message();
if (!message.IsEmpty())
QQmlExpressionPrivate::exceptionToError(message, error);
ep->warning(error);
return v8::Persistent<v8::Function>();
}
v8::Local<v8::Value> result = script->Run(scopeobject);
if (tc.HasCaught()) {
QQmlError error;
error.setDescription(QLatin1String("Exception occurred during function evaluation"));
error.setLine(line);
error.setUrl(QUrl::fromLocalFile(filename));
v8::Local<v8::Message> message = tc.Message();
if (!message.IsEmpty())
QQmlExpressionPrivate::exceptionToError(message, error);
ep->warning(error);
return v8::Persistent<v8::Function>();
}
if (qmlscope) *qmlscope = qPersistentNew<v8::Object>(scopeobject);
return qPersistentNew<v8::Function>(v8::Local<v8::Function>::Cast(result));
}
QQmlExpression *
QQmlExpressionPrivate::create(QQmlContextData *ctxt, QObject *object,
const QString &expr, bool isRewritten,
const QString &url, int lineNumber, int columnNumber)
const QString &expr, bool isRewritten,
const QString &url, int lineNumber, int columnNumber)
{
return new QQmlExpression(ctxt, object, expr, isRewritten, url, lineNumber, columnNumber, *new QQmlExpressionPrivate);
return new QQmlExpression(ctxt, object, expr, isRewritten, url, lineNumber, columnNumber,
*new QQmlExpressionPrivate);
}
/*!
......@@ -382,24 +284,6 @@ QQmlExpression::QQmlExpression(QQmlContextData *ctxt, QObject *scope,
d->init(ctxt, expression, scope);
}
/*!
\internal
To avoid exposing v8 in the public API, functionPtr must be a pointer to a v8::Handle<v8::Function>.
For example:
v8::Handle<v8::Function> function;
new QQmlExpression(ctxt, scope, &function, ...);
*/
QQmlExpression::QQmlExpression(QQmlContextData *ctxt, QObject *scope, void *functionPtr,
QQmlExpressionPrivate &dd)
: QObject(dd, 0)
{
v8::Handle<v8::Function> function = *(v8::Handle<v8::Function> *)functionPtr;
Q_D(QQmlExpression);
d->init(ctxt, function, scope);
}
/*!
Destroy the QQmlExpression instance.
*/
......@@ -463,31 +347,6 @@ void QQmlExpression::setExpression(const QString &expression)
qPersistentDispose(d->v8qmlscope);
}
void QQmlExpressionPrivate::exceptionToError(v8::Handle<v8::Message> message,
QQmlError &error)
{
Q_ASSERT(!message.IsEmpty());
v8::Handle<v8::Value> name = message->GetScriptResourceName();
v8::Handle<v8::String> description = message->Get();
int lineNumber = message->GetLineNumber();
v8::Local<v8::String> file = name->IsString()?name->ToString():v8::Local<v8::String>();
if (file.IsEmpty() || file->Length() == 0)
error.setUrl(QUrl(QLatin1String("<Unknown File>")));
else
error.setUrl(QUrl(QV8Engine::toStringStatic(file)));
error.setLine(lineNumber);
error.setColumn(-1);
QString qDescription = QV8Engine::toStringStatic(description);
if (qDescription.startsWith(QLatin1String("Uncaught ")))
qDescription = qDescription.mid(9 /* strlen("Uncaught ") */);
error.setDescription(qDescription);
}
// Must be called with a valid handle scope
v8::Local<v8::Value> QQmlExpressionPrivate::v8value(QObject *secondaryScope, bool *isUndefined)
{
......
......@@ -96,8 +96,6 @@ Q_SIGNALS:
protected:
QQmlExpression(QQmlContextData *, QObject *, const QString &,
QQmlExpressionPrivate &dd);
QQmlExpression(QQmlContextData *, QObject *, void *,
QQmlExpressionPrivate &dd);
QQmlExpression(QQmlContextData *, QObject *, const QString &, bool,
const QString &, int, int, QQmlExpressionPrivate &dd);
QQmlExpression(QQmlContextData *, QObject *, const QByteArray &, bool,
......
......@@ -79,7 +79,6 @@ public:
~QQmlExpressionPrivate();
void init(QQmlContextData *, const QString &, QObject *);
void init(QQmlContextData *, v8::Handle<v8::Function>, QObject *);
void init(QQmlContextData *, const QString &, bool, QObject *, const QString &, int, int);
void init(QQmlContextData *, const QByteArray &, bool, QObject *, const QString &, int, int);
......@@ -92,18 +91,8 @@ public:
void _q_notify();
static void exceptionToError(v8::Handle<v8::Message>, QQmlError &);
static v8::Persistent<v8::Function> evalFunction(QQmlContextData *ctxt, QObject *scope,
const QString &code, const QString &filename,
int line,
v8::Persistent<v8::Object> *qmlscope = 0);
static v8::Persistent<v8::Function> evalFunction(QQmlContextData *ctxt, QObject *scope,
const char *code, int codeLength,
const QString &filename, int line,
v8::Persistent<v8::Object> *qmlscope = 0);
static QQmlExpression *create(QQmlContextData *, QObject *, const QString &, bool,
const QString &, int, int);
const QString &, int, int);
bool expressionFunctionValid:1;
bool expressionFunctionRewritten:1;
......
......@@ -251,6 +251,115 @@ QQmlDelayedError *QQmlJavaScriptExpression::delayedError()
return &m_vtable.value();
}
void QQmlJavaScriptExpression::exceptionToError(v8::Handle<v8::Message> message, QQmlError &error)
{
Q_ASSERT(!message.IsEmpty());
v8::Handle<v8::Value> name = message->GetScriptResourceName();
v8::Handle<v8::String> description = message->Get();
int lineNumber = message->GetLineNumber();
v8::Local<v8::String> file = name->IsString()?name->ToString():v8::Local<v8::String>();
if (file.IsEmpty() || file->Length() == 0)
error.setUrl(QUrl(QLatin1String("<Unknown File>")));
else
error.setUrl(QUrl(QV8Engine::toStringStatic(file)));
error.setLine(lineNumber);
error.setColumn(-1);
QString qDescription = QV8Engine::toStringStatic(description);
if (qDescription.startsWith(QLatin1String("Uncaught ")))
qDescription = qDescription.mid(9 /* strlen("Uncaught ") */);
error.setDescription(qDescription);
}
// Callee owns the persistent handle
v8::Persistent<v8::Function>
QQmlJavaScriptExpression::evalFunction(QQmlContextData *ctxt, QObject *scope,
const char *code, int codeLength,
const QString &filename, int line,
v8::Persistent<v8::Object> *qmlscope)
{
QQmlEngine *engine = ctxt->engine;
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
v8::HandleScope handle_scope;
v8::Context::Scope ctxtscope(ep->v8engine()->context());
v8::TryCatch tc;
v8::Local<v8::Object> scopeobject = ep->v8engine()->qmlScope(ctxt, scope);
v8::Local<v8::Script> script = ep->v8engine()->qmlModeCompile(code, codeLength, filename, line);
if (tc.HasCaught()) {
QQmlError error;
error.setDescription(QLatin1String("Exception occurred during function compilation"));
error.setLine(line);
error.setUrl(QUrl::fromLocalFile(filename));
v8::Local<v8::Message> message = tc.Message();
if (!message.IsEmpty())
QQmlExpressionPrivate::exceptionToError(message, error);
ep->warning(error);
return v8::Persistent<v8::Function>();
}
v8::Local<v8::Value> result = script->Run(scopeobject);
if (tc.HasCaught()) {
QQmlError error;
error.setDescription(QLatin1String("Exception occurred during function evaluation"));
error.setLine(line);
error.setUrl(QUrl::fromLocalFile(filename));
v8::Local<v8::Message> message = tc.Message();
if (!message.IsEmpty())
QQmlExpressionPrivate::exceptionToError(message, error);
ep->warning(error);
return v8::Persistent<v8::Function>();
}
if (qmlscope) *qmlscope = qPersistentNew<v8::Object>(scopeobject);
return qPersistentNew<v8::Function>(v8::Local<v8::Function>::Cast(result));
}
// Callee owns the persistent handle
v8::Persistent<v8::Function>
QQmlJavaScriptExpression::evalFunction(QQmlContextData *ctxt, QObject *scope,
const QString &code, const QString &filename, int line,
v8::Persistent<v8::Object> *qmlscope)
{
QQmlEngine *engine = ctxt->engine;
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
v8::HandleScope handle_scope;
v8::Context::Scope ctxtscope(ep->v8engine()->context());
v8::TryCatch tc;
v8::Local<v8::Object> scopeobject = ep->v8engine()->qmlScope(ctxt, scope);
v8::Local<v8::Script> script = ep->v8engine()->qmlModeCompile(code, filename, line);
if (tc.HasCaught()) {
QQmlError error;
error.setDescription(QLatin1String("Exception occurred during function compilation"));
error.setLine(line);
error.setUrl(QUrl::fromLocalFile(filename));
v8::Local<v8::Message> message = tc.Message();
if (!message.IsEmpty())
QQmlExpressionPrivate::exceptionToError(message, error);
ep->warning(error);
return v8::Persistent<v8::Function>();
}
v8::Local<v8::Value> result = script->Run(scopeobject);
if (tc.HasCaught()) {
QQmlError error;
error.setDescription(QLatin1String("Exception occurred during function evaluation"));
error.setLine(line);
error.setUrl(QUrl::fromLocalFile(filename));
v8::Local<v8::Message> message = tc.Message();
if (!message.IsEmpty())
QQmlExpressionPrivate::exceptionToError(message, error);
ep->warning(error);
return v8::Persistent<v8::Function>();
}
if (qmlscope) *qmlscope = qPersistentNew<v8::Object>(scopeobject);
return qPersistentNew<v8::Function>(v8::Local<v8::Function>::Cast(result));
}
void QQmlJavaScriptExpression::clearGuards()
{
while (Guard *g = activeGuards.takeFirst())
......
......@@ -132,6 +132,15 @@ public:
void clearError();
QQmlDelayedError *delayedError();
static void exceptionToError(v8::Handle<v8::Message>, QQmlError &);
static v8::Persistent<v8::Function> evalFunction(QQmlContextData *ctxt, QObject *scope,
const QString &code, const QString &filename,
int line,
v8::Persistent<v8::Object> *qmlscope = 0);
static v8::Persistent<v8::Function> evalFunction(QQmlContextData *ctxt, QObject *scope,
const char *code, int codeLength,
const QString &filename, int line,
v8::Persistent<v8::Object> *qmlscope = 0);
protected:
~QQmlJavaScriptExpression();
......
......@@ -1521,24 +1521,6 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object,
return true;
}
bool QQmlPropertyPrivate::writeBinding(const QQmlProperty &that,
QQmlContextData *context,
QQmlJavaScriptExpression *expression,
v8::Handle<v8::Value> result, bool isUndefined,
WriteFlags flags)
{
QQmlPropertyPrivate *pp = that.d;
if (!pp)
return true;
QObject *object = that.object();
if (!object)
return true;