aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/v8/qv8worker.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2013-05-16 12:17:22 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2013-05-21 09:55:29 +0200
commita24e7d802db9380776a00cb86825cdd604a272b6 (patch)
tree7bb77e378a2751cdbe0410616669cddbe4ba8f57 /src/qml/qml/v8/qv8worker.cpp
parent4f32973d290a46e1e7265b4e1016d4f73b0dca89 (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.cpp188
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);