From: Lars Knoll Date: Mon, 20 May 2013 09:00:58 +0000 (+0200) Subject: Fix some parts of workerscript and convert to v4 X-Git-Tag: upstream/5.2.1~669^2~463 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c7c6f955df2733f4ded7340c073ce418c15c30e9;p=platform%2Fupstream%2Fqtdeclarative.git Fix some parts of workerscript and convert to v4 Add some try/catch blocks around calls to v4, fixing some crashes in the worker script auto test. Change-Id: I591a25facc8afd5c6f99ffb7b75530c890318280 Reviewed-by: Simon Hausmann --- diff --git a/src/qml/types/qquickworkerscript.cpp b/src/qml/types/qquickworkerscript.cpp index b62cd4d..5f072d1 100644 --- a/src/qml/types/qquickworkerscript.cpp +++ b/src/qml/types/qquickworkerscript.cpp @@ -144,10 +144,10 @@ public: QQuickWorkerScriptEnginePrivate *p; - v8::Handle sendFunction(int id); - void callOnMessage(v8::Handle object, v8::Handle arg); - private: + QV4::Value sendFunction(int id); + QV4::PersistentValue onmessage; + private: QV4::PersistentValue createsend; QNetworkAccessManager *accessManager; }; @@ -174,7 +174,7 @@ public: }; QHash workers; - v8::Handle getWorker(WorkerScript *); + QV4::Value getWorker(WorkerScript *); int m_nextId; @@ -235,27 +235,26 @@ void QQuickWorkerScriptEnginePrivate::WorkerEngine::init() v8::Handle args[] = { V8FUNCTION(QQuickWorkerScriptEnginePrivate::sendMessage, this) }; - v8::Handle createsendvalue = createsendconstructor->Call(v8::Value::fromV4Value(global()), 1, args); + v8::Handle createsendvalue = createsendconstructor->Call(global(), 1, args); createsend = createsendvalue->v4Value(); } } // Requires handle and context scope -v8::Handle QQuickWorkerScriptEnginePrivate::WorkerEngine::sendFunction(int id) +QV4::Value QQuickWorkerScriptEnginePrivate::WorkerEngine::sendFunction(int id) { QV4::Value args[] = { QV4::Value::fromInt32(id) }; QV4::FunctionObject *f = createsend.value().asFunctionObject(); - return f->call(f->internalClass->engine->current, global(), args, 1); -} - -// Requires handle and context scope -void QQuickWorkerScriptEnginePrivate::WorkerEngine::callOnMessage(v8::Handle object, - v8::Handle arg) -{ - QV4::Value args[] = { object->v4Value(), arg->v4Value() }; - QV4::FunctionObject *f = onmessage.value().asFunctionObject(); - onmessage.value().asFunctionObject()->call(f->internalClass->engine->current, global(), args, 2); + QV4::Value v = QV4::Value::undefinedValue(); + QV4::ExecutionContext *ctx = f->internalClass->engine->current; + try { + v = f->call(ctx, global(), args, 1); + } catch (QV4::Exception &e) { + e.accept(ctx); + v = e.value(); + } + return v; } QNetworkAccessManager *QQuickWorkerScriptEnginePrivate::WorkerEngine::networkAccessManager() @@ -295,19 +294,21 @@ QV4::Value QQuickWorkerScriptEnginePrivate::sendMessage(const v8::Arguments &arg } // Requires handle scope and context scope -v8::Handle QQuickWorkerScriptEnginePrivate::getWorker(WorkerScript *script) +QV4::Value QQuickWorkerScriptEnginePrivate::getWorker(WorkerScript *script) { if (!script->initialized) { script->initialized = true; + QV4::ExecutionEngine *v4 = QV8Engine::getV4(workerEngine); + script->object = workerEngine->contextWrapper()->urlScope(script->source)->v4Value(); workerEngine->contextWrapper()->setReadOnly(script->object.value(), false); - v8::Handle api = v8::Object::New(); - api->Set(v8::String::New("sendMessage"), workerEngine->sendFunction(script->id)); + QV4::Object *api = v4->newObject(); + api->put(v4->newString("sendMessage"), workerEngine->sendFunction(script->id)); - v8::Handle(script->object)->Set(v8::String::New("WorkerScript"), api); + script->object.value().asObject()->put(v4->newString("WorkerScript"), QV4::Value::fromObject(api)); workerEngine->contextWrapper()->setReadOnly(script->object.value(), true); } @@ -343,14 +344,18 @@ void QQuickWorkerScriptEnginePrivate::processMessage(int id, const QByteArray &d if (!script) return; - v8::Handle value = QV4::Serialize::deserialize(data, workerEngine); - - v8::TryCatch tc; - workerEngine->callOnMessage(script->object.value(), value); + QV4::Value value = QV4::Serialize::deserialize(data, workerEngine); - if (tc.HasCaught()) { + QV4::Value args[] = { script->object.value(), value }; + QV4::FunctionObject *f = workerEngine->onmessage.value().asFunctionObject(); + QV4::ExecutionContext *ctx = f->internalClass->engine->current; + try { + workerEngine->onmessage.value().asFunctionObject()->call(f->internalClass->engine->current, workerEngine->global(), args, 2); + } catch (QV4::Exception &e) { + e.accept(ctx); QQmlError error; - QQmlExpressionPrivate::exceptionToError(tc.Message(), error); + error.setDescription(e.value().toQString()); +// ### QQmlExpressionPrivate::exceptionToError(e, error); reportScriptException(script, error); } } @@ -372,8 +377,8 @@ void QQuickWorkerScriptEnginePrivate::processLoad(int id, const QUrl &url) if (!script) return; script->source = url; - v8::Handle activation = getWorker(script); - if (activation.IsEmpty()) + QV4::Value activation = getWorker(script); + if (activation.isEmpty()) return; // XXX ??? @@ -659,11 +664,11 @@ void QQuickWorkerScript::sendMessage(QQmlV4Function *args) return; } - v8::Handle argument = QV4::Value::undefinedValue(); + QV4::Value argument = QV4::Value::undefinedValue(); if (args->length() != 0) argument = (*args)[0]; - m_engine->sendMessage(m_scriptId, QV4::Serialize::serialize(argument->v4Value(), args->engine())); + m_engine->sendMessage(m_scriptId, QV4::Serialize::serialize(argument, args->engine())); } void QQuickWorkerScript::classBegin() @@ -712,8 +717,8 @@ bool QQuickWorkerScript::event(QEvent *event) if (engine) { WorkerDataEvent *workerEvent = static_cast(event); QV8Engine *v8engine = QQmlEnginePrivate::get(engine)->v8engine(); - v8::Handle value = QV4::Serialize::deserialize(workerEvent->data(), v8engine); - emit message(QQmlV4Handle(value->v4Value())); + QV4::Value value = QV4::Serialize::deserialize(workerEvent->data(), v8engine); + emit message(QQmlV4Handle(value)); } return true; } else if (event->type() == (QEvent::Type)WorkerErrorEvent::WorkerError) {