From 6c9f1c8ed93374c16ca6ac540f39e98b451be0d8 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 11 Sep 2013 21:48:23 +0200 Subject: [PATCH] Use a ReturnedValue for Managed::getIndexed() Change-Id: I0371ed21c4ef99564d3ffa1082dd109e890a78bf Reviewed-by: Simon Hausmann --- src/imports/localstorage/plugin.cpp | 8 ++-- src/qml/jsapi/qjsvalue.cpp | 2 +- src/qml/jsruntime/qv4arrayobject.cpp | 64 ++++++++++++++++++--------- src/qml/jsruntime/qv4functionobject.cpp | 2 +- src/qml/jsruntime/qv4jsonobject.cpp | 12 +++-- src/qml/jsruntime/qv4managed.cpp | 2 +- src/qml/jsruntime/qv4managed_p.h | 4 +- src/qml/jsruntime/qv4object.cpp | 22 +++++---- src/qml/jsruntime/qv4object_p.h | 6 +-- src/qml/jsruntime/qv4qobjectwrapper.cpp | 6 ++- src/qml/jsruntime/qv4regexp.cpp | 4 +- src/qml/jsruntime/qv4regexp_p.h | 2 +- src/qml/jsruntime/qv4runtime.cpp | 2 +- src/qml/jsruntime/qv4sequenceobject.cpp | 6 +-- src/qml/jsruntime/qv4serialize.cpp | 12 ++--- src/qml/jsruntime/qv4string.cpp | 8 ++-- src/qml/jsruntime/qv4string_p.h | 2 +- src/qml/qml/qqmllistwrapper.cpp | 8 ++-- src/qml/qml/qqmllistwrapper_p.h | 2 +- src/qml/qml/qqmlvmemetaobject.cpp | 19 ++++---- src/qml/qml/qqmlxmlhttprequest.cpp | 16 +++---- src/qml/qml/v8/qv8engine.cpp | 19 +++++--- src/qml/types/qqmldelegatemodel.cpp | 11 +++-- src/qml/types/qqmllistmodel.cpp | 39 +++++++++++----- src/quick/items/context2d/qquickcontext2d.cpp | 14 +++--- src/quick/util/qquickglobal.cpp | 9 ++-- 26 files changed, 185 insertions(+), 116 deletions(-) diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp index 2cb62eb..de89f12 100644 --- a/src/imports/localstorage/plugin.cpp +++ b/src/imports/localstorage/plugin.cpp @@ -105,7 +105,7 @@ public: ~QQmlSqlDatabaseWrapper() { } - static Value getIndexed(Managed *m, uint index, bool *hasProperty); + static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty); static void destroy(Managed *that) { static_cast(that)->~QQmlSqlDatabaseWrapper(); } @@ -217,13 +217,13 @@ static Value qmlsqldatabase_rows_index(QQmlSqlDatabaseWrapper *r, ExecutionEngin } } -Value QQmlSqlDatabaseWrapper::getIndexed(Managed *m, uint index, bool *hasProperty) +ReturnedValue QQmlSqlDatabaseWrapper::getIndexed(Managed *m, uint index, bool *hasProperty) { QQmlSqlDatabaseWrapper *r = m->as(); if (!r || r->type != QQmlSqlDatabaseWrapper::Rows) return Object::getIndexed(m, index, hasProperty); - return qmlsqldatabase_rows_index(r, m->engine(), index, hasProperty); + return qmlsqldatabase_rows_index(r, m->engine(), index, hasProperty).asReturnedValue(); } static Value qmlsqldatabase_rows_item(SimpleCallContext *ctx) @@ -265,7 +265,7 @@ static Value qmlsqldatabase_executeSql(SimpleCallContext *ctx) if (ArrayObject *array = values.asArrayObject()) { quint32 size = array->arrayLength(); for (quint32 ii = 0; ii < size; ++ii) - query.bindValue(ii, engine->toVariant(array->getIndexed(ii), -1)); + query.bindValue(ii, engine->toVariant(QV4::Value::fromReturnedValue(array->getIndexed(ii)), -1)); } else if (Object *object = values.asObject()) { ObjectIterator it(object, ObjectIterator::WithProtoChain|ObjectIterator::EnumerableOnly); while (1) { diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp index 7b0b8bc..dabb9f5 100644 --- a/src/qml/jsapi/qjsvalue.cpp +++ b/src/qml/jsapi/qjsvalue.cpp @@ -841,7 +841,7 @@ QJSValue QJSValue::property(quint32 arrayIndex) const QV4::ExecutionContext *ctx = engine->current; try { - QV4::ScopedValue v(scope, arrayIndex == UINT_MAX ? o->get(engine->id_uintMax) : o->getIndexed(arrayIndex).asReturnedValue()); + QV4::ScopedValue v(scope, arrayIndex == UINT_MAX ? o->get(engine->id_uintMax) : o->getIndexed(arrayIndex)); return new QJSValuePrivate(engine, v); } catch (QV4::Exception &e) { e.accept(ctx); diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp index 8942df0..c4c9994 100644 --- a/src/qml/jsruntime/qv4arrayobject.cpp +++ b/src/qml/jsruntime/qv4arrayobject.cpp @@ -211,13 +211,14 @@ Value ArrayPrototype::method_join(SimpleCallContext *ctx) // ### FIXME if (ArrayObject *a = self->asArrayObject()) { + ScopedValue e(scope); for (uint i = 0; i < a->arrayLength(); ++i) { if (i) R += r4; - Value e = a->getIndexed(i); - if (! (e.isUndefined() || e.isNull())) - R += e.toString(ctx)->toQString(); + e = a->getIndexed(i); + if (!e->isNullOrUndefined()) + R += e->toString(ctx)->toQString(); } } else { // @@ -245,6 +246,7 @@ Value ArrayPrototype::method_join(SimpleCallContext *ctx) Value ArrayPrototype::method_pop(SimpleCallContext *ctx) { + Scope scope(ctx); Object *instance = ctx->thisObject.toObject(ctx); uint len = getLength(ctx, instance); @@ -254,7 +256,7 @@ Value ArrayPrototype::method_pop(SimpleCallContext *ctx) return Value::undefinedValue(); } - Value result = instance->getIndexed(len - 1); + ScopedValue result(scope, instance->getIndexed(len - 1)); instance->deleteIndexedProperty(len - 1); if (instance->isArrayObject()) @@ -319,15 +321,18 @@ Value ArrayPrototype::method_push(SimpleCallContext *ctx) Value ArrayPrototype::method_reverse(SimpleCallContext *ctx) { + Scope scope(ctx); Object *instance = ctx->thisObject.toObject(ctx); uint length = getLength(ctx, instance); int lo = 0, hi = length - 1; + ScopedValue lval(scope); + ScopedValue hval(scope); for (; lo < hi; ++lo, --hi) { bool loExists, hiExists; - Value lval = instance->getIndexed(lo, &loExists); - Value hval = instance->getIndexed(hi, &hiExists); + lval = instance->getIndexed(lo, &loExists); + hval = instance->getIndexed(hi, &hiExists); if (hiExists) instance->putIndexed(lo, hval); else @@ -342,6 +347,7 @@ Value ArrayPrototype::method_reverse(SimpleCallContext *ctx) Value ArrayPrototype::method_shift(SimpleCallContext *ctx) { + Scope scope(ctx); Object *instance = ctx->thisObject.toObject(ctx); uint len = getLength(ctx, instance); @@ -373,10 +379,11 @@ Value ArrayPrototype::method_shift(SimpleCallContext *ctx) instance->freeArrayValue(idx); } } else { + ScopedValue v(scope); // do it the slow way for (uint k = 1; k < len; ++k) { bool exists; - Value v = instance->getIndexed(k, &exists); + v = instance->getIndexed(k, &exists); if (exists) instance->putIndexed(k - 1, v); else @@ -394,6 +401,7 @@ Value ArrayPrototype::method_shift(SimpleCallContext *ctx) Value ArrayPrototype::method_slice(SimpleCallContext *ctx) { + Scope scope(ctx); Object *o = ctx->thisObject.toObject(ctx); ArrayObject *result = ctx->engine->newArrayObject(); @@ -417,10 +425,11 @@ Value ArrayPrototype::method_slice(SimpleCallContext *ctx) end = (uint) e; } + ScopedValue v(scope); uint n = 0; for (uint i = start; i < end; ++i) { bool exists; - Value v = o->getIndexed(i, &exists); + v = o->getIndexed(i, &exists); if (exists) { result->arraySet(n, v); } @@ -442,6 +451,7 @@ Value ArrayPrototype::method_sort(SimpleCallContext *ctx) Value ArrayPrototype::method_splice(SimpleCallContext *ctx) { + Scope scope(ctx); Object *instance = ctx->thisObject.toObject(ctx); uint len = getLength(ctx, instance); @@ -459,7 +469,7 @@ Value ArrayPrototype::method_splice(SimpleCallContext *ctx) newArray->arrayReserve(deleteCount); Property *pd = newArray->arrayData; for (uint i = 0; i < deleteCount; ++i) { - pd->value = instance->getIndexed(start + i); + pd->value = Value::fromReturnedValue(instance->getIndexed(start + i)); ++pd; } newArray->arrayDataLen = deleteCount; @@ -467,10 +477,11 @@ Value ArrayPrototype::method_splice(SimpleCallContext *ctx) uint itemCount = ctx->argumentCount < 2 ? 0 : ctx->argumentCount - 2; + ScopedValue v(scope); if (itemCount < deleteCount) { for (uint k = start; k < len - deleteCount; ++k) { bool exists; - Value v = instance->getIndexed(k + deleteCount, &exists); + v = instance->getIndexed(k + deleteCount, &exists); if (exists) instance->putIndexed(k + itemCount, v); else @@ -482,7 +493,7 @@ Value ArrayPrototype::method_splice(SimpleCallContext *ctx) uint k = len - deleteCount; while (k > start) { bool exists; - Value v = instance->getIndexed(k + deleteCount - 1, &exists); + v = instance->getIndexed(k + deleteCount - 1, &exists); if (exists) instance->putIndexed(k + itemCount - 1, v); else @@ -502,6 +513,7 @@ Value ArrayPrototype::method_splice(SimpleCallContext *ctx) Value ArrayPrototype::method_unshift(SimpleCallContext *ctx) { + Scope scope(ctx); Object *instance = ctx->thisObject.toObject(ctx); uint len = getLength(ctx, instance); @@ -527,9 +539,10 @@ Value ArrayPrototype::method_unshift(SimpleCallContext *ctx) } } } else { + ScopedValue v(scope); for (uint k = len; k > 0; --k) { bool exists; - Value v = instance->getIndexed(k - 1, &exists); + v = instance->getIndexed(k - 1, &exists); if (exists) instance->putIndexed(k + ctx->argumentCount - 1, v); else @@ -647,11 +660,12 @@ Value ArrayPrototype::method_every(SimpleCallContext *ctx) callData->args[2] = Value::fromObject(instance); callData->thisObject = thisArg; ScopedValue r(scope); + ScopedValue v(scope); bool ok = true; for (uint k = 0; ok && k < len; ++k) { bool exists; - Value v = instance->getIndexed(k, &exists); + v = instance->getIndexed(k, &exists); if (!exists) continue; @@ -677,10 +691,11 @@ Value ArrayPrototype::method_some(SimpleCallContext *ctx) ScopedCallData callData(scope, 3); callData->thisObject = ctx->argument(1); callData->args[2] = Value::fromObject(instance); + ScopedValue v(scope); for (uint k = 0; k < len; ++k) { bool exists; - Value v = instance->getIndexed(k, &exists); + v = instance->getIndexed(k, &exists); if (!exists) continue; @@ -708,9 +723,10 @@ Value ArrayPrototype::method_forEach(SimpleCallContext *ctx) callData->thisObject = ctx->argument(1); callData->args[2] = Value::fromObject(instance); + ScopedValue v(scope); for (uint k = 0; k < len; ++k) { bool exists; - Value v = instance->getIndexed(k, &exists); + v = instance->getIndexed(k, &exists); if (!exists) continue; @@ -743,9 +759,10 @@ Value ArrayPrototype::method_map(SimpleCallContext *ctx) callData->thisObject = thisArg; callData->args[2] = Value::fromObject(instance); + ScopedValue v(scope); for (uint k = 0; k < len; ++k) { bool exists; - Value v = instance->getIndexed(k, &exists); + v = instance->getIndexed(k, &exists); if (!exists) continue; @@ -778,10 +795,12 @@ Value ArrayPrototype::method_filter(SimpleCallContext *ctx) callData->thisObject = thisArg; callData->args[2] = Value::fromObject(instance); + ScopedValue v(scope); + uint to = 0; for (uint k = 0; k < len; ++k) { bool exists; - Value v = instance->getIndexed(k, &exists); + v = instance->getIndexed(k, &exists); if (!exists) continue; @@ -809,12 +828,14 @@ Value ArrayPrototype::method_reduce(SimpleCallContext *ctx) uint k = 0; ScopedValue acc(scope); + ScopedValue v(scope); + if (ctx->argumentCount > 1) { acc = ctx->argument(1); } else { bool kPresent = false; while (k < len && !kPresent) { - Value v = instance->getIndexed(k, &kPresent); + v = instance->getIndexed(k, &kPresent); if (kPresent) acc = v; ++k; @@ -830,7 +851,7 @@ Value ArrayPrototype::method_reduce(SimpleCallContext *ctx) while (k < len) { bool kPresent; - Value v = instance->getIndexed(k, &kPresent); + v = instance->getIndexed(k, &kPresent); if (kPresent) { callData->args[0] = acc; callData->args[1] = v; @@ -861,12 +882,13 @@ Value ArrayPrototype::method_reduceRight(SimpleCallContext *ctx) uint k = len; ScopedValue acc(scope); + ScopedValue v(scope); if (ctx->argumentCount > 1) { acc = ctx->argument(1); } else { bool kPresent = false; while (k > 0 && !kPresent) { - Value v = instance->getIndexed(k - 1, &kPresent); + v = instance->getIndexed(k - 1, &kPresent); if (kPresent) acc = v; --k; @@ -881,7 +903,7 @@ Value ArrayPrototype::method_reduceRight(SimpleCallContext *ctx) while (k > 0) { bool kPresent; - Value v = instance->getIndexed(k - 1, &kPresent); + v = instance->getIndexed(k - 1, &kPresent); if (kPresent) { callData->args[0] = acc; callData->args[1] = v; diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index 03d09a7..6feca33 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -318,7 +318,7 @@ Value FunctionPrototype::method_apply(SimpleCallContext *ctx) if (len) { if (arr->protoHasArray() || arr->hasAccessorProperty) { for (quint32 i = 0; i < len; ++i) - callData->args[i] = arr->getIndexed(i); + callData->args[i] = Value::fromReturnedValue(arr->getIndexed(i)); } else { int alen = qMin(len, arr->arrayDataLen); for (quint32 i = 0; i < alen; ++i) diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp index ea8afcb..c1cc539 100644 --- a/src/qml/jsruntime/qv4jsonobject.cpp +++ b/src/qml/jsruntime/qv4jsonobject.cpp @@ -825,6 +825,8 @@ QString Stringify::JA(ArrayObject *a) if (stack.contains(a)) ctx->throwTypeError(); + Scope scope(a->engine()); + QString result; stack.push(a); QString stepback = indent; @@ -832,9 +834,10 @@ QString Stringify::JA(ArrayObject *a) QStringList partial; uint len = a->arrayLength(); + ScopedValue v(scope); for (uint i = 0; i < len; ++i) { bool exists; - Value v = a->getIndexed(i, &exists); + v = a->getIndexed(i, &exists); if (!exists) { partial += QStringLiteral("null"); continue; @@ -1028,6 +1031,8 @@ QJsonArray JsonObject::toJsonArray(ArrayObject *a, V4ObjectSet &visitedObjects) if (!a) return result; + Scope scope(a->engine()); + if (visitedObjects.contains(a)) { // Avoid recursion. // For compatibility with QVariant{List,Map} conversion, we return an @@ -1037,10 +1042,11 @@ QJsonArray JsonObject::toJsonArray(ArrayObject *a, V4ObjectSet &visitedObjects) visitedObjects.insert(a); + ScopedValue v(scope); quint32 length = a->arrayLength(); for (quint32 i = 0; i < length; ++i) { - Value v = a->getIndexed(i); - result.append(toJsonValue(v.asFunctionObject() ? QV4::Value::nullValue() : v, visitedObjects)); + v = a->getIndexed(i); + result.append(toJsonValue(v->asFunctionObject() ? QV4::Value::nullValue() : v, visitedObjects)); } visitedObjects.remove(a); diff --git a/src/qml/jsruntime/qv4managed.cpp b/src/qml/jsruntime/qv4managed.cpp index a8f7077..4179527 100644 --- a/src/qml/jsruntime/qv4managed.cpp +++ b/src/qml/jsruntime/qv4managed.cpp @@ -206,7 +206,7 @@ ReturnedValue Managed::get(String *name, bool *hasProperty) return vtbl->get(this, name, hasProperty); } -Value Managed::getIndexed(uint index, bool *hasProperty) +ReturnedValue Managed::getIndexed(uint index, bool *hasProperty) { return vtbl->getIndexed(this, index, hasProperty); } diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h index e72cf10..2ffacf6 100644 --- a/src/qml/jsruntime/qv4managed_p.h +++ b/src/qml/jsruntime/qv4managed_p.h @@ -98,7 +98,7 @@ struct ManagedVTable void (*collectDeletables)(Managed *, GCDeletable **deletable); bool (*hasInstance)(Managed *, const Value &value); ReturnedValue (*get)(Managed *, String *name, bool *hasProperty); - Value (*getIndexed)(Managed *, uint index, bool *hasProperty); + ReturnedValue (*getIndexed)(Managed *, uint index, bool *hasProperty); void (*put)(Managed *, String *name, const Value &value); void (*putIndexed)(Managed *, uint index, const Value &value); PropertyAttributes (*query)(const Managed *, String *name); @@ -263,7 +263,7 @@ public: ReturnedValue construct(CallData *d); ReturnedValue call(CallData *d); ReturnedValue get(String *name, bool *hasProperty = 0); - Value getIndexed(uint index, bool *hasProperty = 0); + ReturnedValue getIndexed(uint index, bool *hasProperty = 0); void put(String *name, const Value &value) { vtbl->put(this, name, value); } void putIndexed(uint index, const Value &value) diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 056430d..e682f80 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -454,7 +454,7 @@ ReturnedValue Object::get(Managed *m, String *name, bool *hasProperty) return static_cast(m)->internalGet(name, hasProperty); } -Value Object::getIndexed(Managed *m, uint index, bool *hasProperty) +ReturnedValue Object::getIndexed(Managed *m, uint index, bool *hasProperty) { return static_cast(m)->internalGetIndexed(index, hasProperty); } @@ -658,7 +658,7 @@ ReturnedValue Object::internalGet(String *name, bool *hasProperty) { uint idx = name->asArrayIndex(); if (idx != UINT_MAX) - return getIndexed(idx, hasProperty).asReturnedValue(); + return getIndexed(idx, hasProperty); name->makeIdentifier(); @@ -679,7 +679,7 @@ ReturnedValue Object::internalGet(String *name, bool *hasProperty) return Value::undefinedValue().asReturnedValue(); } -Value Object::internalGetIndexed(uint index, bool *hasProperty) +ReturnedValue Object::internalGetIndexed(uint index, bool *hasProperty) { Property *pd = 0; PropertyAttributes attrs = Attr_Data; @@ -707,12 +707,12 @@ Value Object::internalGetIndexed(uint index, bool *hasProperty) if (pd) { if (hasProperty) *hasProperty = true; - return Value::fromReturnedValue(getValue(pd, attrs)); + return getValue(pd, attrs); } if (hasProperty) *hasProperty = false; - return Value::undefinedValue(); + return Value::undefinedValue().asReturnedValue(); } @@ -1116,7 +1116,7 @@ void Object::copyArrayData(Object *other) Q_ASSERT(len); for (uint i = 0; i < len; ++i) { - arraySet(i, other->getIndexed(i)); + arraySet(i, Value::fromReturnedValue(other->getIndexed(i))); } } else { arrayReserve(other->arrayDataLen); @@ -1204,7 +1204,7 @@ void Object::arrayConcat(const ArrayObject *other) if (other->arrayAttributes) { for (int i = 0; i < arrayDataLen; ++i) { bool exists; - arrayData[oldSize + i].value = const_cast(other)->getIndexed(i, &exists); + arrayData[oldSize + i].value = Value::fromReturnedValue(const_cast(other)->getIndexed(i, &exists)); if (arrayAttributes) arrayAttributes[oldSize + i] = Attr_Data; if (!exists) { @@ -1460,10 +1460,14 @@ QStringList ArrayObject::toQStringList() const QStringList result; QV4::ExecutionEngine *engine = internalClass->engine; + Scope scope(engine); + ScopedValue v(scope); uint32_t length = arrayLength(); - for (uint32_t i = 0; i < length; ++i) - result.append(const_cast(this)->getIndexed(i).toString(engine->current)->toQString()); + for (uint32_t i = 0; i < length; ++i) { + v = const_cast(this)->getIndexed(i); + result.append(v->toString(engine->current)->toQString()); + } return result; } diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index 738bfbf..e11eecf 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -295,7 +295,7 @@ public: inline ReturnedValue get(String *name, bool *hasProperty = 0) { return vtbl->get(this, name, hasProperty); } - inline Value getIndexed(uint idx, bool *hasProperty = 0) + inline ReturnedValue getIndexed(uint idx, bool *hasProperty = 0) { return vtbl->getIndexed(this, idx, hasProperty); } inline void put(String *name, const Value &v) { vtbl->put(this, name, v); } @@ -317,7 +317,7 @@ protected: static void destroy(Managed *that); static void markObjects(Managed *that); static ReturnedValue get(Managed *m, String *name, bool *hasProperty); - static Value getIndexed(Managed *m, uint index, bool *hasProperty); + static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty); static void put(Managed *m, String *name, const Value &value); static void putIndexed(Managed *m, uint index, const Value &value); static PropertyAttributes query(const Managed *m, String *name); @@ -331,7 +331,7 @@ protected: private: ReturnedValue internalGet(String *name, bool *hasProperty); - Value internalGetIndexed(uint index, bool *hasProperty); + ReturnedValue internalGetIndexed(uint index, bool *hasProperty); void internalPut(String *name, const Value &value); void internalPutIndexed(uint index, const Value &value); bool internalDeleteProperty(String *name); diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index da05fe2..b428517 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -1517,10 +1517,14 @@ void CallArgument::fromValue(int callType, QV8Engine *engine, const QV4::Value & } else if (callType == qMetaTypeId >()) { qlistPtr = new (&allocData) QList(); if (QV4::ArrayObject *array = value.asArrayObject()) { + QV4::Scope scope(array->engine()); + Scoped qobjectWrapper(scope); + uint32_t length = array->arrayLength(); for (uint32_t ii = 0; ii < length; ++ii) { QObject *o = 0; - if (QV4::QObjectWrapper *qobjectWrapper = array->getIndexed(ii).as()) + qobjectWrapper = array->getIndexed(ii); + if (!!qobjectWrapper) o = qobjectWrapper->object(); qlistPtr->append(o); } diff --git a/src/qml/jsruntime/qv4regexp.cpp b/src/qml/jsruntime/qv4regexp.cpp index 7483abd..5a9a8d9 100644 --- a/src/qml/jsruntime/qv4regexp.cpp +++ b/src/qml/jsruntime/qv4regexp.cpp @@ -141,9 +141,9 @@ ReturnedValue RegExp::get(Managed *, String *, bool *) return Value::undefinedValue().asReturnedValue(); } -Value RegExp::getIndexed(Managed *m, uint index, bool *hasProperty) +ReturnedValue RegExp::getIndexed(Managed *m, uint index, bool *hasProperty) { - return Value::undefinedValue(); + return Value::undefinedValue().asReturnedValue(); } void RegExp::put(Managed *m, String *name, const Value &value) diff --git a/src/qml/jsruntime/qv4regexp_p.h b/src/qml/jsruntime/qv4regexp_p.h index 3032952..f91faf5 100644 --- a/src/qml/jsruntime/qv4regexp_p.h +++ b/src/qml/jsruntime/qv4regexp_p.h @@ -112,7 +112,7 @@ protected: static void destroy(Managed *that); static void markObjects(Managed *that); static ReturnedValue get(Managed *, String *, bool *); - static Value getIndexed(Managed *m, uint index, bool *hasProperty); + static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty); static void put(Managed *m, String *name, const Value &value); static void putIndexed(Managed *m, uint index, const Value &value); static PropertyAttributes query(const Managed *m, String *name); diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index 31f477b..107ae69 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -688,7 +688,7 @@ ReturnedValue __qmljs_get_element(ExecutionContext *ctx, const ValueRef object, } } - return o->getIndexed(idx).asReturnedValue(); + return o->getIndexed(idx); } String *name = index->toString(ctx); diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp index b1df8d9..68ae333 100644 --- a/src/qml/jsruntime/qv4sequenceobject.cpp +++ b/src/qml/jsruntime/qv4sequenceobject.cpp @@ -458,7 +458,7 @@ public: Container result; quint32 length = array->arrayLength(); for (quint32 i = 0; i < length; ++i) - result << convertValueToElement(array->getIndexed(i)); + result << convertValueToElement(QV4::Value::fromReturnedValue(array->getIndexed(i))); return QVariant::fromValue(result); } @@ -486,8 +486,8 @@ private: int m_propertyIndex; bool m_isReference; - static QV4::Value getIndexed(QV4::Managed *that, uint index, bool *hasProperty) - { return static_cast *>(that)->containerGetIndexed(index, hasProperty); } + static QV4::ReturnedValue getIndexed(QV4::Managed *that, uint index, bool *hasProperty) + { return static_cast *>(that)->containerGetIndexed(index, hasProperty).asReturnedValue(); } static void putIndexed(Managed *that, uint index, const QV4::Value &value) { static_cast *>(that)->containerPutIndexed(index, value); } static QV4::PropertyAttributes queryIndexed(const QV4::Managed *that, uint index) diff --git a/src/qml/jsruntime/qv4serialize.cpp b/src/qml/jsruntime/qv4serialize.cpp index b183baf..0bd3f79 100644 --- a/src/qml/jsruntime/qv4serialize.cpp +++ b/src/qml/jsruntime/qv4serialize.cpp @@ -189,7 +189,7 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, QV8Engine *engi reserve(data, sizeof(quint32) + length * sizeof(quint32)); push(data, valueheader(WorkerArray, length)); for (uint32_t ii = 0; ii < length; ++ii) - serialize(data, array->getIndexed(ii), engine); + serialize(data, QV4::Value::fromReturnedValue(array->getIndexed(ii)), engine); } else if (v.isInteger()) { reserve(data, 2 * sizeof(quint32)); push(data, valueheader(WorkerInt32)); @@ -252,7 +252,7 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, QV8Engine *engi push(data, valueheader(WorkerSequence, length)); serialize(data, QV4::Value::fromInt32(QV4::SequencePrototype::metaTypeForSequence(o)), engine); // sequence type for (uint32_t ii = 0; ii < seqLength; ++ii) - serialize(data, o->getIndexed(ii), engine); // sequence elements + serialize(data, QV4::Value::fromReturnedValue(o->getIndexed(ii)), engine); // sequence elements return; } @@ -267,14 +267,14 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, QV8Engine *engi push(data, valueheader(WorkerObject, length)); QV4::ScopedValue val(scope); + QV4::ScopedValue s(scope); for (quint32 ii = 0; ii < length; ++ii) { - QV4::String *s = properties->getIndexed(ii).asString(); - serialize(data, QV4::Value::fromString(s), engine); + s = properties->getIndexed(ii); + serialize(data, s, engine); - bool hasCaught = false; QV4::ExecutionContext *ctx = v4->current; try { - val = o->get(s); + val = o->get(s->asString()); } catch (QV4::Exception &e) { e.accept(ctx); } diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp index 7342b27..2b2eda7 100644 --- a/src/qml/jsruntime/qv4string.cpp +++ b/src/qml/jsruntime/qv4string.cpp @@ -150,25 +150,25 @@ ReturnedValue String::get(Managed *m, String *name, bool *hasProperty) return v4->stringClass->prototype->getValue(Value::fromString(that), pd, attrs); } -Value String::getIndexed(Managed *m, uint index, bool *hasProperty) +ReturnedValue String::getIndexed(Managed *m, uint index, bool *hasProperty) { String *that = static_cast(m); ExecutionEngine *engine = that->engine(); if (index < that->_text.length()) { if (hasProperty) *hasProperty = true; - return Value::fromString(engine->newString(that->toQString().mid(index, 1))); + return Value::fromString(engine->newString(that->toQString().mid(index, 1))).asReturnedValue(); } PropertyAttributes attrs; Property *pd = engine->stringClass->prototype->__getPropertyDescriptor__(index, &attrs); if (!pd || attrs.isGeneric()) { if (hasProperty) *hasProperty = false; - return Value::undefinedValue(); + return Value::undefinedValue().asReturnedValue(); } if (hasProperty) *hasProperty = true; - return Value::fromReturnedValue(engine->stringClass->prototype->getValue(Value::fromString(that), pd, attrs)); + return engine->stringClass->prototype->getValue(Value::fromString(that), pd, attrs); } void String::put(Managed *m, String *name, const Value &value) diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h index 49914c1..3e4ab54 100644 --- a/src/qml/jsruntime/qv4string_p.h +++ b/src/qml/jsruntime/qv4string_p.h @@ -133,7 +133,7 @@ struct Q_QML_EXPORT String : public Managed { protected: static void destroy(Managed *); static ReturnedValue get(Managed *m, String *name, bool *hasProperty); - static Value getIndexed(Managed *m, uint index, bool *hasProperty); + static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty); static void put(Managed *m, String *name, const Value &value); static void putIndexed(Managed *m, uint index, const Value &value); static PropertyAttributes query(const Managed *m, String *name); diff --git a/src/qml/qml/qqmllistwrapper.cpp b/src/qml/qml/qqmllistwrapper.cpp index 749702b..e8f01bb 100644 --- a/src/qml/qml/qqmllistwrapper.cpp +++ b/src/qml/qml/qqmllistwrapper.cpp @@ -112,12 +112,12 @@ ReturnedValue QmlListWrapper::get(Managed *m, String *name, bool *hasProperty) uint idx = name->asArrayIndex(); if (idx != UINT_MAX) - return getIndexed(m, idx, hasProperty).asReturnedValue(); + return getIndexed(m, idx, hasProperty); return Object::get(m, name, hasProperty); } -Value QmlListWrapper::getIndexed(Managed *m, uint index, bool *hasProperty) +ReturnedValue QmlListWrapper::getIndexed(Managed *m, uint index, bool *hasProperty) { QV4::ExecutionEngine *e = m->engine(); QmlListWrapper *w = m->as(); @@ -126,9 +126,9 @@ Value QmlListWrapper::getIndexed(Managed *m, uint index, bool *hasProperty) 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)); + return QV4::QObjectWrapper::wrap(e, w->property.at(&w->property, index)).asReturnedValue(); - return Value::undefinedValue(); + return Value::undefinedValue().asReturnedValue(); } void QmlListWrapper::put(Managed *m, String *name, const Value &value) diff --git a/src/qml/qml/qqmllistwrapper_p.h b/src/qml/qml/qqmllistwrapper_p.h index 797e39b..4778443 100644 --- a/src/qml/qml/qqmllistwrapper_p.h +++ b/src/qml/qml/qqmllistwrapper_p.h @@ -82,7 +82,7 @@ public: QVariant toVariant() const; static ReturnedValue get(Managed *m, String *name, bool *hasProperty); - static Value getIndexed(Managed *m, uint index, bool *hasProperty); + static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty); static void put(Managed *m, String *name, const Value &value); static Property *advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attributes); static void destroy(Managed *that); diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index f8c2590..360528e 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -992,7 +992,7 @@ QV4::Value QQmlVMEMetaObject::readVarProperty(int id) Q_ASSERT(id >= firstVarPropertyIndex); if (ensureVarPropertiesAllocated()) - return varProperties.value().asObject()->getIndexed(id - firstVarPropertyIndex); + return QV4::Value::fromReturnedValue(varProperties.value().asObject()->getIndexed(id - firstVarPropertyIndex)); return QV4::Value::emptyValue(); } @@ -1001,7 +1001,7 @@ QVariant QQmlVMEMetaObject::readPropertyAsVariant(int id) if (id >= firstVarPropertyIndex) { if (ensureVarPropertiesAllocated()) return QQmlEnginePrivate::get(ctxt->engine)->v8engine()->toVariant( - varProperties.value().asObject()->getIndexed(id - firstVarPropertyIndex), -1); + QV4::Value::fromReturnedValue(varProperties.value().asObject()->getIndexed(id - firstVarPropertyIndex)), -1); return QVariant(); } else { if (data[id].dataType() == QMetaType::QObjectStar) { @@ -1018,11 +1018,12 @@ void QQmlVMEMetaObject::writeVarProperty(int id, const QV4::Value &value) if (!ensureVarPropertiesAllocated()) return; + QV4::Scope scope(varProperties.engine()); // Importantly, if the current value is a scarce resource, we need to ensure that it // gets automatically released by the engine if no other references to it exist. - QV4::Value oldv = varProperties.value().asObject()->getIndexed(id - firstVarPropertyIndex); - if (QV4::VariantObject *v = oldv.as()) - v->removeVmePropertyReference(); + QV4::Scoped oldv(scope, varProperties.value().asObject()->getIndexed(id - firstVarPropertyIndex)); + if (!!oldv) + oldv->removeVmePropertyReference(); QObject *valueObject = 0; QQmlVMEVariantQObjectPtr *guard = getQObjectGuardForProperty(id); @@ -1059,11 +1060,13 @@ void QQmlVMEMetaObject::writeProperty(int id, const QVariant &value) if (!ensureVarPropertiesAllocated()) return; + QV4::Scope scope(varProperties.engine()); + // Importantly, if the current value is a scarce resource, we need to ensure that it // gets automatically released by the engine if no other references to it exist. - QV4::Value oldv = varProperties.value().asObject()->getIndexed(id - firstVarPropertyIndex); - if (QV4::VariantObject *v = oldv.as()) - v->removeVmePropertyReference(); + QV4::Scoped oldv(scope, varProperties.value().asObject()->getIndexed(id - firstVarPropertyIndex)); + if (!!oldv) + oldv->removeVmePropertyReference(); // 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. diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index 212f64f..85ae7fb 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -205,7 +205,7 @@ public: that->as()->~NamedNodeMap(); } static ReturnedValue get(Managed *m, String *name, bool *hasProperty); - static Value getIndexed(Managed *m, uint index, bool *hasProperty); + static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty); QList list; // Only used in NamedNodeMap NodeImpl *d; @@ -236,7 +236,7 @@ public: that->as()->~NodeList(); } static ReturnedValue get(Managed *m, String *name, bool *hasProperty); - static Value getIndexed(Managed *m, uint index, bool *hasProperty); + static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty); // C++ API static Value create(QV8Engine *, NodeImpl *); @@ -843,7 +843,7 @@ bool Node::isNull() const return d == 0; } -Value NamedNodeMap::getIndexed(Managed *m, uint index, bool *hasProperty) +ReturnedValue NamedNodeMap::getIndexed(Managed *m, uint index, bool *hasProperty) { QV4::ExecutionEngine *v4 = m->engine(); NamedNodeMap *r = m->as(); @@ -855,11 +855,11 @@ Value NamedNodeMap::getIndexed(Managed *m, uint index, bool *hasProperty) if ((int)index < r->list.count()) { if (hasProperty) *hasProperty = true; - return Node::create(engine, r->list.at(index)); + return Node::create(engine, r->list.at(index)).asReturnedValue(); } if (hasProperty) *hasProperty = false; - return Value::undefinedValue(); + return Value::undefinedValue().asReturnedValue(); } ReturnedValue NamedNodeMap::get(Managed *m, String *name, bool *hasProperty) @@ -897,7 +897,7 @@ Value NamedNodeMap::create(QV8Engine *engine, NodeImpl *data, const QListengine(); NodeList *r = m->as(); @@ -909,11 +909,11 @@ Value NodeList::getIndexed(Managed *m, uint index, bool *hasProperty) if ((int)index < r->d->children.count()) { if (hasProperty) *hasProperty = true; - return Node::create(engine, r->d->children.at(index)); + return Node::create(engine, r->d->children.at(index)).asReturnedValue(); } if (hasProperty) *hasProperty = false; - return Value::undefinedValue(); + return Value::undefinedValue().asReturnedValue(); } ReturnedValue NodeList::get(Managed *m, String *name, bool *hasProperty) diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp index 33447c3..6899bd4 100644 --- a/src/qml/qml/v8/qv8engine.cpp +++ b/src/qml/qml/v8/qv8engine.cpp @@ -153,12 +153,14 @@ QVariant QV8Engine::toVariant(const QV4::Value &value, int typeHint) } if (QV4::ArrayObject *a = value.asArrayObject()) { + QV4::Scope scope(a->engine()); if (typeHint == qMetaTypeId >()) { QList list; uint32_t length = a->arrayLength(); + QV4::Scoped qobjectWrapper(scope); for (uint32_t ii = 0; ii < length; ++ii) { - QV4::Value arrayItem = a->getIndexed(ii); - if (QV4::QObjectWrapper *qobjectWrapper = arrayItem.as()) { + qobjectWrapper = a->getIndexed(ii); + if (!!qobjectWrapper) { list << qobjectWrapper->object(); } else { list << 0; @@ -381,11 +383,15 @@ QVariant QV8Engine::toBasicVariant(const QV4::Value &value) if (QV4::RegExpObject *re = value.as()) return re->toQRegExp(); if (QV4::ArrayObject *a = value.asArrayObject()) { + QV4::Scope scope(a->engine()); + QV4::ScopedValue v(scope); QVariantList rv; int length = a->arrayLength(); - for (int ii = 0; ii < length; ++ii) - rv << toVariant(a->getIndexed(ii), -1); + for (int ii = 0; ii < length; ++ii) { + v = a->getIndexed(ii); + rv << toVariant(v, -1); + } return rv; } if (!value.asFunctionObject()) @@ -534,9 +540,12 @@ QVariantList QV8Engine::variantListFromJS(QV4::ArrayObject *a, visitedObjects.insert(a); + QV4::Scope scope(a->engine()); + QV4::ScopedValue v(scope); + quint32 length = a->arrayLength(); for (quint32 i = 0; i < length; ++i) { - QV4::Value v = a->getIndexed(i); + v = a->getIndexed(i); result.append(variantFromJS(v, visitedObjects)); } diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp index bb75a47..3e7b231 100644 --- a/src/qml/types/qqmldelegatemodel.cpp +++ b/src/qml/types/qqmldelegatemodel.cpp @@ -1676,9 +1676,12 @@ int QQmlDelegateModelItemMetaType::parseGroups(const QV4::Value &groups) const if (index != -1) groupFlags |= 2 << index; } else if (QV4::ArrayObject *array = groups.asArrayObject()) { + QV4::Scope scope(array->engine()); + QV4::ScopedValue v(scope); uint arrayLength = array->arrayLength(); for (uint i = 0; i < arrayLength; ++i) { - const QString groupName = array->getIndexed(i).toQStringNoThrow(); + v = array->getIndexed(i); + const QString groupName = v->toQStringNoThrow(); int index = groupNames.indexOf(groupName); if (index != -1) groupFlags |= 2 << index; @@ -3143,7 +3146,7 @@ public: virtual quint32 count() const = 0; virtual const QQmlChangeSet::Change &at(int index) const = 0; - static QV4::Value getIndexed(QV4::Managed *m, uint index, bool *hasProperty) + static QV4::ReturnedValue getIndexed(QV4::Managed *m, uint index, bool *hasProperty) { QV4::ExecutionEngine *v4 = m->engine(); QQmlDelegateModelGroupChangeArray *array = m->as(); @@ -3153,7 +3156,7 @@ public: if (index >= array->count()) { if (hasProperty) *hasProperty = false; - return QV4::Value::undefinedValue(); + return QV4::Value::undefinedValue().asReturnedValue(); } const QQmlChangeSet::Change &change = array->at(index); @@ -3165,7 +3168,7 @@ public: if (hasProperty) *hasProperty = true; - return QV4::Value::fromObject(object); + return QV4::Value::fromObject(object).asReturnedValue(); } static QV4::ReturnedValue get(QV4::Managed *m, QV4::String *name, bool *hasProperty) diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp index 067d91e..87e907e 100644 --- a/src/qml/types/qqmllistmodel.cpp +++ b/src/qml/types/qqmllistmodel.cpp @@ -414,6 +414,9 @@ void ListModel::set(int elementIndex, QV4::Object *object, QVector *roles, ListElement *e = elements[elementIndex]; QV4::ExecutionEngine *v4 = object->engine(); + QV4::Scope scope(v4); + QV4::Scoped o(scope); + QV4::ObjectIterator it(object, QV4::ObjectIterator::WithProtoChain|QV4::ObjectIterator::EnumerableOnly); while (1) { QV4::Value propertyValue; @@ -437,8 +440,8 @@ void ListModel::set(int elementIndex, QV4::Object *object, QVector *roles, int arrayLength = a->arrayLength(); for (int j=0 ; j < arrayLength ; ++j) { - QV4::Object *subObject = a->getIndexed(j).asObject(); - subModel->append(subObject, eng); + o = a->getIndexed(j); + subModel->append(o.getPointer(), eng); } roleIndex = e->setListProperty(r, subModel); @@ -480,6 +483,9 @@ void ListModel::set(int elementIndex, QV4::Object *object, QV8Engine *eng) ListElement *e = elements[elementIndex]; QV4::ExecutionEngine *v4 = object->engine(); + QV4::Scope scope(v4); + QV4::Scoped o(scope); + QV4::ObjectIterator it(object, QV4::ObjectIterator::WithProtoChain|QV4::ObjectIterator::EnumerableOnly); while (1) { QV4::Value propertyValue; @@ -504,8 +510,8 @@ void ListModel::set(int elementIndex, QV4::Object *object, QV8Engine *eng) int arrayLength = a->arrayLength(); for (int j=0 ; j < arrayLength ; ++j) { - QV4::Object *subObject = a->getIndexed(j).asObject(); - subModel->append(subObject, eng); + o = a->getIndexed(j); + subModel->append(o.getPointer(), eng); } e->setListPropertyFast(r, subModel); @@ -1164,11 +1170,14 @@ int ListElement::setJsProperty(const ListLayout::Role &role, const QV4::Value &d roleIndex = setDoubleProperty(role, d.asDouble()); } else if (QV4::ArrayObject *a = d.asArrayObject()) { if (role.type == ListLayout::Role::List) { + QV4::Scope scope(a->engine()); + QV4::Scoped o(scope); + ListModel *subModel = new ListModel(role.subLayout, 0, -1); int arrayLength = a->arrayLength(); for (int j=0 ; j < arrayLength ; ++j) { - QV4::Object *subObject = a->getIndexed(j).asObject(); - subModel->append(subObject, eng); + o = a->getIndexed(j); + subModel->append(o.getPointer(), eng); } roleIndex = setListProperty(role, subModel); } else { @@ -1924,14 +1933,17 @@ void QQmlListModel::insert(QQmlV4Function *args) QV4::Value arg1 = (*args)[1]; if (QV4::ArrayObject *objectArray = arg1.asArrayObject()) { + QV4::Scope scope(objectArray->engine()); + QV4::Scoped argObject(scope); + int objectArrayLength = objectArray->arrayLength(); for (int i=0 ; i < objectArrayLength ; ++i) { - QV4::Object *argObject = objectArray->getIndexed(i).asObject(); + argObject = objectArray->getIndexed(i); if (m_dynamicRoles) { - m_modelObjects.insert(index+i, DynamicRoleModelNode::create(args->engine()->variantMapFromJS(argObject), this)); + m_modelObjects.insert(index+i, DynamicRoleModelNode::create(args->engine()->variantMapFromJS(argObject.getPointer()), this)); } else { - m_listModel->insert(index+i, argObject, args->engine()); + m_listModel->insert(index+i, argObject.getPointer(), args->engine()); } } emitItemsInserted(index, objectArrayLength); @@ -2022,16 +2034,19 @@ void QQmlListModel::append(QQmlV4Function *args) QV4::Value arg = (*args)[0]; if (QV4::ArrayObject *objectArray = arg.asArrayObject()) { + QV4::Scope scope(objectArray->engine()); + QV4::Scoped argObject(scope); + int objectArrayLength = objectArray->arrayLength(); int index = count(); for (int i=0 ; i < objectArrayLength ; ++i) { - QV4::Object *argObject = objectArray->getIndexed(i).asObject(); + argObject = objectArray->getIndexed(i); if (m_dynamicRoles) { - m_modelObjects.append(DynamicRoleModelNode::create(args->engine()->variantMapFromJS(argObject), this)); + m_modelObjects.append(DynamicRoleModelNode::create(args->engine()->variantMapFromJS(argObject.getPointer()), this)); } else { - m_listModel->append(argObject, args->engine()); + m_listModel->append(argObject.getPointer(), args->engine()); } } diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp index 81f5505..cf692c3 100644 --- a/src/quick/items/context2d/qquickcontext2d.cpp +++ b/src/quick/items/context2d/qquickcontext2d.cpp @@ -873,7 +873,7 @@ struct QQuickJSContext2DPixelData : public QV4::Object static void destroy(QV4::Managed *that) { static_cast(that)->~QQuickJSContext2DPixelData(); } - static QV4::Value getIndexed(QV4::Managed *m, uint index, bool *hasProperty); + static QV4::ReturnedValue getIndexed(QV4::Managed *m, uint index, bool *hasProperty); static void putIndexed(QV4::Managed *m, uint index, const QV4::Value &value); static QV4::Value proto_get_length(QV4::SimpleCallContext *ctx); @@ -3005,7 +3005,7 @@ QV4::Value QQuickJSContext2DPixelData::proto_get_length(QV4::SimpleCallContext * return QV4::Value::fromInt32(r->image.width() * r->image.height() * 4); } -QV4::Value QQuickJSContext2DPixelData::getIndexed(QV4::Managed *m, uint index, bool *hasProperty) +QV4::ReturnedValue QQuickJSContext2DPixelData::getIndexed(QV4::Managed *m, uint index, bool *hasProperty) { QQuickJSContext2DPixelData *r = m->as(); if (!m) @@ -3021,18 +3021,18 @@ QV4::Value QQuickJSContext2DPixelData::getIndexed(QV4::Managed *m, uint index, b pixel += col; switch (index % 4) { case 0: - return QV4::Value::fromInt32(qRed(*pixel)); + return QV4::Value::fromInt32(qRed(*pixel)).asReturnedValue(); case 1: - return QV4::Value::fromInt32(qGreen(*pixel)); + return QV4::Value::fromInt32(qGreen(*pixel)).asReturnedValue(); case 2: - return QV4::Value::fromInt32(qBlue(*pixel)); + return QV4::Value::fromInt32(qBlue(*pixel)).asReturnedValue(); case 3: - return QV4::Value::fromInt32(qAlpha(*pixel)); + return QV4::Value::fromInt32(qAlpha(*pixel)).asReturnedValue(); } } if (hasProperty) *hasProperty = false; - return QV4::Value::undefinedValue(); + return QV4::Value::undefinedValue().asReturnedValue(); } void QQuickJSContext2DPixelData::putIndexed(QV4::Managed *m, uint index, const QV4::Value &value) diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp index 1af0450..c08719d 100644 --- a/src/quick/util/qquickglobal.cpp +++ b/src/quick/util/qquickglobal.cpp @@ -394,15 +394,18 @@ public: if (!array) return QMatrix4x4(); + QV4::Scope scope(array->engine()); + if (array->arrayLength() != 16) return QMatrix4x4(); float matVals[16]; + QV4::ScopedValue v(scope); for (quint32 i = 0; i < 16; ++i) { - QV4::Value v = array->getIndexed(i); - if (!v.isNumber()) + v = array->getIndexed(i); + if (!v->isNumber()) return QMatrix4x4(); - matVals[i] = v.asDouble(); + matVals[i] = v->asDouble(); } if (ok) *ok = true; -- 2.7.4