From bdb27b96acbd38531879378c48959a5a1cd60963 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 11 Sep 2013 16:28:17 +0200 Subject: Use ReturnedValue for Managed::get(). Change-Id: Ia8f35d227b69d32e1f6a041283abbbd083aa34ca Reviewed-by: Simon Hausmann --- src/qml/jsapi/qjsvalue.cpp | 16 ++++-- src/qml/jsapi/qjsvalueiterator.cpp | 4 +- src/qml/jsruntime/qv4arrayobject.cpp | 41 ++++++++------ src/qml/jsruntime/qv4context.cpp | 24 +++++--- src/qml/jsruntime/qv4dateobject.cpp | 3 +- src/qml/jsruntime/qv4debugging.cpp | 2 +- src/qml/jsruntime/qv4functionobject.cpp | 15 +++-- src/qml/jsruntime/qv4functionobject_p.h | 4 ++ src/qml/jsruntime/qv4jsonobject.cpp | 8 ++- src/qml/jsruntime/qv4lookup.cpp | 4 +- src/qml/jsruntime/qv4managed.cpp | 2 +- src/qml/jsruntime/qv4managed_p.h | 12 +++- src/qml/jsruntime/qv4object.cpp | 24 ++++---- src/qml/jsruntime/qv4object_p.h | 14 +++-- src/qml/jsruntime/qv4objectiterator.cpp | 4 +- src/qml/jsruntime/qv4objectproto.cpp | 35 ++++++------ src/qml/jsruntime/qv4qobjectwrapper.cpp | 14 ++--- src/qml/jsruntime/qv4qobjectwrapper_p.h | 2 +- src/qml/jsruntime/qv4regexp.cpp | 4 +- src/qml/jsruntime/qv4regexp_p.h | 2 +- src/qml/jsruntime/qv4regexpobject.cpp | 3 +- src/qml/jsruntime/qv4runtime.cpp | 16 +++--- src/qml/jsruntime/qv4scopedvalue_p.h | 81 +++++++++++++++++++++++++++ src/qml/jsruntime/qv4serialize.cpp | 7 ++- src/qml/jsruntime/qv4string.cpp | 8 +-- src/qml/jsruntime/qv4string_p.h | 6 +- src/qml/jsruntime/qv4stringobject.cpp | 6 +- src/qml/jsruntime/qv4value.cpp | 6 -- src/qml/jsruntime/qv4value_def_p.h | 2 - src/qml/qml/qqmlcontextwrapper.cpp | 35 ++++++------ src/qml/qml/qqmlcontextwrapper_p.h | 2 +- src/qml/qml/qqmljavascriptexpression.cpp | 2 +- src/qml/qml/qqmllistwrapper.cpp | 6 +- src/qml/qml/qqmllistwrapper_p.h | 2 +- src/qml/qml/qqmltypewrapper.cpp | 18 +++--- src/qml/qml/qqmltypewrapper_p.h | 2 +- src/qml/qml/qqmlvaluetypewrapper.cpp | 10 ++-- src/qml/qml/qqmlvaluetypewrapper_p.h | 2 +- src/qml/qml/qqmlxmlhttprequest.cpp | 28 ++++----- src/qml/types/qqmldelegatemodel.cpp | 4 +- src/quick/items/context2d/qquickcontext2d.cpp | 6 +- src/quick/util/qquickglobal.cpp | 22 ++++---- 42 files changed, 319 insertions(+), 189 deletions(-) (limited to 'src') diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp index eb2390fa01..7b0b8bc2fd 100644 --- a/src/qml/jsapi/qjsvalue.cpp +++ b/src/qml/jsapi/qjsvalue.cpp @@ -791,11 +791,15 @@ bool QJSValue::strictlyEquals(const QJSValue& other) const */ QJSValue QJSValue::property(const QString& name) const { + ExecutionEngine *engine = d->engine; + if (!engine) + return QJSValue(); + QV4::Scope scope(engine); + Object *o = d->value.asObject(); if (!o) return QJSValue(); - ExecutionEngine *engine = d->engine; String *s = engine->newString(name); uint idx = s->asArrayIndex(); if (idx < UINT_MAX) @@ -804,7 +808,7 @@ QJSValue QJSValue::property(const QString& name) const s->makeIdentifier(); QV4::ExecutionContext *ctx = engine->current; try { - QV4::Value v = o->get(s); + QV4::ScopedValue v(scope, o->get(s)); return new QJSValuePrivate(engine, v); } catch (QV4::Exception &e) { e.accept(ctx); @@ -826,14 +830,18 @@ QJSValue QJSValue::property(const QString& name) const */ QJSValue QJSValue::property(quint32 arrayIndex) const { + ExecutionEngine *engine = d->engine; + if (!engine) + return QJSValue(); + + QV4::Scope scope(engine); Object *o = d->value.asObject(); if (!o) return QJSValue(); - ExecutionEngine *engine = d->engine; QV4::ExecutionContext *ctx = engine->current; try { - QV4::Value v = arrayIndex == UINT_MAX ? o->get(engine->id_uintMax) : o->getIndexed(arrayIndex); + QV4::ScopedValue v(scope, arrayIndex == UINT_MAX ? o->get(engine->id_uintMax) : o->getIndexed(arrayIndex).asReturnedValue()); return new QJSValuePrivate(engine, v); } catch (QV4::Exception &e) { e.accept(ctx); diff --git a/src/qml/jsapi/qjsvalueiterator.cpp b/src/qml/jsapi/qjsvalueiterator.cpp index 545250f27a..2b074c3cb2 100644 --- a/src/qml/jsapi/qjsvalueiterator.cpp +++ b/src/qml/jsapi/qjsvalueiterator.cpp @@ -174,9 +174,11 @@ QJSValue QJSValueIterator::value() const QV4::Object *o = d_ptr->iterator.object; QV4::ExecutionEngine *engine = o->internalClass->engine; + QV4::Scope scope(engine); + QV4::ExecutionContext *ctx = engine->current; try { - QV4::Value v; + QV4::ScopedValue v(scope); if (d_ptr->currentName) v = o->get(d_ptr->currentName); else if (d_ptr->currentIndex != UINT_MAX) diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp index 280062eb0d..8942df0c22 100644 --- a/src/qml/jsruntime/qv4arrayobject.cpp +++ b/src/qml/jsruntime/qv4arrayobject.cpp @@ -123,7 +123,9 @@ uint ArrayPrototype::getLength(ExecutionContext *ctx, Object *o) { if (o->isArrayObject()) return o->arrayLength(); - return o->get(ctx->engine->id_length).toUInt32(); + Scope scope(ctx); + ScopedValue v(scope, o->get(ctx->engine->id_length)); + return v->toUInt32(); } Value ArrayPrototype::method_isArray(SimpleCallContext *ctx) @@ -135,10 +137,11 @@ Value ArrayPrototype::method_isArray(SimpleCallContext *ctx) Value ArrayPrototype::method_toString(SimpleCallContext *ctx) { + QV4::Scope scope(ctx); QV4::Object *o = ctx->thisObject.toObject(ctx); - FunctionObject *f = o->get(ctx->engine->newString("join")).asFunctionObject(); + ScopedValue v(scope, o->get(ctx->engine->newString("join"))); + FunctionObject *f = v->asFunctionObject(); if (f) { - Scope scope(ctx); ScopedCallData d(scope, 0); d->thisObject = ctx->thisObject; return Value::fromReturnedValue(f->call(d)); @@ -183,6 +186,7 @@ Value ArrayPrototype::method_concat(SimpleCallContext *ctx) Value ArrayPrototype::method_join(SimpleCallContext *ctx) { + Scope scope(ctx); Value arg = ctx->argument(0); QString r4; @@ -191,22 +195,22 @@ Value ArrayPrototype::method_join(SimpleCallContext *ctx) else r4 = arg.toString(ctx)->toQString(); - Value self = ctx->thisObject; - const Value length = self.property(ctx, ctx->engine->id_length); - const quint32 r2 = Value::toUInt32(length.isUndefined() ? 0 : length.toNumber()); + Scoped self(scope, ctx->thisObject); + ScopedValue length(scope, self->get(ctx->engine->id_length)); + const quint32 r2 = Value::toUInt32(length->isUndefined() ? 0 : length->toNumber()); static QSet visitedArrayElements; - if (! r2 || visitedArrayElements.contains(self.objectValue())) + if (! r2 || visitedArrayElements.contains(self.getPointer())) return Value::fromString(ctx, QString()); // avoid infinite recursion - visitedArrayElements.insert(self.objectValue()); + visitedArrayElements.insert(self.getPointer()); QString R; // ### FIXME - if (ArrayObject *a = self.asArrayObject()) { + if (ArrayObject *a = self->asArrayObject()) { for (uint i = 0; i < a->arrayLength(); ++i) { if (i) R += r4; @@ -219,22 +223,23 @@ Value ArrayPrototype::method_join(SimpleCallContext *ctx) // // crazy! // - Value r6 = self.property(ctx, ctx->engine->newString(QStringLiteral("0"))); - if (!(r6.isUndefined() || r6.isNull())) - R = r6.toString(ctx)->toQString(); + ScopedValue r6(scope, self->get(ctx->engine->newString(QStringLiteral("0")))); + if (!r6->isNullOrUndefined()) + R = r6->toString(ctx)->toQString(); + ScopedValue r12(scope); for (quint32 k = 1; k < r2; ++k) { R += r4; String *name = Value::fromDouble(k).toString(ctx); - Value r12 = self.property(ctx, name); + r12 = self->get(name); - if (! (r12.isUndefined() || r12.isNull())) - R += r12.toString(ctx)->toQString(); + if (!r12->isNullOrUndefined()) + R += r12->toString(ctx)->toQString(); } } - visitedArrayElements.remove(self.objectValue()); + visitedArrayElements.remove(self.getPointer()); return Value::fromString(ctx, R); } @@ -351,7 +356,7 @@ Value ArrayPrototype::method_shift(SimpleCallContext *ctx) if (pidx < UINT_MAX && (!instance->arrayAttributes || !instance->arrayAttributes[0].isGeneric())) front = instance->arrayData + pidx; - Value result = front ? instance->getValue(front, instance->arrayAttributes ? instance->arrayAttributes[pidx] : Attr_Data) : Value::undefinedValue(); + Value result = front ? Value::fromReturnedValue(instance->getValue(front, instance->arrayAttributes ? instance->arrayAttributes[pidx] : Attr_Data)) : Value::undefinedValue(); if (!instance->protoHasArray() && instance->arrayDataLen <= len) { if (!instance->sparseArray) { @@ -392,7 +397,7 @@ Value ArrayPrototype::method_slice(SimpleCallContext *ctx) Object *o = ctx->thisObject.toObject(ctx); ArrayObject *result = ctx->engine->newArrayObject(); - uint len = o->get(ctx->engine->id_length).toUInt32(); + uint len = ArrayPrototype::getLength(ctx, o); double s = ctx->argument(0).toInteger(); uint start; if (s < 0) diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index 0bcee14064..1a1efc0b4c 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -405,6 +405,8 @@ void ExecutionContext::setProperty(String *name, const Value& value) ReturnedValue ExecutionContext::getProperty(String *name) { + Scope scope(this); + ScopedValue v(scope); name->makeIdentifier(); if (name->isEqualTo(engine->id_this)) @@ -417,7 +419,7 @@ ReturnedValue ExecutionContext::getProperty(String *name) Object *w = static_cast(ctx)->withObject; hasWith = true; bool hasProperty = false; - Value v = w->get(name, &hasProperty); + v = w->get(name, &hasProperty); if (hasProperty) { return v.asReturnedValue(); } @@ -444,7 +446,7 @@ ReturnedValue ExecutionContext::getProperty(String *name) } if (c->activation) { bool hasProperty = false; - Value v = c->activation->get(name, &hasProperty); + v = c->activation->get(name, &hasProperty); if (hasProperty) return v.asReturnedValue(); } @@ -456,7 +458,7 @@ ReturnedValue ExecutionContext::getProperty(String *name) else if (ctx->type == Type_GlobalContext) { GlobalContext *g = static_cast(ctx); bool hasProperty = false; - Value v = g->global->get(name, &hasProperty); + v = g->global->get(name, &hasProperty); if (hasProperty) return v.asReturnedValue(); } @@ -467,6 +469,8 @@ ReturnedValue ExecutionContext::getProperty(String *name) ReturnedValue ExecutionContext::getPropertyNoThrow(String *name) { + Scope scope(this); + ScopedValue v(scope); name->makeIdentifier(); if (name->isEqualTo(engine->id_this)) @@ -479,7 +483,7 @@ ReturnedValue ExecutionContext::getPropertyNoThrow(String *name) Object *w = static_cast(ctx)->withObject; hasWith = true; bool hasProperty = false; - Value v = w->get(name, &hasProperty); + v = w->get(name, &hasProperty); if (hasProperty) { return v.asReturnedValue(); } @@ -506,7 +510,7 @@ ReturnedValue ExecutionContext::getPropertyNoThrow(String *name) } if (c->activation) { bool hasProperty = false; - Value v = c->activation->get(name, &hasProperty); + v = c->activation->get(name, &hasProperty); if (hasProperty) return v.asReturnedValue(); } @@ -518,7 +522,7 @@ ReturnedValue ExecutionContext::getPropertyNoThrow(String *name) else if (ctx->type == Type_GlobalContext) { GlobalContext *g = static_cast(ctx); bool hasProperty = false; - Value v = g->global->get(name, &hasProperty); + v = g->global->get(name, &hasProperty); if (hasProperty) return v.asReturnedValue(); } @@ -528,6 +532,8 @@ ReturnedValue ExecutionContext::getPropertyNoThrow(String *name) ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Object **base) { + Scope scope(this); + ScopedValue v(scope); *base = 0; name->makeIdentifier(); @@ -541,7 +547,7 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Object **base) Object *w = static_cast(ctx)->withObject; hasWith = true; bool hasProperty = false; - Value v = w->get(name, &hasProperty); + v = w->get(name, &hasProperty); if (hasProperty) { *base = w; return v.asReturnedValue(); @@ -569,7 +575,7 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Object **base) } if (c->activation) { bool hasProperty = false; - Value v = c->activation->get(name, &hasProperty); + v = c->activation->get(name, &hasProperty); if (hasProperty) { if (ctx->type == Type_QmlContext) *base = c->activation; @@ -584,7 +590,7 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Object **base) else if (ctx->type == Type_GlobalContext) { GlobalContext *g = static_cast(ctx); bool hasProperty = false; - Value v = g->global->get(name, &hasProperty); + v = g->global->get(name, &hasProperty); if (hasProperty) return v.asReturnedValue(); } diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp index c2a15b8725..de56fcd5f3 100644 --- a/src/qml/jsruntime/qv4dateobject.cpp +++ b/src/qml/jsruntime/qv4dateobject.cpp @@ -1298,7 +1298,8 @@ Value DatePrototype::method_toJSON(SimpleCallContext *ctx) if (tv->isNumber() && !std::isfinite(tv->toNumber())) return Value::nullValue(); - FunctionObject *toIso = O->objectValue()->get(ctx->engine->newString(QStringLiteral("toISOString"))).asFunctionObject(); + ScopedValue v(scope, O->objectValue()->get(ctx->engine->newString(QStringLiteral("toISOString")))); + FunctionObject *toIso = v->asFunctionObject(); if (!toIso) ctx->throwTypeError(); diff --git a/src/qml/jsruntime/qv4debugging.cpp b/src/qml/jsruntime/qv4debugging.cpp index 6879e432e8..8080ed6c62 100644 --- a/src/qml/jsruntime/qv4debugging.cpp +++ b/src/qml/jsruntime/qv4debugging.cpp @@ -275,7 +275,7 @@ static void realDumpValue(QV4::Value v, QV4::ExecutionContext *ctx, std::string cout << prefix << "\t\"" << qPrintable(name.stringValue()->toQString()) << "\"" << endl; PropertyAttributes attrs; Property *d = o->__getOwnProperty__(name.stringValue(), &attrs); - Value pval = o->getValue(d, 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 475874ce01..03d09a7bc4 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -138,7 +138,9 @@ bool FunctionObject::hasInstance(Managed *that, const Value &value) return false; ExecutionContext *ctx = f->engine()->current; - Object *o = f->get(ctx->engine->id_prototype).asObject(); + QV4::Scope scope(ctx); + + Scoped o(scope, f->get(ctx->engine->id_prototype)); if (!o) ctx->throwTypeError(); @@ -147,7 +149,7 @@ bool FunctionObject::hasInstance(Managed *that, const Value &value) if (! v) break; - else if (o == v) + else if (o.getPointer() == v) return true; } @@ -158,11 +160,12 @@ ReturnedValue FunctionObject::construct(Managed *that, CallData *) { FunctionObject *f = static_cast(that); ExecutionEngine *v4 = f->engine(); + Scope scope(v4); InternalClass *ic = v4->objectClass; - Value proto = f->get(v4->id_prototype); - if (proto.isObject()) - ic = v4->emptyClass->changePrototype(proto.objectValue()); + Scoped proto(scope, f->get(v4->id_prototype)); + if (!!proto) + ic = v4->emptyClass->changePrototype(proto.getPointer()); Object *obj = v4->newObject(ic); return Value::fromObject(obj).asReturnedValue(); } @@ -647,7 +650,7 @@ BoundFunction::BoundFunction(ExecutionContext *scope, FunctionObject *target, Va , boundArgs(boundArgs) { vtbl = &static_vtbl; - int len = target->get(scope->engine->id_length).toUInt32(); + int len = Value::fromReturnedValue(target->get(scope->engine->id_length)).toUInt32(); len -= boundArgs.size(); if (len < 0) len = 0; diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h index bc5bc5c8df..8869083d08 100644 --- a/src/qml/jsruntime/qv4functionobject_p.h +++ b/src/qml/jsruntime/qv4functionobject_p.h @@ -126,6 +126,10 @@ struct Q_QML_EXPORT FunctionObject: Object { return vtbl->call(this, callData); } + static FunctionObject *cast(const Value &v) { + return v.asFunctionObject(); + } + static FunctionObject *creatScriptFunction(ExecutionContext *scope, Function *function); protected: diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp index 56e8d1ffe7..ea8afcbaf9 100644 --- a/src/qml/jsruntime/qv4jsonobject.cpp +++ b/src/qml/jsruntime/qv4jsonobject.cpp @@ -702,8 +702,8 @@ QString Stringify::Str(const QString &key, Value value) QString result; if (Object *o = value.asObject()) { - FunctionObject *toJSON = o->get(ctx->engine->newString(QStringLiteral("toJSON"))).asFunctionObject(); - if (toJSON) { + Scoped toJSON(scope, o->get(ctx->engine->newString(QStringLiteral("toJSON")))); + if (!!toJSON) { ScopedCallData callData(scope, 1); callData->thisObject = value; callData->args[0] = Value::fromString(ctx, key); @@ -773,6 +773,8 @@ QString Stringify::JO(Object *o) if (stack.contains(o)) ctx->throwTypeError(); + Scope scope(o->engine()); + QString result; stack.push(o); QString stepback = indent; @@ -795,7 +797,7 @@ QString Stringify::JO(Object *o) } else { for (int i = 0; i < propertyList.size(); ++i) { bool exists; - Value v = o->get(propertyList.at(i), &exists); + ScopedValue v(scope, o->get(propertyList.at(i), &exists)); if (!exists) continue; QString member = makeMember(propertyList.at(i)->toQString(), v); diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp index 35aaa1918a..e2392d84f5 100644 --- a/src/qml/jsruntime/qv4lookup.cpp +++ b/src/qml/jsruntime/qv4lookup.cpp @@ -137,7 +137,7 @@ void Lookup::getterGeneric(QV4::Lookup *l, QV4::Value *result, const QV4::Value l->getter = Lookup::primitiveGetterAccessor1; if (result) *result = p->value; - Value res = proto->getValue(object, p, attrs); + Value res = Value::fromReturnedValue(proto->getValue(object, p, attrs)); if (result) *result = res; return; @@ -383,7 +383,7 @@ void Lookup::globalGetterGeneric(Lookup *l, ExecutionContext *ctx, Value *result l->globalGetter = globalGetterAccessor1; else if (l->level == 2) l->globalGetter = globalGetterAccessor2; - Value res = o->getValue(p, attrs); + Value res = Value::fromReturnedValue(o->getValue(p, attrs)); if (result) *result = res; return; diff --git a/src/qml/jsruntime/qv4managed.cpp b/src/qml/jsruntime/qv4managed.cpp index 711c7cf259..a8f70778c4 100644 --- a/src/qml/jsruntime/qv4managed.cpp +++ b/src/qml/jsruntime/qv4managed.cpp @@ -201,7 +201,7 @@ bool Managed::isEqualTo(Managed *, Managed *) return false; } -Value Managed::get(String *name, bool *hasProperty) +ReturnedValue Managed::get(String *name, bool *hasProperty) { return vtbl->get(this, name, hasProperty); } diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h index 44d809c605..e72cf10bf8 100644 --- a/src/qml/jsruntime/qv4managed_p.h +++ b/src/qml/jsruntime/qv4managed_p.h @@ -97,7 +97,7 @@ struct ManagedVTable void (*destroy)(Managed *); void (*collectDeletables)(Managed *, GCDeletable **deletable); bool (*hasInstance)(Managed *, const Value &value); - Value (*get)(Managed *, String *name, bool *hasProperty); + ReturnedValue (*get)(Managed *, String *name, bool *hasProperty); Value (*getIndexed)(Managed *, uint index, bool *hasProperty); void (*put)(Managed *, String *name, const Value &value); void (*putIndexed)(Managed *, uint index, const Value &value); @@ -223,6 +223,14 @@ public: return vtbl == &T::static_vtbl ? static_cast(this) : 0; } + template + static T *cast(const Value &v) { + return v.as(); + } + static Managed *cast(const Value &v) { + return v.asManaged(); + } + ArrayObject *asArrayObject() { return type == Type_ArrayObject ? reinterpret_cast(this) : 0; } FunctionObject *asFunctionObject() { return type == Type_FunctionObject ? reinterpret_cast(this) : 0; } BooleanObject *asBooleanObject() { return type == Type_BooleanObject ? reinterpret_cast(this) : 0; } @@ -254,7 +262,7 @@ public: } ReturnedValue construct(CallData *d); ReturnedValue call(CallData *d); - Value get(String *name, bool *hasProperty = 0); + ReturnedValue get(String *name, bool *hasProperty = 0); Value getIndexed(uint index, bool *hasProperty = 0); void put(String *name, const Value &value) { vtbl->put(this, name, value); } diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 8b68b4811a..056430d5ea 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -127,18 +127,18 @@ void Object::put(ExecutionContext *ctx, const QString &name, const Value &value) put(ctx->engine->newString(name), value); } -Value Object::getValue(const Value &thisObject, const Property *p, PropertyAttributes attrs) +ReturnedValue Object::getValue(const Value &thisObject, const Property *p, PropertyAttributes attrs) { if (!attrs.isAccessor()) - return p->value; + return p->value.asReturnedValue(); FunctionObject *getter = p->getter(); if (!getter) - return Value::undefinedValue(); + return Value::undefinedValue().asReturnedValue(); Scope scope(getter->engine()); ScopedCallData callData(scope, 0); callData->thisObject = thisObject; - return Value::fromReturnedValue(getter->call(callData)); + return getter->call(callData); } void Object::putValue(Property *pd, PropertyAttributes attrs, const Value &value) @@ -449,7 +449,7 @@ bool Object::__hasProperty__(uint index) const return false; } -Value Object::get(Managed *m, String *name, bool *hasProperty) +ReturnedValue Object::get(Managed *m, String *name, bool *hasProperty) { return static_cast(m)->internalGet(name, hasProperty); } @@ -535,7 +535,7 @@ void Object::getLookup(Managed *m, Lookup *l, Value *result) l->getter = Lookup::getterAccessor2; if (result) *result = p->value; - Value res = o->getValue(p, attrs); + Value res = Value::fromReturnedValue(o->getValue(p, attrs)); if (result) *result = res; return; @@ -654,11 +654,11 @@ Property *Object::advanceIterator(Managed *m, ObjectIterator *it, String **name, } // Section 8.12.3 -Value Object::internalGet(String *name, bool *hasProperty) +ReturnedValue Object::internalGet(String *name, bool *hasProperty) { uint idx = name->asArrayIndex(); if (idx != UINT_MAX) - return getIndexed(idx, hasProperty); + return getIndexed(idx, hasProperty).asReturnedValue(); name->makeIdentifier(); @@ -676,7 +676,7 @@ Value Object::internalGet(String *name, bool *hasProperty) if (hasProperty) *hasProperty = false; - return Value::undefinedValue(); + return Value::undefinedValue().asReturnedValue(); } Value Object::internalGetIndexed(uint index, bool *hasProperty) @@ -707,7 +707,7 @@ Value Object::internalGetIndexed(uint index, bool *hasProperty) if (pd) { if (hasProperty) *hasProperty = true; - return getValue(pd, attrs); + return Value::fromReturnedValue(getValue(pd, attrs)); } if (hasProperty) @@ -1244,11 +1244,11 @@ void Object::arraySort(ExecutionContext *context, Object *thisObject, const Valu while (--len > i) if (!arrayAttributes[len].isGeneric()) break; - arrayData[i].value = getValue(arrayData + len, arrayAttributes[len]); + arrayData[i].value = Value::fromReturnedValue(getValue(arrayData + len, arrayAttributes[len])); arrayAttributes[i] = Attr_Data; arrayAttributes[len].clear(); } else if (arrayAttributes[i].isAccessor()) { - arrayData[i].value = getValue(arrayData + i, arrayAttributes[i]); + arrayData[i].value = Value::fromReturnedValue(getValue(arrayData + i, arrayAttributes[i])); arrayAttributes[i] = Attr_Data; } } diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index c656985aea..738bfbf524 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -149,8 +149,8 @@ struct Q_QML_EXPORT Object: Managed { // void put(ExecutionContext *ctx, const QString &name, const Value &value); - static Value getValue(const Value &thisObject, const Property *p, PropertyAttributes attrs); - Value getValue(const Property *p, PropertyAttributes attrs) const { + static ReturnedValue getValue(const Value &thisObject, const Property *p, PropertyAttributes attrs); + ReturnedValue getValue(const Property *p, PropertyAttributes attrs) const { return getValue(Value::fromObject(const_cast(this)), p, attrs); } @@ -179,6 +179,10 @@ struct Q_QML_EXPORT Object: Managed { ReturnedValue asReturnedValue() { return Value::fromObject(this).asReturnedValue(); } + static Object *cast(const Value &v) { + return v.asObject(); + } + // Array handling uint allocArrayValue() { @@ -289,7 +293,7 @@ public: } void ensureMemberIndex(uint idx); - inline Value get(String *name, bool *hasProperty = 0) + inline ReturnedValue get(String *name, bool *hasProperty = 0) { return vtbl->get(this, name, hasProperty); } inline Value getIndexed(uint idx, bool *hasProperty = 0) { return vtbl->getIndexed(this, idx, hasProperty); } @@ -312,7 +316,7 @@ protected: static const ManagedVTable static_vtbl; static void destroy(Managed *that); static void markObjects(Managed *that); - static Value get(Managed *m, String *name, bool *hasProperty); + static ReturnedValue get(Managed *m, String *name, bool *hasProperty); static Value 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); @@ -326,7 +330,7 @@ protected: private: - Value internalGet(String *name, bool *hasProperty); + ReturnedValue internalGet(String *name, bool *hasProperty); Value internalGetIndexed(uint index, bool *hasProperty); void internalPut(String *name, const Value &value); void internalPutIndexed(uint index, const Value &value); diff --git a/src/qml/jsruntime/qv4objectiterator.cpp b/src/qml/jsruntime/qv4objectiterator.cpp index 338398c0d8..8fdf281c7f 100644 --- a/src/qml/jsruntime/qv4objectiterator.cpp +++ b/src/qml/jsruntime/qv4objectiterator.cpp @@ -102,7 +102,7 @@ Value ObjectIterator::nextPropertyName(Value *value) return Value::nullValue(); if (value) - *value = object->getValue(p, attrs); + *value = Value::fromReturnedValue(object->getValue(p, attrs)); if (name) return Value::fromString(name); @@ -120,7 +120,7 @@ Value ObjectIterator::nextPropertyNameAsString(Value *value) return Value::nullValue(); if (value) - *value = object->getValue(p, attrs); + *value = Value::fromReturnedValue(object->getValue(p, attrs)); if (name) return Value::fromString(name); diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp index 37becf8deb..1192dd5952 100644 --- a/src/qml/jsruntime/qv4objectproto.cpp +++ b/src/qml/jsruntime/qv4objectproto.cpp @@ -81,13 +81,14 @@ ObjectCtor::ObjectCtor(ExecutionContext *scope) ReturnedValue ObjectCtor::construct(Managed *that, CallData *callData) { - ObjectCtor *ctor = static_cast(that); ExecutionEngine *v4 = that->engine(); + Scope scope(v4); + ObjectCtor *ctor = static_cast(that); if (!callData->argc || callData->args[0].isUndefined() || callData->args[0].isNull()) { Object *obj = v4->newObject(); - Value proto = ctor->get(v4->id_prototype); - if (proto.isObject()) - obj->setPrototype(proto.objectValue()); + Scoped proto(scope, ctor->get(v4->id_prototype)); + if (!!proto) + obj->setPrototype(proto.getPointer()); return Value::fromObject(obj).asReturnedValue(); } return Value::fromReturnedValue(__qmljs_to_object(v4->current, ValueRef(&callData->args[0]))).asReturnedValue(); @@ -221,7 +222,7 @@ Value ObjectPrototype::method_defineProperties(SimpleCallContext *ctx) break; Property n; PropertyAttributes nattrs; - toPropertyDescriptor(ctx, o->getValue(pd, attrs), &n, &nattrs); + toPropertyDescriptor(ctx, Value::fromReturnedValue(o->getValue(pd, attrs)), &n, &nattrs); bool ok; if (name) ok = O.objectValue()->__defineOwnProperty__(ctx, name, n, nattrs); @@ -383,8 +384,7 @@ Value ObjectPrototype::method_toLocaleString(SimpleCallContext *ctx) { Scope scope(ctx); Object *o = ctx->thisObject.toObject(ctx); - Value ts = o->get(ctx->engine->newString(QStringLiteral("toString"))); - FunctionObject *f = ts.asFunctionObject(); + Scoped f(scope, o->get(ctx->engine->newString(QStringLiteral("toString")))); if (!f) ctx->throwTypeError(); ScopedCallData callData(scope, 0); @@ -514,6 +514,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope if (!v.isObject()) ctx->throwTypeError(); + Scope scope(ctx); Object *o = v.objectValue(); attrs->clear(); @@ -521,17 +522,17 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope desc->setSetter(0); if (o->__hasProperty__(ctx->engine->id_enumerable)) - attrs->setEnumerable(o->get(ctx->engine->id_enumerable).toBoolean()); + attrs->setEnumerable(Value::fromReturnedValue(o->get(ctx->engine->id_enumerable)).toBoolean()); if (o->__hasProperty__(ctx->engine->id_configurable)) - attrs->setConfigurable(o->get(ctx->engine->id_configurable).toBoolean()); + attrs->setConfigurable(Value::fromReturnedValue(o->get(ctx->engine->id_configurable)).toBoolean()); if (o->__hasProperty__(ctx->engine->id_get)) { - Value get = o->get(ctx->engine->id_get); - FunctionObject *f = get.asFunctionObject(); + ScopedValue get(scope, o->get(ctx->engine->id_get)); + FunctionObject *f = get->asFunctionObject(); if (f) { desc->setGetter(f); - } else if (get.isUndefined()) { + } else if (get->isUndefined()) { desc->setGetter((FunctionObject *)0x1); } else { ctx->throwTypeError(); @@ -540,11 +541,11 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope } if (o->__hasProperty__(ctx->engine->id_set)) { - Value set = o->get(ctx->engine->id_set); - FunctionObject *f = set.asFunctionObject(); + ScopedValue set(scope, o->get(ctx->engine->id_set)); + FunctionObject *f = set->asFunctionObject(); if (f) { desc->setSetter(f); - } else if (set.isUndefined()) { + } else if (set->isUndefined()) { desc->setSetter((FunctionObject *)0x1); } else { ctx->throwTypeError(); @@ -555,7 +556,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope if (o->__hasProperty__(ctx->engine->id_writable)) { if (attrs->isAccessor()) ctx->throwTypeError(); - attrs->setWritable(o->get(ctx->engine->id_writable).toBoolean()); + attrs->setWritable(Value::fromReturnedValue(o->get(ctx->engine->id_writable)).toBoolean()); // writable forces it to be a data descriptor desc->value = Value::undefinedValue(); } @@ -563,7 +564,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope if (o->__hasProperty__(ctx->engine->id_value)) { if (attrs->isAccessor()) ctx->throwTypeError(); - desc->value = o->get(ctx->engine->id_value); + desc->value = Value::fromReturnedValue(o->get(ctx->engine->id_value)); attrs->setType(PropertyAttributes::Data); } diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 2f3301e298..da05fe2f9e 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -311,7 +311,7 @@ Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qml } } } - return QV4::Object::get(this, name, hasProperty); + return QV4::Value::fromReturnedValue(QV4::Object::get(this, name, hasProperty)); } QQmlData::flushPendingBinding(m_object, result->coreIndex); @@ -340,8 +340,8 @@ Value QObjectWrapper::getQmlProperty(ExecutionContext *ctx, QQmlContextData *qml QV4::String *connect = ctx->engine->newIdentifier(QStringLiteral("connect")); QV4::String *disconnect = ctx->engine->newIdentifier(QStringLiteral("disconnect")); - handler->put(connect, ctx->engine->functionClass->prototype->get(connect)); - handler->put(disconnect, ctx->engine->functionClass->prototype->get(disconnect)); + 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); } else { @@ -601,12 +601,12 @@ QV4::Value QObjectWrapper::create(ExecutionEngine *engine, QQmlData *ddata, QObj return Value::fromObject(new (engine->memoryManager) QV4::QObjectWrapper(engine, object)); } -QV4::Value QObjectWrapper::get(Managed *m, String *name, bool *hasProperty) +QV4::ReturnedValue QObjectWrapper::get(Managed *m, String *name, bool *hasProperty) { 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); + return that->getQmlProperty(v4->current, qmlContext, name, IgnoreRevision, hasProperty, /*includeImports*/ true).asReturnedValue(); } void QObjectWrapper::put(Managed *m, String *name, const Value &value) @@ -655,7 +655,7 @@ Property *QObjectWrapper::advanceIterator(Managed *m, ObjectIterator *it, String ++it->arrayIndex; if (attributes) *attributes = QV4::Attr_Data; - it->tmpDynamicProperty.value = that->get(*name); + it->tmpDynamicProperty.value = QV4::Value::fromReturnedValue(that->get(*name)); return &it->tmpDynamicProperty; } const int methodCount = mo->methodCount(); @@ -664,7 +664,7 @@ Property *QObjectWrapper::advanceIterator(Managed *m, ObjectIterator *it, String ++it->arrayIndex; if (attributes) *attributes = QV4::Attr_Data; - it->tmpDynamicProperty.value = that->get(*name); + it->tmpDynamicProperty.value = QV4::Value::fromReturnedValue(that->get(*name)); return &it->tmpDynamicProperty; } return QV4::Object::advanceIterator(m, it, name, index, attributes); diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h index 4034e14cf5..716e72d375 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper_p.h +++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h @@ -105,7 +105,7 @@ private: String *m_destroy; String *m_toString; - static Value get(Managed *m, String *name, bool *hasProperty); + static ReturnedValue get(Managed *m, String *name, bool *hasProperty); static void put(Managed *m, String *name, const Value &value); static PropertyAttributes query(const Managed *, String *name); static Property *advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attributes); diff --git a/src/qml/jsruntime/qv4regexp.cpp b/src/qml/jsruntime/qv4regexp.cpp index ab01ce7650..7483abd2ae 100644 --- a/src/qml/jsruntime/qv4regexp.cpp +++ b/src/qml/jsruntime/qv4regexp.cpp @@ -136,9 +136,9 @@ void RegExp::markObjects(Managed *that) { } -Value RegExp::get(Managed *m, String *name, bool *hasProperty) +ReturnedValue RegExp::get(Managed *, String *, bool *) { - return Value::undefinedValue(); + return Value::undefinedValue().asReturnedValue(); } Value RegExp::getIndexed(Managed *m, uint index, bool *hasProperty) diff --git a/src/qml/jsruntime/qv4regexp_p.h b/src/qml/jsruntime/qv4regexp_p.h index 6edbd4b2ad..3032952ec5 100644 --- a/src/qml/jsruntime/qv4regexp_p.h +++ b/src/qml/jsruntime/qv4regexp_p.h @@ -111,7 +111,7 @@ public: protected: static void destroy(Managed *that); static void markObjects(Managed *that); - static Value get(Managed *m, String *name, bool *hasProperty); + static ReturnedValue get(Managed *, String *, bool *); static Value 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); diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp index 4ad8c4a0a1..3dcd49f6a5 100644 --- a/src/qml/jsruntime/qv4regexpobject.cpp +++ b/src/qml/jsruntime/qv4regexpobject.cpp @@ -206,7 +206,8 @@ QString RegExpObject::toString() const QString RegExpObject::source() const { - return const_cast(this)->get(internalClass->engine->newIdentifier(QStringLiteral("source"))).stringValue()->toQString(); + Value s = Value::fromReturnedValue(const_cast(this)->get(internalClass->engine->newIdentifier(QStringLiteral("source")))); + return s.stringValue()->toQString(); } uint RegExpObject::flags() const diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index a6257958b4..31f477bedd 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -692,7 +692,7 @@ ReturnedValue __qmljs_get_element(ExecutionContext *ctx, const ValueRef object, } String *name = index->toString(ctx); - return o->get(name).asReturnedValue(); + return o->get(name); } void __qmljs_set_element(ExecutionContext *ctx, const ValueRef object, const ValueRef index, const ValueRef value) @@ -769,7 +769,7 @@ ReturnedValue __qmljs_get_property(ExecutionContext *ctx, const ValueRef object, Value res; Managed *m = object->asManaged(); if (m) - return m->get(name).asReturnedValue(); + return m->get(name); if (object->isNullOrUndefined()) { QString message = QStringLiteral("Cannot read property '%1' of %2").arg(name->toQString()).arg(object->toQStringNoThrow()); @@ -777,7 +777,7 @@ ReturnedValue __qmljs_get_property(ExecutionContext *ctx, const ValueRef object, } m = __qmljs_convert_to_object(ctx, object); - return m->get(name).asReturnedValue(); + return m->get(name); } ReturnedValue __qmljs_get_activation_property(ExecutionContext *ctx, String *name) @@ -974,6 +974,7 @@ ReturnedValue __qmljs_call_activation_property(ExecutionContext *context, String ReturnedValue __qmljs_call_property(ExecutionContext *context, String *name, CallDataRef callData) { + Scope scope(context); Managed *baseObject = callData->thisObject.asManaged(); if (!baseObject) { if (callData->thisObject.isNullOrUndefined()) { @@ -985,7 +986,7 @@ ReturnedValue __qmljs_call_property(ExecutionContext *context, String *name, Cal callData->thisObject = Value::fromObject(static_cast(baseObject)); } - FunctionObject *o = baseObject->get(name).asFunctionObject(); + Scoped o(scope, baseObject->get(name)); if (!o) { QString error = QString("Property '%1' of object %2 is not a function").arg(name->toQString(), callData->thisObject.toQStringNoThrow()); context->throwTypeError(error); @@ -1010,10 +1011,11 @@ ReturnedValue __qmljs_call_property_lookup(ExecutionContext *context, uint index ReturnedValue __qmljs_call_element(ExecutionContext *context, const ValueRef index, CallDataRef callData) { + Scope scope(context); Object *baseObject = callData->thisObject.toObject(context); callData->thisObject = Value::fromObject(baseObject); - Object *o = baseObject->get(index->toString(context)).asObject(); + Scoped o(scope, baseObject->get(index->toString(context))); if (!o) context->throwTypeError(); @@ -1069,10 +1071,10 @@ ReturnedValue __qmljs_construct_value(ExecutionContext *context, const ValueRef ReturnedValue __qmljs_construct_property(ExecutionContext *context, const ValueRef base, String *name, CallDataRef callData) { + Scope scope(context); Object *thisObject = base->toObject(context); - Value func = thisObject->get(name); - Object *f = func.asObject(); + Scoped f(scope, thisObject->get(name)); if (!f) context->throwTypeError(); diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h index 7bb98e7a62..4fe0362c46 100644 --- a/src/qml/jsruntime/qv4scopedvalue_p.h +++ b/src/qml/jsruntime/qv4scopedvalue_p.h @@ -170,6 +170,87 @@ struct ScopedValue Value *ptr; }; +template +struct Scoped +{ + Scoped(const Scope &scope) + { + ptr = scope.engine->jsStackTop++; +#ifndef QT_NO_DEBUG + ++scope.size; +#endif + } + + Scoped(const Scope &scope, const Value &v) + { + ptr = scope.engine->jsStackTop++; + if (T::cast(v)) + *ptr = v; + else + *ptr = QV4::Value::undefinedValue(); +#ifndef QT_NO_DEBUG + ++scope.size; +#endif + } + + Scoped(const Scope &scope, const ReturnedValue &v) + { + ptr = scope.engine->jsStackTop++; + if (T::cast(QV4::Value::fromReturnedValue(v))) + ptr->val = v; + else + *ptr = QV4::Value::undefinedValue(); +#ifndef QT_NO_DEBUG + ++scope.size; +#endif + } + + Scoped &operator=(const Value &v) { + if (T::cast(v)) + *ptr = v; + else + *ptr = QV4::Value::undefinedValue(); + return *this; + } + + Scoped &operator=(const ReturnedValue &v) { + if (T::cast(QV4::Value::fromReturnedValue(v))) + ptr->val = v; + else + *ptr = QV4::Value::undefinedValue(); + return *this; + } + + Scoped &operator=(const Scoped &other) { + *ptr = *other.ptr; + return *this; + } + + T *operator->() { + return static_cast(ptr->asManaged()); + } + +// const Value *operator->() const { +// return T::cast(*ptr); +// } + + bool operator!() const { + return !ptr->asManaged(); + } + + T *getPointer() { + return static_cast(ptr->asManaged()); + } + + Value asValue() const { + return *ptr; + } + + ReturnedValue asReturnedValue() const { return ptr->val; } + + Value *ptr; +}; + struct ScopedCallData { ScopedCallData(Scope &scope, int argc) { diff --git a/src/qml/jsruntime/qv4serialize.cpp b/src/qml/jsruntime/qv4serialize.cpp index f7389dc6d7..b183baf0c2 100644 --- a/src/qml/jsruntime/qv4serialize.cpp +++ b/src/qml/jsruntime/qv4serialize.cpp @@ -150,6 +150,8 @@ static inline void *popPtr(const char *&data) void Serialize::serialize(QByteArray &data, const QV4::Value &v, QV8Engine *engine) { QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); + QV4::Scope scope(v4); + if (v.isEmpty()) { } else if (v.isUndefined()) { push(data, valueheader(WorkerUndefined)); @@ -240,7 +242,7 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, QV8Engine *engi if (o->isListType()) { // valid sequence. we generate a length (sequence length + 1 for the sequence type) - uint32_t seqLength = o->get(v4->id_length).toUInt32(); + uint32_t seqLength = ScopedValue(scope, o->get(v4->id_length))->toUInt32(); uint32_t length = seqLength + 1; if (length > 0xFFFFFF) { push(data, valueheader(WorkerUndefined)); @@ -264,14 +266,13 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, QV8Engine *engi } push(data, valueheader(WorkerObject, length)); - QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); + QV4::ScopedValue val(scope); for (quint32 ii = 0; ii < length; ++ii) { QV4::String *s = properties->getIndexed(ii).asString(); serialize(data, QV4::Value::fromString(s), engine); bool hasCaught = false; QV4::ExecutionContext *ctx = v4->current; - QV4::Value val = QV4::Value::undefinedValue(); try { val = o->get(s); } catch (QV4::Exception &e) { diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp index 11d3100180..7342b27fb8 100644 --- a/src/qml/jsruntime/qv4string.cpp +++ b/src/qml/jsruntime/qv4string.cpp @@ -129,21 +129,21 @@ void String::destroy(Managed *that) static_cast(that)->~String(); } -Value String::get(Managed *m, String *name, bool *hasProperty) +ReturnedValue String::get(Managed *m, String *name, bool *hasProperty) { String *that = static_cast(m); ExecutionEngine *v4 = m->engine(); if (name == v4->id_length) { if (hasProperty) *hasProperty = true; - return Value::fromInt32(that->_text.length()); + return Value::fromInt32(that->_text.length()).asReturnedValue(); } PropertyAttributes attrs; Property *pd = v4->stringClass->prototype->__getPropertyDescriptor__(name, &attrs); if (!pd || attrs.isGeneric()) { if (hasProperty) *hasProperty = false; - return Value::undefinedValue(); + return Value::undefinedValue().asReturnedValue(); } if (hasProperty) *hasProperty = true; @@ -168,7 +168,7 @@ Value String::getIndexed(Managed *m, uint index, bool *hasProperty) } if (hasProperty) *hasProperty = true; - return engine->stringClass->prototype->getValue(Value::fromString(that), pd, attrs); + return Value::fromReturnedValue(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 96e3393700..49914c1485 100644 --- a/src/qml/jsruntime/qv4string_p.h +++ b/src/qml/jsruntime/qv4string_p.h @@ -119,6 +119,10 @@ struct Q_QML_EXPORT String : public Managed { return _text.length(); } + static String *cast(const Value &v) { + return v.asString(); + } + ReturnedValue asReturnedValue() { return Value::fromString(this).asReturnedValue(); } QString _text; @@ -128,7 +132,7 @@ struct Q_QML_EXPORT String : public Managed { protected: static void destroy(Managed *); - static Value get(Managed *m, String *name, bool *hasProperty); + static ReturnedValue get(Managed *m, String *name, bool *hasProperty); static Value 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); diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp index 8df40ea488..7a5252f3ad 100644 --- a/src/qml/jsruntime/qv4stringobject.cpp +++ b/src/qml/jsruntime/qv4stringobject.cpp @@ -369,7 +369,7 @@ Value StringPrototype::method_match(SimpleCallContext *context) bool global = rx->global; // ### use the standard builtin function, not the one that might be redefined in the proto - FunctionObject *exec = context->engine->regExpClass->prototype->get(context->engine->newString(QStringLiteral("exec")), 0).asFunctionObject(); + Scoped exec(scope, context->engine->regExpClass->prototype->get(context->engine->newString(QStringLiteral("exec")), 0)); ScopedCallData callData(scope, 1); callData->thisObject = Value::fromObject(rx); @@ -385,12 +385,14 @@ Value StringPrototype::method_match(SimpleCallContext *context) uint n = 0; ScopedValue result(scope); ScopedValue matchStr(scope); + ScopedValue index(scope); while (1) { result = exec->call(callData); if (result->isNull()) break; assert(result->isObject()); - double thisIndex = rx->get(lastIndex, 0).toInteger(); + index = rx->get(lastIndex, 0); + double thisIndex = index->toInteger(); if (previousLastIndex == thisIndex) { previousLastIndex = thisIndex + 1; rx->put(lastIndex, Value::fromDouble(previousLastIndex)); diff --git a/src/qml/jsruntime/qv4value.cpp b/src/qml/jsruntime/qv4value.cpp index d0857556b6..384df32601 100644 --- a/src/qml/jsruntime/qv4value.cpp +++ b/src/qml/jsruntime/qv4value.cpp @@ -316,12 +316,6 @@ Object *Value::toObject(ExecutionContext *ctx) const } -Value Value::property(ExecutionContext *ctx, String *name) const -{ - return isObject() ? objectValue()->get(name) : undefinedValue(); -} - - PersistentValue::PersistentValue(const Value &val) : d(new PersistentValuePrivate(val)) { diff --git a/src/qml/jsruntime/qv4value_def_p.h b/src/qml/jsruntime/qv4value_def_p.h index c55ad0c6f7..866e5e7e7d 100644 --- a/src/qml/jsruntime/qv4value_def_p.h +++ b/src/qml/jsruntime/qv4value_def_p.h @@ -268,8 +268,6 @@ struct Q_QML_EXPORT Value uint asArrayIndex() const; uint asArrayLength(bool *ok) const; - Value property(ExecutionContext *ctx, String *name) const; - inline ExecutionEngine *engine() const; ReturnedValue asReturnedValue() const { return val; } diff --git a/src/qml/qml/qqmlcontextwrapper.cpp b/src/qml/qml/qqmlcontextwrapper.cpp index bd0b211403..f84f288770 100644 --- a/src/qml/qml/qqmlcontextwrapper.cpp +++ b/src/qml/qml/qqmlcontextwrapper.cpp @@ -124,21 +124,22 @@ void QmlContextWrapper::takeContextOwnership(const Value &qmlglobal) } -Value QmlContextWrapper::get(Managed *m, String *name, bool *hasProperty) +ReturnedValue QmlContextWrapper::get(Managed *m, String *name, bool *hasProperty) { - QmlContextWrapper *resource = m->as(); QV4::ExecutionEngine *v4 = m->engine(); + QV4::Scope scope(v4); + QmlContextWrapper *resource = m->as(); if (!resource) v4->current->throwTypeError(); // In V8 the JS global object would come _before_ the QML global object, // so simulate that here. bool hasProp; - QV4::Value result = v4->globalObject->get(name, &hasProp); + QV4::ScopedValue result(scope, v4->globalObject->get(name, &hasProp)); if (hasProp) { if (hasProperty) *hasProperty = hasProp; - return result; + return result.asReturnedValue(); } if (resource->isNullWrapper) @@ -151,7 +152,7 @@ Value QmlContextWrapper::get(Managed *m, String *name, bool *hasProperty) if (hasProp) { if (hasProperty) *hasProperty = hasProp; - return result; + return result.asReturnedValue(); } // Its possible we could delay the calculation of the "actual" context (in the case @@ -162,7 +163,7 @@ Value QmlContextWrapper::get(Managed *m, String *name, bool *hasProperty) if (!context) { if (hasProperty) *hasProperty = true; - return result; + return result.asReturnedValue(); } // Search type (attached property/enum/imported scripts) names @@ -187,13 +188,13 @@ Value QmlContextWrapper::get(Managed *m, String *name, bool *hasProperty) if (r.scriptIndex != -1) { int index = r.scriptIndex; if (index < context->importedScripts.count()) - return context->importedScripts.at(index).value(); + return context->importedScripts.at(index).value().asReturnedValue(); else - return QV4::Value::undefinedValue(); + return QV4::Value::undefinedValue().asReturnedValue(); } else if (r.type) { - return QmlTypeWrapper::create(engine, scopeObject, r.type); + return QmlTypeWrapper::create(engine, scopeObject, r.type).asReturnedValue(); } else if (r.importNamespace) { - return QmlTypeWrapper::create(engine, scopeObject, context->imports, r.importNamespace); + return QmlTypeWrapper::create(engine, scopeObject, context->imports, r.importNamespace).asReturnedValue(); } Q_ASSERT(!"Unreachable"); } @@ -215,7 +216,7 @@ Value 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]); + return QV4::QObjectWrapper::wrap(v4, context->idValues[propertyIdx]).asReturnedValue(); } else { QQmlContextPrivate *cp = context->asQQmlContextPrivate(); @@ -230,9 +231,9 @@ Value 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 >()); + return QmlListWrapper::create(engine, prop, qMetaTypeId >()).asReturnedValue(); } else { - return engine->fromVariant(cp->propertyValues.at(propertyIdx)); + return engine->fromVariant(cp->propertyValues.at(propertyIdx)).asReturnedValue(); } } } @@ -245,7 +246,7 @@ Value QmlContextWrapper::get(Managed *m, String *name, bool *hasProperty) if (hasProp) { if (hasProperty) *hasProperty = true; - return result; + return result.asReturnedValue(); } } scopeObject = 0; @@ -254,11 +255,11 @@ Value QmlContextWrapper::get(Managed *m, String *name, bool *hasProperty) // Search context object if (context->contextObject) { bool hasProp = false; - QV4::Value result = QV4::QObjectWrapper::getQmlProperty(v4->current, context, context->contextObject, name, QV4::QObjectWrapper::CheckRevision, &hasProp); + result = QV4::QObjectWrapper::getQmlProperty(v4->current, context, context->contextObject, name, QV4::QObjectWrapper::CheckRevision, &hasProp); if (hasProp) { if (hasProperty) *hasProperty = true; - return result; + return result.asReturnedValue(); } } @@ -267,7 +268,7 @@ Value QmlContextWrapper::get(Managed *m, String *name, bool *hasProperty) expressionContext->unresolvedNames = true; - return Value::undefinedValue(); + return Value::undefinedValue().asReturnedValue(); } void QmlContextWrapper::put(Managed *m, String *name, const Value &value) diff --git a/src/qml/qml/qqmlcontextwrapper_p.h b/src/qml/qml/qqmlcontextwrapper_p.h index 0f44952567..0ed933014b 100644 --- a/src/qml/qml/qqmlcontextwrapper_p.h +++ b/src/qml/qml/qqmlcontextwrapper_p.h @@ -82,7 +82,7 @@ struct Q_QML_EXPORT QmlContextWrapper : Object void setReadOnly(bool b) { readOnly = b; } - static Value get(Managed *m, String *name, bool *hasProperty); + static ReturnedValue get(Managed *m, String *name, bool *hasProperty); static void put(Managed *m, String *name, const Value &value); static void destroy(Managed *that); diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp index 4f67a1dd28..12f594ee5f 100644 --- a/src/qml/qml/qqmljavascriptexpression.cpp +++ b/src/qml/qml/qqmljavascriptexpression.cpp @@ -312,7 +312,7 @@ void QQmlJavaScriptExpression::exceptionToError(const QV4::Exception &e, QQmlErr } QV4::ErrorObject *errorObj = e.value().asErrorObject(); if (errorObj && errorObj->asSyntaxError()) - error.setDescription(errorObj->get(errorObj->engine()->newString("message")).toQStringNoThrow()); + error.setDescription(QV4::Value::fromReturnedValue(errorObj->get(errorObj->engine()->newString("message"))).toQStringNoThrow()); else error.setDescription(e.value().toQStringNoThrow()); } diff --git a/src/qml/qml/qqmllistwrapper.cpp b/src/qml/qml/qqmllistwrapper.cpp index 1c1386d5b7..749702b357 100644 --- a/src/qml/qml/qqmllistwrapper.cpp +++ b/src/qml/qml/qqmllistwrapper.cpp @@ -98,7 +98,7 @@ QVariant QmlListWrapper::toVariant() const } -Value QmlListWrapper::get(Managed *m, String *name, bool *hasProperty) +ReturnedValue QmlListWrapper::get(Managed *m, String *name, bool *hasProperty) { QV4::ExecutionEngine *v4 = m->engine(); QmlListWrapper *w = m->as(); @@ -107,12 +107,12 @@ Value QmlListWrapper::get(Managed *m, String *name, bool *hasProperty) if (name == v4->id_length && !w->object.isNull()) { quint32 count = w->property.count ? w->property.count(&w->property) : 0; - return Value::fromUInt32(count); + return Value::fromUInt32(count).asReturnedValue(); } uint idx = name->asArrayIndex(); if (idx != UINT_MAX) - return getIndexed(m, idx, hasProperty); + return getIndexed(m, idx, hasProperty).asReturnedValue(); return Object::get(m, name, hasProperty); } diff --git a/src/qml/qml/qqmllistwrapper_p.h b/src/qml/qml/qqmllistwrapper_p.h index c87b9b22d5..797e39bedd 100644 --- a/src/qml/qml/qqmllistwrapper_p.h +++ b/src/qml/qml/qqmllistwrapper_p.h @@ -81,7 +81,7 @@ public: QVariant toVariant() const; - static Value get(Managed *m, String *name, bool *hasProperty); + static ReturnedValue get(Managed *m, String *name, bool *hasProperty); static Value 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); diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp index 33b8fb8e7a..8f05a877ef 100644 --- a/src/qml/qml/qqmltypewrapper.cpp +++ b/src/qml/qml/qqmltypewrapper.cpp @@ -112,7 +112,7 @@ Value QmlTypeWrapper::create(QV8Engine *v8, QObject *o, QQmlTypeNameCache *t, co } -Value QmlTypeWrapper::get(Managed *m, String *name, bool *hasProperty) +ReturnedValue QmlTypeWrapper::get(Managed *m, String *name, bool *hasProperty) { QmlTypeWrapper *w = m->as(); QV4::ExecutionEngine *v4 = m->engine(); @@ -149,13 +149,13 @@ Value QmlTypeWrapper::get(Managed *m, String *name, bool *hasProperty) bool ok; int value = e.keyToValue(enumName.constData(), &ok); if (ok) - return QV4::Value::fromInt32(value); + return QV4::Value::fromInt32(value).asReturnedValue(); } } } // check for property. - return QV4::QObjectWrapper::getQmlProperty(v4->current, context, qobjectSingleton, name, QV4::QObjectWrapper::IgnoreRevision, hasProperty); + return QV4::QObjectWrapper::getQmlProperty(v4->current, context, qobjectSingleton, name, QV4::QObjectWrapper::IgnoreRevision, hasProperty).asReturnedValue(); } 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. @@ -172,14 +172,14 @@ Value QmlTypeWrapper::get(Managed *m, String *name, bool *hasProperty) bool ok = false; int value = type->enumValue(name, &ok); if (ok) - return QV4::Value::fromInt32(value); + return QV4::Value::fromInt32(value).asReturnedValue(); // Fall through to base implementation } 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); + return QV4::QObjectWrapper::getQmlProperty(v4->current, context, ao, name, QV4::QObjectWrapper::IgnoreRevision, hasProperty).asReturnedValue(); // Fall through to base implementation } @@ -196,16 +196,16 @@ Value 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); + return create(w->v8, object, r.type, w->mode).asReturnedValue(); } else if (r.scriptIndex != -1) { int index = r.scriptIndex; if (index < context->importedScripts.count()) - return context->importedScripts.at(index).value(); + return context->importedScripts.at(index).value().asReturnedValue(); } else if (r.importNamespace) { - return create(w->v8, object, context->imports, r.importNamespace); + return create(w->v8, object, context->imports, r.importNamespace).asReturnedValue(); } - return QV4::Value::undefinedValue(); + return QV4::Value::undefinedValue().asReturnedValue(); } diff --git a/src/qml/qml/qqmltypewrapper_p.h b/src/qml/qml/qqmltypewrapper_p.h index 944621b1d6..c545e1cc3b 100644 --- a/src/qml/qml/qqmltypewrapper_p.h +++ b/src/qml/qml/qqmltypewrapper_p.h @@ -82,7 +82,7 @@ public: static QV4::Value create(QV8Engine *, QObject *, QQmlTypeNameCache *, const void *, TypeNameMode = IncludeEnums); - static Value get(Managed *m, String *name, bool *hasProperty); + static ReturnedValue get(Managed *m, String *name, bool *hasProperty); static void put(Managed *m, String *name, const Value &value); static PropertyAttributes query(const Managed *, String *name); static void destroy(Managed *that); diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index f494fba11f..98b2497b0d 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -263,7 +263,7 @@ Value QmlValueTypeWrapper::method_toString(SimpleCallContext *ctx) } } -Value QmlValueTypeWrapper::get(Managed *m, String *name, bool *hasProperty) +ReturnedValue QmlValueTypeWrapper::get(Managed *m, String *name, bool *hasProperty) { QmlValueTypeWrapper *r = m->as(); QV4::ExecutionEngine *v4 = m->engine(); @@ -275,7 +275,7 @@ Value QmlValueTypeWrapper::get(Managed *m, String *name, bool *hasProperty) QmlValueTypeReference *reference = static_cast(r); if (!reference->object || !readReferenceValue(reference)) - return Value::undefinedValue(); + return Value::undefinedValue().asReturnedValue(); } else { Q_ASSERT(r->objectType == QmlValueTypeWrapper::Copy); @@ -301,7 +301,7 @@ Value QmlValueTypeWrapper::get(Managed *m, String *name, bool *hasProperty) 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); + return QV4::QObjectWrapper::getQmlProperty(v4->current, qmlContext, r->type, name, QV4::QObjectWrapper::IgnoreRevision).asReturnedValue(); } #define VALUE_TYPE_LOAD(metatype, cpptype, constructor) \ @@ -309,7 +309,7 @@ Value QmlValueTypeWrapper::get(Managed *m, String *name, bool *hasProperty) cpptype v; \ void *args[] = { &v, 0 }; \ r->type->qt_metacall(QMetaObject::ReadProperty, result->coreIndex, args); \ - return constructor(v); \ + return constructor(v).asReturnedValue(); \ } // These four types are the most common used by the value type wrappers @@ -321,7 +321,7 @@ Value QmlValueTypeWrapper::get(Managed *m, String *name, bool *hasProperty) 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); + return r->v8->fromVariant(v).asReturnedValue(); #undef VALUE_TYPE_ACCESSOR } diff --git a/src/qml/qml/qqmlvaluetypewrapper_p.h b/src/qml/qml/qqmlvaluetypewrapper_p.h index f5088a5954..aa9de3330e 100644 --- a/src/qml/qml/qqmlvaluetypewrapper_p.h +++ b/src/qml/qml/qqmlvaluetypewrapper_p.h @@ -83,7 +83,7 @@ public: bool isEqual(const QVariant& value); - static Value get(Managed *m, String *name, bool *hasProperty); + static ReturnedValue get(Managed *m, String *name, bool *hasProperty); static void put(Managed *m, String *name, const Value &value); static void destroy(Managed *that); static bool isEqualTo(Managed *m, Managed *other); diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index 849e226a37..212f64fcef 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -204,7 +204,7 @@ public: static void destroy(Managed *that) { that->as()->~NamedNodeMap(); } - static Value get(Managed *m, String *name, bool *hasProperty); + static ReturnedValue get(Managed *m, String *name, bool *hasProperty); static Value getIndexed(Managed *m, uint index, bool *hasProperty); QList list; // Only used in NamedNodeMap @@ -235,7 +235,7 @@ public: static void destroy(Managed *that) { that->as()->~NodeList(); } - static Value get(Managed *m, String *name, bool *hasProperty); + static ReturnedValue get(Managed *m, String *name, bool *hasProperty); static Value getIndexed(Managed *m, uint index, bool *hasProperty); // C++ API @@ -862,7 +862,7 @@ Value NamedNodeMap::getIndexed(Managed *m, uint index, bool *hasProperty) return Value::undefinedValue(); } -Value NamedNodeMap::get(Managed *m, String *name, bool *hasProperty) +ReturnedValue NamedNodeMap::get(Managed *m, String *name, bool *hasProperty) { NamedNodeMap *r = m->as(); QV4::ExecutionEngine *v4 = m->engine(); @@ -871,7 +871,7 @@ Value NamedNodeMap::get(Managed *m, String *name, bool *hasProperty) name->makeIdentifier(); if (name->isEqualTo(v4->id_length)) - return Value::fromInt32(r->list.count()); + return Value::fromInt32(r->list.count()).asReturnedValue(); QV8Engine *engine = v4->v8Engine; @@ -880,13 +880,13 @@ Value NamedNodeMap::get(Managed *m, String *name, bool *hasProperty) if (r->list.at(ii)->name == str) { if (hasProperty) *hasProperty = true; - return Node::create(engine, r->list.at(ii)); + return Node::create(engine, r->list.at(ii)).asReturnedValue(); } } if (hasProperty) *hasProperty = false; - return Value::undefinedValue(); + return Value::undefinedValue().asReturnedValue(); } Value NamedNodeMap::create(QV8Engine *engine, NodeImpl *data, const QList &list) @@ -916,7 +916,7 @@ Value NodeList::getIndexed(Managed *m, uint index, bool *hasProperty) return Value::undefinedValue(); } -Value NodeList::get(Managed *m, String *name, bool *hasProperty) +ReturnedValue NodeList::get(Managed *m, String *name, bool *hasProperty) { QV4::ExecutionEngine *v4 = m->engine(); NodeList *r = m->as(); @@ -926,7 +926,7 @@ Value NodeList::get(Managed *m, String *name, bool *hasProperty) name->makeIdentifier(); if (name->isEqualTo(v4->id_length)) - return Value::fromInt32(r->d->children.count()); + return Value::fromInt32(r->d->children.count()).asReturnedValue(); return Object::get(m, name, hasProperty); } @@ -1467,24 +1467,24 @@ void QQmlXMLHttpRequest::dispatchCallback(const Value &me) if (!o) ctx->throwError(QStringLiteral("QQmlXMLHttpRequest: internal error: empty ThisObject")); - Object *thisObj = o->get(v4->newString(QStringLiteral("ThisObject"))).asObject(); + Scoped thisObj(scope, o->get(v4->newString(QStringLiteral("ThisObject")))); if (!thisObj) ctx->throwError(QStringLiteral("QQmlXMLHttpRequest: internal error: empty ThisObject")); - FunctionObject *callback = thisObj->get(v4->newString(QStringLiteral("onreadystatechange"))).asFunctionObject(); + Scoped callback(scope, thisObj->get(v4->newString(QStringLiteral("onreadystatechange")))); if (!callback) { // not an error, but no onreadystatechange function to call. return; } - Value activationObject = o->get(v4->newString(QStringLiteral("ActivationObject"))); - if (!activationObject.asObject()) + Scoped activationObject(scope, o->get(v4->newString(QStringLiteral("ActivationObject")))); + if (!activationObject) v4->current->throwError(QStringLiteral("QQmlXMLHttpRequest: internal error: empty ActivationObject")); - QQmlContextData *callingContext = QmlContextWrapper::getContext(activationObject); + QQmlContextData *callingContext = QmlContextWrapper::getContext(activationObject.asValue()); if (callingContext) { QV4::ScopedCallData callData(scope, 0); - callData->thisObject = activationObject; + callData->thisObject = activationObject.asValue(); callback->call(callData); } diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp index 0744b18197..bb75a47eef 100644 --- a/src/qml/types/qqmldelegatemodel.cpp +++ b/src/qml/types/qqmldelegatemodel.cpp @@ -3168,7 +3168,7 @@ public: return QV4::Value::fromObject(object); } - static QV4::Value get(QV4::Managed *m, QV4::String *name, bool *hasProperty) + static QV4::ReturnedValue get(QV4::Managed *m, QV4::String *name, bool *hasProperty) { QQmlDelegateModelGroupChangeArray *array = m->as(); if (!array) @@ -3177,7 +3177,7 @@ public: if (name == m->engine()->id_length) { if (hasProperty) *hasProperty = true; - return QV4::Value::fromInt32(array->count()); + return QV4::Value::fromInt32(array->count()).asReturnedValue(); } return Object::get(m, name, hasProperty); diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp index f17b3d45e6..81f5505245 100644 --- a/src/quick/items/context2d/qquickcontext2d.cpp +++ b/src/quick/items/context2d/qquickcontext2d.cpp @@ -68,6 +68,7 @@ #include #include #include +#include #if defined(Q_OS_QNX) || defined(Q_OS_ANDROID) #include @@ -1673,6 +1674,7 @@ QV4::Value QQuickJSContext2DPrototype::method_createPattern(QV4::SimpleCallConte QV8Engine *engine = ctx->engine->v8Engine; QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); + QV4::Scope scope(v4); if (ctx->argumentCount == 2) { QQuickContext2DStyle *pattern = new (v4->memoryManager) QQuickContext2DStyle(v4); @@ -1689,8 +1691,8 @@ QV4::Value QQuickJSContext2DPrototype::method_createPattern(QV4::SimpleCallConte QImage patternTexture; if (QV4::Object *o = ctx->arguments[0].asObject()) { - QQuickJSContext2DPixelData *pixelData = o->get(ctx->engine->newString(QStringLiteral("data"))).as(); - if (pixelData) { + QV4::Scoped pixelData(scope, o->get(ctx->engine->newString(QStringLiteral("data")))); + if (!!pixelData) { patternTexture = pixelData->image; } } else { diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp index 117b89e88b..1af04505b3 100644 --- a/src/quick/util/qquickglobal.cpp +++ b/src/quick/util/qquickglobal.cpp @@ -326,17 +326,17 @@ public: QV4::ExecutionEngine *v4 = obj->engine(); - QV4::Value vbold = obj->get(v4->newString(QStringLiteral("bold"))); - QV4::Value vcap = obj->get(v4->newString(QStringLiteral("capitalization"))); - QV4::Value vfam = obj->get(v4->newString(QStringLiteral("family"))); - QV4::Value vital = obj->get(v4->newString(QStringLiteral("italic"))); - QV4::Value vlspac = obj->get(v4->newString(QStringLiteral("letterSpacing"))); - QV4::Value vpixsz = obj->get(v4->newString(QStringLiteral("pixelSize"))); - QV4::Value vpntsz = obj->get(v4->newString(QStringLiteral("pointSize"))); - QV4::Value vstrk = obj->get(v4->newString(QStringLiteral("strikeout"))); - QV4::Value vundl = obj->get(v4->newString(QStringLiteral("underline"))); - QV4::Value vweight = obj->get(v4->newString(QStringLiteral("weight"))); - QV4::Value vwspac = obj->get(v4->newString(QStringLiteral("wordSpacing"))); + QV4::Value vbold = QV4::Value::fromReturnedValue(obj->get(v4->newString(QStringLiteral("bold")))); + QV4::Value vcap = QV4::Value::fromReturnedValue(obj->get(v4->newString(QStringLiteral("capitalization")))); + QV4::Value vfam = QV4::Value::fromReturnedValue(obj->get(v4->newString(QStringLiteral("family")))); + QV4::Value vital = QV4::Value::fromReturnedValue(obj->get(v4->newString(QStringLiteral("italic")))); + QV4::Value vlspac = QV4::Value::fromReturnedValue(obj->get(v4->newString(QStringLiteral("letterSpacing")))); + QV4::Value vpixsz = QV4::Value::fromReturnedValue(obj->get(v4->newString(QStringLiteral("pixelSize")))); + QV4::Value vpntsz = QV4::Value::fromReturnedValue(obj->get(v4->newString(QStringLiteral("pointSize")))); + QV4::Value vstrk = QV4::Value::fromReturnedValue(obj->get(v4->newString(QStringLiteral("strikeout")))); + QV4::Value vundl = QV4::Value::fromReturnedValue(obj->get(v4->newString(QStringLiteral("underline")))); + QV4::Value vweight = QV4::Value::fromReturnedValue(obj->get(v4->newString(QStringLiteral("weight")))); + QV4::Value vwspac = QV4::Value::fromReturnedValue(obj->get(v4->newString(QStringLiteral("wordSpacing")))); // pull out the values, set ok to true if at least one valid field is given. if (vbold.isBoolean()) { -- cgit v1.2.3