diff options
author | Lars Knoll <lars.knoll@digia.com> | 2013-05-16 12:17:22 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2013-05-21 09:55:29 +0200 |
commit | a24e7d802db9380776a00cb86825cdd604a272b6 (patch) | |
tree | 7bb77e378a2751cdbe0410616669cddbe4ba8f57 /src/qml/qml/v8/qv8worker.cpp | |
parent | 4f32973d290a46e1e7265b4e1016d4f73b0dca89 (diff) |
convert qv8workerscript to v4
Change-Id: Ifc204f53a46c857a2a7caaa4f6900d4300163dbb
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml/qml/v8/qv8worker.cpp')
-rw-r--r-- | src/qml/qml/v8/qv8worker.cpp | 188 |
1 files changed, 98 insertions, 90 deletions
diff --git a/src/qml/qml/v8/qv8worker.cpp b/src/qml/qml/v8/qv8worker.cpp index 3b653cee29..b5f4ad59df 100644 --- a/src/qml/qml/v8/qv8worker.cpp +++ b/src/qml/qml/v8/qv8worker.cpp @@ -45,6 +45,8 @@ #include <private/qqmllistmodelworkeragent_p.h> #include <private/qv4value_p.h> +#include <private/qv4dateobject_p.h> +#include <private/qv4regexpobject_p.h> QT_BEGIN_NAMESPACE @@ -140,20 +142,18 @@ static inline void *popPtr(const char *&data) // serialization/deserialization failures #define ALIGN(size) (((size) + 3) & ~3) -void QV8Worker::serialize(QByteArray &data, v8::Handle<v8::Value> v, QV8Engine *engine) +void QV8Worker::serialize(QByteArray &data, const QV4::Value &v, QV8Engine *engine) { - if (v.IsEmpty()) { - } else if (v->IsUndefined()) { + if (v.isEmpty()) { + } else if (v.isUndefined()) { push(data, valueheader(WorkerUndefined)); - } else if (v->IsNull()) { + } 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; + } else if (v.isBoolean()) { + push(data, valueheader(v.booleanValue() == true ? WorkerTrue : WorkerFalse)); + } else if (QV4::String *s = v.asString()) { + const QString &qstr = s->toQString(); + int length = qstr.length(); if (length > 0xFFFFFF) { push(data, valueheader(WorkerUndefined)); return; @@ -167,14 +167,13 @@ void QV8Worker::serialize(QByteArray &data, v8::Handle<v8::Value> v, QV8Engine * data.resize(data.size() + utf16size); char *buffer = data.data() + offset; - string->Write((uint16_t*)buffer); - } else if (v->IsFunction()) { + memcpy(buffer, qstr.constData(), length*sizeof(QChar)); + } else if (v.asFunctionObject()) { // 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(); + } else if (QV4::ArrayObject *array = v.asArrayObject()) { + uint32_t length = array->arrayLength(); if (length > 0xFFFFFF) { push(data, valueheader(WorkerUndefined)); return; @@ -182,29 +181,27 @@ void QV8Worker::serialize(QByteArray &data, v8::Handle<v8::Value> v, QV8Engine * 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()) { + serialize(data, array->getIndexed(ii), engine); + } else if (v.isInteger()) { 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()) { + push(data, (quint32)v.integerValue()); +// } 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()) { + push(data, v.asDouble()); + } else if (QV4::DateObject *d = v.asDateObject()) { 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::Handle<v8::String> source = regexp->GetSource(); - - int length = source->Length() + 1; + push(data, d->value.asDouble()); + } else if (QV4::RegExpObject *re = v.asRegExpObject()) { + quint32 flags = re->flags(); + QString pattern = re->source(); + int length = pattern.length() + 1; if (length > 0xFFFFFF) { push(data, valueheader(WorkerUndefined)); return; @@ -214,52 +211,31 @@ void QV8Worker::serialize(QByteArray &data, v8::Handle<v8::Value> v, QV8Engine * 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::Handle<v8::Array> properties = engine->getOwnPropertyNames(object->v4Value()); - 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::Handle<v8::String> str = properties->Get(ii)->ToString(); - serialize(data, str, engine); - - v8::Handle<v8::Value> val = object->Get(str); - if (tc.HasCaught()) { - serialize(data, QV4::Value::undefinedValue(), engine); - tc.Reset(); - } else { - serialize(data, val, engine); - } - } - } else if (engine->isQObject(v->v4Value())) { - // XXX TODO: Generalize passing objects between the main thread and worker scripts so + memcpy(buffer, pattern.constData(), length*sizeof(QChar)); + } 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. - QQmlListModel *lm = qobject_cast<QQmlListModel *>(engine->toQObject(v->v4Value())); + QQmlListModel *lm = qobject_cast<QQmlListModel *>(engine->toQObject(v)); if (lm && lm->agent()) { QQmlListModelWorkerAgent *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()); + } else if (QV4::Object *o = v.asObject()) { + v8::Handle<v8::Object> v8object(v); + QV8ObjectResource *r = static_cast<QV8ObjectResource *>(v8object->GetExternalResource()); + if (r) { if (r->resourceType() == QV8ObjectResource::SequenceType) { + // we can convert sequences, but not other types with external data. QVariant sequenceVariant = engine->sequenceWrapper()->toVariant(r); if (!sequenceVariant.isNull()) { // valid sequence. we generate a length (sequence length + 1 for the sequence type) @@ -271,26 +247,58 @@ void QV8Worker::serialize(QByteArray &data, v8::Handle<v8::Value> v, QV8Engine * } reserve(data, sizeof(quint32) + length * sizeof(quint32)); push(data, valueheader(WorkerSequence, length)); - serialize(data, v8::Integer::New(sequenceVariant.userType()), engine); // sequence type + serialize(data, v8::Integer::New(sequenceVariant.userType())->v4Value(), engine); // sequence type for (uint32_t ii = 0; ii < seqLength; ++ii) { - serialize(data, seqObj->Get(ii), engine); // sequence elements + serialize(data, v8object->Get(ii)->v4Value(), engine); // sequence elements } return; } } + + // not a sequence. + push(data, valueheader(WorkerUndefined)); + return; } - // not a sequence. + // regular object + QV4::ArrayObject *properties = engine->getOwnPropertyNames(v).asArrayObject(); + quint32 length = properties->arrayLength(); + if (length > 0xFFFFFF) { + push(data, valueheader(WorkerUndefined)); + return; + } + push(data, valueheader(WorkerObject, length)); + + QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); + for (quint32 ii = 0; ii < length; ++ii) { + QV4::String *s = properties->getIndexed(ii).asString(); + serialize(data, QV4::Value::fromString(s), engine); + + bool hasCaught = false; + QV4::ExecutionContext *ctx = v4->current; + QV4::Value val = QV4::Value::undefinedValue(); + try { + val = o->get(s); + } catch (QV4::Exception &e) { + e.accept(ctx); + } + + serialize(data, val, engine); + } + return; + } else { push(data, valueheader(WorkerUndefined)); } } -v8::Handle<v8::Value> QV8Worker::deserialize(const char *&data, QV8Engine *engine) +QV4::Value QV8Worker::deserialize(const char *&data, QV8Engine *engine) { quint32 header = popUint32(data); Type type = headertype(header); + QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); + switch (type) { case WorkerUndefined: return QV4::Value::undefinedValue(); @@ -303,9 +311,9 @@ v8::Handle<v8::Value> QV8Worker::deserialize(const char *&data, QV8Engine *engin case WorkerString: { quint32 size = headersize(header); - v8::Handle<v8::String> string = v8::String::New((uint16_t*)data, size - 1); + QString qstr((QChar *)data, size); data += ALIGN(size * sizeof(uint16_t)); - return string; + return QV4::Value::fromString(v4->newString(qstr)); } case WorkerFunction: Q_ASSERT(!"Unreachable"); @@ -313,38 +321,38 @@ v8::Handle<v8::Value> QV8Worker::deserialize(const char *&data, QV8Engine *engin case WorkerArray: { quint32 size = headersize(header); - v8::Handle<v8::Array> array = v8::Array::New(size); + QV4::ArrayObject *a = v4->newArrayObject(); for (quint32 ii = 0; ii < size; ++ii) { - array->Set(ii, deserialize(data, engine)); + a->putIndexed(ii, deserialize(data, engine)); } - return array; + return QV4::Value::fromObject(a); } case WorkerObject: { quint32 size = headersize(header); - v8::Handle<v8::Object> o = v8::Object::New(); + QV4::Object *o = v4->newObject(); 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); + QV4::Value name = deserialize(data, engine); + QV4::Value value = deserialize(data, engine); + o->put(name.asString(), value); } - return o; + return QV4::Value::fromObject(o); } case WorkerInt32: - return v8::Integer::New((qint32)popUint32(data)); + return QV4::Value::fromInt32((qint32)popUint32(data)); case WorkerUint32: - return v8::Integer::NewFromUnsigned(popUint32(data)); + return QV4::Value::fromUInt32(popUint32(data)); case WorkerNumber: - return v8::Number::New(popDouble(data)); + return QV4::Value::fromDouble(popDouble(data)); case WorkerDate: - return v8::Date::New(popDouble(data)); + return QV4::Value::fromObject(v4->newDateObject(QV4::Value::fromDouble(popDouble(data)))); case WorkerRegexp: { quint32 flags = headersize(header); quint32 length = popUint32(data); - v8::Handle<v8::String> source = v8::String::New((uint16_t*)data, length - 1); + QString pattern = QString((QChar *)data, length - 1); data += ALIGN(length * sizeof(uint16_t)); - return v8::RegExp::New(source, (v8::RegExp::Flags)flags); + return QV4::Value::fromObject(v4->newRegExpObject(pattern, flags)); } case WorkerListModel: { @@ -358,33 +366,33 @@ v8::Handle<v8::Value> QV8Worker::deserialize(const char *&data, QV8Engine *engin } agent->release(); agent->setV8Engine(engine); - return rv; + return rv->v4Value(); } case WorkerSequence: { bool succeeded = false; quint32 length = headersize(header); quint32 seqLength = length - 1; - int sequenceType = deserialize(data, engine)->Int32Value(); + int sequenceType = deserialize(data, engine).integerValue(); v8::Handle<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); + return engine->sequenceWrapper()->fromVariant(seqVariant, &succeeded)->v4Value(); } } Q_ASSERT(!"Unreachable"); return QV4::Value::undefinedValue(); } -QByteArray QV8Worker::serialize(v8::Handle<v8::Value> value, QV8Engine *engine) +QByteArray QV8Worker::serialize(const QV4::Value &value, QV8Engine *engine) { QByteArray rv; serialize(rv, value, engine); return rv; } -v8::Handle<v8::Value> QV8Worker::deserialize(const QByteArray &data, QV8Engine *engine) +QV4::Value QV8Worker::deserialize(const QByteArray &data, QV8Engine *engine) { const char *stream = data.constData(); return deserialize(stream, engine); |