summaryrefslogtreecommitdiff
path: root/src/declarative/qml/v8/qv8worker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/qml/v8/qv8worker.cpp')
-rw-r--r--src/declarative/qml/v8/qv8worker.cpp392
1 files changed, 0 insertions, 392 deletions
diff --git a/src/declarative/qml/v8/qv8worker.cpp b/src/declarative/qml/v8/qv8worker.cpp
deleted file mode 100644
index 90c8b8441d..0000000000
--- a/src/declarative/qml/v8/qv8worker.cpp
+++ /dev/null
@@ -1,392 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the QtDeclarative 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$
-**
-****************************************************************************/
-
-#include "qv8worker_p.h"
-
-#include <private/qdeclarativelistmodel_p.h>
-#include <private/qdeclarativelistmodelworkeragent_p.h>
-
-QT_BEGIN_NAMESPACE
-
-// We allow the following JavaScript types to be passed between the main and
-// the secondary thread:
-// + undefined
-// + null
-// + Boolean
-// + String
-// + Function
-// + Array
-// + "Simple" Objects
-// + Number
-// + Date
-// + RegExp
-// <quint8 type><quint24 size><data>
-
-enum Type {
- WorkerUndefined,
- WorkerNull,
- WorkerTrue,
- WorkerFalse,
- WorkerString,
- WorkerFunction,
- WorkerArray,
- WorkerObject,
- WorkerInt32,
- WorkerUint32,
- WorkerNumber,
- WorkerDate,
- WorkerRegexp,
- WorkerListModel,
- WorkerSequence
-};
-
-static inline quint32 valueheader(Type type, quint32 size = 0)
-{
- return quint8(type) << 24 | (size & 0xFFFFFF);
-}
-
-static inline Type headertype(quint32 header)
-{
- return (Type)(header >> 24);
-}
-
-static inline quint32 headersize(quint32 header)
-{
- return header & 0xFFFFFF;
-}
-
-static inline void push(QByteArray &data, quint32 value)
-{
- data.append((const char *)&value, sizeof(quint32));
-}
-
-static inline void push(QByteArray &data, double value)
-{
- data.append((const char *)&value, sizeof(double));
-}
-
-static inline void push(QByteArray &data, void *ptr)
-{
- data.append((const char *)&ptr, sizeof(void *));
-}
-
-static inline void reserve(QByteArray &data, int extra)
-{
- data.reserve(data.size() + extra);
-}
-
-static inline quint32 popUint32(const char *&data)
-{
- quint32 rv = *((quint32 *)data);
- data += sizeof(quint32);
- return rv;
-}
-
-static inline double popDouble(const char *&data)
-{
- double rv = *((double *)data);
- data += sizeof(double);
- return rv;
-}
-
-static inline void *popPtr(const char *&data)
-{
- void *rv = *((void **)data);
- data += sizeof(void *);
- return rv;
-}
-
-// XXX TODO: Check that worker script is exception safe in the case of
-// serialization/deserialization failures
-
-#define ALIGN(size) (((size) + 3) & ~3)
-void QV8Worker::serialize(QByteArray &data, v8::Handle<v8::Value> v, QV8Engine *engine)
-{
- if (v.IsEmpty()) {
- } else if (v->IsUndefined()) {
- push(data, valueheader(WorkerUndefined));
- } else if (v->IsNull()) {
- push(data, valueheader(WorkerNull));
- } else if (v->IsTrue()) {
- push(data, valueheader(WorkerTrue));
- } else if (v->IsFalse()) {
- push(data, valueheader(WorkerFalse));
- } else if (v->IsString()) {
- v8::Handle<v8::String> string = v->ToString();
- int length = string->Length() + 1;
- if (length > 0xFFFFFF) {
- push(data, valueheader(WorkerUndefined));
- return;
- }
- int utf16size = ALIGN(length * sizeof(uint16_t));
-
- reserve(data, utf16size + sizeof(quint32));
- push(data, valueheader(WorkerString, length));
-
- int offset = data.size();
- data.resize(data.size() + utf16size);
- char *buffer = data.data() + offset;
-
- string->Write((uint16_t*)buffer);
- } else if (v->IsFunction()) {
- // XXX TODO: Implement passing function objects between the main and
- // worker scripts
- push(data, valueheader(WorkerUndefined));
- } else if (v->IsArray()) {
- v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(v);
- uint32_t length = array->Length();
- if (length > 0xFFFFFF) {
- push(data, valueheader(WorkerUndefined));
- return;
- }
- reserve(data, sizeof(quint32) + length * sizeof(quint32));
- push(data, valueheader(WorkerArray, length));
- for (uint32_t ii = 0; ii < length; ++ii)
- serialize(data, array->Get(ii), engine);
- } else if (v->IsInt32()) {
- reserve(data, 2 * sizeof(quint32));
- push(data, valueheader(WorkerInt32));
- push(data, (quint32)v->Int32Value());
- } else if (v->IsUint32()) {
- reserve(data, 2 * sizeof(quint32));
- push(data, valueheader(WorkerUint32));
- push(data, v->Uint32Value());
- } else if (v->IsNumber()) {
- reserve(data, sizeof(quint32) + sizeof(double));
- push(data, valueheader(WorkerNumber));
- push(data, v->NumberValue());
- } else if (v->IsDate()) {
- reserve(data, sizeof(quint32) + sizeof(double));
- push(data, valueheader(WorkerDate));
- push(data, v8::Handle<v8::Date>::Cast(v)->NumberValue());
- } else if (v->IsRegExp()) {
- v8::Handle<v8::RegExp> regexp = v8::Handle<v8::RegExp>::Cast(v);
- quint32 flags = regexp->GetFlags();
- v8::Local<v8::String> source = regexp->GetSource();
-
- int length = source->Length() + 1;
- if (length > 0xFFFFFF) {
- push(data, valueheader(WorkerUndefined));
- return;
- }
- int utf16size = ALIGN(length * sizeof(uint16_t));
-
- reserve(data, sizeof(quint32) + utf16size);
- push(data, valueheader(WorkerRegexp, flags));
- push(data, (quint32)length);
- int offset = data.size();
- data.resize(data.size() + utf16size);
- char *buffer = data.data() + offset;
-
- source->Write((uint16_t*)buffer);
- } else if (v->IsObject() && !v->ToObject()->GetExternalResource()) {
- v8::Handle<v8::Object> object = v->ToObject();
- v8::Local<v8::Array> properties = engine->getOwnPropertyNames(object);
- quint32 length = properties->Length();
- if (length > 0xFFFFFF) {
- push(data, valueheader(WorkerUndefined));
- return;
- }
- push(data, valueheader(WorkerObject, length));
- v8::TryCatch tc;
- for (quint32 ii = 0; ii < length; ++ii) {
- v8::Local<v8::String> str = properties->Get(ii)->ToString();
- serialize(data, str, engine);
-
- v8::Local<v8::Value> val = object->Get(str);
- if (tc.HasCaught()) {
- serialize(data, v8::Undefined(), engine);
- tc.Reset();
- } else {
- serialize(data, val, engine);
- }
- }
- } else if (engine->isQObject(v)) {
- // XXX TODO: Generalize passing objects between the main thread and worker scripts so
- // that others can trivially plug in their elements.
- QDeclarativeListModel *lm = qobject_cast<QDeclarativeListModel *>(engine->toQObject(v));
- if (lm && lm->agent()) {
- QDeclarativeListModelWorkerAgent *agent = lm->agent();
- agent->addref();
- push(data, valueheader(WorkerListModel));
- push(data, (void *)agent);
- return;
- }
- // No other QObject's are allowed to be sent
- push(data, valueheader(WorkerUndefined));
- } else {
- // we can convert sequences, but not other types with external data.
- if (v->IsObject()) {
- v8::Handle<v8::Object> seqObj = v->ToObject();
- QV8ObjectResource *r = static_cast<QV8ObjectResource *>(seqObj->GetExternalResource());
- if (r->resourceType() == QV8ObjectResource::SequenceType) {
- QVariant sequenceVariant = engine->sequenceWrapper()->toVariant(r);
- if (!sequenceVariant.isNull()) {
- // valid sequence. we generate a length (sequence length + 1 for the sequence type)
- uint32_t seqLength = engine->sequenceWrapper()->sequenceLength(r);
- uint32_t length = seqLength + 1;
- if (length > 0xFFFFFF) {
- push(data, valueheader(WorkerUndefined));
- return;
- }
- reserve(data, sizeof(quint32) + length * sizeof(quint32));
- push(data, valueheader(WorkerSequence, length));
- serialize(data, v8::Integer::New(sequenceVariant.userType()), engine); // sequence type
- for (uint32_t ii = 0; ii < seqLength; ++ii) {
- serialize(data, seqObj->Get(ii), engine); // sequence elements
- }
-
- return;
- }
- }
- }
-
- // not a sequence.
- push(data, valueheader(WorkerUndefined));
- }
-}
-
-v8::Handle<v8::Value> QV8Worker::deserialize(const char *&data, QV8Engine *engine)
-{
- quint32 header = popUint32(data);
- Type type = headertype(header);
-
- switch (type) {
- case WorkerUndefined:
- return v8::Undefined();
- case WorkerNull:
- return v8::Null();
- case WorkerTrue:
- return v8::True();
- case WorkerFalse:
- return v8::False();
- case WorkerString:
- {
- quint32 size = headersize(header);
- v8::Local<v8::String> string = v8::String::New((uint16_t*)data, size - 1);
- data += ALIGN(size * sizeof(uint16_t));
- return string;
- }
- case WorkerFunction:
- Q_ASSERT(!"Unreachable");
- break;
- case WorkerArray:
- {
- quint32 size = headersize(header);
- v8::Local<v8::Array> array = v8::Array::New(size);
- for (quint32 ii = 0; ii < size; ++ii) {
- array->Set(ii, deserialize(data, engine));
- }
- return array;
- }
- case WorkerObject:
- {
- quint32 size = headersize(header);
- v8::Local<v8::Object> o = v8::Object::New();
- for (quint32 ii = 0; ii < size; ++ii) {
- v8::Handle<v8::Value> name = deserialize(data, engine);
- v8::Handle<v8::Value> value = deserialize(data, engine);
- o->Set(name, value);
- }
- return o;
- }
- case WorkerInt32:
- return v8::Integer::New((qint32)popUint32(data));
- case WorkerUint32:
- return v8::Integer::NewFromUnsigned(popUint32(data));
- case WorkerNumber:
- return v8::Number::New(popDouble(data));
- case WorkerDate:
- return v8::Date::New(popDouble(data));
- case WorkerRegexp:
- {
- quint32 flags = headersize(header);
- quint32 length = popUint32(data);
- v8::Local<v8::String> source = v8::String::New((uint16_t*)data, length - 1);
- data += ALIGN(length * sizeof(uint16_t));
- return v8::RegExp::New(source, (v8::RegExp::Flags)flags);
- }
- case WorkerListModel:
- {
- void *ptr = popPtr(data);
- QDeclarativeListModelWorkerAgent *agent = (QDeclarativeListModelWorkerAgent *)ptr;
- v8::Handle<v8::Value> rv = engine->newQObject(agent);
- if (rv->IsObject()) {
- QDeclarativeListModelWorkerAgent::VariantRef ref(agent);
- QVariant var = qVariantFromValue(ref);
- rv->ToObject()->SetHiddenValue(v8::String::New("qml::ref"), engine->fromVariant(var));
- }
- agent->release();
- agent->setV8Engine(engine);
- return rv;
- }
- case WorkerSequence:
- {
- bool succeeded = false;
- quint32 length = headersize(header);
- quint32 seqLength = length - 1;
- int sequenceType = deserialize(data, engine)->Int32Value();
- v8::Local<v8::Array> array = v8::Array::New(seqLength);
- for (quint32 ii = 0; ii < seqLength; ++ii)
- array->Set(ii, deserialize(data, engine));
- QVariant seqVariant = engine->sequenceWrapper()->toVariant(array, sequenceType, &succeeded);
- return engine->sequenceWrapper()->fromVariant(seqVariant, &succeeded);
- }
- }
- Q_ASSERT(!"Unreachable");
- return v8::Undefined();
-}
-
-QByteArray QV8Worker::serialize(v8::Handle<v8::Value> value, QV8Engine *engine)
-{
- QByteArray rv;
- serialize(rv, value, engine);
- return rv;
-}
-
-v8::Handle<v8::Value> QV8Worker::deserialize(const QByteArray &data, QV8Engine *engine)
-{
- const char *stream = data.constData();
- return deserialize(stream, engine);
-}
-
-QT_END_NAMESPACE
-