diff options
28 files changed, 144 insertions, 102 deletions
diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp index 6aef93771d..f485032a35 100644 --- a/src/imports/localstorage/plugin.cpp +++ b/src/imports/localstorage/plugin.cpp @@ -315,6 +315,8 @@ static Value qmlsqldatabase_changeVersion(SimpleCallContext *ctx) if (ctx->argumentCount < 2) return Value::undefinedValue(); + ValueScope scope(ctx); + QQmlSqlDatabaseWrapper *r = ctx->thisObject.as<QQmlSqlDatabaseWrapper>(); if (!r || r->type != QQmlSqlDatabaseWrapper::Database) V4THROW_REFERENCE("Not a SQLDatabase object"); @@ -341,7 +343,7 @@ static Value qmlsqldatabase_changeVersion(SimpleCallContext *ctx) ok = false; db.transaction(); - ScopedCallData callData(ctx->engine, 1); + ScopedCallData callData(scope, 1); callData->thisObject = engine->global(); callData->args[0] = Value::fromObject(w); try { @@ -377,6 +379,7 @@ static Value qmlsqldatabase_transaction_shared(SimpleCallContext *ctx, bool read if (!r || r->type != QQmlSqlDatabaseWrapper::Database) V4THROW_REFERENCE("Not a SQLDatabase object"); + ValueScope scope(ctx); QV8Engine *engine = ctx->engine->v8Engine; FunctionObject *callback = ctx->argumentCount ? ctx->arguments[0].asFunctionObject() : 0; @@ -395,7 +398,7 @@ static Value qmlsqldatabase_transaction_shared(SimpleCallContext *ctx, bool read db.transaction(); if (callback) { - ScopedCallData callData(ctx->engine, 1); + ScopedCallData callData(scope, 1); callData->thisObject = engine->global(); callData->args[0] = Value::fromObject(w); try { @@ -678,7 +681,8 @@ void QQuickLocalStorage::openDatabaseSync(QQmlV4Function *args) db->version = version; if (created && dbcreationCallback) { - ScopedCallData callData(ctx->engine, 1); + ValueScope scope(ctx); + ScopedCallData callData(scope, 1); callData->thisObject = engine->global(); callData->args[0] = Value::fromObject(db); dbcreationCallback->call(callData); diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp index ea5c021231..96e318fafb 100644 --- a/src/qml/jsapi/qjsvalue.cpp +++ b/src/qml/jsapi/qjsvalue.cpp @@ -507,7 +507,7 @@ QJSValue QJSValue::call(const QJSValueList &args) assert(engine); ValueScope scope(engine); - ScopedCallData callData(engine, args.length()); + ScopedCallData callData(scope, args.length()); callData->thisObject = Value::fromObject(engine->globalObject); for (int i = 0; i < args.size(); ++i) { if (!args.at(i).d->checkEngine(engine)) { @@ -564,7 +564,7 @@ QJSValue QJSValue::callWithInstance(const QJSValue &instance, const QJSValueList return QJSValue(); } - ScopedCallData callData(engine, args.size()); + ScopedCallData callData(scope, args.size()); callData->thisObject = instance.d->getValue(engine); for (int i = 0; i < args.size(); ++i) { if (!args.at(i).d->checkEngine(engine)) { @@ -613,7 +613,8 @@ QJSValue QJSValue::callAsConstructor(const QJSValueList &args) ExecutionEngine *engine = d->engine; assert(engine); - ScopedCallData callData(engine, args.size()); + ValueScope scope(engine); + ScopedCallData callData(scope, args.size()); for (int i = 0; i < args.size(); ++i) { if (!args.at(i).d->checkEngine(engine)) { qWarning("QJSValue::callAsConstructor() failed: cannot construct function with argument created in a different engine"); diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp index 89b6f49f1d..9a2c38ebea 100644 --- a/src/qml/jsruntime/qv4argumentsobject.cpp +++ b/src/qml/jsruntime/qv4argumentsobject.cpp @@ -106,6 +106,7 @@ void ArgumentsObject::destroy(Managed *that) bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const Property &desc, PropertyAttributes attrs) { + ValueScope scope(ctx); uint pidx = propertyIndexFromArrayIndex(index); Property *pd = arrayData + pidx; Property map; @@ -130,7 +131,7 @@ bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const if (isMapped && attrs.isData()) { if (!attrs.isGeneric()) { - ScopedCallData callData(ctx->engine, 1); + ScopedCallData callData(scope, 1); callData->thisObject = Value::fromObject(this); callData->args[0] = desc.value; map.setter()->call(callData); diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp index 58a2f256cc..e8cb5284c8 100644 --- a/src/qml/jsruntime/qv4arrayobject.cpp +++ b/src/qml/jsruntime/qv4arrayobject.cpp @@ -138,7 +138,8 @@ Value ArrayPrototype::method_toString(SimpleCallContext *ctx) QV4::Object *o = ctx->thisObject.toObject(ctx); FunctionObject *f = o->get(ctx->engine->newString("join")).asFunctionObject(); if (f) { - ScopedCallData d(ctx->engine, 0); + ValueScope scope(ctx); + ScopedCallData d(scope, 0); d->thisObject = ctx->thisObject; return Value::fromReturnedValue(f->call(d)); } @@ -626,6 +627,7 @@ Value ArrayPrototype::method_lastIndexOf(SimpleCallContext *ctx) Value ArrayPrototype::method_every(SimpleCallContext *ctx) { + ValueScope scope(ctx); Object *instance = ctx->thisObject.toObject(ctx); uint len = getLength(ctx, instance); @@ -636,6 +638,11 @@ Value ArrayPrototype::method_every(SimpleCallContext *ctx) Value thisArg = ctx->argument(1); + ScopedCallData callData(scope, 3); + callData->args[2] = Value::fromObject(instance); + callData->thisObject = thisArg; + ScopedValue r(scope); + bool ok = true; for (uint k = 0; ok && k < len; ++k) { bool exists; @@ -643,19 +650,17 @@ Value ArrayPrototype::method_every(SimpleCallContext *ctx) if (!exists) continue; - ScopedCallData callData(ctx->engine, 3); callData->args[0] = v; callData->args[1] = Value::fromDouble(k); - callData->args[2] = Value::fromObject(instance); - callData->thisObject = thisArg; - Value r = Value::fromReturnedValue(callback->call(callData)); - ok = r.toBoolean(); + r = callback->call(callData); + ok = r->toBoolean(); } return Value::fromBoolean(ok); } Value ArrayPrototype::method_some(SimpleCallContext *ctx) { + ValueScope scope(ctx); Object *instance = ctx->thisObject.toObject(ctx); uint len = getLength(ctx, instance); @@ -664,7 +669,9 @@ Value ArrayPrototype::method_some(SimpleCallContext *ctx) if (!callback) ctx->throwTypeError(); - Value thisArg = ctx->argument(1); + ScopedCallData callData(scope, 3); + callData->thisObject = ctx->argument(1); + callData->args[2] = Value::fromObject(instance); for (uint k = 0; k < len; ++k) { bool exists; @@ -672,11 +679,8 @@ Value ArrayPrototype::method_some(SimpleCallContext *ctx) if (!exists) continue; - ScopedCallData callData(ctx->engine, 3); - callData->thisObject = thisArg; callData->args[0] = v; callData->args[1] = Value::fromDouble(k); - callData->args[2] = Value::fromObject(instance); Value r = Value::fromReturnedValue(callback->call(callData)); if (r.toBoolean()) return Value::fromBoolean(true); @@ -686,6 +690,7 @@ Value ArrayPrototype::method_some(SimpleCallContext *ctx) Value ArrayPrototype::method_forEach(SimpleCallContext *ctx) { + ValueScope scope(ctx); Object *instance = ctx->thisObject.toObject(ctx); uint len = getLength(ctx, instance); @@ -694,7 +699,9 @@ Value ArrayPrototype::method_forEach(SimpleCallContext *ctx) if (!callback) ctx->throwTypeError(); - Value thisArg = ctx->argument(1); + ScopedCallData callData(scope, 3); + callData->thisObject = ctx->argument(1); + callData->args[2] = Value::fromObject(instance); for (uint k = 0; k < len; ++k) { bool exists; @@ -702,11 +709,8 @@ Value ArrayPrototype::method_forEach(SimpleCallContext *ctx) if (!exists) continue; - ScopedCallData callData(ctx->engine, 3); - callData->thisObject = thisArg; callData->args[0] = v; callData->args[1] = Value::fromDouble(k); - callData->args[2] = Value::fromObject(instance); callback->call(callData); } return Value::undefinedValue(); @@ -730,7 +734,7 @@ Value ArrayPrototype::method_map(SimpleCallContext *ctx) a->setArrayLengthUnchecked(len); ScopedValue mapped(scope); - ScopedCallData callData(ctx->engine, 3); + ScopedCallData callData(scope, 3); callData->thisObject = thisArg; callData->args[2] = Value::fromObject(instance); @@ -765,7 +769,7 @@ Value ArrayPrototype::method_filter(SimpleCallContext *ctx) a->arrayReserve(len); ScopedValue selected(scope); - ScopedCallData callData(ctx->engine, 3); + ScopedCallData callData(scope, 3); callData->thisObject = thisArg; callData->args[2] = Value::fromObject(instance); @@ -814,7 +818,7 @@ Value ArrayPrototype::method_reduce(SimpleCallContext *ctx) ctx->throwTypeError(); } - ScopedCallData callData(ctx->engine, 4); + ScopedCallData callData(scope, 4); callData->thisObject = Value::undefinedValue(); callData->args[0] = acc; callData->args[3] = Value::fromObject(instance); @@ -866,7 +870,7 @@ Value ArrayPrototype::method_reduceRight(SimpleCallContext *ctx) ctx->throwTypeError(); } - ScopedCallData callData(ctx->engine, 4); + ScopedCallData callData(scope, 4); callData->thisObject = Value::undefinedValue(); callData->args[3] = Value::fromObject(instance); diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp index ec4c0028a0..7dc922c3a8 100644 --- a/src/qml/jsruntime/qv4dateobject.cpp +++ b/src/qml/jsruntime/qv4dateobject.cpp @@ -1303,7 +1303,7 @@ Value DatePrototype::method_toJSON(SimpleCallContext *ctx) if (!toIso) ctx->throwTypeError(); - ScopedCallData callData(ctx->engine, 0); + ScopedCallData callData(scope, 0); callData->thisObject = ctx->thisObject; return Value::fromReturnedValue(toIso->call(callData)); } diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index a2fb4d270b..4e08ede286 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -124,7 +124,8 @@ FunctionObject::~FunctionObject() Value FunctionObject::newInstance() { - ScopedCallData callData(engine(), 0); + ValueScope scope(engine()); + ScopedCallData callData(scope, 0); return construct(callData); } @@ -288,6 +289,7 @@ Value FunctionPrototype::method_toString(SimpleCallContext *ctx) Value FunctionPrototype::method_apply(SimpleCallContext *ctx) { + ValueScope scope(ctx); FunctionObject *o = ctx->thisObject.asFunctionObject(); if (!o) ctx->throwTypeError(); @@ -308,7 +310,7 @@ Value FunctionPrototype::method_apply(SimpleCallContext *ctx) len = ArrayPrototype::getLength(ctx, arr); } - ScopedCallData callData(ctx->engine, len); + ScopedCallData callData(scope, len); if (len) { if (arr->protoHasArray() || arr->hasAccessorProperty) { @@ -329,13 +331,14 @@ Value FunctionPrototype::method_apply(SimpleCallContext *ctx) Value FunctionPrototype::method_call(SimpleCallContext *ctx) { + ValueScope scope(ctx); Value thisArg = ctx->argument(0); FunctionObject *o = ctx->thisObject.asFunctionObject(); if (!o) ctx->throwTypeError(); - ScopedCallData callData(ctx->engine, ctx->argumentCount ? ctx->argumentCount - 1 : 0); + ScopedCallData callData(scope, ctx->argumentCount ? ctx->argumentCount - 1 : 0); if (ctx->argumentCount) { std::copy(ctx->arguments + 1, ctx->arguments + ctx->argumentCount, callData->args); @@ -664,8 +667,9 @@ void BoundFunction::destroy(Managed *that) ReturnedValue BoundFunction::call(Managed *that, CallData *dd) { BoundFunction *f = static_cast<BoundFunction *>(that); + ValueScope scope(f->scope->engine); - ScopedCallData callData(f->scope->engine, f->boundArgs.size() + dd->argc); + ScopedCallData callData(scope, f->boundArgs.size() + dd->argc); callData->thisObject = f->boundThis; memcpy(callData->args, f->boundArgs.constData(), f->boundArgs.size()*sizeof(Value)); memcpy(callData->args + f->boundArgs.size(), dd->args, dd->argc*sizeof(Value)); @@ -675,7 +679,8 @@ ReturnedValue BoundFunction::call(Managed *that, CallData *dd) Value BoundFunction::construct(Managed *that, CallData *dd) { BoundFunction *f = static_cast<BoundFunction *>(that); - ScopedCallData callData(f->scope->engine, f->boundArgs.size() + dd->argc); + ValueScope scope(f->scope->engine); + ScopedCallData callData(scope, f->boundArgs.size() + dd->argc); memcpy(callData->args, f->boundArgs.constData(), f->boundArgs.size()*sizeof(Value)); memcpy(callData->args + f->boundArgs.size(), dd->args, dd->argc*sizeof(Value)); return f->target->construct(callData); diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp index e6f3de712d..e72de4ccd3 100644 --- a/src/qml/jsruntime/qv4globalobject.cpp +++ b/src/qml/jsruntime/qv4globalobject.cpp @@ -392,7 +392,7 @@ ReturnedValue EvalFunction::evalCall(Value /*thisObject*/, Value *args, int argc if (strictMode) { FunctionObject *e = FunctionObject::creatScriptFunction(ctx, function); - ScopedCallData callData(ctx->engine, 0); + ScopedCallData callData(scope, 0); callData->thisObject = ctx->thisObject; return e->call(callData); } diff --git a/src/qml/jsruntime/qv4include.cpp b/src/qml/jsruntime/qv4include.cpp index 7a5ca8e0ab..c01619c816 100644 --- a/src/qml/jsruntime/qv4include.cpp +++ b/src/qml/jsruntime/qv4include.cpp @@ -104,8 +104,9 @@ void QV4Include::callback(const QV4::Value &callback, const QV4::Value &status) return; QV4::ExecutionContext *ctx = f->engine()->current; + QV4::ValueScope scope(ctx); try { - QV4::ScopedCallData callData(ctx->engine, 1); + QV4::ScopedCallData callData(scope, 1); callData->thisObject = QV4::Value::fromObject(f->engine()->globalObject); callData->args[0] = status; f->call(callData); diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp index 3048d00ddb..12508d77cd 100644 --- a/src/qml/jsruntime/qv4jsonobject.cpp +++ b/src/qml/jsruntime/qv4jsonobject.cpp @@ -698,12 +698,13 @@ static QString quote(const QString &str) QString Stringify::Str(const QString &key, Value value) { + ValueScope scope(ctx); QString result; if (Object *o = value.asObject()) { FunctionObject *toJSON = o->get(ctx->engine->newString(QStringLiteral("toJSON"))).asFunctionObject(); if (toJSON) { - ScopedCallData callData(ctx->engine, 1); + ScopedCallData callData(scope, 1); callData->thisObject = value; callData->args[0] = Value::fromString(ctx, key); value = Value::fromReturnedValue(toJSON->call(callData)); @@ -714,7 +715,7 @@ QString Stringify::Str(const QString &key, Value value) Object *holder = ctx->engine->newObject(); Value holderValue = Value::fromObject(holder); holder->put(ctx, QString(), value); - ScopedCallData callData(ctx->engine, 2); + ScopedCallData callData(scope, 2); callData->args[0] = Value::fromString(ctx, key); callData->args[1] = value; callData->thisObject = holderValue; diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp index b630bbed5b..6ad617c4d6 100644 --- a/src/qml/jsruntime/qv4lookup.cpp +++ b/src/qml/jsruntime/qv4lookup.cpp @@ -198,12 +198,13 @@ void Lookup::getterAccessor0(Lookup *l, Value *result, const Value &object) { if (Object *o = object.asObject()) { if (l->classList[0] == o->internalClass) { + ValueScope scope(o->engine()); Value res; FunctionObject *getter = o->memberData[l->index].getter(); if (!getter) { res = Value::undefinedValue(); } else { - ScopedCallData callData(o->engine(), 0); + ScopedCallData callData(scope, 0); callData->thisObject = object; res = Value::fromReturnedValue(getter->call(callData)); } @@ -221,12 +222,13 @@ void Lookup::getterAccessor1(Lookup *l, Value *result, const Value &object) if (Object *o = object.asObject()) { if (l->classList[0] == o->internalClass && l->classList[1] == o->prototype()->internalClass) { + ValueScope scope(o->engine()); Value res; FunctionObject *getter = o->prototype()->memberData[l->index].getter(); if (!getter) { res = Value::undefinedValue(); } else { - ScopedCallData callData(o->engine(), 0); + ScopedCallData callData(scope, 0); callData->thisObject = object; res = Value::fromReturnedValue(getter->call(callData)); } @@ -247,12 +249,13 @@ void Lookup::getterAccessor2(Lookup *l, Value *result, const Value &object) if (l->classList[1] == o->internalClass) { o = o->prototype(); if (l->classList[2] == o->internalClass) { + ValueScope scope(o->engine()); Value res; FunctionObject *getter = o->memberData[l->index].getter(); if (!getter) { res = Value::undefinedValue(); } else { - ScopedCallData callData(o->engine(), 0); + ScopedCallData callData(scope, 0); callData->thisObject = object; res = Value::fromReturnedValue(getter->call(callData)); } @@ -302,12 +305,13 @@ void Lookup::primitiveGetterAccessor0(Lookup *l, Value *result, const Value &obj if (object.type() == l->type) { Object *o = l->proto; if (l->classList[0] == o->internalClass) { + ValueScope scope(o->engine()); Value res; FunctionObject *getter = o->memberData[l->index].getter(); if (!getter) { res = Value::undefinedValue(); } else { - ScopedCallData callData(o->engine(), 0); + ScopedCallData callData(scope, 0); callData->thisObject = object; res = Value::fromReturnedValue(getter->call(callData)); } @@ -326,12 +330,13 @@ void Lookup::primitiveGetterAccessor1(Lookup *l, Value *result, const Value &obj Object *o = l->proto; if (l->classList[0] == o->internalClass && l->classList[1] == o->prototype()->internalClass) { + ValueScope scope(o->engine()); Value res; FunctionObject *getter = o->prototype()->memberData[l->index].getter(); if (!getter) { res = Value::undefinedValue(); } else { - ScopedCallData callData(o->engine(), 0); + ScopedCallData callData(scope, 0); callData->thisObject = object; res = Value::fromReturnedValue(getter->call(callData)); } @@ -431,11 +436,12 @@ void Lookup::globalGetterAccessor0(Lookup *l, ExecutionContext *ctx, Value *resu { Object *o = ctx->engine->globalObject; if (l->classList[0] == o->internalClass) { + ValueScope scope(o->engine()); FunctionObject *getter = o->memberData[l->index].getter(); if (!getter) { *result = Value::undefinedValue(); } else { - ScopedCallData callData(ctx->engine, 0); + ScopedCallData callData(scope, 0); callData->thisObject = Value::undefinedValue(); *result = Value::fromReturnedValue(getter->call(callData)); } @@ -450,11 +456,12 @@ void Lookup::globalGetterAccessor1(Lookup *l, ExecutionContext *ctx, Value *resu Object *o = ctx->engine->globalObject; if (l->classList[0] == o->internalClass && l->classList[1] == o->prototype()->internalClass) { + ValueScope scope(o->engine()); FunctionObject *getter = o->prototype()->memberData[l->index].getter(); if (!getter) { *result = Value::undefinedValue(); } else { - ScopedCallData callData(ctx->engine, 0); + ScopedCallData callData(scope, 0); callData->thisObject = Value::undefinedValue(); *result = Value::fromReturnedValue(getter->call(callData)); } @@ -472,11 +479,12 @@ void Lookup::globalGetterAccessor2(Lookup *l, ExecutionContext *ctx, Value *resu if (l->classList[1] == o->internalClass) { o = o->prototype(); if (l->classList[2] == o->internalClass) { + ValueScope scope(o->engine()); FunctionObject *getter = o->memberData[l->index].getter(); if (!getter) { *result = Value::undefinedValue(); } else { - ScopedCallData callData(ctx->engine, 0); + ScopedCallData callData(scope, 0); callData->thisObject = Value::undefinedValue(); *result = Value::fromReturnedValue(getter->call(callData)); } diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 7236307278..288bf8b8d7 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -135,7 +135,8 @@ Value Object::getValue(const Value &thisObject, const Property *p, PropertyAttri if (!getter) return Value::undefinedValue(); - ScopedCallData callData(getter->engine(), 0); + ValueScope scope(getter->engine()); + ScopedCallData callData(scope, 0); callData->thisObject = thisObject; return Value::fromReturnedValue(getter->call(callData)); } @@ -144,7 +145,8 @@ void Object::putValue(Property *pd, PropertyAttributes attrs, const Value &value { if (attrs.isAccessor()) { if (pd->set) { - ScopedCallData callData(pd->set->engine(), 1); + ValueScope scope(pd->set->engine()); + ScopedCallData callData(scope, 1); callData->args[0] = value; callData->thisObject = Value::fromObject(this); pd->set->call(callData); @@ -774,7 +776,8 @@ void Object::internalPut(String *name, const Value &value) if (pd && attrs.isAccessor()) { assert(pd->setter() != 0); - ScopedCallData callData(engine(), 1); + ValueScope scope(engine()); + ScopedCallData callData(scope, 1); callData->args[0] = value; callData->thisObject = Value::fromObject(this); pd->setter()->call(callData); @@ -852,7 +855,8 @@ void Object::internalPutIndexed(uint index, const Value &value) if (pd && attrs.isAccessor()) { assert(pd->setter() != 0); - ScopedCallData callData(engine(), 1); + ValueScope scope(engine()); + ScopedCallData callData(scope, 1); callData->args[0] = value; callData->thisObject = Value::fromObject(this); pd->setter()->call(callData); diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp index 5dc4d333ce..8cab0d2d12 100644 --- a/src/qml/jsruntime/qv4objectproto.cpp +++ b/src/qml/jsruntime/qv4objectproto.cpp @@ -381,12 +381,13 @@ Value ObjectPrototype::method_toString(SimpleCallContext *ctx) Value ObjectPrototype::method_toLocaleString(SimpleCallContext *ctx) { + ValueScope scope(ctx); Object *o = ctx->thisObject.toObject(ctx); Value ts = o->get(ctx->engine->newString(QStringLiteral("toString"))); FunctionObject *f = ts.asFunctionObject(); if (!f) ctx->throwTypeError(); - ScopedCallData callData(ctx->engine, 0); + ScopedCallData callData(scope, 0); callData->thisObject = Value::fromObject(o); return Value::fromReturnedValue(f->call(callData)); } diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 0ccb37f48b..31fb5dc221 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -701,7 +701,8 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase QV4::ExecutionEngine *v4 = f->internalClass->engine; QV4::ExecutionContext *ctx = v4->current; - QV4::ScopedCallData callData(v4, argCount); + ValueScope scope(v4); + QV4::ScopedCallData callData(scope, argCount); callData->thisObject = This->thisObject.isEmpty() ? Value::fromObject(v4->globalObject) : This->thisObject.value(); for (int ii = 0; ii < argCount; ++ii) { int type = argsTypes[ii + 1]; diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp index 7497b3e1ba..1cee9ed67c 100644 --- a/src/qml/jsruntime/qv4regexpobject.cpp +++ b/src/qml/jsruntime/qv4regexpobject.cpp @@ -359,11 +359,12 @@ Value RegExpPrototype::method_toString(SimpleCallContext *ctx) Value RegExpPrototype::method_compile(SimpleCallContext *ctx) { + ValueScope scope(ctx); RegExpObject *r = ctx->thisObject.as<RegExpObject>(); if (!r) ctx->throwTypeError(); - ScopedCallData callData(ctx->engine, ctx->argumentCount); + ScopedCallData callData(scope, ctx->argumentCount); memcpy(callData->args, ctx->arguments, ctx->argumentCount*sizeof(Value)); RegExpObject *re = ctx->engine->regExpCtor.asFunctionObject()->construct(callData).as<RegExpObject>(); diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index a6fc9f8967..ad2ac19ea6 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -570,20 +570,19 @@ ReturnedValue __qmljs_object_default_value(Object *object, int typeHint) qSwap(meth1, meth2); ExecutionContext *ctx = engine->current; + ValueScope scope(ctx); + ScopedCallData callData(scope, 0); + callData->thisObject = Value::fromObject(object); - Value conv = object->get(meth1); - if (FunctionObject *o = conv.asFunctionObject()) { - ScopedCallData callData(engine, 0); - callData->thisObject = Value::fromObject(object); + ScopedValue conv(scope, object->get(meth1)); + if (FunctionObject *o = conv->asFunctionObject()) { Value r = Value::fromReturnedValue(o->call(callData)); if (r.isPrimitive()) return r.asReturnedValue(); } conv = object->get(meth2); - if (FunctionObject *o = conv.asFunctionObject()) { - ScopedCallData callData(engine, 0); - callData->thisObject = Value::fromObject(object); + if (FunctionObject *o = conv->asFunctionObject()) { Value r = Value::fromReturnedValue(o->call(callData)); if (r.isPrimitive()) return r.asReturnedValue(); @@ -698,6 +697,7 @@ ReturnedValue __qmljs_get_element(ExecutionContext *ctx, const ValueRef object, void __qmljs_set_element(ExecutionContext *ctx, const ValueRef object, const ValueRef index, const ValueRef value) { + ValueScope scope(ctx); Object *o = object->toObject(ctx); uint idx = index->asArrayIndex(); @@ -724,7 +724,7 @@ void __qmljs_set_element(ExecutionContext *ctx, const ValueRef object, const Val return; } - ScopedCallData callData(ctx->engine, 1); + ScopedCallData callData(scope, 1); callData->thisObject = Value::fromObject(o); callData->args[0] = *value; setter->call(callData); diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h index 427140b4bf..d1b4a93aa3 100644 --- a/src/qml/jsruntime/qv4scopedvalue_p.h +++ b/src/qml/jsruntime/qv4scopedvalue_p.h @@ -82,6 +82,9 @@ struct ScopedValue; struct ValueScope { ValueScope(ExecutionContext *ctx) : engine(ctx->engine) +#ifndef QT_NO_DEBUG + , size(0) +#endif { mark = ctx->engine->jsStackTop; } @@ -99,6 +102,9 @@ struct ValueScope { ExecutionEngine *engine; Value *mark; +#ifndef QT_NO_DEBUG + mutable int size; +#endif }; struct ScopedValue; @@ -109,18 +115,27 @@ struct ScopedValue ScopedValue(const ValueScope &scope) { ptr = scope.engine->jsStackTop++; +#ifndef QT_NO_DEBUG + ++scope.size; +#endif } ScopedValue(const ValueScope &scope, const Value &v) { ptr = scope.engine->jsStackTop++; *ptr = v; +#ifndef QT_NO_DEBUG + ++scope.size; +#endif } ScopedValue(const ValueScope &scope, const ReturnedValue &v) { ptr = scope.engine->jsStackTop++; ptr->val = v; +#ifndef QT_NO_DEBUG + ++scope.size; +#endif } ScopedValue &operator=(const Value &v) { @@ -156,24 +171,14 @@ struct ScopedValue }; struct ScopedCallData { - ScopedCallData(ExecutionEngine *e, int argc) - : engine(e) - // ### this check currently won't work because of exceptions -#ifndef QT_NO_DEBUG - , size(qMax(argc, (int)QV4::Global::ReservedArgumentCount) + offsetof(QV4::CallData, args)/sizeof(QV4::Value)) -#endif + ScopedCallData(ValueScope &scope, int argc) { - ptr = reinterpret_cast<CallData *>(e->stackPush(qMax(argc, (int)QV4::Global::ReservedArgumentCount) + offsetof(QV4::CallData, args)/sizeof(QV4::Value))); + int size = qMax(argc, (int)QV4::Global::ReservedArgumentCount) + offsetof(QV4::CallData, args)/sizeof(QV4::Value); + ptr = reinterpret_cast<CallData *>(scope.engine->stackPush(size)); ptr->tag = 0; ptr->argc = argc; - } - - ~ScopedCallData() { #ifndef QT_NO_DEBUG - engine->stackPop(size); - Q_ASSERT((void *)engine->jsStackTop == (void *)ptr); -#else - engine->jsStackTop = reinterpret_cast<Value *>(ptr); + scope.size += size; #endif } @@ -185,11 +190,6 @@ struct ScopedCallData { return ptr; } - - ExecutionEngine *engine; -#ifndef QT_NO_DEBUG - int size; -#endif CallData *ptr; }; diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index 57938ff5b7..dd5a3e8a4f 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -250,7 +250,7 @@ Value Script::run() } else { FunctionObject *f = new (engine->memoryManager) QmlBindingWrapper(scope, vmFunction, qml.value().asObject()); - ScopedCallData callData(scope->engine, 0); + ScopedCallData callData(valueScope, 0); callData->thisObject = Value::undefinedValue(); return Value::fromReturnedValue(f->call(callData)); } diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp index 529c395c26..d4d403de08 100644 --- a/src/qml/jsruntime/qv4sequenceobject.cpp +++ b/src/qml/jsruntime/qv4sequenceobject.cpp @@ -355,7 +355,7 @@ public: { QV4::Managed *fun = this->m_compareFn.asManaged(); ValueScope scope(fun->engine()); - ScopedCallData callData(fun->engine(), 2); + ScopedCallData callData(scope, 2); callData->args[0] = convertElementToValue(this->m_ctx->engine, lhs); callData->args[1] = convertElementToValue(this->m_ctx->engine, rhs); callData->thisObject = QV4::Value::fromObject(this->m_ctx->engine->globalObject); diff --git a/src/qml/jsruntime/qv4sparsearray.cpp b/src/qml/jsruntime/qv4sparsearray.cpp index 4a3cf9ebce..dee0d926b4 100644 --- a/src/qml/jsruntime/qv4sparsearray.cpp +++ b/src/qml/jsruntime/qv4sparsearray.cpp @@ -63,7 +63,7 @@ bool ArrayElementLessThan::operator()(const Property &p1, const Property &p2) co if (Object *o = m_comparefn.asObject()) { ValueScope scope(o->engine()); ScopedValue result(scope); - ScopedCallData callData(o->engine(), 2); + ScopedCallData callData(scope, 2); callData->thisObject = Value::undefinedValue(); callData->args[0] = p1.value; callData->args[1] = p2.value; diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp index b66ee6c180..d3a5f68aeb 100644 --- a/src/qml/jsruntime/qv4stringobject.cpp +++ b/src/qml/jsruntime/qv4stringobject.cpp @@ -357,7 +357,7 @@ Value StringPrototype::method_match(SimpleCallContext *context) Value regexp = context->argumentCount ? context->arguments[0] : Value::undefinedValue(); RegExpObject *rx = regexp.as<RegExpObject>(); if (!rx) { - ScopedCallData callData(context->engine, 1); + ScopedCallData callData(scope, 1); callData->args[0] = regexp; rx = context->engine->regExpCtor.asFunctionObject()->construct(callData).as<RegExpObject>(); } @@ -371,7 +371,7 @@ Value StringPrototype::method_match(SimpleCallContext *context) // ### 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(); - ScopedCallData callData(context->engine, 1); + ScopedCallData callData(scope, 1); callData->thisObject = Value::fromObject(rx); callData->args[0] = Value::fromString(s); if (!global) @@ -514,7 +514,7 @@ Value StringPrototype::method_replace(SimpleCallContext *ctx) ScopedValue replacement(scope); if (FunctionObject* searchCallback = replaceValue.asFunctionObject()) { result.reserve(string.length() + 10*numStringMatches); - ScopedCallData callData(ctx->engine, numCaptures + 2); + ScopedCallData callData(scope, numCaptures + 2); callData->thisObject = Value::undefinedValue(); int lastEnd = 0; for (int i = 0; i < numStringMatches; ++i) { @@ -566,6 +566,7 @@ Value StringPrototype::method_replace(SimpleCallContext *ctx) Value StringPrototype::method_search(SimpleCallContext *ctx) { + ValueScope scope(ctx); QString string; if (StringObject *thisString = ctx->thisObject.asStringObject()) string = thisString->value.stringValue()->toQString(); @@ -575,7 +576,7 @@ Value StringPrototype::method_search(SimpleCallContext *ctx) Value regExpValue = ctx->argument(0); RegExpObject *regExp = regExpValue.as<RegExpObject>(); if (!regExp) { - ScopedCallData callData(ctx->engine, 1); + ScopedCallData callData(scope, 1); callData->args[0] = regExpValue; regExpValue = ctx->engine->regExpCtor.asFunctionObject()->construct(callData); regExp = regExpValue.as<RegExpObject>(); diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index a1399b4f43..2c9195a0ef 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -1207,6 +1207,7 @@ void QQmlComponent::createObject(QQmlV4Function *args) QV8Engine *v8engine = args->engine(); QV4::ExecutionEngine *v4engine = QV8Engine::getV4(v8engine); + QV4::ValueScope scope(v4engine); QQmlContext *ctxt = creationContext(); if (!ctxt) ctxt = d->engine->rootContext(); @@ -1226,7 +1227,7 @@ void QQmlComponent::createObject(QQmlV4Function *args) if (!valuemap.isEmpty()) { QQmlComponentExtension *e = componentExtension(v8engine); QV4::Value f = QV4::Script::evaluate(v4engine, QString::fromLatin1(INITIALPROPERTIES_SOURCE), args->qmlGlobal().asObject()); - QV4::ScopedCallData callData(v4engine, 2); + QV4::ScopedCallData callData(scope, 2); callData->thisObject = QV4::Value::fromObject(v4engine->globalObject); callData->args[0] = object; callData->args[1] = valuemap; @@ -1366,6 +1367,7 @@ void QQmlComponentPrivate::initializeObjectWithInitialProperties(const QV4::Valu QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine); QV8Engine *v8engine = ep->v8engine(); QV4::ExecutionEngine *v4engine = QV8Engine::getV4(v8engine); + QV4::ValueScope scope(v4engine); QV4::Value object = QV4::QObjectWrapper::wrap(v4engine, toCreate); Q_ASSERT(object.asObject()); @@ -1373,7 +1375,7 @@ void QQmlComponentPrivate::initializeObjectWithInitialProperties(const QV4::Valu if (!valuemap.isEmpty()) { QQmlComponentExtension *e = componentExtension(v8engine); QV4::Value f = QV4::Script::evaluate(QV8Engine::getV4(v8engine), QString::fromLatin1(INITIALPROPERTIES_SOURCE), qmlGlobal.asObject()); - QV4::ScopedCallData callData(v4engine, 2); + QV4::ScopedCallData callData(scope, 2); callData->thisObject = QV4::Value::fromObject(v4engine->globalObject); callData->args[0] = object; callData->args[1] = valuemap; @@ -1470,9 +1472,10 @@ void QmlIncubatorObject::setInitialState(QObject *o) QQmlComponentExtension *e = componentExtension(v8); QV4::ExecutionEngine *v4 = QV8Engine::getV4(v8); + QV4::ValueScope scope(v4); QV4::Value f = QV4::Script::evaluate(v4, QString::fromLatin1(INITIALPROPERTIES_SOURCE), qmlGlobal.asObject()); - QV4::ScopedCallData callData(v4, 2); + QV4::ScopedCallData callData(scope, 2); callData->thisObject = QV4::Value::fromObject(v4->globalObject); callData->args[0] = QV4::QObjectWrapper::wrap(v4, o); callData->args[1] = valuemap; @@ -1508,8 +1511,9 @@ void QmlIncubatorObject::statusChanged(Status s) if (QV4::FunctionObject *f = callback.asFunctionObject()) { QV4::ExecutionContext *ctx = f->engine()->current; + QV4::ValueScope scope(ctx); try { - QV4::ScopedCallData callData(ctx->engine, 1); + QV4::ScopedCallData callData(scope, 1); callData->thisObject = QV4::Value::fromObject(this); callData->args[0] = QV4::Value::fromUInt32(s); f->call(callData); diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp index 7e726ab96e..37cbba0f02 100644 --- a/src/qml/qml/qqmljavascriptexpression.cpp +++ b/src/qml/qml/qqmljavascriptexpression.cpp @@ -174,7 +174,7 @@ QQmlJavaScriptExpression::evaluate(QQmlContextData *context, This = value; } - QV4::ScopedCallData callData(v4, argc); + QV4::ScopedCallData callData(scope, argc); callData->thisObject = This; memcpy(callData->args, args, argc*sizeof(QV4::Value)); result = function.asFunctionObject()->call(callData); diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index 7ac218772b..bf74ff6452 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -928,7 +928,7 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) QQmlVMEMetaData::MethodData *data = metaData->methodData() + id; QV4::ValueScope scope(function->engine()); - QV4::ScopedCallData callData(function->engine(), data->parameterCount); + QV4::ScopedCallData callData(scope, data->parameterCount); callData->thisObject = ep->v8engine()->global(); for (int ii = 0; ii < data->parameterCount; ++ii) diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index fc3c32fd88..19619400f7 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -1461,6 +1461,7 @@ const QByteArray &QQmlXMLHttpRequest::rawResponseBody() const void QQmlXMLHttpRequest::dispatchCallback(const Value &me) { ExecutionContext *ctx = v4->current; + QV4::ValueScope scope(v4); try { Object *o = me.asObject(); if (!o) @@ -1482,7 +1483,7 @@ void QQmlXMLHttpRequest::dispatchCallback(const Value &me) QQmlContextData *callingContext = QmlContextWrapper::getContext(activationObject); if (callingContext) { - QV4::ScopedCallData callData(v4, 0); + QV4::ScopedCallData callData(scope, 0); callData->thisObject = activationObject; callback->call(callData); } diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp index 57adeb98af..b82d58ba0b 100644 --- a/src/qml/qml/v8/qv8engine.cpp +++ b/src/qml/qml/v8/qv8engine.cpp @@ -443,7 +443,8 @@ void QV8Engine::initializeGlobal() void QV8Engine::freezeObject(const QV4::Value &value) { - QV4::ScopedCallData callData(m_v4Engine, 1); + QV4::ValueScope scope(m_v4Engine); + QV4::ScopedCallData callData(scope, 1); callData->args[0] = value; callData->thisObject = QV4::Value::fromObject(m_v4Engine->globalObject); m_freezeObject.value().asFunctionObject()->call(callData); diff --git a/src/qml/types/qquickworkerscript.cpp b/src/qml/types/qquickworkerscript.cpp index 42548e6ad6..481bc110e8 100644 --- a/src/qml/types/qquickworkerscript.cpp +++ b/src/qml/types/qquickworkerscript.cpp @@ -228,13 +228,14 @@ void QQuickWorkerScriptEnginePrivate::WorkerEngine::init() "}); "\ "})" + QV4::ValueScope scope(m_v4Engine); onmessage = QV4::Script(m_v4Engine->rootContext, CALL_ONMESSAGE_SCRIPT).run(); QV4::Script createsendscript(m_v4Engine->rootContext, SEND_MESSAGE_CREATE_SCRIPT); QV4::FunctionObject *createsendconstructor = createsendscript.run().asFunctionObject(); QV4::Value function = QV4::Value::fromObject(m_v4Engine->newBuiltinFunction(m_v4Engine->rootContext, m_v4Engine->newString(QStringLiteral("sendMessage")), QQuickWorkerScriptEnginePrivate::sendMessage)); - QV4::ScopedCallData callData(m_v4Engine, 1); + QV4::ScopedCallData callData(scope, 1); callData->args[0] = function; callData->thisObject = global(); createsend = createsendconstructor->call(callData); @@ -249,7 +250,7 @@ QV4::Value QQuickWorkerScriptEnginePrivate::WorkerEngine::sendFunction(int id) QV4::ScopedValue v(scope); try { - QV4::ScopedCallData callData(m_v4Engine, 1); + QV4::ScopedCallData callData(scope, 1); callData->args[0] = QV4::Value::fromInt32(id); callData->thisObject = global(); v = f->call(callData); @@ -355,7 +356,7 @@ void QQuickWorkerScriptEnginePrivate::processMessage(int id, const QByteArray &d QV4::ScopedValue value(scope, QV4::Serialize::deserialize(data, workerEngine)); try { - QV4::ScopedCallData callData(ctx->engine, 2); + QV4::ScopedCallData callData(scope, 2); callData->thisObject = workerEngine->global(); callData->args[0] = script->object.value(); callData->args[1] = value; diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp index 60cb3ace3e..f38328da6d 100644 --- a/src/quick/items/context2d/qquickcanvasitem.cpp +++ b/src/quick/items/context2d/qquickcanvasitem.cpp @@ -660,12 +660,13 @@ void QQuickCanvasItem::updatePolish() QMap<int, QV4::PersistentValue> animationCallbacks = d->animationCallbacks; d->animationCallbacks.clear(); + QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(qmlEngine(this)); + QV4::ValueScope scope(v4); + QV4::ScopedCallData callData(scope, 1); + callData->thisObject = QV4::QObjectWrapper::wrap(v4, this); + foreach (int key, animationCallbacks.keys()) { - QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(qmlEngine(this)); QV4::FunctionObject *f = animationCallbacks.value(key).value().asFunctionObject(); - - QV4::ScopedCallData callData(v4, 1); - callData->thisObject = QV4::QObjectWrapper::wrap(v4, this); callData->args[0] = QV4::Value::fromUInt32(QDateTime::currentDateTimeUtc().toTime_t()); f->call(callData); } diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 260afa2185..caff36cf0d 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -2273,7 +2273,8 @@ static inline bool evaluate_error(QV8Engine *engine, const QV4::Value &o, const QV4::FunctionObject *function = program.run().asFunctionObject(); if (!function) return false; - QV4::ScopedCallData d(ctx->engine, 1); + QV4::ValueScope scope(ctx); + QV4::ScopedCallData d(scope, 1); d->args[0] = o; d->thisObject = engine->global(); function->call(d); @@ -2301,7 +2302,7 @@ static inline bool evaluate_value(QV8Engine *engine, const QV4::Value &o, QV4::ValueScope scope(ctx); QV4::ScopedValue value(scope); QV4::ScopedValue res(scope, result); - QV4::ScopedCallData d(ctx->engine, 1); + QV4::ScopedCallData d(scope, 1); d->args[0] = o; d->thisObject = engine->global(); value = function->call(d); @@ -2326,7 +2327,7 @@ static inline QV4::Value evaluate(QV8Engine *engine, const QV4::Value & o, if (!function) return QV4::Value::emptyValue(); QV4::ValueScope scope(ctx); - QV4::ScopedCallData d(ctx->engine, 1); + QV4::ScopedCallData d(scope, 1); d->args[0] = o; d->thisObject = engine->global(); QV4::ScopedValue value(scope, function->call(d)); |