diff options
Diffstat (limited to 'src/qml/jsruntime')
22 files changed, 204 insertions, 182 deletions
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp index 10d8f4e5c1..5508372265 100644 --- a/src/qml/jsruntime/qv4arrayobject.cpp +++ b/src/qml/jsruntime/qv4arrayobject.cpp @@ -600,7 +600,7 @@ ReturnedValue ArrayPrototype::method_indexOf(SimpleCallContext *ctx) return Value::fromInt32(-1).asReturnedValue(); } - return instance->arrayIndexOf(searchValue, fromIndex, len, ctx, instance).asReturnedValue(); + return instance->arrayIndexOf(searchValue, fromIndex, len, ctx, instance); } ReturnedValue ArrayPrototype::method_lastIndexOf(SimpleCallContext *ctx) diff --git a/src/qml/jsruntime/qv4debugging.cpp b/src/qml/jsruntime/qv4debugging.cpp index 8080ed6c62..2b6dc4616c 100644 --- a/src/qml/jsruntime/qv4debugging.cpp +++ b/src/qml/jsruntime/qv4debugging.cpp @@ -209,6 +209,9 @@ static void realDumpValue(QV4::Value v, QV4::ExecutionContext *ctx, std::string { using namespace QV4; using namespace std; + + Scope scope(ctx); + cout << prefix << "tag: " << hex << v.tag << dec << endl << prefix << "\t-> "; switch (v.type()) { case Value::Undefined_Type: cout << "Undefined" << endl; return; @@ -271,10 +274,11 @@ static void realDumpValue(QV4::Value v, QV4::ExecutionContext *ctx, std::string cout << prefix << "properties:" << endl; ForEachIteratorObject it(ctx, o); - for (Value name = it.nextPropertyName(); !name.isNull(); name = it.nextPropertyName()) { - cout << prefix << "\t\"" << qPrintable(name.stringValue()->toQString()) << "\"" << endl; + QV4::ScopedValue name(scope); + for (name = it.nextPropertyName(); !name->isNull(); name = it.nextPropertyName()) { + cout << prefix << "\t\"" << qPrintable(name->stringValue()->toQString()) << "\"" << endl; PropertyAttributes attrs; - Property *d = o->__getOwnProperty__(name.stringValue(), &attrs); + Property *d = o->__getOwnProperty__(name->stringValue(), &attrs); Value pval = Value::fromReturnedValue(o->getValue(d, attrs)); cout << prefix << "\tvalue:" << endl; realDumpValue(pval, ctx, prefix + "\t"); diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index a80ea3fc12..a13aa2c29d 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -618,6 +618,7 @@ ReturnedValue IndexedBuiltinFunction::call(Managed *that, CallData *callData) IndexedBuiltinFunction *f = static_cast<IndexedBuiltinFunction *>(that); ExecutionEngine *v4 = f->engine(); ExecutionContext *context = v4->current; + Scope scope(v4); SimpleCallContext ctx; ctx.initSimpleCallContext(f->scope->engine); @@ -628,7 +629,7 @@ ReturnedValue IndexedBuiltinFunction::call(Managed *that, CallData *callData) ctx.argumentCount = callData->argc; v4->pushContext(&ctx); - Value result; + ScopedValue result(scope); try { result = f->code(&ctx, f->index); } catch (Exception &ex) { diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h index 25bc39047f..37f9d0bf46 100644 --- a/src/qml/jsruntime/qv4functionobject_p.h +++ b/src/qml/jsruntime/qv4functionobject_p.h @@ -180,10 +180,10 @@ struct IndexedBuiltinFunction: FunctionObject { Q_MANAGED - Value (*code)(SimpleCallContext *ctx, uint index); + ReturnedValue (*code)(SimpleCallContext *ctx, uint index); uint index; - IndexedBuiltinFunction(ExecutionContext *scope, uint index, Value (*code)(SimpleCallContext *ctx, uint index)) + IndexedBuiltinFunction(ExecutionContext *scope, uint index, ReturnedValue (*code)(SimpleCallContext *ctx, uint index)) : FunctionObject(scope, /*name*/0) , code(code) , index(index) diff --git a/src/qml/jsruntime/qv4include.cpp b/src/qml/jsruntime/qv4include.cpp index 43e566b5fb..ac9a50c3a1 100644 --- a/src/qml/jsruntime/qv4include.cpp +++ b/src/qml/jsruntime/qv4include.cpp @@ -82,7 +82,7 @@ QV4Include::~QV4Include() delete m_reply; m_reply = 0; } -QV4::Value QV4Include::resultValue(QV4::ExecutionEngine *v4, Status status) +QV4::ReturnedValue QV4Include::resultValue(QV4::ExecutionEngine *v4, Status status) { // XXX It seems inefficient to create this object from scratch each time. @@ -94,7 +94,7 @@ QV4::Value QV4Include::resultValue(QV4::ExecutionEngine *v4, Status status) o->put(v4->newString("status"), QV4::Value::fromInt32(status)); - return QV4::Value::fromObject(o); + return QV4::Value::fromObject(o).asReturnedValue(); } void QV4Include::callback(const QV4::Value &callback, const QV4::Value &status) @@ -115,9 +115,9 @@ void QV4Include::callback(const QV4::Value &callback, const QV4::Value &status) } } -QV4::Value QV4Include::result() +QV4::ReturnedValue QV4Include::result() { - return m_resultObject.value(); + return m_resultObject.value().asReturnedValue(); } #define INCLUDE_MAXIMUM_REDIRECT_RECURSION 15 diff --git a/src/qml/jsruntime/qv4include_p.h b/src/qml/jsruntime/qv4include_p.h index ccc634e066..6e299bce91 100644 --- a/src/qml/jsruntime/qv4include_p.h +++ b/src/qml/jsruntime/qv4include_p.h @@ -88,9 +88,9 @@ private: const QV4::Value &qmlglobal, const QV4::Value &callback); ~QV4Include(); - QV4::Value result(); + QV4::ReturnedValue result(); - static QV4::Value resultValue(QV4::ExecutionEngine *v4, Status status = Loading); + static QV4::ReturnedValue resultValue(QV4::ExecutionEngine *v4, Status status = Loading); static void callback(const QV4::Value &callback, const QV4::Value &status); QV4::ExecutionEngine *v4; diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp index f63d67ef0e..a42cfd4873 100644 --- a/src/qml/jsruntime/qv4jsonobject.cpp +++ b/src/qml/jsruntime/qv4jsonobject.cpp @@ -783,13 +783,14 @@ QString Stringify::JO(Object *o) QStringList partial; if (propertyList.isEmpty()) { ObjectIterator it(o, ObjectIterator::EnumerableOnly); + ScopedValue name(scope); while (1) { Value v; - Value name = it.nextPropertyNameAsString(&v); - if (name.isNull()) + name = it.nextPropertyNameAsString(&v); + if (name->isNull()) break; - QString key = name.toQStringNoThrow(); + QString key = name->toQStringNoThrow(); QString member = makeMember(key, v); if (!member.isEmpty()) partial += member; @@ -936,22 +937,22 @@ ReturnedValue JsonObject::method_stringify(SimpleCallContext *ctx) -QV4::Value JsonObject::fromJsonValue(ExecutionEngine *engine, const QJsonValue &value) +ReturnedValue JsonObject::fromJsonValue(ExecutionEngine *engine, const QJsonValue &value) { if (value.isString()) - return Value::fromString(engine->current, value.toString()); + return Value::fromString(engine->current, value.toString()).asReturnedValue(); else if (value.isDouble()) - return Value::fromDouble(value.toDouble()); + return Encode(value.toDouble()); else if (value.isBool()) - return Value::fromBoolean(value.toBool()); + return Encode(value.toBool()); else if (value.isArray()) return fromJsonArray(engine, value.toArray()); else if (value.isObject()) return fromJsonObject(engine, value.toObject()); else if (value.isNull()) - return Value::nullValue(); + return Encode::null(); else - return Value::undefinedValue(); + return Encode::undefined(); } QJsonValue JsonObject::toJsonValue(const QV4::Value &value, @@ -973,12 +974,13 @@ QJsonValue JsonObject::toJsonValue(const QV4::Value &value, return QJsonValue(QJsonValue::Undefined); } -QV4::Value JsonObject::fromJsonObject(ExecutionEngine *engine, const QJsonObject &object) +QV4::ReturnedValue JsonObject::fromJsonObject(ExecutionEngine *engine, const QJsonObject &object) { - Object *o = engine->newObject(); + Scope scope(engine); + Scoped<Object> o(scope, Value::fromObject(engine->newObject())); for (QJsonObject::const_iterator it = object.begin(); it != object.end(); ++it) - o->put(engine->newString(it.key()), fromJsonValue(engine, it.value())); - return Value::fromObject(o); + o->put(engine->newString(it.key()), Value::fromReturnedValue(fromJsonValue(engine, it.value()))); + return o.asReturnedValue(); } QJsonObject JsonObject::toJsonObject(QV4::Object *o, V4ObjectSet &visitedObjects) @@ -987,6 +989,8 @@ QJsonObject JsonObject::toJsonObject(QV4::Object *o, V4ObjectSet &visitedObjects if (!o || o->asFunctionObject()) return result; + Scope scope(o->engine()); + if (visitedObjects.contains(o)) { // Avoid recursion. // For compatibility with QVariant{List,Map} conversion, we return an @@ -997,13 +1001,14 @@ QJsonObject JsonObject::toJsonObject(QV4::Object *o, V4ObjectSet &visitedObjects visitedObjects.insert(o); ObjectIterator it(o, ObjectIterator::EnumerableOnly); + ScopedValue name(scope); while (1) { Value v; - Value name = it.nextPropertyNameAsString(&v); - if (name.isNull()) + name = it.nextPropertyNameAsString(&v); + if (name->isNull()) break; - QString key = name.toQStringNoThrow(); + QString key = name->toQStringNoThrow(); if (!v.asFunctionObject()) result.insert(key, toJsonValue(v, visitedObjects)); } @@ -1013,16 +1018,16 @@ QJsonObject JsonObject::toJsonObject(QV4::Object *o, V4ObjectSet &visitedObjects return result; } -QV4::Value JsonObject::fromJsonArray(ExecutionEngine *engine, const QJsonArray &array) +QV4::ReturnedValue JsonObject::fromJsonArray(ExecutionEngine *engine, const QJsonArray &array) { int size = array.size(); ArrayObject *a = engine->newArrayObject(); a->arrayReserve(size); a->arrayDataLen = size; for (int i = 0; i < size; i++) - a->arrayData[i].value = fromJsonValue(engine, array.at(i)); + a->arrayData[i].value = Value::fromReturnedValue(fromJsonValue(engine, array.at(i))); a->setArrayLengthUnchecked(size); - return Value::fromObject(a); + return Value::fromObject(a).asReturnedValue(); } QJsonArray JsonObject::toJsonArray(ArrayObject *a, V4ObjectSet &visitedObjects) diff --git a/src/qml/jsruntime/qv4jsonobject_p.h b/src/qml/jsruntime/qv4jsonobject_p.h index e68236622a..821cffcc7c 100644 --- a/src/qml/jsruntime/qv4jsonobject_p.h +++ b/src/qml/jsruntime/qv4jsonobject_p.h @@ -59,9 +59,9 @@ public: static ReturnedValue method_parse(SimpleCallContext *ctx); static ReturnedValue method_stringify(SimpleCallContext *ctx); - static QV4::Value fromJsonValue(ExecutionEngine *engine, const QJsonValue &value); - static QV4::Value fromJsonObject(ExecutionEngine *engine, const QJsonObject &object); - static QV4::Value fromJsonArray(ExecutionEngine *engine, const QJsonArray &array); + static ReturnedValue fromJsonValue(ExecutionEngine *engine, const QJsonValue &value); + static ReturnedValue fromJsonObject(ExecutionEngine *engine, const QJsonObject &object); + static ReturnedValue fromJsonArray(ExecutionEngine *engine, const QJsonArray &array); static inline QJsonValue toJsonValue(const QV4::Value &value) { V4ObjectSet visitedObjects; return toJsonValue(value, visitedObjects); } diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index cec9ee3761..7b372a4e17 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -1127,7 +1127,7 @@ void Object::copyArrayData(Object *other) } -Value Object::arrayIndexOf(Value v, uint fromIndex, uint endIndex, ExecutionContext *ctx, Object *o) +ReturnedValue Object::arrayIndexOf(Value v, uint fromIndex, uint endIndex, ExecutionContext *ctx, Object *o) { Scope scope(engine()); ScopedValue value(scope); @@ -1138,13 +1138,13 @@ Value Object::arrayIndexOf(Value v, uint fromIndex, uint endIndex, ExecutionCont bool exists; value = o->getIndexed(i, &exists); if (exists && __qmljs_strict_equal(value, ValueRef(&v))) - return Value::fromDouble(i); + return Encode(i); } } else if (sparseArray) { for (SparseArrayNode *n = sparseArray->lowerBound(fromIndex); n != sparseArray->end() && n->key() < endIndex; n = n->nextNode()) { value = o->getValue(arrayData + n->value, arrayAttributes ? arrayAttributes[n->value] : Attr_Data); if (__qmljs_strict_equal(value, ValueRef(&v))) - return Value::fromDouble(n->key()); + return Encode(n->key()); } } else { if ((int) endIndex > arrayDataLen) @@ -1156,12 +1156,12 @@ Value Object::arrayIndexOf(Value v, uint fromIndex, uint endIndex, ExecutionCont if (!arrayAttributes || !arrayAttributes[pd - arrayData].isGeneric()) { value = o->getValue(pd, arrayAttributes ? arrayAttributes[pd - arrayData] : Attr_Data); if (__qmljs_strict_equal(value, ValueRef(&v))) - return Value::fromDouble(pd - arrayData); + return Encode((uint)(pd - arrayData)); } ++pd; } } - return Value::fromInt32(-1); + return Encode(-1); } void Object::arrayConcat(const ArrayObject *other) diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index 983f058148..5ae167d782 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -277,7 +277,7 @@ public: void arrayConcat(const ArrayObject *other); void arraySort(ExecutionContext *context, Object *thisObject, const Value &comparefn, uint arrayDataLen); - Value arrayIndexOf(Value v, uint fromIndex, uint arrayDataLen, ExecutionContext *ctx, Object *o); + ReturnedValue arrayIndexOf(Value v, uint fromIndex, uint arrayDataLen, ExecutionContext *ctx, Object *o); void arrayReserve(uint n); void ensureArrayAttributes(); @@ -350,7 +350,7 @@ struct ForEachIteratorObject: Object { type = Type_ForeachIteratorObject; } - Value nextPropertyName() { return it.nextPropertyNameAsString(); } + ReturnedValue nextPropertyName() { return it.nextPropertyNameAsString(); } protected: static void markObjects(Managed *that); diff --git a/src/qml/jsruntime/qv4objectiterator.cpp b/src/qml/jsruntime/qv4objectiterator.cpp index 8fdf281c7f..f03c2d6b86 100644 --- a/src/qml/jsruntime/qv4objectiterator.cpp +++ b/src/qml/jsruntime/qv4objectiterator.cpp @@ -92,38 +92,38 @@ Property *ObjectIterator::next(String **name, uint *index, PropertyAttributes *a return 0; } -Value ObjectIterator::nextPropertyName(Value *value) +ReturnedValue ObjectIterator::nextPropertyName(Value *value) { PropertyAttributes attrs; uint index; String *name; Property *p = next(&name, &index, &attrs); if (!p) - return Value::nullValue(); + return Encode::null(); if (value) *value = Value::fromReturnedValue(object->getValue(p, attrs)); if (name) - return Value::fromString(name); + return Value::fromString(name).asReturnedValue(); assert(index < UINT_MAX); - return Value::fromDouble(index); + return Encode(index); } -Value ObjectIterator::nextPropertyNameAsString(Value *value) +ReturnedValue ObjectIterator::nextPropertyNameAsString(Value *value) { PropertyAttributes attrs; uint index; String *name; Property *p = next(&name, &index, &attrs); if (!p) - return Value::nullValue(); + return Encode::null(); if (value) *value = Value::fromReturnedValue(object->getValue(p, attrs)); if (name) - return Value::fromString(name); + return Value::fromString(name).asReturnedValue(); assert(index < UINT_MAX); - return Value::fromString(object->engine()->newString(QString::number(index))); + return Value::fromString(object->engine()->newString(QString::number(index))).asReturnedValue(); } diff --git a/src/qml/jsruntime/qv4objectiterator_p.h b/src/qml/jsruntime/qv4objectiterator_p.h index 95439397f5..d5464891f1 100644 --- a/src/qml/jsruntime/qv4objectiterator_p.h +++ b/src/qml/jsruntime/qv4objectiterator_p.h @@ -76,8 +76,8 @@ struct Q_QML_EXPORT ObjectIterator ObjectIterator(Object *o, uint flags); Property *next(String **name, uint *index, PropertyAttributes *attributes = 0); - Value nextPropertyName(Value *value = 0); - Value nextPropertyNameAsString(Value *value = 0); + ReturnedValue nextPropertyName(Value *value = 0); + ReturnedValue nextPropertyNameAsString(Value *value = 0); }; } diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp index da66b2436b..fe041f0bd7 100644 --- a/src/qml/jsruntime/qv4objectproto.cpp +++ b/src/qml/jsruntime/qv4objectproto.cpp @@ -352,14 +352,16 @@ ReturnedValue ObjectPrototype::method_keys(SimpleCallContext *ctx) if (!ctx->argument(0).isObject()) ctx->throwTypeError(); + Scope scope(ctx); Object *o = ctx->argument(0).objectValue(); ArrayObject *a = ctx->engine->newArrayObject(); ObjectIterator it(o, ObjectIterator::EnumerableOnly); + ScopedValue name(scope); while (1) { - Value name = it.nextPropertyNameAsString(); - if (name.isNull()) + name = it.nextPropertyNameAsString(); + if (name->isNull()) break; a->push_back(name); } @@ -605,15 +607,17 @@ ReturnedValue ObjectPrototype::fromPropertyDescriptor(ExecutionContext *ctx, con ArrayObject *ObjectPrototype::getOwnPropertyNames(ExecutionEngine *v4, const Value &o) { + Scope scope(v4); ArrayObject *array = v4->newArrayObject(); Object *O = o.asObject(); if (!O) return array; ObjectIterator it(O, ObjectIterator::NoFlags); + ScopedValue name(scope); while (1) { - Value name = it.nextPropertyNameAsString(); - if (name.isNull()) + name = it.nextPropertyNameAsString(); + if (name->isNull()) break; array->push_back(name); } diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 438465ef9b..91adf7d3e3 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -138,30 +138,16 @@ struct ReadAccessor { } }; -static inline QV4::Value valueToHandle(QV4::ExecutionEngine *, int v) -{ return QV4::Value::fromInt32(v); } -static inline QV4::Value valueToHandle(QV4::ExecutionEngine *, uint v) -{ return QV4::Value::fromUInt32(v); } -static inline QV4::Value valueToHandle(QV4::ExecutionEngine *, bool v) -{ return QV4::Value::fromBoolean(v); } -static inline QV4::Value valueToHandle(QV4::ExecutionEngine *e, const QString &v) -{ return QV4::Value::fromString(e, v); } -static inline QV4::Value valueToHandle(QV4::ExecutionEngine *, float v) -{ return QV4::Value::fromDouble(v); } -static inline QV4::Value valueToHandle(QV4::ExecutionEngine *, double v) -{ return QV4::Value::fromDouble(v); } -static inline QV4::Value valueToHandle(QV4::ExecutionEngine *e, QObject *v) -{ return QV4::QObjectWrapper::wrap(e, v); } - // Load value properties template<void (*ReadFunction)(QObject *, const QQmlPropertyData &, void *, QQmlNotifier **)> -static QV4::Value LoadProperty(QV8Engine *engine, QObject *object, +static QV4::ReturnedValue LoadProperty(QV8Engine *engine, QObject *object, const QQmlPropertyData &property, QQmlNotifier **notifier) { Q_ASSERT(!property.isFunction()); QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); + QV4::Scope scope(v4); if (property.isQObject()) { QObject *rv = 0; @@ -172,35 +158,35 @@ static QV4::Value LoadProperty(QV8Engine *engine, QObject *object, } else if (property.propType == QMetaType::QReal) { qreal v = 0; ReadFunction(object, property, &v, notifier); - return valueToHandle(v4, v); + return QV4::Encode(v); } else if (property.propType == QMetaType::Int || property.isEnum()) { int v = 0; ReadFunction(object, property, &v, notifier); - return valueToHandle(v4, v); + return QV4::Encode(v); } else if (property.propType == QMetaType::Bool) { bool v = false; ReadFunction(object, property, &v, notifier); - return valueToHandle(v4, v); + return QV4::Encode(v); } else if (property.propType == QMetaType::QString) { QString v; ReadFunction(object, property, &v, notifier); - return valueToHandle(v4, v); + return Value::fromString(v4, v).asReturnedValue(); } else if (property.propType == QMetaType::UInt) { uint v = 0; ReadFunction(object, property, &v, notifier); - return valueToHandle(v4, v); + return QV4::Encode(v); } else if (property.propType == QMetaType::Float) { float v = 0; ReadFunction(object, property, &v, notifier); - return valueToHandle(v4, v); + return QV4::Encode(v); } else if (property.propType == QMetaType::Double) { double v = 0; ReadFunction(object, property, &v, notifier); - return valueToHandle(v4, v); + return QV4::Encode(v); } else if (property.isV4Handle()) { QQmlV4Handle handle; ReadFunction(object, property, &handle, notifier); - return handle.toValue(); + return handle.toValue().asReturnedValue(); } else if (property.propType == qMetaTypeId<QJSValue>()) { QJSValue v; ReadFunction(object, property, &v, notifier); @@ -225,16 +211,16 @@ static QV4::Value LoadProperty(QV8Engine *engine, QObject *object, // see if it's a sequence type bool succeeded = false; - QV4::Value retn = QV4::SequencePrototype::newSequence(v4, property.propType, object, property.coreIndex, &succeeded); + QV4::ScopedValue retn(scope, QV4::SequencePrototype::newSequence(v4, property.propType, object, property.coreIndex, &succeeded)); if (succeeded) - return retn; + return retn.asReturnedValue(); } if (property.propType == QMetaType::UnknownType) { QMetaProperty p = object->metaObject()->property(property.coreIndex); qWarning("QMetaProperty::read: Unable to handle unregistered datatype '%s' for property " "'%s::%s'", p.typeName(), object->metaObject()->className(), p.name()); - return QV4::Value::undefinedValue(); + return QV4::Encode::undefined(); } else { QVariant v(property.propType, (void *)0); ReadFunction(object, property, v.data(), notifier); @@ -271,20 +257,23 @@ QQmlPropertyData *QObjectWrapper::findProperty(ExecutionEngine *engine, QQmlCont return result; } -Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, String *name, QObjectWrapper::RevisionMode revisionMode, bool *hasProperty, bool includeImports) +ReturnedValue QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, String *name, QObjectWrapper::RevisionMode revisionMode, + bool *hasProperty, bool includeImports) { if (QQmlData::wasDeleted(m_object)) { if (hasProperty) *hasProperty = false; - return QV4::Value::undefinedValue(); + return QV4::Encode::undefined(); } + QV4:Scope scope(ctx); + if (name->isEqualTo(m_destroy) || name->isEqualTo(m_toString)) { int index = name->isEqualTo(m_destroy) ? QV4::QObjectMethod::DestroyMethod : QV4::QObjectMethod::ToStringMethod; - QV4::Value method = QV4::QObjectMethod::create(ctx->engine->rootContext, m_object, index); + QV4::ScopedValue method(scope, QV4::QObjectMethod::create(ctx->engine->rootContext, m_object, index)); if (hasProperty) *hasProperty = true; - return method; + return method.asReturnedValue(); } QQmlPropertyData local; @@ -301,7 +290,7 @@ Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qml if (r.isValid()) { if (r.scriptIndex != -1) { - return QV4::Value::undefinedValue(); + return QV4::Encode::undefined(); } else if (r.type) { return QmlTypeWrapper::create(ctx->engine->v8Engine, m_object, r.type, QmlTypeWrapper::ExcludeEnums); } else if (r.importNamespace) { @@ -311,7 +300,7 @@ Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qml } } } - return QV4::Value::fromReturnedValue(QV4::Object::get(this, name, hasProperty)); + return QV4::Object::get(this, name, hasProperty); } QQmlData::flushPendingBinding(m_object, result->coreIndex); @@ -321,7 +310,7 @@ Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qml if (ddata && ddata->propertyCache && !ddata->propertyCache->isAllowedInRevision(result)) { if (hasProperty) *hasProperty = false; - return QV4::Value::undefinedValue(); + return QV4::Encode::undefined(); } } @@ -334,7 +323,8 @@ Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qml Q_ASSERT(vmemo); return vmemo->vmeMethod(result->coreIndex); } else if (result->isV4Function()) { - return QV4::QObjectMethod::create(ctx->engine->rootContext, m_object, result->coreIndex, QV4::Value::fromObject(ctx->engine->qmlContextObject())); + return QV4::QObjectMethod::create(ctx->engine->rootContext, m_object, result->coreIndex, + QV4::Value::fromObject(ctx->engine->qmlContextObject())).asReturnedValue(); } else if (result->isSignalHandler()) { QV4::QmlSignalHandler *handler = new (ctx->engine->memoryManager) QV4::QmlSignalHandler(ctx->engine, m_object, result->coreIndex); @@ -343,9 +333,9 @@ Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qml handler->put(connect, QV4::Value::fromReturnedValue(ctx->engine->functionClass->prototype->get(connect))); handler->put(disconnect, QV4::Value::fromReturnedValue(ctx->engine->functionClass->prototype->get(disconnect))); - return QV4::Value::fromObject(handler); + return QV4::Value::fromObject(handler).asReturnedValue(); } else { - return QV4::QObjectMethod::create(ctx->engine->rootContext, m_object, result->coreIndex); + return QV4::QObjectMethod::create(ctx->engine->rootContext, m_object, result->coreIndex).asReturnedValue(); } } @@ -358,15 +348,16 @@ Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qml if (ep && ep->propertyCapture && result->accessors->notifier) nptr = &n; - QV4::Value rv = LoadProperty<ReadAccessor::Accessor>(ctx->engine->v8Engine, m_object, *result, nptr); + QV4::ScopedValue rv(scope, LoadProperty<ReadAccessor::Accessor>(ctx->engine->v8Engine, m_object, *result, nptr)); if (result->accessors->notifier) { - if (n) ep->captureProperty(n); + if (n) + ep->captureProperty(n); } else { ep->captureProperty(m_object, result->coreIndex, result->notifyIndex); } - return rv; + return rv.asReturnedValue(); } if (ep && !result->isConstant()) @@ -383,25 +374,26 @@ Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qml } } -Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, QObject *object, String *name, QObjectWrapper::RevisionMode revisionMode, bool *hasProperty) +ReturnedValue QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, QObject *object, String *name, QObjectWrapper::RevisionMode revisionMode, bool *hasProperty) { + QV4::Scope scope(ctx); if (QQmlData::wasDeleted(object)) { if (hasProperty) *hasProperty = false; - return QV4::Value::nullValue(); + return QV4::Encode::null(); } if (!QQmlData::get(object, true)) { if (hasProperty) *hasProperty = false; - return QV4::Value::nullValue(); + return QV4::Encode::null(); } - QObjectWrapper *wrapper = wrap(ctx->engine, object).as<QV4::QObjectWrapper>(); + QV4::Scoped<QObjectWrapper> wrapper(scope, wrap(ctx->engine, object)); if (!wrapper) { if (hasProperty) *hasProperty = false; - return QV4::Value::nullValue(); + return QV4::Encode::null(); } return wrapper->getQmlProperty(ctx, qmlContext, name, revisionMode, hasProperty); } @@ -540,57 +532,59 @@ bool QObjectWrapper::setQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlC return true; } -Value QObjectWrapper::wrap(ExecutionEngine *engine, QObject *object) +ReturnedValue QObjectWrapper::wrap(ExecutionEngine *engine, QObject *object) { if (QQmlData::wasDeleted(object)) - return QV4::Value::nullValue(); + return QV4::Encode::null(); QQmlData *ddata = QQmlData::get(object, true); if (!ddata) - return QV4::Value::undefinedValue(); + return QV4::Encode::undefined(); + + Scope scope(engine); if (ddata->jsEngineId == engine->m_engineId && !ddata->jsWrapper.isEmpty()) { // We own the JS object - return ddata->jsWrapper.value(); + return ddata->jsWrapper.value().asReturnedValue(); } else if (ddata->jsWrapper.isEmpty() && (ddata->jsEngineId == engine->m_engineId || // We own the QObject ddata->jsEngineId == 0 || // No one owns the QObject !ddata->hasTaintedV8Object)) { // Someone else has used the QObject, but it isn't tainted - QV4::Value rv = create(engine, ddata, object); + QV4::ScopedValue rv(scope, create(engine, ddata, object)); ddata->jsWrapper = rv; ddata->jsEngineId = engine->m_engineId; - return rv; + return rv.asReturnedValue(); } else { // If this object is tainted, we have to check to see if it is in our // tainted object list - Object *alternateWrapper = 0; + Scoped<Object> alternateWrapper(scope, 0); if (engine->m_multiplyWrappedQObjects && ddata->hasTaintedV8Object) - alternateWrapper = engine->m_multiplyWrappedQObjects->value(object); + alternateWrapper = Value::fromObject(engine->m_multiplyWrappedQObjects->value(object)); // If our tainted handle doesn't exist or has been collected, and there isn't // a handle in the ddata, we can assume ownership of the ddata->v8object if (ddata->jsWrapper.isEmpty() && !alternateWrapper) { - QV4::Value result = create(engine, ddata, object); + QV4::ScopedValue result(scope, create(engine, ddata, object)); ddata->jsWrapper = result; ddata->jsEngineId = engine->m_engineId; - return result; + return result.asReturnedValue(); } if (!alternateWrapper) { - alternateWrapper = create(engine, ddata, object).asObject(); + alternateWrapper = create(engine, ddata, object); if (!engine->m_multiplyWrappedQObjects) engine->m_multiplyWrappedQObjects = new MultiplyWrappedQObjectMap; - engine->m_multiplyWrappedQObjects->insert(object, alternateWrapper); + engine->m_multiplyWrappedQObjects->insert(object, alternateWrapper.getPointer()); ddata->hasTaintedV8Object = true; } - return QV4::Value::fromObject(alternateWrapper); + return alternateWrapper.asReturnedValue(); } } -QV4::Value QObjectWrapper::create(ExecutionEngine *engine, QQmlData *ddata, QObject *object) +ReturnedValue QObjectWrapper::create(ExecutionEngine *engine, QQmlData *ddata, QObject *object) { QQmlEngine *qmlEngine = engine->v8Engine->engine(); if (!ddata->propertyCache && qmlEngine) { @@ -598,7 +592,7 @@ QV4::Value QObjectWrapper::create(ExecutionEngine *engine, QQmlData *ddata, QObj if (ddata->propertyCache) ddata->propertyCache->addref(); } - return Value::fromObject(new (engine->memoryManager) QV4::QObjectWrapper(engine, object)); + return Value::fromObject(new (engine->memoryManager) QV4::QObjectWrapper(engine, object)).asReturnedValue(); } QV4::ReturnedValue QObjectWrapper::get(Managed *m, String *name, bool *hasProperty) @@ -606,7 +600,7 @@ QV4::ReturnedValue QObjectWrapper::get(Managed *m, String *name, bool *hasProper QObjectWrapper *that = static_cast<QObjectWrapper*>(m); ExecutionEngine *v4 = m->engine(); QQmlContextData *qmlContext = QV4::QmlContextWrapper::callingContext(v4); - return that->getQmlProperty(v4->current, qmlContext, name, IgnoreRevision, hasProperty, /*includeImports*/ true).asReturnedValue(); + return that->getQmlProperty(v4->current, qmlContext, name, IgnoreRevision, hasProperty, /*includeImports*/ true); } void QObjectWrapper::put(Managed *m, String *name, const Value &value) @@ -707,9 +701,9 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase for (int ii = 0; ii < argCount; ++ii) { int type = argsTypes[ii + 1]; if (type == qMetaTypeId<QVariant>()) { - callData->args[ii] = v4->v8Engine->fromVariant(*((QVariant *)metaArgs[ii + 1])); + callData->args[ii] = QV4::Value::fromReturnedValue(v4->v8Engine->fromVariant(*((QVariant *)metaArgs[ii + 1]))); } else { - callData->args[ii] = v4->v8Engine->fromVariant(QVariant(type, metaArgs[ii + 1])); + callData->args[ii] = QV4::Value::fromReturnedValue(v4->v8Engine->fromVariant(QVariant(type, metaArgs[ii + 1]))); } } @@ -968,7 +962,7 @@ struct CallArgument { inline void initAsType(int type); inline void fromValue(int type, QV8Engine *, const QV4::Value&); - inline QV4::Value toValue(QV8Engine *); + inline ReturnedValue toValue(QV8Engine *); private: CallArgument(const CallArgument &); @@ -1052,7 +1046,7 @@ static QV4::ReturnedValue CallMethod(QObject *object, int index, int returnType, QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, index, argData.data()); - return args[0].toValue(engine).asReturnedValue(); + return args[0].toValue(engine); } else if (returnType != QMetaType::Void) { @@ -1063,7 +1057,7 @@ static QV4::ReturnedValue CallMethod(QObject *object, int index, int returnType, QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, index, args); - return arg.toValue(engine).asReturnedValue(); + return arg.toValue(engine); } else { @@ -1581,23 +1575,25 @@ void CallArgument::fromValue(int callType, QV8Engine *engine, const QV4::Value & } } -QV4::Value CallArgument::toValue(QV8Engine *engine) +QV4::ReturnedValue CallArgument::toValue(QV8Engine *engine) { QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); + QV4::Scope scope(v4); + if (type == qMetaTypeId<QJSValue>()) { return QJSValuePrivate::get(*qjsValuePtr)->getValue(v4); } else if (type == QMetaType::Int) { - return QV4::Value::fromInt32(int(intValue)); + return QV4::Encode(int(intValue)); } else if (type == QMetaType::UInt) { - return QV4::Value::fromUInt32(intValue); + return QV4::Encode((uint)intValue); } else if (type == QMetaType::Bool) { - return QV4::Value::fromBoolean(boolValue); + return QV4::Encode(boolValue); } else if (type == QMetaType::Double) { - return QV4::Value::fromDouble(doubleValue); + return QV4::Encode(doubleValue); } else if (type == QMetaType::Float) { - return QV4::Value::fromDouble(floatValue); + return QV4::Encode(floatValue); } else if (type == QMetaType::QString) { - return engine->toString(*qstringPtr); + return engine->toString(*qstringPtr).asReturnedValue(); } else if (type == QMetaType::QObjectStar) { QObject *object = qobjectPtr; if (object) @@ -1611,11 +1607,11 @@ QV4::Value CallArgument::toValue(QV8Engine *engine) array->arrayReserve(list.count()); array->arrayDataLen = list.count(); for (int ii = 0; ii < list.count(); ++ii) - array->arrayData[ii].value = QV4::QObjectWrapper::wrap(v4, list.at(ii)); + array->arrayData[ii].value = Value::fromReturnedValue(QV4::QObjectWrapper::wrap(v4, list.at(ii))); array->setArrayLengthUnchecked(list.count()); - return QV4::Value::fromObject(array); + return QV4::Value::fromObject(array).asReturnedValue(); } else if (type == qMetaTypeId<QQmlV4Handle>()) { - return handlePtr->toValue(); + return handlePtr->toValue().asReturnedValue(); } else if (type == QMetaType::QJsonArray) { return QV4::JsonObject::fromJsonArray(v4, *jsonArrayPtr); } else if (type == QMetaType::QJsonObject) { @@ -1624,14 +1620,14 @@ QV4::Value CallArgument::toValue(QV8Engine *engine) return QV4::JsonObject::fromJsonValue(v4, *jsonValuePtr); } else if (type == -1 || type == qMetaTypeId<QVariant>()) { QVariant value = *qvariantPtr; - QV4::Value rv = engine->fromVariant(value); - if (QV4::QObjectWrapper *qobjectWrapper = rv.as<QV4::QObjectWrapper>()) { + QV4::ScopedValue rv(scope, engine->fromVariant(value)); + if (QV4::QObjectWrapper *qobjectWrapper = rv->as<QV4::QObjectWrapper>()) { if (QObject *object = qobjectWrapper->object()) QQmlData::get(object, true)->setImplicitDestructible(); } - return rv; + return rv.asReturnedValue(); } else { - return QV4::Value::undefinedValue(); + return QV4::Encode::undefined(); } } diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h index 4c860e1786..95986a4b0d 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper_p.h +++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h @@ -85,17 +85,17 @@ struct Q_QML_EXPORT QObjectWrapper : public QV4::Object QObject *object() const { return m_object.data(); } - Value getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, bool *hasProperty = 0, bool includeImports = false); - static Value getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, QObject *object, String *name, RevisionMode revisionMode, bool *hasProperty = 0); + ReturnedValue getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, bool *hasProperty = 0, bool includeImports = false); + static ReturnedValue getQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, QObject *object, String *name, RevisionMode revisionMode, bool *hasProperty = 0); static bool setQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlContext, QObject *object, String *name, RevisionMode revisionMode, const Value &value); - static Value wrap(ExecutionEngine *engine, QObject *object); + static ReturnedValue wrap(ExecutionEngine *engine, QObject *object); using Object::get; private: - static Value create(ExecutionEngine *engine, QQmlData *ddata, QObject *object); + static ReturnedValue create(ExecutionEngine *engine, QQmlData *ddata, QObject *object); QObjectWrapper(ExecutionEngine *engine, QObject *object); diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index e17d9b833d..0a8b1b4055 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -755,7 +755,7 @@ ReturnedValue __qmljs_foreach_next_property_name(const ValueRef foreach_iterator ForEachIteratorObject *it = static_cast<ForEachIteratorObject *>(foreach_iterator->objectValue()); Q_ASSERT(it->as<ForEachIteratorObject>()); - return it->nextPropertyName().asReturnedValue(); + return it->nextPropertyName(); } diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 0441c3cce6..e3c9505ab7 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -263,12 +263,12 @@ Function *Script::function() return vmFunction; } -Value Script::qmlBinding() +ReturnedValue Script::qmlBinding() { if (!parsed) parse(); QV4::ExecutionEngine *v4 = scope->engine; - return Value::fromObject(new (v4->memoryManager) QmlBindingWrapper(scope, vmFunction, qml.value().asObject())); + return Value::fromObject(new (v4->memoryManager) QmlBindingWrapper(scope, vmFunction, qml.value().asObject())).asReturnedValue(); } QV4::ReturnedValue Script::evaluate(ExecutionEngine *engine, const QString &script, Object *scopeObject) diff --git a/src/qml/jsruntime/qv4script_p.h b/src/qml/jsruntime/qv4script_p.h index b0c863d6be..46f28ccb1e 100644 --- a/src/qml/jsruntime/qv4script_p.h +++ b/src/qml/jsruntime/qv4script_p.h @@ -75,7 +75,7 @@ struct Q_QML_EXPORT Script { void parse(); ReturnedValue run(); - Value qmlBinding(); + ReturnedValue qmlBinding(); Function *function(); diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp index 99c1878a9e..72356204b5 100644 --- a/src/qml/jsruntime/qv4sequenceobject.cpp +++ b/src/qml/jsruntime/qv4sequenceobject.cpp @@ -571,36 +571,38 @@ bool SequencePrototype::isSequenceType(int sequenceTypeId) #define NEW_REFERENCE_SEQUENCE(ElementType, ElementTypeName, SequenceType, unused) \ if (sequenceType == qMetaTypeId<SequenceType>()) { \ - QV4::Object *obj = new (engine->memoryManager) QQml##ElementTypeName##List(engine, object, propertyIndex); \ - return QV4::Value::fromObject(obj); \ + QV4::Scoped<QV4::Object> obj(scope, QV4::Value::fromObject(new (engine->memoryManager) QQml##ElementTypeName##List(engine, object, propertyIndex))); \ + return obj.asReturnedValue(); \ } else -QV4::Value SequencePrototype::newSequence(QV4::ExecutionEngine *engine, int sequenceType, QObject *object, int propertyIndex, bool *succeeded) +ReturnedValue SequencePrototype::newSequence(QV4::ExecutionEngine *engine, int sequenceType, QObject *object, int propertyIndex, bool *succeeded) { + QV4::Scope scope(engine); // This function is called when the property is a QObject Q_PROPERTY of // the given sequence type. Internally we store a typed-sequence // (as well as object ptr + property index for updated-read and write-back) // and so access/mutate avoids variant conversion. *succeeded = true; - FOREACH_QML_SEQUENCE_TYPE(NEW_REFERENCE_SEQUENCE) { /* else */ *succeeded = false; return QV4::Value::undefinedValue(); } + FOREACH_QML_SEQUENCE_TYPE(NEW_REFERENCE_SEQUENCE) { /* else */ *succeeded = false; return QV4::Encode::undefined(); } } #undef NEW_REFERENCE_SEQUENCE #define NEW_COPY_SEQUENCE(ElementType, ElementTypeName, SequenceType, unused) \ if (sequenceType == qMetaTypeId<SequenceType>()) { \ - QV4::Object *obj = new (engine->memoryManager) QQml##ElementTypeName##List(engine, v.value<SequenceType >()); \ - return QV4::Value::fromObject(obj); \ + QV4::Scoped<QV4::Object> obj(scope, QV4::Value::fromObject(new (engine->memoryManager) QQml##ElementTypeName##List(engine, v.value<SequenceType >()))); \ + return obj.asReturnedValue(); \ } else -QV4::Value SequencePrototype::fromVariant(QV4::ExecutionEngine *engine, const QVariant& v, bool *succeeded) +ReturnedValue SequencePrototype::fromVariant(QV4::ExecutionEngine *engine, const QVariant& v, bool *succeeded) { + QV4::Scope scope(engine); // This function is called when assigning a sequence value to a normal JS var // in a JS block. Internally, we store a sequence of the specified type. // Access and mutation is extremely fast since it will not need to modify any // QObject property. int sequenceType = v.userType(); *succeeded = true; - FOREACH_QML_SEQUENCE_TYPE(NEW_COPY_SEQUENCE) { /* else */ *succeeded = false; return QV4::Value::undefinedValue(); } + FOREACH_QML_SEQUENCE_TYPE(NEW_COPY_SEQUENCE) { /* else */ *succeeded = false; return QV4::Encode::undefined(); } } #undef NEW_COPY_SEQUENCE diff --git a/src/qml/jsruntime/qv4sequenceobject_p.h b/src/qml/jsruntime/qv4sequenceobject_p.h index 2a81f81d26..f2d06d8918 100644 --- a/src/qml/jsruntime/qv4sequenceobject_p.h +++ b/src/qml/jsruntime/qv4sequenceobject_p.h @@ -69,7 +69,7 @@ struct SequencePrototype : public QV4::Object void init(QV4::ExecutionEngine *engine); - static QV4::ReturnedValue method_valueOf(QV4::SimpleCallContext *ctx) + static ReturnedValue method_valueOf(QV4::SimpleCallContext *ctx) { return QV4::Value::fromString(ctx->thisObject.toString(ctx)).asReturnedValue(); } @@ -77,8 +77,8 @@ struct SequencePrototype : public QV4::Object static ReturnedValue method_sort(QV4::SimpleCallContext *ctx); static bool isSequenceType(int sequenceTypeId); - static QV4::Value newSequence(QV4::ExecutionEngine *engine, int sequenceTypeId, QObject *object, int propertyIndex, bool *succeeded); - static QV4::Value fromVariant(QV4::ExecutionEngine *engine, const QVariant& v, bool *succeeded); + static ReturnedValue newSequence(QV4::ExecutionEngine *engine, int sequenceTypeId, QObject *object, int propertyIndex, bool *succeeded); + static ReturnedValue fromVariant(QV4::ExecutionEngine *engine, const QVariant& v, bool *succeeded); static int metaTypeForSequence(QV4::Object *object); static QVariant toVariant(QV4::Object *object); static QVariant toVariant(const QV4::Value &array, int typeHint, bool *succeeded); diff --git a/src/qml/jsruntime/qv4serialize.cpp b/src/qml/jsruntime/qv4serialize.cpp index 0bd3f79a5b..b1bdec10df 100644 --- a/src/qml/jsruntime/qv4serialize.cpp +++ b/src/qml/jsruntime/qv4serialize.cpp @@ -287,28 +287,29 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, QV8Engine *engi } } -QV4::Value Serialize::deserialize(const char *&data, QV8Engine *engine) +ReturnedValue Serialize::deserialize(const char *&data, QV8Engine *engine) { quint32 header = popUint32(data); Type type = headertype(header); QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); + Scope scope(v4); switch (type) { case WorkerUndefined: - return QV4::Value::undefinedValue(); + return QV4::Encode::undefined(); case WorkerNull: - return QV4::Value::nullValue(); + return QV4::Encode::null(); case WorkerTrue: - return QV4::Value::fromBoolean(true); + return QV4::Encode(true); case WorkerFalse: - return QV4::Value::fromBoolean(false); + return QV4::Encode(false); case WorkerString: { quint32 size = headersize(header); QString qstr((QChar *)data, size); data += ALIGN(size * sizeof(uint16_t)); - return QV4::Value::fromString(v4->newString(qstr)); + return QV4::Value::fromString(v4->newString(qstr)).asReturnedValue(); } case WorkerFunction: Q_ASSERT(!"Unreachable"); @@ -317,70 +318,79 @@ QV4::Value Serialize::deserialize(const char *&data, QV8Engine *engine) { quint32 size = headersize(header); QV4::ArrayObject *a = v4->newArrayObject(); + ScopedValue v(scope); for (quint32 ii = 0; ii < size; ++ii) { - a->putIndexed(ii, deserialize(data, engine)); + v = deserialize(data, engine); + a->putIndexed(ii, v); } - return QV4::Value::fromObject(a); + return QV4::Value::fromObject(a).asReturnedValue(); } case WorkerObject: { quint32 size = headersize(header); QV4::Object *o = v4->newObject(); + ScopedValue name(scope); + ScopedValue value(scope); for (quint32 ii = 0; ii < size; ++ii) { - QV4::Value name = deserialize(data, engine); - QV4::Value value = deserialize(data, engine); - o->put(name.asString(), value); + name = deserialize(data, engine); + value = deserialize(data, engine); + o->put(name->asString(), value); } - return QV4::Value::fromObject(o); + return QV4::Value::fromObject(o).asReturnedValue(); } case WorkerInt32: - return QV4::Value::fromInt32((qint32)popUint32(data)); + return QV4::Encode((qint32)popUint32(data)); case WorkerUint32: - return QV4::Value::fromUInt32(popUint32(data)); + return QV4::Encode(popUint32(data)); case WorkerNumber: - return QV4::Value::fromDouble(popDouble(data)); + return QV4::Encode(popDouble(data)); case WorkerDate: - return QV4::Value::fromObject(v4->newDateObject(QV4::Value::fromDouble(popDouble(data)))); + return QV4::Value::fromObject(v4->newDateObject(QV4::Value::fromDouble(popDouble(data)))).asReturnedValue(); case WorkerRegexp: { quint32 flags = headersize(header); quint32 length = popUint32(data); QString pattern = QString((QChar *)data, length - 1); data += ALIGN(length * sizeof(uint16_t)); - return QV4::Value::fromObject(v4->newRegExpObject(pattern, flags)); + return QV4::Value::fromObject(v4->newRegExpObject(pattern, flags)).asReturnedValue(); } case WorkerListModel: { void *ptr = popPtr(data); QQmlListModelWorkerAgent *agent = (QQmlListModelWorkerAgent *)ptr; - QV4::Value rv = QV4::QObjectWrapper::wrap(v4, agent); + QV4::ScopedValue rv(scope, QV4::QObjectWrapper::wrap(v4, agent)); // ### Find a better solution then the ugly property QQmlListModelWorkerAgent::VariantRef ref(agent); QVariant var = qVariantFromValue(ref); - rv.asObject()->defineReadonlyProperty(v4->newString("__qml:hidden:ref"), engine->fromVariant(var)); + QV4::ScopedValue v(scope, engine->fromVariant((var))); + rv->asObject()->defineReadonlyProperty(v4->newString("__qml:hidden:ref"), v); agent->release(); agent->setV8Engine(engine); - return rv; + return rv.asReturnedValue(); } case WorkerSequence: { + ScopedValue value(scope); bool succeeded = false; quint32 length = headersize(header); quint32 seqLength = length - 1; - int sequenceType = deserialize(data, engine).integerValue(); + value = deserialize(data, engine); + int sequenceType = value->integerValue(); QV4::ArrayObject *array = v4->newArrayObject(); array->arrayReserve(seqLength); array->arrayDataLen = seqLength; - for (quint32 ii = 0; ii < seqLength; ++ii) - array->arrayData[ii].value = deserialize(data, engine); + for (quint32 ii = 0; ii < seqLength; ++ii) { + value = deserialize(data, engine); + array->arrayData[ii].value = value; + } array->setArrayLengthUnchecked(seqLength); QVariant seqVariant = QV4::SequencePrototype::toVariant(QV4::Value::fromObject(array), sequenceType, &succeeded); return QV4::SequencePrototype::fromVariant(v4, seqVariant, &succeeded); } } Q_ASSERT(!"Unreachable"); - return QV4::Value::undefinedValue(); + return QV4::Encode::undefined(); } QByteArray Serialize::serialize(const QV4::Value &value, QV8Engine *engine) @@ -390,7 +400,7 @@ QByteArray Serialize::serialize(const QV4::Value &value, QV8Engine *engine) return rv; } -QV4::Value Serialize::deserialize(const QByteArray &data, QV8Engine *engine) +ReturnedValue Serialize::deserialize(const QByteArray &data, QV8Engine *engine) { const char *stream = data.constData(); return deserialize(stream, engine); diff --git a/src/qml/jsruntime/qv4serialize_p.h b/src/qml/jsruntime/qv4serialize_p.h index 5a04c9d25f..caedb962b1 100644 --- a/src/qml/jsruntime/qv4serialize_p.h +++ b/src/qml/jsruntime/qv4serialize_p.h @@ -66,11 +66,11 @@ class Serialize { public: static QByteArray serialize(const Value &, QV8Engine *); - static Value deserialize(const QByteArray &, QV8Engine *); + static ReturnedValue deserialize(const QByteArray &, QV8Engine *); private: static void serialize(QByteArray &, const Value &, QV8Engine *); - static Value deserialize(const char *&, QV8Engine *); + static ReturnedValue deserialize(const char *&, QV8Engine *); }; } |