From a2d115fbaffee282a1d32ed92c6700e6c3dd811b Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 12 Sep 2013 22:37:41 +0200 Subject: Convert most remaining return values from Value to ReturnedValue Change-Id: If8b0c3b91be50678693868c10fefc3678008834d Reviewed-by: Simon Hausmann --- src/qml/jsapi/qjsengine.cpp | 8 +- src/qml/jsapi/qjsvalue.cpp | 38 ++++--- src/qml/jsapi/qjsvalue_p.h | 2 +- src/qml/jsruntime/qv4arrayobject.cpp | 2 +- src/qml/jsruntime/qv4debugging.cpp | 10 +- src/qml/jsruntime/qv4functionobject.cpp | 3 +- src/qml/jsruntime/qv4functionobject_p.h | 4 +- src/qml/jsruntime/qv4include.cpp | 8 +- src/qml/jsruntime/qv4include_p.h | 4 +- src/qml/jsruntime/qv4jsonobject.cpp | 43 ++++---- src/qml/jsruntime/qv4jsonobject_p.h | 6 +- src/qml/jsruntime/qv4object.cpp | 10 +- src/qml/jsruntime/qv4object_p.h | 4 +- src/qml/jsruntime/qv4objectiterator.cpp | 16 +-- src/qml/jsruntime/qv4objectiterator_p.h | 4 +- src/qml/jsruntime/qv4objectproto.cpp | 12 ++- src/qml/jsruntime/qv4qobjectwrapper.cpp | 156 ++++++++++++++-------------- src/qml/jsruntime/qv4qobjectwrapper_p.h | 8 +- src/qml/jsruntime/qv4runtime.cpp | 2 +- src/qml/jsruntime/qv4script.cpp | 4 +- src/qml/jsruntime/qv4script_p.h | 2 +- src/qml/jsruntime/qv4sequenceobject.cpp | 18 ++-- src/qml/jsruntime/qv4sequenceobject_p.h | 6 +- src/qml/jsruntime/qv4serialize.cpp | 60 ++++++----- src/qml/jsruntime/qv4serialize_p.h | 4 +- src/qml/qml/qqmlbinding.cpp | 9 +- src/qml/qml/qqmlboundsignal.cpp | 6 +- src/qml/qml/qqmlcomponent.cpp | 12 +-- src/qml/qml/qqmlcontextwrapper.cpp | 21 ++-- src/qml/qml/qqmlcontextwrapper_p.h | 4 +- src/qml/qml/qqmlexpression.cpp | 5 +- src/qml/qml/qqmlexpression_p.h | 2 +- src/qml/qml/qqmljavascriptexpression.cpp | 36 ++++--- src/qml/qml/qqmljavascriptexpression_p.h | 4 +- src/qml/qml/qqmllistwrapper.cpp | 14 +-- src/qml/qml/qqmllistwrapper_p.h | 4 +- src/qml/qml/qqmllocale.cpp | 4 +- src/qml/qml/qqmllocale_p.h | 2 +- src/qml/qml/qqmltypewrapper.cpp | 27 ++--- src/qml/qml/qqmltypewrapper_p.h | 4 +- src/qml/qml/qqmlvaluetypewrapper.cpp | 12 +-- src/qml/qml/qqmlvaluetypewrapper_p.h | 4 +- src/qml/qml/qqmlvme.cpp | 8 +- src/qml/qml/qqmlvmemetaobject.cpp | 27 ++--- src/qml/qml/qqmlvmemetaobject_p.h | 8 +- src/qml/qml/qqmlxmlhttprequest.cpp | 4 +- src/qml/qml/v8/qqmlbuiltinfunctions.cpp | 52 +++++----- src/qml/qml/v8/qv8engine.cpp | 169 +++++++++++++++---------------- src/qml/qml/v8/qv8engine_p.h | 13 ++- src/qml/types/qqmldelegatemodel.cpp | 35 ++++--- src/qml/types/qqmldelegatemodel_p_p.h | 8 +- src/qml/types/qqmllistmodel.cpp | 46 +++++---- src/qml/types/qquickworkerscript.cpp | 3 +- src/qml/util/qqmladaptormodel.cpp | 21 ++-- 54 files changed, 523 insertions(+), 475 deletions(-) (limited to 'src/qml') diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp index 7bc8b80396..0f291d7c98 100644 --- a/src/qml/jsapi/qjsengine.cpp +++ b/src/qml/jsapi/qjsengine.cpp @@ -327,8 +327,10 @@ QJSValue QJSEngine::newQObject(QObject *object) { Q_D(QJSEngine); QV4::ExecutionEngine *v4 = QV8Engine::getV4(d); + QV4::Scope scope(v4); QQmlEngine::setObjectOwnership(object, QQmlEngine::JavaScriptOwnership); - return new QJSValuePrivate(v4, QV4::QObjectWrapper::wrap(v4, object)); + QV4::ScopedValue v(scope, QV4::QObjectWrapper::wrap(v4, object)); + return new QJSValuePrivate(v4, v); } /*! @@ -353,7 +355,7 @@ QJSValue QJSEngine::globalObject() const QJSValue QJSEngine::create(int type, const void *ptr) { Q_D(QJSEngine); - return new QJSValuePrivate(d->m_v4Engine, d->metaTypeToJS(type, ptr)); + return new QJSValuePrivate(d->m_v4Engine, QV4::Value::fromReturnedValue(d->metaTypeToJS(type, ptr))); } /*! @@ -365,7 +367,7 @@ bool QJSEngine::convertV2(const QJSValue &value, int type, void *ptr) QJSValuePrivate *vp = QJSValuePrivate::get(value); QV8Engine *engine = vp->engine ? vp->engine->v8Engine : 0; if (engine) { - return engine->metaTypeFromJS(vp->getValue(engine->m_v4Engine), type, ptr); + return engine->metaTypeFromJS(QV4::Value::fromReturnedValue(vp->getValue(engine->m_v4Engine)), type, ptr); } else { switch (type) { case QMetaType::Bool: diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp index e596cb6303..ca2f398f2f 100644 --- a/src/qml/jsapi/qjsvalue.cpp +++ b/src/qml/jsapi/qjsvalue.cpp @@ -57,13 +57,13 @@ #include #include -QV4::Value QJSValuePrivate::getValue(QV4::ExecutionEngine *e) +QV4::ReturnedValue QJSValuePrivate::getValue(QV4::ExecutionEngine *e) { if (!this->engine) this->engine = e; else if (this->engine != e) { qWarning("JSValue can't be reassigned to another engine."); - return QV4::Value::emptyValue(); + return QV4::Value::emptyValue().asReturnedValue(); } if (value.asString() == &string) { value = QV4::Value::fromString(engine->newString(string.toQString())); @@ -74,7 +74,7 @@ QV4::Value QJSValuePrivate::getValue(QV4::ExecutionEngine *e) if (next) next->prev = &this->next; } - return value; + return value.asReturnedValue(); } /*! @@ -514,7 +514,7 @@ QJSValue QJSValue::call(const QJSValueList &args) qWarning("QJSValue::call() failed: cannot call function with argument created in a different engine"); return QJSValue(); } - callData->args[i] = args.at(i).d->getValue(engine); + callData->args[i] = QV4::Value::fromReturnedValue(args.at(i).d->getValue(engine)); } ScopedValue result(scope); @@ -565,13 +565,13 @@ QJSValue QJSValue::callWithInstance(const QJSValue &instance, const QJSValueList } ScopedCallData callData(scope, args.size()); - callData->thisObject = instance.d->getValue(engine); + callData->thisObject = QV4::Value::fromReturnedValue(instance.d->getValue(engine)); for (int i = 0; i < args.size(); ++i) { if (!args.at(i).d->checkEngine(engine)) { qWarning("QJSValue::call() failed: cannot call function with argument created in a different engine"); return QJSValue(); } - callData->args[i] = args.at(i).d->getValue(engine); + callData->args[i] = QV4::Value::fromReturnedValue(args.at(i).d->getValue(engine)); } ScopedValue result(scope); @@ -620,7 +620,7 @@ QJSValue QJSValue::callAsConstructor(const QJSValueList &args) qWarning("QJSValue::callAsConstructor() failed: cannot construct function with argument created in a different engine"); return QJSValue(); } - callData->args[i] = args.at(i).d->getValue(engine); + callData->args[i] = QV4::Value::fromReturnedValue(args.at(i).d->getValue(engine)); } ScopedValue result(scope); @@ -864,7 +864,12 @@ QJSValue QJSValue::property(quint32 arrayIndex) const */ void QJSValue::setProperty(const QString& name, const QJSValue& value) { - Object *o = d->value.asObject(); + ExecutionEngine *engine = d->engine; + if (!engine) + return; + Scope scope(engine); + + Scoped o(scope, d->value); if (!o) return; @@ -873,7 +878,6 @@ void QJSValue::setProperty(const QString& name, const QJSValue& value) return; } - ExecutionEngine *engine = d->engine; String *s = engine->newString(name); uint idx = s->asArrayIndex(); if (idx < UINT_MAX) { @@ -884,7 +888,8 @@ void QJSValue::setProperty(const QString& name, const QJSValue& value) QV4::ExecutionContext *ctx = engine->current; s->makeIdentifier(); try { - o->put(s, value.d->getValue(engine)); + QV4::ScopedValue v(scope, value.d->getValue(engine)); + o->put(s, v); } catch (QV4::Exception &e) { e.accept(ctx); } @@ -904,17 +909,22 @@ void QJSValue::setProperty(const QString& name, const QJSValue& value) */ void QJSValue::setProperty(quint32 arrayIndex, const QJSValue& value) { - Object *o = d->value.asObject(); + ExecutionEngine *engine = d->engine; + if (!engine) + return; + Scope scope(engine); + + Scoped o(scope, d->value); if (!o) return; - ExecutionEngine *engine = d->engine; QV4::ExecutionContext *ctx = engine->current; + QV4::ScopedValue v(scope, value.d->getValue(engine)); try { if (arrayIndex != UINT_MAX) - o->putIndexed(arrayIndex, value.d->getValue(engine)); + o->putIndexed(arrayIndex, v); else - o->put(engine->id_uintMax, value.d->getValue(engine)); + o->put(engine->id_uintMax, v); } catch (QV4::Exception &e) { e.accept(ctx); } diff --git a/src/qml/jsapi/qjsvalue_p.h b/src/qml/jsapi/qjsvalue_p.h index 69046e84df..f99fed7c44 100644 --- a/src/qml/jsapi/qjsvalue_p.h +++ b/src/qml/jsapi/qjsvalue_p.h @@ -88,7 +88,7 @@ public: value = QV4::Value::fromString(&string); } - QV4::Value getValue(QV4::ExecutionEngine *e); + QV4::ReturnedValue getValue(QV4::ExecutionEngine *e); static QJSValuePrivate *get(const QJSValue &v) { return v.d; } 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(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 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 -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 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(ctx->engine->v8Engine, m_object, *result, nptr); + QV4::ScopedValue rv(scope, LoadProperty(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::Scoped 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 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(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()) { - 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()) { 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()) { - 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 value = *qvariantPtr; - QV4::Value rv = engine->fromVariant(value); - if (QV4::QObjectWrapper *qobjectWrapper = rv.as()) { + QV4::ScopedValue rv(scope, engine->fromVariant(value)); + if (QV4::QObjectWrapper *qobjectWrapper = rv->as()) { 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(foreach_iterator->objectValue()); Q_ASSERT(it->as()); - 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()) { \ - QV4::Object *obj = new (engine->memoryManager) QQml##ElementTypeName##List(engine, object, propertyIndex); \ - return QV4::Value::fromObject(obj); \ + QV4::Scoped 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()) { \ - QV4::Object *obj = new (engine->memoryManager) QQml##ElementTypeName##List(engine, v.value()); \ - return QV4::Value::fromObject(obj); \ + QV4::Scoped obj(scope, QV4::Value::fromObject(new (engine->memoryManager) QQml##ElementTypeName##List(engine, v.value()))); \ + 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 *); }; } diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index eff17ddd9a..a5e281dc56 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -244,12 +244,13 @@ void QQmlBinding::update(QQmlPropertyPrivate::WriteFlags flags) } else { QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context()->engine); + QV4::Scope scope(ep->v4engine()); + ep->referenceScarceResources(); bool isUndefined = false; - QV4::Value result = - QQmlJavaScriptExpression::evaluate(context(), v4function.value(), &isUndefined); + QV4::ScopedValue result(scope, QQmlJavaScriptExpression::evaluate(context(), v4function.value(), &isUndefined)); trace.event("writing binding result"); @@ -285,12 +286,12 @@ void QQmlBinding::update(QQmlPropertyPrivate::WriteFlags flags) QVariant QQmlBinding::evaluate() { QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context()->engine); + QV4::Scope scope(ep->v4engine()); ep->referenceScarceResources(); bool isUndefined = false; - QV4::Value result = - QQmlJavaScriptExpression::evaluate(context(), v4function.value(), &isUndefined); + QV4::ScopedValue result(scope, QQmlJavaScriptExpression::evaluate(context(), v4function.value(), &isUndefined)); ep->dereferenceScarceResources(); diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp index b7cb52bdbc..deb93b990d 100644 --- a/src/qml/qml/qqmlboundsignal.cpp +++ b/src/qml/qml/qqmlboundsignal.cpp @@ -194,7 +194,7 @@ void QQmlBoundSignalExpression::evaluate(void **a) // for several cases (such as QVariant type and QObject-derived types) //args[ii] = engine->metaTypeToJS(type, a[ii + 1]); if (type == QMetaType::QVariant) { - args[ii] = engine->fromVariant(*((QVariant *)a[ii + 1])); + args[ii] = QV4::Value::fromReturnedValue(engine->fromVariant(*((QVariant *)a[ii + 1]))); } else if (type == QMetaType::Int) { //### optimization. Can go away if we switch to metaTypeToJS, or be expanded otherwise args[ii] = QV4::Value::fromInt32(*reinterpret_cast(a[ii + 1])); @@ -204,9 +204,9 @@ void QQmlBoundSignalExpression::evaluate(void **a) if (!*reinterpret_cast(a[ii + 1])) args[ii] = QV4::Value::nullValue(); else - args[ii] = QV4::QObjectWrapper::wrap(ep->v4engine(), *reinterpret_cast(a[ii + 1])); + args[ii] = QV4::Value::fromReturnedValue(QV4::QObjectWrapper::wrap(ep->v4engine(), *reinterpret_cast(a[ii + 1]))); } else { - args[ii] = engine->fromVariant(QVariant(type, a[ii + 1])); + args[ii] = QV4::Value::fromReturnedValue(engine->fromVariant(QVariant(type, a[ii + 1]))); } } diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index eb5e314ead..f822728f08 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -1221,8 +1221,8 @@ void QQmlComponent::createObject(QQmlV4Function *args) QQmlComponent_setQmlParent(rv, parent); - QV4::Value object = QV4::QObjectWrapper::wrap(v4engine, rv); - Q_ASSERT(object.asObject()); + QV4::ScopedValue object(scope, QV4::QObjectWrapper::wrap(v4engine, rv)); + Q_ASSERT(object->isObject()); if (!valuemap.isEmpty()) { QQmlComponentExtension *e = componentExtension(v8engine); @@ -1369,8 +1369,8 @@ void QQmlComponentPrivate::initializeObjectWithInitialProperties(const QV4::Valu QV4::ExecutionEngine *v4engine = QV8Engine::getV4(v8engine); QV4::Scope scope(v4engine); - QV4::Value object = QV4::QObjectWrapper::wrap(v4engine, toCreate); - Q_ASSERT(object.asObject()); + QV4::ScopedValue object(scope, QV4::QObjectWrapper::wrap(v4engine, toCreate)); + Q_ASSERT(object->asObject()); if (!valuemap.isEmpty()) { QQmlComponentExtension *e = componentExtension(v8engine); @@ -1412,7 +1412,7 @@ QV4::ReturnedValue QmlIncubatorObject::method_get_object(QV4::SimpleCallContext if (!o) ctx->throwTypeError(); - return QV4::QObjectWrapper::wrap(ctx->engine, o->object()).asReturnedValue(); + return QV4::QObjectWrapper::wrap(ctx->engine, o->object()); } QV4::ReturnedValue QmlIncubatorObject::method_forceCompletion(QV4::SimpleCallContext *ctx) @@ -1478,7 +1478,7 @@ void QmlIncubatorObject::setInitialState(QObject *o) QV4::Scoped f(scope, QV4::Script::evaluate(v4, QString::fromLatin1(INITIALPROPERTIES_SOURCE), qmlGlobal.asObject())); QV4::ScopedCallData callData(scope, 2); callData->thisObject = QV4::Value::fromObject(v4->globalObject); - callData->args[0] = QV4::QObjectWrapper::wrap(v4, o); + callData->args[0] = QV4::Value::fromReturnedValue(QV4::QObjectWrapper::wrap(v4, o)); callData->args[1] = valuemap; f->call(callData); } diff --git a/src/qml/qml/qqmlcontextwrapper.cpp b/src/qml/qml/qqmlcontextwrapper.cpp index f84f288770..50d1f32c10 100644 --- a/src/qml/qml/qqmlcontextwrapper.cpp +++ b/src/qml/qml/qqmlcontextwrapper.cpp @@ -73,15 +73,15 @@ QmlContextWrapper::~QmlContextWrapper() context->destroy(); } -QV4::Value QmlContextWrapper::qmlScope(QV8Engine *v8, QQmlContextData *ctxt, QObject *scope) +ReturnedValue QmlContextWrapper::qmlScope(QV8Engine *v8, QQmlContextData *ctxt, QObject *scope) { ExecutionEngine *v4 = QV8Engine::getV4(v8); QmlContextWrapper *w = new (v4->memoryManager) QmlContextWrapper(v8, ctxt, scope); - return Value::fromObject(w); + return Value::fromObject(w).asReturnedValue(); } -QV4::Value QmlContextWrapper::urlScope(QV8Engine *v8, const QUrl &url) +ReturnedValue QmlContextWrapper::urlScope(QV8Engine *v8, const QUrl &url) { ExecutionEngine *v4 = QV8Engine::getV4(v8); @@ -92,7 +92,7 @@ QV4::Value QmlContextWrapper::urlScope(QV8Engine *v8, const QUrl &url) QmlContextWrapper *w = new (v4->memoryManager) QmlContextWrapper(v8, context, 0); w->isNullWrapper = true; - return Value::fromObject(w); + return Value::fromObject(w).asReturnedValue(); } QQmlContextData *QmlContextWrapper::callingContext(ExecutionEngine *v4) @@ -192,9 +192,9 @@ ReturnedValue QmlContextWrapper::get(Managed *m, String *name, bool *hasProperty else return QV4::Value::undefinedValue().asReturnedValue(); } else if (r.type) { - return QmlTypeWrapper::create(engine, scopeObject, r.type).asReturnedValue(); + return QmlTypeWrapper::create(engine, scopeObject, r.type); } else if (r.importNamespace) { - return QmlTypeWrapper::create(engine, scopeObject, context->imports, r.importNamespace).asReturnedValue(); + return QmlTypeWrapper::create(engine, scopeObject, context->imports, r.importNamespace); } Q_ASSERT(!"Unreachable"); } @@ -216,7 +216,7 @@ ReturnedValue QmlContextWrapper::get(Managed *m, String *name, bool *hasProperty ep->captureProperty(&context->idValues[propertyIdx].bindings); if (hasProperty) *hasProperty = true; - return QV4::QObjectWrapper::wrap(v4, context->idValues[propertyIdx]).asReturnedValue(); + return QV4::QObjectWrapper::wrap(v4, context->idValues[propertyIdx]); } else { QQmlContextPrivate *cp = context->asQQmlContextPrivate(); @@ -231,9 +231,9 @@ ReturnedValue QmlContextWrapper::get(Managed *m, String *name, bool *hasProperty QQmlListProperty prop(context->asQQmlContext(), (void*) qintptr(propertyIdx), QQmlContextPrivate::context_count, QQmlContextPrivate::context_at); - return QmlListWrapper::create(engine, prop, qMetaTypeId >()).asReturnedValue(); + return QmlListWrapper::create(engine, prop, qMetaTypeId >()); } else { - return engine->fromVariant(cp->propertyValues.at(propertyIdx)).asReturnedValue(); + return engine->fromVariant(cp->propertyValues.at(propertyIdx)); } } } @@ -242,7 +242,8 @@ ReturnedValue QmlContextWrapper::get(Managed *m, String *name, bool *hasProperty // Search scope object if (scopeObject) { bool hasProp = false; - QV4::Value result = QV4::QObjectWrapper::getQmlProperty(v4->current, context, scopeObject, name, QV4::QObjectWrapper::CheckRevision, &hasProp); + QV4::ScopedValue result(scope, QV4::QObjectWrapper::getQmlProperty(v4->current, context, scopeObject, + name, QV4::QObjectWrapper::CheckRevision, &hasProp)); if (hasProp) { if (hasProperty) *hasProperty = true; diff --git a/src/qml/qml/qqmlcontextwrapper_p.h b/src/qml/qml/qqmlcontextwrapper_p.h index 0ed933014b..c5f7f251c1 100644 --- a/src/qml/qml/qqmlcontextwrapper_p.h +++ b/src/qml/qml/qqmlcontextwrapper_p.h @@ -70,8 +70,8 @@ struct Q_QML_EXPORT QmlContextWrapper : Object QmlContextWrapper(QV8Engine *engine, QQmlContextData *context, QObject *scopeObject, bool ownsContext = false); ~QmlContextWrapper(); - static QV4::Value qmlScope(QV8Engine *e, QQmlContextData *ctxt, QObject *scope); - static QV4::Value urlScope(QV8Engine *e, const QUrl &); + static ReturnedValue qmlScope(QV8Engine *e, QQmlContextData *ctxt, QObject *scope); + static ReturnedValue urlScope(QV8Engine *e, const QUrl &); static QQmlContextData *callingContext(ExecutionEngine *v4); static void takeContextOwnership(const QV4::Value &qmlglobal); diff --git a/src/qml/qml/qqmlexpression.cpp b/src/qml/qml/qqmlexpression.cpp index ddebf02c6c..76214c17a4 100644 --- a/src/qml/qml/qqmlexpression.cpp +++ b/src/qml/qml/qqmlexpression.cpp @@ -260,7 +260,7 @@ void QQmlExpression::setExpression(const QString &expression) } // Must be called with a valid handle scope -QV4::Value QQmlExpressionPrivate::v4value(bool *isUndefined) +QV4::ReturnedValue QQmlExpressionPrivate::v4value(bool *isUndefined) { if (!expressionFunctionValid) { function = qmlBinding(context(), scopeObject(), expression, url, line, &qmlscope); @@ -285,7 +285,8 @@ QVariant QQmlExpressionPrivate::value(bool *isUndefined) ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation. { - QV4::Value result = v4value(isUndefined); + QV4::Scope scope(QV8Engine::getV4(ep->v8engine())); + QV4::ScopedValue result(scope, v4value(isUndefined)); rv = ep->v8engine()->toVariant(result, -1); } diff --git a/src/qml/qml/qqmlexpression_p.h b/src/qml/qml/qqmlexpression_p.h index 9cc5a326f8..e84d193837 100644 --- a/src/qml/qml/qqmlexpression_p.h +++ b/src/qml/qml/qqmlexpression_p.h @@ -81,7 +81,7 @@ public: QVariant value(bool *isUndefined = 0); - QV4::Value v4value(bool *isUndefined = 0); + QV4::ReturnedValue v4value(bool *isUndefined = 0); static inline QQmlExpressionPrivate *get(QQmlExpression *expr); static inline QQmlExpression *get(QQmlExpressionPrivate *expr); diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp index 322100f47e..d16d421ed2 100644 --- a/src/qml/qml/qqmljavascriptexpression.cpp +++ b/src/qml/qml/qqmljavascriptexpression.cpp @@ -122,15 +122,13 @@ void QQmlJavaScriptExpression::resetNotifyOnValueChanged() clearGuards(); } -QV4::Value -QQmlJavaScriptExpression::evaluate(QQmlContextData *context, +QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QQmlContextData *context, const QV4::Value &function, bool *isUndefined) { return evaluate(context, function, 0, 0, isUndefined); } -QV4::Value -QQmlJavaScriptExpression::evaluate(QQmlContextData *context, +QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QQmlContextData *context, const QV4::Value &function, int argc, QV4::Value *args, bool *isUndefined) @@ -140,7 +138,7 @@ QQmlJavaScriptExpression::evaluate(QQmlContextData *context, if (function.isEmpty() || function.isUndefined()) { if (isUndefined) *isUndefined = true; - return QV4::Value::emptyValue(); + return QV4::Value::emptyValue().asReturnedValue(); } QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context->engine); @@ -167,15 +165,14 @@ QQmlJavaScriptExpression::evaluate(QQmlContextData *context, QV4::ScopedValue result(scope, QV4::Value::undefinedValue()); QV4::ExecutionContext *ctx = v4->current; try { - QV4::Value This = ep->v8engine()->global(); + QV4::ScopedCallData callData(scope, argc); + callData->thisObject = ep->v8engine()->global(); if (scopeObject() && requiresThisObject()) { - QV4::Value value = QV4::QObjectWrapper::wrap(ctx->engine, scopeObject()); - if (value.isObject()) - This = value; + QV4::ScopedValue value(scope, QV4::QObjectWrapper::wrap(ctx->engine, scopeObject())); + if (value->isObject()) + callData->thisObject = value; } - QV4::ScopedCallData callData(scope, argc); - callData->thisObject = This; memcpy(callData->args, args, argc*sizeof(QV4::Value)); result = function.asFunctionObject()->call(callData); @@ -211,7 +208,7 @@ QQmlJavaScriptExpression::evaluate(QQmlContextData *context, ep->propertyCapture = lastPropertyCapture; - return result; + return result.asReturnedValue(); } void QQmlJavaScriptExpression::GuardCapture::captureProperty(QQmlNotifier *n) @@ -360,7 +357,7 @@ QQmlJavaScriptExpression::evalFunction(QQmlContextData *ctxt, QObject *scopeObje return result.asReturnedValue(); } -QV4::PersistentValue QQmlJavaScriptExpression::qmlBinding(QQmlContextData *ctxt, QObject *scope, +QV4::PersistentValue QQmlJavaScriptExpression::qmlBinding(QQmlContextData *ctxt, QObject *qmlScope, const QString &code, const QString &filename, quint16 line, QV4::PersistentValue *qmlscope) { @@ -369,10 +366,11 @@ QV4::PersistentValue QQmlJavaScriptExpression::qmlBinding(QQmlContextData *ctxt, QV4::ExecutionEngine *v4 = QV8Engine::getV4(ep->v8engine()); QV4::ExecutionContext *ctx = v4->current; + QV4::Scope scope(v4); - QV4::Value scopeObject = QV4::QmlContextWrapper::qmlScope(ep->v8engine(), ctxt, scope); - QV4::Script script(v4, scopeObject.asObject(), code, filename, line); - QV4::Value result; + QV4::ScopedValue qmlScopeObject(scope, QV4::QmlContextWrapper::qmlScope(ep->v8engine(), ctxt, qmlScope)); + QV4::Script script(v4, qmlScopeObject->asObject(), code, filename, line); + QV4::ScopedValue result(scope); try { script.parse(); result = script.qmlBinding(); @@ -386,13 +384,13 @@ QV4::PersistentValue QQmlJavaScriptExpression::qmlBinding(QQmlContextData *ctxt, error.setLine(line); if (error.url().isEmpty()) error.setUrl(QUrl::fromLocalFile(filename)); - error.setObject(scope); + error.setObject(qmlScope); ep->warning(error); return QV4::PersistentValue(); } if (qmlscope) - *qmlscope = scopeObject; - return result; + *qmlscope = qmlScopeObject; + return result.asReturnedValue(); } diff --git a/src/qml/qml/qqmljavascriptexpression_p.h b/src/qml/qml/qqmljavascriptexpression_p.h index ef36a2f91a..f08b3af6cf 100644 --- a/src/qml/qml/qqmljavascriptexpression_p.h +++ b/src/qml/qml/qqmljavascriptexpression_p.h @@ -110,9 +110,9 @@ public: QQmlJavaScriptExpression(VTable *vtable); - QV4::Value evaluate(QQmlContextData *, const QV4::Value &function, + QV4::ReturnedValue evaluate(QQmlContextData *, const QV4::Value &function, bool *isUndefined); - QV4::Value evaluate(QQmlContextData *, const QV4::Value &function, + QV4::ReturnedValue evaluate(QQmlContextData *, const QV4::Value &function, int argc, QV4::Value *args, bool *isUndefined); diff --git a/src/qml/qml/qqmllistwrapper.cpp b/src/qml/qml/qqmllistwrapper.cpp index e8f01bbc08..23aca851a6 100644 --- a/src/qml/qml/qqmllistwrapper.cpp +++ b/src/qml/qml/qqmllistwrapper.cpp @@ -63,10 +63,10 @@ QmlListWrapper::~QmlListWrapper() { } -Value QmlListWrapper::create(QV8Engine *v8, QObject *object, int propId, int propType) +ReturnedValue QmlListWrapper::create(QV8Engine *v8, QObject *object, int propId, int propType) { if (!object || propId == -1) - return Value::nullValue(); + return Encode::null(); ExecutionEngine *v4 = QV8Engine::getV4(v8); @@ -75,10 +75,10 @@ Value QmlListWrapper::create(QV8Engine *v8, QObject *object, int propId, int pro r->propertyType = propType; void *args[] = { &r->property, 0 }; QMetaObject::metacall(object, QMetaObject::ReadProperty, propId, args); - return Value::fromObject(r); + return Value::fromObject(r).asReturnedValue(); } -Value QmlListWrapper::create(QV8Engine *v8, const QQmlListProperty &prop, int propType) +ReturnedValue QmlListWrapper::create(QV8Engine *v8, const QQmlListProperty &prop, int propType) { ExecutionEngine *v4 = QV8Engine::getV4(v8); @@ -86,7 +86,7 @@ Value QmlListWrapper::create(QV8Engine *v8, const QQmlListProperty &pro r->object = prop.object; r->property = prop; r->propertyType = propType; - return Value::fromObject(r); + return Value::fromObject(r).asReturnedValue(); } QVariant QmlListWrapper::toVariant() const @@ -126,7 +126,7 @@ ReturnedValue QmlListWrapper::getIndexed(Managed *m, uint index, bool *hasProper quint32 count = w->property.count ? w->property.count(&w->property) : 0; if (index < count && w->property.at) - return QV4::QObjectWrapper::wrap(e, w->property.at(&w->property, index)).asReturnedValue(); + return QV4::QObjectWrapper::wrap(e, w->property.at(&w->property, index)); return Value::undefinedValue().asReturnedValue(); } @@ -156,7 +156,7 @@ Property *QmlListWrapper::advanceIterator(Managed *m, ObjectIterator *it, String *attrs = QV4::Attr_Data; *index = it->arrayIndex; ++it->arrayIndex; - it->tmpDynamicProperty.value = QV4::QObjectWrapper::wrap(w->engine(), w->property.at(&w->property, *index)); + it->tmpDynamicProperty.value = QV4::Value::fromReturnedValue(QV4::QObjectWrapper::wrap(w->engine(), w->property.at(&w->property, *index))); return &it->tmpDynamicProperty; } return QV4::Object::advanceIterator(m, it, name, index, attrs); diff --git a/src/qml/qml/qqmllistwrapper_p.h b/src/qml/qml/qqmllistwrapper_p.h index 4778443d6b..0de028a35b 100644 --- a/src/qml/qml/qqmllistwrapper_p.h +++ b/src/qml/qml/qqmllistwrapper_p.h @@ -76,8 +76,8 @@ protected: public: - static Value create(QV8Engine *v8, QObject *object, int propId, int propType); - static Value create(QV8Engine *v8, const QQmlListProperty &prop, int propType); + static ReturnedValue create(QV8Engine *v8, QObject *object, int propId, int propType); + static ReturnedValue create(QV8Engine *v8, const QQmlListProperty &prop, int propType); QVariant toVariant() const; diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp index 27c8dff598..38ffc5386d 100644 --- a/src/qml/qml/qqmllocale.cpp +++ b/src/qml/qml/qqmllocale.cpp @@ -807,7 +807,7 @@ QQmlLocale::~QQmlLocale() { } -QV4::Value QQmlLocale::locale(QV8Engine *v8engine, const QString &locale) +QV4::ReturnedValue QQmlLocale::locale(QV8Engine *v8engine, const QString &locale) { QV8LocaleDataDeletable *d = localeV8Data(v8engine); QV4::ExecutionEngine *engine = QV8Engine::getV4(v8engine); @@ -815,7 +815,7 @@ QV4::Value QQmlLocale::locale(QV8Engine *v8engine, const QString &locale) if (!locale.isEmpty()) wrapper->locale = QLocale(locale); wrapper->setPrototype(d->prototype.value().asObject()); - return QV4::Value::fromObject(wrapper); + return QV4::Value::fromObject(wrapper).asReturnedValue(); } void QQmlLocale::registerStringLocaleCompare(QV4::ExecutionEngine *engine) diff --git a/src/qml/qml/qqmllocale_p.h b/src/qml/qml/qqmllocale_p.h index 5088693269..8075bd462f 100644 --- a/src/qml/qml/qqmllocale_p.h +++ b/src/qml/qml/qqmllocale_p.h @@ -118,7 +118,7 @@ public: Saturday = Qt::Saturday }; - static QV4::Value locale(QV8Engine *v8engine, const QString &lang); + static QV4::ReturnedValue locale(QV8Engine *v8engine, const QString &lang); static void registerStringLocaleCompare(QV4::ExecutionEngine *engine); diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp index 8f05a877ef..09ef732e2d 100644 --- a/src/qml/qml/qqmltypewrapper.cpp +++ b/src/qml/qml/qqmltypewrapper.cpp @@ -87,19 +87,19 @@ QVariant QmlTypeWrapper::toVariant() const // Returns a type wrapper for type t on o. This allows access of enums, and attached properties. -Value QmlTypeWrapper::create(QV8Engine *v8, QObject *o, QQmlType *t, TypeNameMode mode) +ReturnedValue QmlTypeWrapper::create(QV8Engine *v8, QObject *o, QQmlType *t, TypeNameMode mode) { Q_ASSERT(t); ExecutionEngine *v4 = QV8Engine::getV4(v8); QmlTypeWrapper *w = new (v4->memoryManager) QmlTypeWrapper(v8); w->mode = mode; w->object = o; w->type = t; - return Value::fromObject(w); + return Value::fromObject(w).asReturnedValue(); } // Returns a type wrapper for importNamespace (of t) on o. This allows nested resolution of a type in a // namespace. -Value QmlTypeWrapper::create(QV8Engine *v8, QObject *o, QQmlTypeNameCache *t, const void *importNamespace, TypeNameMode mode) +ReturnedValue QmlTypeWrapper::create(QV8Engine *v8, QObject *o, QQmlTypeNameCache *t, const void *importNamespace, TypeNameMode mode) { Q_ASSERT(t); Q_ASSERT(importNamespace); @@ -108,17 +108,20 @@ Value QmlTypeWrapper::create(QV8Engine *v8, QObject *o, QQmlTypeNameCache *t, co QmlTypeWrapper *w = new (v4->memoryManager) QmlTypeWrapper(v8); w->mode = mode; w->object = o; w->typeNamespace = t; w->importNamespace = importNamespace; t->addref(); - return Value::fromObject(w); + return Value::fromObject(w).asReturnedValue(); } ReturnedValue QmlTypeWrapper::get(Managed *m, String *name, bool *hasProperty) { - QmlTypeWrapper *w = m->as(); QV4::ExecutionEngine *v4 = m->engine(); + QV4::Scope scope(v4); + + QmlTypeWrapper *w = m->as(); if (!w) v4->current->throwTypeError(); + if (hasProperty) *hasProperty = true; @@ -155,12 +158,12 @@ ReturnedValue QmlTypeWrapper::get(Managed *m, String *name, bool *hasProperty) } // check for property. - return QV4::QObjectWrapper::getQmlProperty(v4->current, context, qobjectSingleton, name, QV4::QObjectWrapper::IgnoreRevision, hasProperty).asReturnedValue(); + return QV4::QObjectWrapper::getQmlProperty(v4->current, context, qobjectSingleton, name, QV4::QObjectWrapper::IgnoreRevision, hasProperty); } else if (!siinfo->scriptApi(e).isUndefined()) { QV4::ExecutionEngine *engine = QV8Engine::getV4(v8engine); // NOTE: if used in a binding, changes will not trigger re-evaluation since non-NOTIFYable. - QV4::Object *o = QJSValuePrivate::get(siinfo->scriptApi(e))->getValue(engine).asObject(); - if (o) + QV4::Scoped o(scope, QJSValuePrivate::get(siinfo->scriptApi(e))->getValue(engine)); + if (!!o) return o->get(name); } @@ -179,7 +182,7 @@ ReturnedValue QmlTypeWrapper::get(Managed *m, String *name, bool *hasProperty) } else if (w->object) { QObject *ao = qmlAttachedPropertiesObjectById(type->attachedPropertiesId(), object); if (ao) - return QV4::QObjectWrapper::getQmlProperty(v4->current, context, ao, name, QV4::QObjectWrapper::IgnoreRevision, hasProperty).asReturnedValue(); + return QV4::QObjectWrapper::getQmlProperty(v4->current, context, ao, name, QV4::QObjectWrapper::IgnoreRevision, hasProperty); // Fall through to base implementation } @@ -196,16 +199,16 @@ ReturnedValue QmlTypeWrapper::get(Managed *m, String *name, bool *hasProperty) if (r.isValid()) { QQmlContextData *context = v8engine->callingContext(); if (r.type) { - return create(w->v8, object, r.type, w->mode).asReturnedValue(); + return create(w->v8, object, r.type, w->mode); } else if (r.scriptIndex != -1) { int index = r.scriptIndex; if (index < context->importedScripts.count()) return context->importedScripts.at(index).value().asReturnedValue(); } else if (r.importNamespace) { - return create(w->v8, object, context->imports, r.importNamespace).asReturnedValue(); + return create(w->v8, object, context->imports, r.importNamespace); } - return QV4::Value::undefinedValue().asReturnedValue(); + return QV4::Encode::undefined(); } diff --git a/src/qml/qml/qqmltypewrapper_p.h b/src/qml/qml/qqmltypewrapper_p.h index c545e1cc3b..acf6845736 100644 --- a/src/qml/qml/qqmltypewrapper_p.h +++ b/src/qml/qml/qqmltypewrapper_p.h @@ -78,8 +78,8 @@ public: QVariant toVariant() const; - static QV4::Value create(QV8Engine *, QObject *, QQmlType *, TypeNameMode = IncludeEnums); - static QV4::Value create(QV8Engine *, QObject *, QQmlTypeNameCache *, const void *, TypeNameMode = IncludeEnums); + static ReturnedValue create(QV8Engine *, QObject *, QQmlType *, TypeNameMode = IncludeEnums); + static ReturnedValue create(QV8Engine *, QObject *, QQmlTypeNameCache *, const void *, TypeNameMode = IncludeEnums); static ReturnedValue get(Managed *m, String *name, bool *hasProperty); diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index d9ee928858..88704d58b3 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -139,7 +139,7 @@ void QmlValueTypeWrapper::initProto(ExecutionEngine *v4) v4->qmlExtensions()->valueTypeWrapperPrototype = o; } -Value QmlValueTypeWrapper::create(QV8Engine *v8, QObject *object, int property, QQmlValueType *type) +ReturnedValue QmlValueTypeWrapper::create(QV8Engine *v8, QObject *object, int property, QQmlValueType *type) { ExecutionEngine *v4 = QV8Engine::getV4(v8); initProto(v4); @@ -147,10 +147,10 @@ Value QmlValueTypeWrapper::create(QV8Engine *v8, QObject *object, int property, QmlValueTypeReference *r = new (v4->memoryManager) QmlValueTypeReference(v8); r->setPrototype(v4->qmlExtensions()->valueTypeWrapperPrototype); r->type = type; r->object = object; r->property = property; - return Value::fromObject(r); + return Value::fromObject(r).asReturnedValue(); } -Value QmlValueTypeWrapper::create(QV8Engine *v8, const QVariant &value, QQmlValueType *type) +ReturnedValue QmlValueTypeWrapper::create(QV8Engine *v8, const QVariant &value, QQmlValueType *type) { ExecutionEngine *v4 = QV8Engine::getV4(v8); initProto(v4); @@ -158,7 +158,7 @@ Value QmlValueTypeWrapper::create(QV8Engine *v8, const QVariant &value, QQmlValu QmlValueTypeCopy *r = new (v4->memoryManager) QmlValueTypeCopy(v8); r->setPrototype(v4->qmlExtensions()->valueTypeWrapperPrototype); r->type = type; r->value = value; - return Value::fromObject(r); + return Value::fromObject(r).asReturnedValue(); } QVariant QmlValueTypeWrapper::toVariant() const @@ -301,7 +301,7 @@ ReturnedValue QmlValueTypeWrapper::get(Managed *m, String *name, bool *hasProper if (result->isFunction()) { // calling a Q_INVOKABLE function of a value type QQmlContextData *qmlContext = QV4::QmlContextWrapper::callingContext(v4); - return QV4::QObjectWrapper::getQmlProperty(v4->current, qmlContext, r->type, name, QV4::QObjectWrapper::IgnoreRevision).asReturnedValue(); + return QV4::QObjectWrapper::getQmlProperty(v4->current, qmlContext, r->type, name, QV4::QObjectWrapper::IgnoreRevision); } #define VALUE_TYPE_LOAD(metatype, cpptype, constructor) \ @@ -321,7 +321,7 @@ ReturnedValue QmlValueTypeWrapper::get(Managed *m, String *name, bool *hasProper QVariant v(result->propType, (void *)0); void *args[] = { v.data(), 0 }; r->type->qt_metacall(QMetaObject::ReadProperty, result->coreIndex, args); - return r->v8->fromVariant(v).asReturnedValue(); + return r->v8->fromVariant(v); #undef VALUE_TYPE_ACCESSOR } diff --git a/src/qml/qml/qqmlvaluetypewrapper_p.h b/src/qml/qml/qqmlvaluetypewrapper_p.h index 2483b8e26b..355000bb39 100644 --- a/src/qml/qml/qqmlvaluetypewrapper_p.h +++ b/src/qml/qml/qqmlvaluetypewrapper_p.h @@ -76,8 +76,8 @@ protected: public: - static Value create(QV8Engine *v8, QObject *, int, QQmlValueType *); - static Value create(QV8Engine *v8, const QVariant &, QQmlValueType *); + static ReturnedValue create(QV8Engine *v8, QObject *, int, QQmlValueType *); + static ReturnedValue create(QV8Engine *v8, const QVariant &, QQmlValueType *); QVariant toVariant() const; bool isEqual(const QVariant& value); diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp index e32193e6f6..1a6577d7ad 100644 --- a/src/qml/qml/qqmlvme.cpp +++ b/src/qml/qml/qqmlvme.cpp @@ -372,7 +372,7 @@ QObject *QQmlVME::run(QList *errors, // Store a created object in a property. These all pop from the objects stack. QML_STORE_VALUE(StoreObject, QObject *, objects.pop()); QML_STORE_VALUE(StoreVariantObject, QVariant, QVariant::fromValue(objects.pop())); - QML_STORE_VAR(StoreVarObject, QV4::QObjectWrapper::wrap(ep->v4engine(), objects.pop())); + QML_STORE_VAR(StoreVarObject, QV4::Value::fromReturnedValue(QV4::QObjectWrapper::wrap(ep->v4engine(), objects.pop()))); // Store a literal value in a corresponding property QML_STORE_VALUE(StoreFloat, float, instr.value); @@ -420,7 +420,7 @@ QObject *QQmlVME::run(QList *errors, // Store a literal value in a var property. // We deliberately do not use string converters here - QML_STORE_VAR(StoreVar, ep->v8engine()->fromVariant(PRIMITIVES.at(instr.value))); + QML_STORE_VAR(StoreVar, QV4::Value::fromReturnedValue(ep->v8engine()->fromVariant(PRIMITIVES.at(instr.value)))); QML_STORE_VAR(StoreVarInteger, QV4::Value::fromInt32(instr.value)); QML_STORE_VAR(StoreVarDouble, QV4::Value::fromDouble(instr.value)); QML_STORE_VAR(StoreVarBool, QV4::Value::fromBoolean(instr.value)); @@ -1113,6 +1113,8 @@ QV4::PersistentValue QQmlVME::run(QQmlContextData *parentCtxt, QQmlScriptData *s Q_ASSERT(parentCtxt && parentCtxt->engine); QQmlEnginePrivate *ep = QQmlEnginePrivate::get(parentCtxt->engine); QV8Engine *v8engine = ep->v8engine(); + QV4::ExecutionEngine *v4 = QV8Engine::getV4(parentCtxt->engine); + QV4::Scope scope(v4); if (script->hasError()) { ep->warning(script->error()); @@ -1178,7 +1180,7 @@ QV4::PersistentValue QQmlVME::run(QQmlContextData *parentCtxt, QQmlScriptData *s return QV4::PersistentValue(); } - QV4::Value qmlglobal = QV4::QmlContextWrapper::qmlScope(v8engine, ctxt, 0); + QV4::ScopedValue qmlglobal(scope, QV4::QmlContextWrapper::qmlScope(v8engine, ctxt, 0)); QV4::QmlContextWrapper::takeContextOwnership(qmlglobal); QV4::ExecutionContext *ctx = QV8Engine::getV4(v8engine)->current; diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index 360528ea7a..488b4a0adf 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -911,8 +911,10 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) QQmlEnginePrivate *ep = QQmlEnginePrivate::get(ctxt->engine); ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation. + QV4::Scope scope(ep->v4engine()); - QV4::FunctionObject *function = method(id).asFunctionObject(); + + QV4::Scoped function(scope, method(id)); if (!function) { // The function was not compiled. There are some exceptional cases which the // expression rewriter does not rewrite properly (e.g., \r-terminated lines @@ -927,12 +929,11 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) QQmlVMEMetaData::MethodData *data = metaData->methodData() + id; - QV4::Scope scope(function->engine()); QV4::ScopedCallData callData(scope, data->parameterCount); callData->thisObject = ep->v8engine()->global(); for (int ii = 0; ii < data->parameterCount; ++ii) - callData->args[ii] = ep->v8engine()->fromVariant(*(QVariant *)a[ii + 1]); + callData->args[ii] = QV4::Value::fromReturnedValue(ep->v8engine()->fromVariant(*(QVariant *)a[ii + 1])); QV4::ScopedValue result(scope); QV4::ExecutionContext *ctx = function->engine()->current; @@ -961,11 +962,11 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) return object->qt_metacall(c, _id, a); } -QV4::Value QQmlVMEMetaObject::method(int index) +QV4::ReturnedValue QQmlVMEMetaObject::method(int index) { if (!ctxt || !ctxt->isValid()) { qWarning("QQmlVMEMetaObject: Internal error - attempted to evaluate a function in an invalid context"); - return QV4::Value::emptyValue(); + return QV4::Value::emptyValue().asReturnedValue(); } if (!v8methods) @@ -984,16 +985,16 @@ QV4::Value QQmlVMEMetaObject::method(int index) ctxt->urlString, data->lineNumber); } - return v8methods[index]; + return v8methods[index].value().asReturnedValue(); } -QV4::Value QQmlVMEMetaObject::readVarProperty(int id) +QV4::ReturnedValue QQmlVMEMetaObject::readVarProperty(int id) { Q_ASSERT(id >= firstVarPropertyIndex); if (ensureVarPropertiesAllocated()) - return QV4::Value::fromReturnedValue(varProperties.value().asObject()->getIndexed(id - firstVarPropertyIndex)); - return QV4::Value::emptyValue(); + return varProperties.value().asObject()->getIndexed(id - firstVarPropertyIndex); + return QV4::Value::emptyValue().asReturnedValue(); } QVariant QQmlVMEMetaObject::readPropertyAsVariant(int id) @@ -1070,8 +1071,8 @@ void QQmlVMEMetaObject::writeProperty(int id, const QVariant &value) // And, if the new value is a scarce resource, we need to ensure that it does not get // automatically released by the engine until no other references to it exist. - QV4::Value newv = QQmlEnginePrivate::get(ctxt->engine)->v8engine()->fromVariant(value); - if (QV4::VariantObject *v = newv.as()) + QV4::ScopedValue newv(scope, QQmlEnginePrivate::get(ctxt->engine)->v8engine()->fromVariant(value)); + if (QV4::VariantObject *v = newv->as()) v->addVmePropertyReference(); // Write the value and emit change signal as appropriate. @@ -1150,7 +1151,7 @@ quint16 QQmlVMEMetaObject::vmeMethodLineNumber(int index) return data->lineNumber; } -QV4::Value QQmlVMEMetaObject::vmeMethod(int index) +QV4::ReturnedValue QQmlVMEMetaObject::vmeMethod(int index) { if (index < methodOffset()) { Q_ASSERT(parentVMEMetaObject()); @@ -1178,7 +1179,7 @@ void QQmlVMEMetaObject::setVmeMethod(int index, QV4::PersistentValue function) v8methods[methodIndex] = function; } -QV4::Value QQmlVMEMetaObject::vmeProperty(int index) +QV4::ReturnedValue QQmlVMEMetaObject::vmeProperty(int index) { if (index < propOffset()) { Q_ASSERT(parentVMEMetaObject()); diff --git a/src/qml/qml/qqmlvmemetaobject_p.h b/src/qml/qml/qqmlvmemetaobject_p.h index 9824e0d54b..35592c4906 100644 --- a/src/qml/qml/qqmlvmemetaobject_p.h +++ b/src/qml/qml/qqmlvmemetaobject_p.h @@ -164,10 +164,10 @@ public: bool aliasTarget(int index, QObject **target, int *coreIndex, int *valueTypeIndex) const; void registerInterceptor(int index, int valueIndex, QQmlPropertyValueInterceptor *interceptor); - QV4::Value vmeMethod(int index); + QV4::ReturnedValue vmeMethod(int index); quint16 vmeMethodLineNumber(int index); void setVmeMethod(int index, QV4::PersistentValue function); - QV4::Value vmeProperty(int index); + QV4::ReturnedValue vmeProperty(int index); void setVMEProperty(int index, const QV4::Value &v); void connectAliasSignal(int index, bool indexInSignalRange); @@ -217,9 +217,9 @@ public: QQmlPropertyValueInterceptor *interceptors; QV4::PersistentValue *v8methods; - QV4::Value method(int); + QV4::ReturnedValue method(int); - QV4::Value readVarProperty(int); + QV4::ReturnedValue readVarProperty(int); void writeVarProperty(int, const QV4::Value &); QVariant readPropertyAsVariant(int); void writeProperty(int, const QVariant &); diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index 651a2703f3..b7447aee07 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -100,9 +100,11 @@ static inline QQmlXMLHttpRequestData *xhrdata(QV8Engine *engine) static Value constructMeObject(const Value &thisObj, QV8Engine *e) { ExecutionEngine *v4 = QV8Engine::getV4(e); + Scope scope(v4); Object *meObj = v4->newObject(); meObj->put(v4->newString(QStringLiteral("ThisObject")), thisObj); - meObj->put(v4->newString(QStringLiteral("ActivationObject")), QmlContextWrapper::qmlScope(e, e->callingContext(), 0)); + ScopedValue v(scope, QmlContextWrapper::qmlScope(e, e->callingContext(), 0)); + meObj->put(v4->newString(QStringLiteral("ActivationObject")), v); return Value::fromObject(meObj); } diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index 59457df30c..2a75bf9834 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -202,7 +202,7 @@ ReturnedValue QtObject::method_rgba(QV4::SimpleCallContext *ctx) if (a < 0.0) a=0.0; if (a > 1.0) a=1.0; - return ctx->engine->v8Engine->fromVariant(QQml_colorProvider()->fromRgbF(r, g, b, a)).asReturnedValue(); + return ctx->engine->v8Engine->fromVariant(QQml_colorProvider()->fromRgbF(r, g, b, a)); } /*! @@ -231,7 +231,7 @@ ReturnedValue QtObject::method_hsla(QV4::SimpleCallContext *ctx) if (a < 0.0) a=0.0; if (a > 1.0) a=1.0; - return ctx->engine->v8Engine->fromVariant(QQml_colorProvider()->fromHslF(h, s, l, a)).asReturnedValue(); + return ctx->engine->v8Engine->fromVariant(QQml_colorProvider()->fromHslF(h, s, l, a)); } /*! @@ -292,7 +292,7 @@ ReturnedValue QtObject::method_rect(QV4::SimpleCallContext *ctx) double w = ctx->arguments[2].toNumber(); double h = ctx->arguments[3].toNumber(); - return ctx->engine->v8Engine->fromVariant(QVariant::fromValue(QRectF(x, y, w, h))).asReturnedValue(); + return ctx->engine->v8Engine->fromVariant(QVariant::fromValue(QRectF(x, y, w, h))); } /*! @@ -307,7 +307,7 @@ ReturnedValue QtObject::method_point(QV4::SimpleCallContext *ctx) double x = ctx->arguments[0].toNumber(); double y = ctx->arguments[1].toNumber(); - return ctx->engine->v8Engine->fromVariant(QVariant::fromValue(QPointF(x, y))).asReturnedValue(); + return ctx->engine->v8Engine->fromVariant(QVariant::fromValue(QPointF(x, y))); } /*! @@ -322,7 +322,7 @@ ReturnedValue QtObject::method_size(QV4::SimpleCallContext *ctx) double w = ctx->arguments[0].toNumber(); double h = ctx->arguments[1].toNumber(); - return ctx->engine->v8Engine->fromVariant(QVariant::fromValue(QSizeF(w, h))).asReturnedValue(); + return ctx->engine->v8Engine->fromVariant(QVariant::fromValue(QSizeF(w, h))); } /*! @@ -343,7 +343,7 @@ ReturnedValue QtObject::method_font(QV4::SimpleCallContext *ctx) QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QFont, QQmlV4Handle(ctx->arguments[0]), v8engine, &ok); if (!ok) V4THROW_ERROR("Qt.font(): Invalid argument: no valid font subproperties specified"); - return v8engine->fromVariant(v).asReturnedValue(); + return v8engine->fromVariant(v); } @@ -363,7 +363,7 @@ ReturnedValue QtObject::method_vector2d(QV4::SimpleCallContext *ctx) const void *params[] = { xy }; QV8Engine *v8engine = ctx->engine->v8Engine; - return v8engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector2D, 1, params)).asReturnedValue(); + return v8engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector2D, 1, params)); } /*! @@ -382,7 +382,7 @@ ReturnedValue QtObject::method_vector3d(QV4::SimpleCallContext *ctx) const void *params[] = { xyz }; QV8Engine *v8engine = ctx->engine->v8Engine; - return v8engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector3D, 1, params)).asReturnedValue(); + return v8engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector3D, 1, params)); } /*! @@ -402,7 +402,7 @@ ReturnedValue QtObject::method_vector4d(QV4::SimpleCallContext *ctx) const void *params[] = { xyzw }; QV8Engine *v8engine = ctx->engine->v8Engine; - return v8engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector4D, 1, params)).asReturnedValue(); + return v8engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector4D, 1, params)); } /*! @@ -422,7 +422,7 @@ ReturnedValue QtObject::method_quaternion(QV4::SimpleCallContext *ctx) const void *params[] = { sxyz }; QV8Engine *v8engine = ctx->engine->v8Engine; - return v8engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QQuaternion, 1, params)).asReturnedValue(); + return v8engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QQuaternion, 1, params)); } /*! @@ -441,7 +441,7 @@ ReturnedValue QtObject::method_matrix4x4(QV4::SimpleCallContext *ctx) QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QMatrix4x4, QQmlV4Handle(ctx->arguments[0]), v8engine, &ok); if (!ok) V4THROW_ERROR("Qt.matrix4x4(): Invalid argument: not a valid matrix4x4 values array"); - return v8engine->fromVariant(v).asReturnedValue(); + return v8engine->fromVariant(v); } if (ctx->argumentCount != 16) @@ -466,7 +466,7 @@ ReturnedValue QtObject::method_matrix4x4(QV4::SimpleCallContext *ctx) vals[15] = ctx->arguments[15].toNumber(); const void *params[] = { vals }; - return v8engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 1, params)).asReturnedValue(); + return v8engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 1, params)); } /*! @@ -504,7 +504,7 @@ ReturnedValue QtObject::method_lighter(QV4::SimpleCallContext *ctx) if (ctx->argumentCount == 2) factor = ctx->arguments[1].toNumber(); - return v8engine->fromVariant(QQml_colorProvider()->lighter(v, factor)).asReturnedValue(); + return v8engine->fromVariant(QQml_colorProvider()->lighter(v, factor)); } /*! @@ -543,7 +543,7 @@ ReturnedValue QtObject::method_darker(QV4::SimpleCallContext *ctx) if (ctx->argumentCount == 2) factor = ctx->arguments[1].toNumber(); - return v8engine->fromVariant(QQml_colorProvider()->darker(v, factor)).asReturnedValue(); + return v8engine->fromVariant(QQml_colorProvider()->darker(v, factor)); } /*! @@ -601,7 +601,7 @@ ReturnedValue QtObject::method_tint(QV4::SimpleCallContext *ctx) return QV4::Encode::null(); } - return v8engine->fromVariant(QQml_colorProvider()->tint(v1, v2)).asReturnedValue(); + return v8engine->fromVariant(QQml_colorProvider()->tint(v1, v2)); } /*! @@ -645,7 +645,7 @@ ReturnedValue QtObject::method_formatDate(QV4::SimpleCallContext *ctx) formattedDate = date.toString(enumFormat); } - return v8engine->fromVariant(QVariant::fromValue(formattedDate)).asReturnedValue(); + return v8engine->fromVariant(QVariant::fromValue(formattedDate)); } /*! @@ -694,7 +694,7 @@ ReturnedValue QtObject::method_formatTime(QV4::SimpleCallContext *ctx) formattedTime = time.toString(enumFormat); } - return v8engine->fromVariant(QVariant::fromValue(formattedTime)).asReturnedValue(); + return v8engine->fromVariant(QVariant::fromValue(formattedTime)); } /*! @@ -812,7 +812,7 @@ ReturnedValue QtObject::method_formatDateTime(QV4::SimpleCallContext *ctx) formattedDt = dt.toString(enumFormat); } - return v8engine->fromVariant(QVariant::fromValue(formattedDt)).asReturnedValue(); + return v8engine->fromVariant(QVariant::fromValue(formattedDt)); } /*! @@ -827,7 +827,7 @@ ReturnedValue QtObject::method_openUrlExternally(QV4::SimpleCallContext *ctx) QV8Engine *v8engine = ctx->engine->v8Engine; QUrl url(Value::fromReturnedValue(method_resolvedUrl(ctx)).toQStringNoThrow()); - return v8engine->fromVariant(QQml_guiProvider()->openUrlExternally(url)).asReturnedValue(); + return v8engine->fromVariant(QQml_guiProvider()->openUrlExternally(url)); } /*! @@ -863,7 +863,7 @@ ReturnedValue QtObject::method_fontFamilies(SimpleCallContext *ctx) V4THROW_ERROR("Qt.fontFamilies(): Invalid arguments"); QV8Engine *v8engine = ctx->engine->v8Engine; - return v8engine->fromVariant(QVariant(QQml_guiProvider()->fontFamilies())).asReturnedValue(); + return v8engine->fromVariant(QVariant(QQml_guiProvider()->fontFamilies())); } /*! @@ -1039,7 +1039,7 @@ ReturnedValue QtObject::method_createQmlObject(SimpleCallContext *ctx) Q_ASSERT(obj); - return QV4::QObjectWrapper::wrap(ctx->engine, obj).asReturnedValue(); + return QV4::QObjectWrapper::wrap(ctx->engine, obj); } /*! @@ -1133,7 +1133,7 @@ ReturnedValue QtObject::method_createComponent(SimpleCallContext *ctx) QQmlData::get(c, true)->explicitIndestructibleSet = false; QQmlData::get(c)->indestructible = false; - return QV4::QObjectWrapper::wrap(ctx->engine, c).asReturnedValue(); + return QV4::QObjectWrapper::wrap(ctx->engine, c); } /*! @@ -1168,7 +1168,7 @@ ReturnedValue QtObject::method_locale(SimpleCallContext *ctx) if (ctx->argumentCount == 1) code = ctx->arguments[0].toQStringNoThrow(); - return QQmlLocale::locale(v8engine, code).asReturnedValue(); + return QQmlLocale::locale(v8engine, code); } namespace { @@ -1276,7 +1276,7 @@ ReturnedValue QtObject::method_get_platform(SimpleCallContext *ctx) // Only allocate a platform object once qt->m_platform = new QQmlPlatform(ctx->engine->v8Engine->publicEngine()); - return QV4::QObjectWrapper::wrap(ctx->engine, qt->m_platform).asReturnedValue(); + return QV4::QObjectWrapper::wrap(ctx->engine, qt->m_platform); } ReturnedValue QtObject::method_get_application(SimpleCallContext *ctx) @@ -1293,7 +1293,7 @@ ReturnedValue QtObject::method_get_application(SimpleCallContext *ctx) // Only allocate an application object once qt->m_application = QQml_guiProvider()->application(ctx->engine->v8Engine->publicEngine()); - return QV4::QObjectWrapper::wrap(ctx->engine, qt->m_application).asReturnedValue(); + return QV4::QObjectWrapper::wrap(ctx->engine, qt->m_application); } #ifndef QT_NO_IM @@ -1301,7 +1301,7 @@ ReturnedValue QtObject::method_get_inputMethod(SimpleCallContext *ctx) { QObject *o = QQml_guiProvider()->inputMethod(); QQmlEngine::setObjectOwnership(o, QQmlEngine::CppOwnership); - return QV4::QObjectWrapper::wrap(ctx->engine, o).asReturnedValue(); + return QV4::QObjectWrapper::wrap(ctx->engine, o); } #endif diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp index c377608341..63ab33a457 100644 --- a/src/qml/qml/v8/qv8engine.cpp +++ b/src/qml/qml/v8/qv8engine.cpp @@ -181,7 +181,7 @@ QVariant QV8Engine::toVariant(const QV4::Value &value, int typeHint) return toBasicVariant(value); } -static QV4::Value arrayFromStringList(QV8Engine *engine, const QStringList &list) +static QV4::ReturnedValue arrayFromStringList(QV8Engine *engine, const QStringList &list) { QV4::ExecutionEngine *e = QV8Engine::getV4(engine); QV4::ArrayObject *a = e->newArrayObject(); @@ -191,10 +191,10 @@ static QV4::Value arrayFromStringList(QV8Engine *engine, const QStringList &list for (int ii = 0; ii < len; ++ii) a->arrayData[ii].value = QV4::Value::fromString(e->newString(list.at(ii))); a->setArrayLengthUnchecked(len); - return QV4::Value::fromObject(a); + return QV4::Value::fromObject(a).asReturnedValue(); } -static QV4::Value arrayFromVariantList(QV8Engine *engine, const QVariantList &list) +static QV4::ReturnedValue arrayFromVariantList(QV8Engine *engine, const QVariantList &list) { QV4::ExecutionEngine *e = QV8Engine::getV4(engine); QV4::ArrayObject *a = e->newArrayObject(); @@ -202,23 +202,23 @@ static QV4::Value arrayFromVariantList(QV8Engine *engine, const QVariantList &li a->arrayReserve(len); a->arrayDataLen = len; for (int ii = 0; ii < len; ++ii) - a->arrayData[ii].value = engine->fromVariant(list.at(ii)); + a->arrayData[ii].value = QV4::Value::fromReturnedValue(engine->fromVariant(list.at(ii))); a->setArrayLengthUnchecked(len); - return QV4::Value::fromObject(a); + return QV4::Value::fromObject(a).asReturnedValue(); } -static QV4::Value objectFromVariantMap(QV8Engine *engine, const QVariantMap &map) +static QV4::ReturnedValue objectFromVariantMap(QV8Engine *engine, const QVariantMap &map) { QV4::ExecutionEngine *e = QV8Engine::getV4(engine); QV4::Object *o = e->newObject(); for (QVariantMap::ConstIterator iter = map.begin(); iter != map.end(); ++iter) - o->put(e->newString(iter.key()), engine->fromVariant(iter.value())); - return QV4::Value::fromObject(o); + o->put(e->newString(iter.key()), QV4::Value::fromReturnedValue(engine->fromVariant(iter.value()))); + return QV4::Value::fromObject(o).asReturnedValue(); } Q_CORE_EXPORT QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax); -QV4::Value QV8Engine::fromVariant(const QVariant &variant) +QV4::ReturnedValue QV8Engine::fromVariant(const QVariant &variant) { int type = variant.userType(); const void *ptr = variant.constData(); @@ -227,49 +227,50 @@ QV4::Value QV8Engine::fromVariant(const QVariant &variant) switch (QMetaType::Type(type)) { case QMetaType::UnknownType: case QMetaType::Void: - return QV4::Value::undefinedValue(); + return QV4::Encode::undefined(); case QMetaType::Bool: - return QV4::Value::fromBoolean(*reinterpret_cast(ptr)); + return QV4::Encode(*reinterpret_cast(ptr)); case QMetaType::Int: - return QV4::Value::fromInt32(*reinterpret_cast(ptr)); + return QV4::Encode(*reinterpret_cast(ptr)); case QMetaType::UInt: - return QV4::Value::fromUInt32(*reinterpret_cast(ptr)); + return QV4::Encode(*reinterpret_cast(ptr)); case QMetaType::LongLong: - return QV4::Value::fromDouble(*reinterpret_cast(ptr)); + return QV4::Encode((double)*reinterpret_cast(ptr)); case QMetaType::ULongLong: - return QV4::Value::fromDouble(*reinterpret_cast(ptr)); + return QV4::Encode((double)*reinterpret_cast(ptr)); case QMetaType::Double: - return QV4::Value::fromDouble(*reinterpret_cast(ptr)); + return QV4::Encode(*reinterpret_cast(ptr)); case QMetaType::QString: - return QV4::Value::fromString(m_v4Engine->current, *reinterpret_cast(ptr)); + return QV4::Value::fromString(m_v4Engine->current, *reinterpret_cast(ptr)).asReturnedValue(); case QMetaType::Float: - return QV4::Value::fromDouble(*reinterpret_cast(ptr)); + return QV4::Encode(*reinterpret_cast(ptr)); case QMetaType::Short: - return QV4::Value::fromInt32(*reinterpret_cast(ptr)); + return QV4::Encode((int)*reinterpret_cast(ptr)); case QMetaType::UShort: - return QV4::Value::fromUInt32(*reinterpret_cast(ptr)); + return QV4::Encode((int)*reinterpret_cast(ptr)); case QMetaType::Char: - return QV4::Value::fromInt32(*reinterpret_cast(ptr)); + return QV4::Encode((int)*reinterpret_cast(ptr)); case QMetaType::UChar: - return QV4::Value::fromUInt32(*reinterpret_cast(ptr)); + return QV4::Encode((int)*reinterpret_cast(ptr)); case QMetaType::QChar: - return QV4::Value::fromInt32((*reinterpret_cast(ptr)).unicode()); + return QV4::Encode((int)(*reinterpret_cast(ptr)).unicode()); case QMetaType::QDateTime: - return QV4::Value::fromObject(m_v4Engine->newDateObject(*reinterpret_cast(ptr))); + return QV4::Value::fromObject(m_v4Engine->newDateObject(*reinterpret_cast(ptr))).asReturnedValue(); case QMetaType::QDate: - return QV4::Value::fromObject(m_v4Engine->newDateObject(QDateTime(*reinterpret_cast(ptr)))); + return QV4::Value::fromObject(m_v4Engine->newDateObject(QDateTime(*reinterpret_cast(ptr)))).asReturnedValue(); case QMetaType::QTime: - return QV4::Value::fromObject(m_v4Engine->newDateObject(QDateTime(QDate(1970,1,1), *reinterpret_cast(ptr)))); + return QV4::Value::fromObject(m_v4Engine->newDateObject(QDateTime(QDate(1970,1,1), *reinterpret_cast(ptr)))).asReturnedValue(); case QMetaType::QRegExp: - return QV4::Value::fromObject(m_v4Engine->newRegExpObject(*reinterpret_cast(ptr))); + return QV4::Value::fromObject(m_v4Engine->newRegExpObject(*reinterpret_cast(ptr))).asReturnedValue(); case QMetaType::QObjectStar: return QV4::QObjectWrapper::wrap(m_v4Engine, *reinterpret_cast(ptr)); case QMetaType::QStringList: { bool succeeded = false; - QV4::Value retn = QV4::SequencePrototype::fromVariant(m_v4Engine, variant, &succeeded); + QV4::Scope scope(m_v4Engine); + QV4::ScopedValue retn(scope, QV4::SequencePrototype::fromVariant(m_v4Engine, variant, &succeeded)); if (succeeded) - return retn; + return retn.asReturnedValue(); return arrayFromStringList(this, *reinterpret_cast(ptr)); } case QMetaType::QVariantList: @@ -290,13 +291,14 @@ QV4::Value QV8Engine::fromVariant(const QVariant &variant) if (QQmlValueType *vt = QQmlValueTypeFactory::valueType(type)) return QV4::QmlValueTypeWrapper::create(this, variant, vt); } else { + QV4::Scope scope(m_v4Engine); if (type == qMetaTypeId()) { typedef QQmlListReferencePrivate QDLRP; QDLRP *p = QDLRP::get((QQmlListReference*)ptr); if (p->object) { return QV4::QmlListWrapper::create(this, p->property, p->propertyType); } else { - return QV4::Value::nullValue(); + return QV4::Encode::null(); } } else if (type == qMetaTypeId()) { const QJSValue *value = reinterpret_cast(ptr); @@ -310,9 +312,9 @@ QV4::Value QV8Engine::fromVariant(const QVariant &variant) a->arrayReserve(list.count()); a->arrayDataLen = list.count(); for (int ii = 0; ii < list.count(); ++ii) - a->arrayData[ii].value = QV4::QObjectWrapper::wrap(m_v4Engine, list.at(ii)); + a->arrayData[ii].value = QV4::Value::fromReturnedValue(QV4::QObjectWrapper::wrap(m_v4Engine, list.at(ii))); a->setArrayLengthUnchecked(list.count()); - return QV4::Value::fromObject(a); + return QV4::Value::fromObject(a).asReturnedValue(); } else if (QMetaType::typeFlags(type) & QMetaType::PointerToQObject) { return QV4::QObjectWrapper::wrap(m_v4Engine, *reinterpret_cast(ptr)); } @@ -323,9 +325,9 @@ QV4::Value QV8Engine::fromVariant(const QVariant &variant) return QV4::QObjectWrapper::wrap(m_v4Engine, obj); bool succeeded = false; - QV4::Value retn = QV4::SequencePrototype::fromVariant(m_v4Engine, variant, &succeeded); + QV4::ScopedValue retn(scope, QV4::SequencePrototype::fromVariant(m_v4Engine, variant, &succeeded)); if (succeeded) - return retn; + return retn.asReturnedValue(); if (QQmlValueType *vt = QQmlValueTypeFactory::valueType(type)) return QV4::QmlValueTypeWrapper::create(this, variant, vt); @@ -335,7 +337,7 @@ QV4::Value QV8Engine::fromVariant(const QVariant &variant) // + QObjectList // + QList - return QV4::Value::fromObject(m_v4Engine->newVariantObject(variant)); + return QV4::Value::fromObject(m_v4Engine->newVariantObject(variant)).asReturnedValue(); } QNetworkAccessManager *QV8Engine::networkAccessManager() @@ -513,15 +515,15 @@ QV4::Value QV8Engine::global() // The result is a new Array object with length equal to the length // of the QVariantList, and the elements being the QVariantList's // elements converted to JS, recursively. -QV4::Value QV8Engine::variantListToJS(const QVariantList &lst) +QV4::ReturnedValue QV8Engine::variantListToJS(const QVariantList &lst) { QV4::ArrayObject *a = m_v4Engine->newArrayObject(); a->arrayReserve(lst.size()); a->arrayDataLen = lst.size(); for (int i = 0; i < lst.size(); i++) - a->arrayData[i].value = variantToJS(lst.at(i)); + a->arrayData[i].value = QV4::Value::fromReturnedValue(variantToJS(lst.at(i))); a->setArrayLengthUnchecked(lst.size()); - return QV4::Value::fromObject(a); + return QV4::Value::fromObject(a).asReturnedValue(); } // Converts a JS Array object to a QVariantList. @@ -559,15 +561,15 @@ QVariantList QV8Engine::variantListFromJS(QV4::ArrayObject *a, // The result is a new Object object with property names being // the keys of the QVariantMap, and values being the values of // the QVariantMap converted to JS, recursively. -QV4::Value QV8Engine::variantMapToJS(const QVariantMap &vmap) +QV4::ReturnedValue QV8Engine::variantMapToJS(const QVariantMap &vmap) { QV4::Object *o = m_v4Engine->newObject(); QVariantMap::const_iterator it; for (it = vmap.constBegin(); it != vmap.constEnd(); ++it) { QV4::Property *p = o->insertMember(m_v4Engine->newIdentifier(it.key()), QV4::Attr_Data); - p->value = variantToJS(it.value()); + p->value = QV4::Value::fromReturnedValue(variantToJS(it.value())); } - return QV4::Value::fromObject(o); + return QV4::Value::fromObject(o).asReturnedValue(); } // Converts a JS Object to a QVariantMap. @@ -588,17 +590,19 @@ QVariantMap QV8Engine::variantMapFromJS(QV4::Object *o, // empty object (and no error is thrown). return result; } + QV4::Scope scope(o->engine()); visitedObjects.insert(o); QV4::ObjectIterator it(o, QV4::ObjectIterator::EnumerableOnly); + QV4::ScopedValue name(scope); while (1) { QV4::Value v; - QV4::Value name = it.nextPropertyNameAsString(&v); - if (name.isNull()) + name = it.nextPropertyNameAsString(&v); + if (name->isNull()) break; - QString key = name.toQStringNoThrow(); + QString key = name->toQStringNoThrow(); result.insert(key, variantFromJS(v, visitedObjects)); } @@ -608,96 +612,85 @@ QVariantMap QV8Engine::variantMapFromJS(QV4::Object *o, // Converts the meta-type defined by the given type and data to JS. // Returns the value if conversion succeeded, an empty handle otherwise. -QV4::Value QV8Engine::metaTypeToJS(int type, const void *data) +QV4::ReturnedValue QV8Engine::metaTypeToJS(int type, const void *data) { Q_ASSERT(data != 0); - QV4::Value result; // check if it's one of the types we know switch (QMetaType::Type(type)) { case QMetaType::UnknownType: case QMetaType::Void: - return QV4::Value::undefinedValue(); + return QV4::Encode::undefined(); case QMetaType::Bool: - return QV4::Value::fromBoolean(*reinterpret_cast(data)); + return QV4::Encode(*reinterpret_cast(data)); case QMetaType::Int: - return QV4::Value::fromInt32(*reinterpret_cast(data)); + return QV4::Encode(*reinterpret_cast(data)); case QMetaType::UInt: - return QV4::Value::fromUInt32(*reinterpret_cast(data)); + return QV4::Encode(*reinterpret_cast(data)); case QMetaType::LongLong: - return QV4::Value::fromDouble(double(*reinterpret_cast(data))); + return QV4::Encode(double(*reinterpret_cast(data))); case QMetaType::ULongLong: #if defined(Q_OS_WIN) && defined(_MSC_FULL_VER) && _MSC_FULL_VER <= 12008804 #pragma message("** NOTE: You need the Visual Studio Processor Pack to compile support for 64bit unsigned integers.") - return QV4::Value::fromDouble(double((qlonglong)*reinterpret_cast(data))); + return QV4::Encode(double((qlonglong)*reinterpret_cast(data))); #elif defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET) - return QV4::Value::fromDouble(double((qlonglong)*reinterpret_cast(data))); + return QV4::Encode(double((qlonglong)*reinterpret_cast(data))); #else - return QV4::Value::fromDouble(double(*reinterpret_cast(data))); + return QV4::Encode(double(*reinterpret_cast(data))); #endif case QMetaType::Double: - return QV4::Value::fromDouble(*reinterpret_cast(data)); + return QV4::Encode(*reinterpret_cast(data)); case QMetaType::QString: - return QV4::Value::fromString(m_v4Engine->current, *reinterpret_cast(data)); + return QV4::Value::fromString(m_v4Engine->current, *reinterpret_cast(data)).asReturnedValue(); case QMetaType::Float: - return QV4::Value::fromDouble(*reinterpret_cast(data)); + return QV4::Encode(*reinterpret_cast(data)); case QMetaType::Short: - return QV4::Value::fromInt32(*reinterpret_cast(data)); + return QV4::Encode((int)*reinterpret_cast(data)); case QMetaType::UShort: - return QV4::Value::fromUInt32(*reinterpret_cast(data)); + return QV4::Encode((int)*reinterpret_cast(data)); case QMetaType::Char: - return QV4::Value::fromInt32(*reinterpret_cast(data)); + return QV4::Encode((int)*reinterpret_cast(data)); case QMetaType::UChar: - return QV4::Value::fromUInt32(*reinterpret_cast(data)); + return QV4::Encode((int)*reinterpret_cast(data)); case QMetaType::QChar: - return QV4::Value::fromUInt32((*reinterpret_cast(data)).unicode()); + return QV4::Encode((int)(*reinterpret_cast(data)).unicode()); case QMetaType::QStringList: - result = QV4::Value::fromObject(m_v4Engine->newArrayObject(*reinterpret_cast(data))); - break; + return QV4::Value::fromObject(m_v4Engine->newArrayObject(*reinterpret_cast(data))).asReturnedValue(); case QMetaType::QVariantList: - result = variantListToJS(*reinterpret_cast(data)); - break; + return variantListToJS(*reinterpret_cast(data)); case QMetaType::QVariantMap: - result = variantMapToJS(*reinterpret_cast(data)); - break; + return variantMapToJS(*reinterpret_cast(data)); case QMetaType::QDateTime: - result = QV4::Value::fromObject(m_v4Engine->newDateObject(*reinterpret_cast(data))); - break; + return QV4::Value::fromObject(m_v4Engine->newDateObject(*reinterpret_cast(data))).asReturnedValue(); case QMetaType::QDate: - result = QV4::Value::fromObject(m_v4Engine->newDateObject(QDateTime(*reinterpret_cast(data)))); - break; + return QV4::Value::fromObject(m_v4Engine->newDateObject(QDateTime(*reinterpret_cast(data)))).asReturnedValue(); case QMetaType::QRegExp: - result = QV4::Value::fromObject(m_v4Engine->newRegExpObject(*reinterpret_cast(data))); - break; + return QV4::Value::fromObject(m_v4Engine->newRegExpObject(*reinterpret_cast(data))).asReturnedValue(); case QMetaType::QObjectStar: - result = QV4::QObjectWrapper::wrap(m_v4Engine, *reinterpret_cast(data)); - break; + return QV4::QObjectWrapper::wrap(m_v4Engine, *reinterpret_cast(data)); case QMetaType::QVariant: - result = variantToJS(*reinterpret_cast(data)); - break; + return variantToJS(*reinterpret_cast(data)); case QMetaType::QJsonValue: - result = QV4::JsonObject::fromJsonValue(m_v4Engine, *reinterpret_cast(data)); - break; + return QV4::JsonObject::fromJsonValue(m_v4Engine, *reinterpret_cast(data)); case QMetaType::QJsonObject: - result = QV4::JsonObject::fromJsonObject(m_v4Engine, *reinterpret_cast(data)); - break; + return QV4::JsonObject::fromJsonObject(m_v4Engine, *reinterpret_cast(data)); case QMetaType::QJsonArray: - result = QV4::JsonObject::fromJsonArray(m_v4Engine, *reinterpret_cast(data)); - break; + return QV4::JsonObject::fromJsonArray(m_v4Engine, *reinterpret_cast(data)); default: if (type == qMetaTypeId()) { return QJSValuePrivate::get(*reinterpret_cast(data))->getValue(m_v4Engine); } else { QByteArray typeName = QMetaType::typeName(type); if (typeName.endsWith('*') && !*reinterpret_cast(data)) { - return QV4::Value::nullValue(); + return QV4::Encode::null(); } else { // Fall back to wrapping in a QVariant. - result = QV4::Value::fromObject(m_v4Engine->newVariantObject(QVariant(type, data))); + return QV4::Value::fromObject(m_v4Engine->newVariantObject(QVariant(type, data))).asReturnedValue(); } } } - return result; + Q_UNREACHABLE(); + return 0; } // Converts a JS value to a meta-type. @@ -874,7 +867,7 @@ bool QV8Engine::metaTypeFromJS(const QV4::Value &value, int type, void *data) { } // Converts a QVariant to JS. -QV4::Value QV8Engine::variantToJS(const QVariant &value) +QV4::ReturnedValue QV8Engine::variantToJS(const QVariant &value) { return metaTypeToJS(value.userType(), value.constData()); } diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h index 1296973394..3209e55434 100644 --- a/src/qml/qml/v8/qv8engine_p.h +++ b/src/qml/qml/v8/qv8engine_p.h @@ -121,6 +121,7 @@ namespace QV4 { // valid during the call. If the return value isn't set within myMethod(), the will return // undefined. class QV8Engine; +// ### GC class QQmlV4Function { public: @@ -129,6 +130,7 @@ public: QQmlContextData *context() { return ctx; } QV4::Value qmlGlobal() { return global; } void setReturnValue(const QV4::Value &rv) { *retVal = rv; } + void setReturnValue(QV4::ReturnedValue rv) { *retVal = QV4::Value::fromReturnedValue(rv); } QV8Engine *engine() const { return e; } private: friend struct QV4::QObjectMethod; @@ -149,6 +151,7 @@ private: QV8Engine *e; }; +// ### GC class Q_QML_PRIVATE_EXPORT QQmlV4Handle { public: @@ -210,7 +213,7 @@ public: void freezeObject(const QV4::Value &value); QVariant toVariant(const QV4::Value &value, int typeHint); - QV4::Value fromVariant(const QVariant &); + QV4::ReturnedValue fromVariant(const QVariant &); // Return a JS string for the given QString \a string QV4::Value toString(const QString &string); @@ -232,19 +235,19 @@ public: inline Deletable *extensionData(int) const; void setExtensionData(int, Deletable *); - QV4::Value variantListToJS(const QVariantList &lst); + QV4::ReturnedValue variantListToJS(const QVariantList &lst); inline QVariantList variantListFromJS(QV4::ArrayObject *array) { V8ObjectSet visitedObjects; return variantListFromJS(array, visitedObjects); } - QV4::Value variantMapToJS(const QVariantMap &vmap); + QV4::ReturnedValue variantMapToJS(const QVariantMap &vmap); inline QVariantMap variantMapFromJS(QV4::Object *object) { V8ObjectSet visitedObjects; return variantMapFromJS(object, visitedObjects); } - QV4::Value variantToJS(const QVariant &value); + QV4::ReturnedValue variantToJS(const QVariant &value); inline QVariant variantFromJS(const QV4::Value &value) { V8ObjectSet visitedObjects; return variantFromJS(value, visitedObjects); } - QV4::Value metaTypeToJS(int type, const void *data); + QV4::ReturnedValue metaTypeToJS(int type, const void *data); bool metaTypeFromJS(const QV4::Value &value, int type, void *data); bool convertToNativeQObject(const QV4::Value &value, diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp index 163407c809..0457adb348 100644 --- a/src/qml/types/qqmldelegatemodel.cpp +++ b/src/qml/types/qqmldelegatemodel.cpp @@ -63,10 +63,10 @@ struct DelegateModelGroupFunction: QV4::FunctionObject { Q_MANAGED - QV4::Value (*code)(QQmlDelegateModelItem *item, uint flag, const QV4::Value &arg); + QV4::ReturnedValue (*code)(QQmlDelegateModelItem *item, uint flag, const QV4::Value &arg); uint flag; - DelegateModelGroupFunction(QV4::ExecutionContext *scope, uint flag, QV4::Value (*code)(QQmlDelegateModelItem *item, uint flag, const QV4::Value &arg)) + DelegateModelGroupFunction(QV4::ExecutionContext *scope, uint flag, QV4::ReturnedValue (*code)(QQmlDelegateModelItem *item, uint flag, const QV4::Value &arg)) : FunctionObject(scope, /*name*/0) , code(code) , flag(flag) @@ -89,7 +89,7 @@ struct DelegateModelGroupFunction: QV4::FunctionObject that->engine()->current->throwTypeError(QStringLiteral("Not a valid VisualData object")); QV4::Value v = callData->argc ? callData->args[0] : QV4::Value::undefinedValue(); - return f->code(o->item, f->flag, v).asReturnedValue(); + return f->code(o->item, f->flag, v); } }; @@ -1550,13 +1550,16 @@ bool QQmlDelegateModelPrivate::insert(Compositor::insert_iterator &before, const if (!o) return false; + QV4::Scope scope(o->engine()); + QV4::ObjectIterator it(o, QV4::ObjectIterator::EnumerableOnly|QV4::ObjectIterator::WithProtoChain); + QV4::ScopedValue propertyName(scope); while (1) { QV4::Value value; - QV4::Value propertyName = it.nextPropertyNameAsString(&value); - if (propertyName.isNull()) + propertyName = it.nextPropertyNameAsString(&value); + if (propertyName->isNull()) break; - cacheItem->setValue(propertyName.toQStringNoThrow(), m_cacheMetaType->v8Engine->toVariant(value, QVariant::Invalid)); + cacheItem->setValue(propertyName->toQStringNoThrow(), m_cacheMetaType->v8Engine->toVariant(value, QVariant::Invalid)); } cacheItem->groups = groups | Compositor::UnresolvedFlag | Compositor::CacheFlag; @@ -1698,7 +1701,7 @@ QV4::ReturnedValue QQmlDelegateModelItem::get_model(QV4::SimpleCallContext *ctx) if (!o->item->metaType->model) return QV4::Encode::undefined(); - return o->item->get().asReturnedValue(); + return o->item->get(); } QV4::ReturnedValue QQmlDelegateModelItem::get_groups(QV4::SimpleCallContext *ctx) @@ -1713,7 +1716,7 @@ QV4::ReturnedValue QQmlDelegateModelItem::get_groups(QV4::SimpleCallContext *ctx groups.append(o->item->metaType->groupNames.at(i - 1)); } - return ctx->engine->v8Engine->fromVariant(groups).asReturnedValue(); + return ctx->engine->v8Engine->fromVariant(groups); } QV4::ReturnedValue QQmlDelegateModelItem::set_groups(QV4::SimpleCallContext *ctx) @@ -1735,22 +1738,22 @@ QV4::ReturnedValue QQmlDelegateModelItem::set_groups(QV4::SimpleCallContext *ctx return QV4::Encode::undefined(); } -QV4::Value QQmlDelegateModelItem::get_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &) +QV4::ReturnedValue QQmlDelegateModelItem::get_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &) { - return QV4::Value::fromBoolean(thisItem->groups & (1 << flag)); + return QV4::Encode(bool(thisItem->groups & (1 << flag))); } -QV4::Value QQmlDelegateModelItem::set_member(QQmlDelegateModelItem *cacheItem, uint flag, const QV4::Value &arg) +QV4::ReturnedValue QQmlDelegateModelItem::set_member(QQmlDelegateModelItem *cacheItem, uint flag, const QV4::Value &arg) { if (!cacheItem->metaType->model) - return QV4::Value::undefinedValue(); + return QV4::Encode::undefined(); QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(cacheItem->metaType->model); bool member = arg.toBoolean(); uint groupFlag = (1 << flag); if (member == ((cacheItem->groups & groupFlag) != 0)) - return QV4::Value::undefinedValue(); + return QV4::Encode::undefined(); const int cacheIndex = model->m_cache.indexOf(cacheItem); Compositor::iterator it = model->m_compositor.find(Compositor::Cache, cacheIndex); @@ -1758,12 +1761,12 @@ QV4::Value QQmlDelegateModelItem::set_member(QQmlDelegateModelItem *cacheItem, u model->addGroups(it, 1, Compositor::Cache, groupFlag); else model->removeGroups(it, 1, Compositor::Cache, groupFlag); - return QV4::Value::undefinedValue(); + return QV4::Encode::undefined(); } -QV4::Value QQmlDelegateModelItem::get_index(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &) +QV4::ReturnedValue QQmlDelegateModelItem::get_index(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &) { - return QV4::Value::fromInt32(thisItem->groupIndex(Compositor::Group(flag))); + return QV4::Encode((int)thisItem->groupIndex(Compositor::Group(flag))); } diff --git a/src/qml/types/qqmldelegatemodel_p_p.h b/src/qml/types/qqmldelegatemodel_p_p.h index 9b1b64b8db..aa4e0c30e2 100644 --- a/src/qml/types/qqmldelegatemodel_p_p.h +++ b/src/qml/types/qqmldelegatemodel_p_p.h @@ -128,7 +128,7 @@ public: int modelIndex() const { return index; } void setModelIndex(int idx) { index = idx; Q_EMIT modelIndexChanged(); } - virtual QV4::Value get() { return QV4::QObjectWrapper::wrap(v4, this); } + virtual QV4::ReturnedValue get() { return QV4::QObjectWrapper::wrap(v4, this); } virtual void setValue(const QString &role, const QVariant &value) { Q_UNUSED(role); Q_UNUSED(value); } virtual bool resolveIndex(const QQmlAdaptorModel &, int) { return false; } @@ -136,9 +136,9 @@ public: static QV4::ReturnedValue get_model(QV4::SimpleCallContext *ctx); static QV4::ReturnedValue get_groups(QV4::SimpleCallContext *ctx); static QV4::ReturnedValue set_groups(QV4::SimpleCallContext *ctx); - static QV4::Value get_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &); - static QV4::Value set_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg); - static QV4::Value get_index(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg); + static QV4::ReturnedValue get_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &); + static QV4::ReturnedValue set_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg); + static QV4::ReturnedValue get_index(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg); QV4::ExecutionEngine *v4; QQmlDelegateModelItemMetaType * const metaType; diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp index 87e907e244..20d1211716 100644 --- a/src/qml/types/qqmllistmodel.cpp +++ b/src/qml/types/qqmllistmodel.cpp @@ -418,9 +418,10 @@ void ListModel::set(int elementIndex, QV4::Object *object, QVector *roles, QV4::Scoped o(scope); QV4::ObjectIterator it(object, QV4::ObjectIterator::WithProtoChain|QV4::ObjectIterator::EnumerableOnly); + QV4::Scoped propertyName(scope); while (1) { QV4::Value propertyValue; - QV4::String *propertyName = it.nextPropertyNameAsString(&propertyValue).asString(); + propertyName = it.nextPropertyNameAsString(&propertyValue); if (!propertyName) break; @@ -429,13 +430,13 @@ void ListModel::set(int elementIndex, QV4::Object *object, QVector *roles, // Add the value now if (QV4::String *s = propertyValue.asString()) { - const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::String); + const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::String); roleIndex = e->setStringProperty(r, s->toQString()); } else if (propertyValue.isNumber()) { - const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Number); + const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::Number); roleIndex = e->setDoubleProperty(r, propertyValue.asDouble()); } else if (QV4::ArrayObject *a = propertyValue.asArrayObject()) { - const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::List); + const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::List); ListModel *subModel = new ListModel(r.subLayout, 0, -1); int arrayLength = a->arrayLength(); @@ -446,25 +447,25 @@ void ListModel::set(int elementIndex, QV4::Object *object, QVector *roles, roleIndex = e->setListProperty(r, subModel); } else if (propertyValue.isBoolean()) { - const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Bool); + const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::Bool); roleIndex = e->setBoolProperty(r, propertyValue.booleanValue()); } else if (QV4::DateObject *dd = propertyValue.asDateObject()) { - const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::DateTime); + const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::DateTime); QDateTime dt = dd->toQDateTime(); roleIndex = e->setDateTimeProperty(r, dt); } else if (QV4::Object *o = propertyValue.asObject()) { if (QV4::QObjectWrapper *wrapper = o->as()) { QObject *o = wrapper->object(); - const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::QObject); + const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::QObject); if (role.type == ListLayout::Role::QObject) roleIndex = e->setQObjectProperty(role, o); } else { - const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::VariantMap); + const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::VariantMap); if (role.type == ListLayout::Role::VariantMap) roleIndex = e->setVariantMapProperty(role, o, eng); } } else if (propertyValue.isEmpty() || propertyValue.isUndefined() || propertyValue.isNull()) { - const ListLayout::Role *r = m_layout->getExistingRole(propertyName); + const ListLayout::Role *r = m_layout->getExistingRole(propertyName.getPointer()); if (r) e->clearProperty(*r); } @@ -487,24 +488,25 @@ void ListModel::set(int elementIndex, QV4::Object *object, QV8Engine *eng) QV4::Scoped o(scope); QV4::ObjectIterator it(object, QV4::ObjectIterator::WithProtoChain|QV4::ObjectIterator::EnumerableOnly); + QV4::Scoped propertyName(scope); while (1) { QV4::Value propertyValue; - QV4::String *propertyName = it.nextPropertyNameAsString(&propertyValue).asString(); + propertyName = it.nextPropertyNameAsString(&propertyValue); if (!propertyName) break; // Add the value now if (QV4::String *s = propertyValue.asString()) { - const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::String); + const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::String); if (r.type == ListLayout::Role::String) e->setStringPropertyFast(r, s->toQString()); } else if (propertyValue.isNumber()) { - const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Number); + const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::Number); if (r.type == ListLayout::Role::Number) { e->setDoublePropertyFast(r, propertyValue.asDouble()); } } else if (QV4::ArrayObject *a = propertyValue.asArrayObject()) { - const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::List); + const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::List); if (r.type == ListLayout::Role::List) { ListModel *subModel = new ListModel(r.subLayout, 0, -1); @@ -517,12 +519,12 @@ void ListModel::set(int elementIndex, QV4::Object *object, QV8Engine *eng) e->setListPropertyFast(r, subModel); } } else if (propertyValue.isBoolean()) { - const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Bool); + const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::Bool); if (r.type == ListLayout::Role::Bool) { e->setBoolPropertyFast(r, propertyValue.booleanValue()); } } else if (QV4::DateObject *dd = propertyValue.asDateObject()) { - const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::DateTime); + const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::DateTime); if (r.type == ListLayout::Role::DateTime) { QDateTime dt = dd->toQDateTime();; e->setDateTimePropertyFast(r, dt); @@ -530,16 +532,16 @@ void ListModel::set(int elementIndex, QV4::Object *object, QV8Engine *eng) } else if (QV4::Object *o = propertyValue.asObject()) { if (QV4::QObjectWrapper *wrapper = o->as()) { QObject *o = wrapper->object(); - const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::QObject); + const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::QObject); if (r.type == ListLayout::Role::QObject) e->setQObjectPropertyFast(r, o); } else { - const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::VariantMap); + const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::VariantMap); if (role.type == ListLayout::Role::VariantMap) e->setVariantMapFast(role, o, eng); } } else if (propertyValue.isEmpty() || propertyValue.isUndefined() || propertyValue.isNull()) { - const ListLayout::Role *r = m_layout->getExistingRole(propertyName); + const ListLayout::Role *r = m_layout->getExistingRole(propertyName.getPointer()); if (r) e->clearProperty(*r); } @@ -1252,7 +1254,8 @@ void ModelNodeMetaObject::propertyWritten(int index) QString propName = QString::fromUtf8(name(index)); QVariant value = operator[](index); - QV4::Value v = eng->fromVariant(value); + QV4::Scope scope(QV8Engine::getV4((eng))); + QV4::ScopedValue v(scope, eng->fromVariant(value)); int roleIndex = m_obj->m_model->m_listModel->setExistingProperty(m_obj->m_elementIndex, propName, v, eng); if (roleIndex != -1) { @@ -2103,10 +2106,11 @@ void QQmlListModel::append(QQmlV4Function *args) */ QQmlV4Handle QQmlListModel::get(int index) const { - QV4::Value result = QV4::Value::undefinedValue(); + QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine()); + QV4::Scope scope(v4); + QV4::ScopedValue result(scope, QV4::Value::undefinedValue()); if (index >= 0 && index < count()) { - QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine()); if (m_dynamicRoles) { DynamicRoleModelNode *object = m_modelObjects[index]; diff --git a/src/qml/types/qquickworkerscript.cpp b/src/qml/types/qquickworkerscript.cpp index 3e4748fa7a..4e39682d84 100644 --- a/src/qml/types/qquickworkerscript.cpp +++ b/src/qml/types/qquickworkerscript.cpp @@ -725,7 +725,8 @@ bool QQuickWorkerScript::event(QEvent *event) if (engine) { WorkerDataEvent *workerEvent = static_cast(event); QV8Engine *v8engine = QQmlEnginePrivate::get(engine)->v8engine(); - QV4::Value value = QV4::Serialize::deserialize(workerEvent->data(), v8engine); + QV4::Scope scope(QV8Engine::getV4(v8engine)); + QV4::ScopedValue value(scope, QV4::Serialize::deserialize(workerEvent->data(), v8engine)); emit message(QQmlV4Handle(value)); } return true; diff --git a/src/qml/util/qqmladaptormodel.cpp b/src/qml/util/qqmladaptormodel.cpp index b64a393bd3..9812e2a4a6 100644 --- a/src/qml/util/qqmladaptormodel.cpp +++ b/src/qml/util/qqmladaptormodel.cpp @@ -107,8 +107,8 @@ public: void setValue(const QString &role, const QVariant &value); bool resolveIndex(const QQmlAdaptorModel &model, int idx); - static QV4::Value get_property(QV4::SimpleCallContext *ctx, uint propertyId); - static QV4::Value set_property(QV4::SimpleCallContext *ctx, uint propertyId); + static QV4::ReturnedValue get_property(QV4::SimpleCallContext *ctx, uint propertyId); + static QV4::ReturnedValue set_property(QV4::SimpleCallContext *ctx, uint propertyId); VDMModelDelegateDataType *type; QVector cachedData; @@ -341,7 +341,7 @@ bool QQmlDMCachedModelData::resolveIndex(const QQmlAdaptorModel &, int idx) } } -QV4::Value QQmlDMCachedModelData::get_property(QV4::SimpleCallContext *ctx, uint propertyId) +QV4::ReturnedValue QQmlDMCachedModelData::get_property(QV4::SimpleCallContext *ctx, uint propertyId) { QQmlDelegateModelItemObject *o = ctx->thisObject.as(); if (!o) @@ -357,10 +357,10 @@ QV4::Value QQmlDMCachedModelData::get_property(QV4::SimpleCallContext *ctx, uint return ctx->engine->v8Engine->fromVariant( modelData->value(modelData->type->propertyRoles.at(propertyId))); } - return QV4::Value::undefinedValue(); + return QV4::Encode::undefined(); } -QV4::Value QQmlDMCachedModelData::set_property(QV4::SimpleCallContext *ctx, uint propertyId) +QV4::ReturnedValue QQmlDMCachedModelData::set_property(QV4::SimpleCallContext *ctx, uint propertyId) { QQmlDelegateModelItemObject *o = ctx->thisObject.as(); if (!o) @@ -381,6 +381,7 @@ QV4::Value QQmlDMCachedModelData::set_property(QV4::SimpleCallContext *ctx, uint } } } + return QV4::Encode::undefined(); } //----------------------------------------------------------------- @@ -421,7 +422,7 @@ public: type->model->aim()->index(index, 0, type->model->rootIndex), value, role); } - QV4::Value get() + QV4::ReturnedValue get() { if (type->prototype.isEmpty()) { QQmlAdaptorModelEngineData * const data = engineData(v4->v8Engine); @@ -432,7 +433,7 @@ public: o->setPrototype(proto); QV4::Value data = QV4::Value::fromObject(o); ++scriptRef; - return data; + return data.asReturnedValue(); } }; @@ -584,7 +585,7 @@ public: if (!o) ctx->throwTypeError(QStringLiteral("Not a valid VisualData object")); - return ctx->engine->v8Engine->fromVariant(static_cast(o->item)->cachedData).asReturnedValue(); + return ctx->engine->v8Engine->fromVariant(static_cast(o->item)->cachedData); } static QV4::ReturnedValue set_modelData(QV4::SimpleCallContext *ctx) @@ -599,14 +600,14 @@ public: return QV4::Encode::undefined(); } - QV4::Value get() + QV4::ReturnedValue get() { QQmlAdaptorModelEngineData *data = engineData(v4->v8Engine); QV4::Object *o = new (v4->memoryManager) QQmlDelegateModelItemObject(v4, this); o->setPrototype(data->listItemProto.value().asObject()); QV4::Value val = QV4::Value::fromObject(o); ++scriptRef; - return val; + return val.asReturnedValue(); } void setValue(const QString &role, const QVariant &value) -- cgit v1.2.3