aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative
diff options
context:
space:
mode:
authorChris Adams <christopher.adams@nokia.com>2011-12-30 13:20:33 +1000
committerQt by Nokia <qt-info@nokia.com>2012-02-09 04:54:25 +0100
commitfdf80ee4677a3b83c00e69071e614cadf54f9897 (patch)
tree64c27aea85e58c07c3574cb11d19a55567c09831 /src/declarative
parente51bb395b466bcf88042688ffaf14b0d9fad61fe (diff)
Handle exceptions while compiling v8 bindings
Previously, no exception handling existed, which could cause a crash if an invalid v8 binding expression was generated. Such invalid bindings should usually be rewritten into valid form by the bindings rewriter, but in some cases it is too costly to do so, so we need to handle exceptions. Task-number: QTBUG-24064 Task-number: QTBUG-23387 Change-Id: I7da12a936780a561c9e9cad3a4a7b62c06d6973e Reviewed-by: Alan Alpert <alan.alpert@nokia.com>
Diffstat (limited to 'src/declarative')
-rw-r--r--src/declarative/qml/qdeclarativevme.cpp8
-rw-r--r--src/declarative/qml/v8/qv8bindings.cpp38
2 files changed, 37 insertions, 9 deletions
diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp
index c008e2a28a..a37964aacf 100644
--- a/src/declarative/qml/qdeclarativevme.cpp
+++ b/src/declarative/qml/qdeclarativevme.cpp
@@ -826,9 +826,11 @@ QObject *QDeclarativeVME::run(QList<QDeclarativeError> *errors,
CTXT->v8bindings->configBinding(instr.value, target, scope,
instr.property, instr.line,
instr.column);
- bindValues.push(binding);
- binding->m_mePtr = &bindValues.top();
- binding->addToObject(target, QDeclarativePropertyPrivate::bindingIndex(instr.property));
+ if (binding) {
+ bindValues.push(binding);
+ binding->m_mePtr = &bindValues.top();
+ binding->addToObject(target, QDeclarativePropertyPrivate::bindingIndex(instr.property));
+ }
QML_END_INSTR(StoreV8Binding)
QML_BEGIN_INSTR(StoreValueSource)
diff --git a/src/declarative/qml/v8/qv8bindings.cpp b/src/declarative/qml/v8/qv8bindings.cpp
index 84ed892c09..b21ddf5d2e 100644
--- a/src/declarative/qml/v8/qv8bindings.cpp
+++ b/src/declarative/qml/v8/qv8bindings.cpp
@@ -167,18 +167,41 @@ QV8Bindings::QV8Bindings(const QString &program, int index, int line,
v8::HandleScope handle_scope;
v8::Context::Scope scope(engine->context());
- v8::Local<v8::Script> script = engine->qmlModeCompile(program, compiled->name, line);
- v8::Local<v8::Value> result = script->Run(engine->contextWrapper()->sharedContext());
+ v8::Local<v8::Script> script;
+ bool compileFailed = false;
+ {
+ v8::TryCatch try_catch;
+ script = engine->qmlModeCompile(program, compiled->name, line);
+ if (try_catch.HasCaught()) {
+ // The binding was not compiled. There are some exceptional cases which the
+ // expression rewriter does not rewrite properly (e.g., \r-terminated lines
+ // are not rewritten correctly but this bug is demed out-of-scope to fix for
+ // performance reasons; see QTBUG-24064).
+ compileFailed = true;
+ QDeclarativeError error;
+ error.setDescription(QString(QLatin1String("Exception occurred during compilation of binding at line: %1")).arg(line));
+ v8::Local<v8::Message> message = try_catch.Message();
+ if (!message.IsEmpty())
+ QDeclarativeExpressionPrivate::exceptionToError(message, error);
+ QDeclarativeEnginePrivate::get(engine->engine())->warning(error);
+ compiled->v8bindings[index] = qPersistentNew(v8::Array::New());
+ }
+ }
- if (result->IsArray())
- compiled->v8bindings[index] = qPersistentNew(v8::Local<v8::Array>::Cast(result));
+ if (!compileFailed) {
+ v8::Local<v8::Value> result = script->Run(engine->contextWrapper()->sharedContext());
+ if (result->IsArray()) {
+ compiled->v8bindings[index] = qPersistentNew(v8::Local<v8::Array>::Cast(result));
+ }
+ }
}
url = compiled->url;
functions = qPersistentNew(compiled->v8bindings[index]);
bindingsCount = functions->Length();
- bindings = new QV8Bindings::Binding[bindingsCount];
-
+ if (bindingsCount)
+ bindings = new QV8Bindings::Binding[bindingsCount];
+
setContext(context);
}
@@ -195,6 +218,9 @@ QDeclarativeAbstractBinding *QV8Bindings::configBinding(int index, QObject *targ
const QDeclarativePropertyData &p,
int line, int column)
{
+ if (bindingsCount <= index) // initialization failed.
+ return 0;
+
QV8Bindings::Binding *rv = bindings + index;
rv->line = line;