aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-09-01 11:48:15 +0200
committerLars Knoll <lars.knoll@qt.io>2017-09-02 07:12:17 +0000
commit74c8fe86755af485f8d0a47799d6d50f00070f05 (patch)
tree9e3d8c51d46d9f0fa2555cc77d184d6b3ee1be7d /src
parenta91383545c6f487cff61f401d11f1e85939222e9 (diff)
Always set the correct FunctionObject when calling JS functions
Renamed ScopedCallData to JSCall, enforced passing a JS FunctionObject to it, and added call() and callAsConstructor() methods to it. Change-Id: I30db65c9765c2896b5909fe2105c0934c6dad861 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/imports/localstorage/plugin.cpp24
-rw-r--r--src/qml/jsapi/qjsvalue.cpp22
-rw-r--r--src/qml/jsruntime/qv4argumentsobject.cpp8
-rw-r--r--src/qml/jsruntime/qv4arraybuffer.cpp6
-rw-r--r--src/qml/jsruntime/qv4arraydata.cpp15
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp130
-rw-r--r--src/qml/jsruntime/qv4dateobject.cpp6
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp53
-rw-r--r--src/qml/jsruntime/qv4globalobject.cpp16
-rw-r--r--src/qml/jsruntime/qv4include.cpp8
-rw-r--r--src/qml/jsruntime/qv4jscall_p.h19
-rw-r--r--src/qml/jsruntime/qv4jsonobject.cpp18
-rw-r--r--src/qml/jsruntime/qv4lookup.cpp45
-rw-r--r--src/qml/jsruntime/qv4object.cpp34
-rw-r--r--src/qml/jsruntime/qv4objectproto.cpp6
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp10
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp6
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp10
-rw-r--r--src/qml/jsruntime/qv4script.cpp16
-rw-r--r--src/qml/jsruntime/qv4sequenceobject.cpp14
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp34
-rw-r--r--src/qml/jsruntime/qv4typedarray.cpp10
-rw-r--r--src/qml/qml/qqmlboundsignal.cpp28
-rw-r--r--src/qml/qml/qqmlcomponent.cpp8
-rw-r--r--src/qml/qml/qqmldelayedcallqueue.cpp12
-rw-r--r--src/qml/qml/qqmljavascriptexpression.cpp4
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp9
-rw-r--r--src/qml/qml/qqmlxmlhttprequest.cpp4
-rw-r--r--src/qml/types/qquickworkerscript.cpp26
-rw-r--r--src/quick/items/context2d/qquickcanvasitem.cpp10
30 files changed, 308 insertions, 303 deletions
diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp
index 5f3cfc43c4..795103cd26 100644
--- a/src/imports/localstorage/plugin.cpp
+++ b/src/imports/localstorage/plugin.cpp
@@ -414,12 +414,12 @@ static ReturnedValue qmlsqldatabase_changeVersion(const QV4::BuiltinFunction *b,
ok = false;
db.transaction();
- ScopedCallData callData(scope, 1);
- callData->thisObject = scope.engine->globalObject;
- callData->args[0] = w;
+ JSCall jsCall(scope, callback, 1);
+ jsCall->thisObject = scope.engine->globalObject;
+ jsCall->args[0] = w;
TransactionRollback rollbackOnException(&db, &w->d()->inTransaction);
- callback->call(callData);
+ jsCall.call();
rollbackOnException.clear();
if (!db.commit()) {
db.rollback();
@@ -464,11 +464,11 @@ static ReturnedValue qmlsqldatabase_transaction_shared(const QV4::BuiltinFunctio
db.transaction();
if (callback) {
- ScopedCallData callData(scope, 1);
- callData->thisObject = scope.engine->globalObject;
- callData->args[0] = w;
+ JSCall jsCall(scope, callback, 1);
+ jsCall->thisObject = scope.engine->globalObject;
+ jsCall->args[0] = w;
TransactionRollback rollbackOnException(&db, &w->d()->inTransaction);
- callback->call(callData);
+ jsCall.call();
rollbackOnException.clear();
if (!db.commit())
@@ -763,10 +763,10 @@ void QQuickLocalStorage::openDatabaseSync(QQmlV4Function *args)
*db->d()->version = version;
if (created && dbcreationCallback) {
- ScopedCallData callData(scope, 1);
- callData->thisObject = scope.engine->globalObject;
- callData->args[0] = db;
- dbcreationCallback->call(callData);
+ JSCall jsCall(scope, dbcreationCallback, 1);
+ jsCall->thisObject = scope.engine->globalObject;
+ jsCall->args[0] = db;
+ jsCall.call();
}
args->setReturnValue(db.asReturnedValue());
diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp
index 3e2d0ccef0..afd2b1560f 100644
--- a/src/qml/jsapi/qjsvalue.cpp
+++ b/src/qml/jsapi/qjsvalue.cpp
@@ -657,17 +657,17 @@ QJSValue QJSValue::call(const QJSValueList &args)
Q_ASSERT(engine);
Scope scope(engine);
- ScopedCallData callData(scope, f, args.length());
- callData->thisObject = engine->globalObject;
+ JSCall jsCall(scope, f, args.length());
+ jsCall->thisObject = engine->globalObject;
for (int i = 0; i < args.size(); ++i) {
if (!QJSValuePrivate::checkEngine(engine, args.at(i))) {
qWarning("QJSValue::call() failed: cannot call function with argument created in a different engine");
return QJSValue();
}
- callData->args[i] = QJSValuePrivate::convertedToValue(engine, args.at(i));
+ jsCall->args[i] = QJSValuePrivate::convertedToValue(engine, args.at(i));
}
- ScopedValue result(scope, callData.call());
+ ScopedValue result(scope, jsCall.call());
if (engine->hasException)
result = engine->catchException();
@@ -713,17 +713,17 @@ QJSValue QJSValue::callWithInstance(const QJSValue &instance, const QJSValueList
return QJSValue();
}
- ScopedCallData callData(scope, args.size());
- callData->thisObject = QJSValuePrivate::convertedToValue(engine, instance);
+ JSCall jsCall(scope, f, args.size());
+ jsCall->thisObject = QJSValuePrivate::convertedToValue(engine, instance);
for (int i = 0; i < args.size(); ++i) {
if (!QJSValuePrivate::checkEngine(engine, args.at(i))) {
qWarning("QJSValue::call() failed: cannot call function with argument created in a different engine");
return QJSValue();
}
- callData->args[i] = QJSValuePrivate::convertedToValue(engine, args.at(i));
+ jsCall->args[i] = QJSValuePrivate::convertedToValue(engine, args.at(i));
}
- ScopedValue result(scope, f->call(callData));
+ ScopedValue result(scope, jsCall.call());
if (engine->hasException)
result = engine->catchException();
@@ -762,16 +762,16 @@ QJSValue QJSValue::callAsConstructor(const QJSValueList &args)
Q_ASSERT(engine);
Scope scope(engine);
- ScopedCallData callData(scope, args.size());
+ JSCall jsCall(scope, f, args.size());
for (int i = 0; i < args.size(); ++i) {
if (!QJSValuePrivate::checkEngine(engine, args.at(i))) {
qWarning("QJSValue::callAsConstructor() failed: cannot construct function with argument created in a different engine");
return QJSValue();
}
- callData->args[i] = QJSValuePrivate::convertedToValue(engine, args.at(i));
+ jsCall->args[i] = QJSValuePrivate::convertedToValue(engine, args.at(i));
}
- ScopedValue result(scope, f->construct(callData));
+ ScopedValue result(scope, jsCall.callAsConstructor());
if (engine->hasException)
result = engine->catchException();
diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp
index b90a186551..1a60725d27 100644
--- a/src/qml/jsruntime/qv4argumentsobject.cpp
+++ b/src/qml/jsruntime/qv4argumentsobject.cpp
@@ -139,10 +139,10 @@ bool ArgumentsObject::defineOwnProperty(ExecutionEngine *engine, uint index, con
if (isMapped && attrs.isData()) {
Q_ASSERT(arrayData());
ScopedFunctionObject setter(scope, map->setter());
- ScopedCallData callData(scope, setter, 1);
- callData->thisObject = this->asReturnedValue();
- callData->args[0] = desc->value;
- callData.call();
+ JSCall jsCall(scope, setter, 1);
+ jsCall->thisObject = this->asReturnedValue();
+ jsCall->args[0] = desc->value;
+ jsCall.call();
if (attrs.isWritable()) {
setArrayAttributes(index, mapAttrs);
diff --git a/src/qml/jsruntime/qv4arraybuffer.cpp b/src/qml/jsruntime/qv4arraybuffer.cpp
index 33ef7fa6df..bd47d0bc77 100644
--- a/src/qml/jsruntime/qv4arraybuffer.cpp
+++ b/src/qml/jsruntime/qv4arraybuffer.cpp
@@ -187,10 +187,10 @@ ReturnedValue ArrayBufferPrototype::method_slice(const BuiltinFunction *b, CallD
if (!constructor)
return v4->throwTypeError();
- ScopedCallData cData(scope, 1);
+ JSCall jsCall(scope, constructor, 1);
double newLen = qMax(final - first, 0.);
- cData->args[0] = QV4::Encode(newLen);
- QV4::Scoped<ArrayBuffer> newBuffer(scope, constructor->construct(cData));
+ jsCall->args[0] = QV4::Encode(newLen);
+ QV4::Scoped<ArrayBuffer> newBuffer(scope, jsCall.callAsConstructor());
if (!newBuffer || newBuffer->d()->data->size < (int)newLen)
return v4->throwTypeError();
diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp
index fe9736ea9b..55b6370b42 100644
--- a/src/qml/jsruntime/qv4arraydata.cpp
+++ b/src/qml/jsruntime/qv4arraydata.cpp
@@ -673,15 +673,14 @@ bool ArrayElementLessThan::operator()(Value v1, Value v2) const
return false;
if (v2.isUndefined() || v2.isEmpty())
return true;
- ScopedObject o(scope, m_comparefn);
+ ScopedFunctionObject o(scope, m_comparefn);
if (o) {
Scope scope(o->engine());
ScopedValue result(scope);
- ScopedCallData callData(scope, 2);
- callData->thisObject = Primitive::undefinedValue();
- callData->args[0] = v1;
- callData->args[1] = v2;
- result = QV4::Runtime::method_callValue(scope.engine, m_comparefn, callData);
+ JSCall jsCall(scope, o, 2);
+ jsCall->args[0] = v1;
+ jsCall->args[1] = v2;
+ result = jsCall.call();
return result->toNumber() < 0;
}
@@ -755,7 +754,7 @@ void ArrayData::sort(ExecutionEngine *engine, Object *thisObject, const Value &c
if (!arrayData || !arrayData->length())
return;
- if (!(comparefn.isUndefined() || comparefn.as<Object>())) {
+ if (!comparefn.isUndefined() && !comparefn.isFunctionObject()) {
engine->throwTypeError();
return;
}
@@ -834,7 +833,7 @@ void ArrayData::sort(ExecutionEngine *engine, Object *thisObject, const Value &c
}
- ArrayElementLessThan lessThan(engine, thisObject, comparefn);
+ ArrayElementLessThan lessThan(engine, thisObject, static_cast<const FunctionObject &>(comparefn));
Value *begin = thisObject->arrayData()->values.values;
sortHelper(begin, begin + len, *begin, lessThan);
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp
index f7486471ee..7796da5c70 100644
--- a/src/qml/jsruntime/qv4arrayobject.cpp
+++ b/src/qml/jsruntime/qv4arrayobject.cpp
@@ -126,16 +126,17 @@ ReturnedValue ArrayPrototype::method_isArray(const BuiltinFunction *, CallData *
ReturnedValue ArrayPrototype::method_toString(const BuiltinFunction *builtin, CallData *callData)
{
- Scope scope(builtin);
- ScopedObject o(scope, callData->thisObject, ScopedObject::Convert);
- CHECK_EXCEPTION();
- ScopedString s(scope, scope.engine->newString(QStringLiteral("join")));
- ScopedFunctionObject f(scope, o->get(s));
- if (!!f) {
- ScopedCallData d(scope, 0);
- d->thisObject = callData->thisObject;
- return f->call(d);
+ ExecutionEngine *v4 = builtin->engine();
+ if (!callData->thisObject.isObject()) {
+ callData->thisObject = callData->thisObject.toObject(v4);
+ if (v4->hasException)
+ return QV4::Encode::undefined();
}
+
+ callData->accumulator = v4->newString(QStringLiteral("join"));
+ callData->function = static_cast<Object &>(callData->thisObject).get(static_cast<String *>(&callData->accumulator));
+ if (callData->function.isFunctionObject())
+ return static_cast<FunctionObject &>(callData->function).call(callData);
return ObjectPrototype::method_toString(builtin, callData);
}
@@ -197,8 +198,8 @@ ReturnedValue ArrayPrototype::method_find(const BuiltinFunction *b, CallData *ca
if (!callback)
THROW_TYPE_ERROR();
- ScopedCallData cData(scope, 3);
- cData->thisObject = callData->argument(1);
+ JSCall jsCall(scope, callback, 3);
+ jsCall->thisObject = callData->argument(1);
ScopedValue v(scope);
ScopedValue result(scope);
@@ -207,10 +208,10 @@ ReturnedValue ArrayPrototype::method_find(const BuiltinFunction *b, CallData *ca
v = instance->getIndexed(k);
CHECK_EXCEPTION();
- cData->args[0] = v;
- cData->args[1] = Primitive::fromDouble(k);
- cData->args[2] = instance;
- result = callback->call(cData);
+ jsCall->args[0] = v;
+ jsCall->args[1] = Primitive::fromDouble(k);
+ jsCall->args[2] = instance;
+ result = jsCall.call();
CHECK_EXCEPTION();
if (result->toBoolean())
@@ -233,8 +234,8 @@ ReturnedValue ArrayPrototype::method_findIndex(const BuiltinFunction *b, CallDat
if (!callback)
THROW_TYPE_ERROR();
- ScopedCallData cData(scope, 3);
- cData->thisObject = callData->argument(1);
+ JSCall jsCall(scope, callback, 3);
+ jsCall->thisObject = callData->argument(1);
ScopedValue v(scope);
ScopedValue result(scope);
@@ -243,10 +244,10 @@ ReturnedValue ArrayPrototype::method_findIndex(const BuiltinFunction *b, CallDat
v = instance->getIndexed(k);
CHECK_EXCEPTION();
- cData->args[0] = v;
- cData->args[1] = Primitive::fromDouble(k);
- cData->args[2] = instance;
- result = callback->call(cData);
+ jsCall->args[0] = v;
+ jsCall->args[1] = Primitive::fromDouble(k);
+ jsCall->args[2] = instance;
+ result = jsCall.call();
CHECK_EXCEPTION();
if (result->toBoolean())
@@ -789,8 +790,8 @@ ReturnedValue ArrayPrototype::method_every(const BuiltinFunction *b, CallData *c
if (!callback)
THROW_TYPE_ERROR();
- ScopedCallData cData(scope, 3);
- cData->thisObject = callData->argument(1);
+ JSCall jsCall(scope, callback, 3);
+ jsCall->thisObject = callData->argument(1);
ScopedValue r(scope);
ScopedValue v(scope);
@@ -801,10 +802,10 @@ ReturnedValue ArrayPrototype::method_every(const BuiltinFunction *b, CallData *c
if (!exists)
continue;
- cData->args[0] = v;
- cData->args[1] = Primitive::fromDouble(k);
- cData->args[2] = instance;
- r = callback->call(cData);
+ jsCall->args[0] = v;
+ jsCall->args[1] = Primitive::fromDouble(k);
+ jsCall->args[2] = instance;
+ r = jsCall.call();
ok = r->toBoolean();
}
return Encode(ok);
@@ -823,8 +824,8 @@ ReturnedValue ArrayPrototype::method_some(const BuiltinFunction *b, CallData *ca
if (!callback)
THROW_TYPE_ERROR();
- ScopedCallData cData(scope, 3);
- cData->thisObject = callData->argument(1);
+ JSCall jsCall(scope, callback, 3);
+ jsCall->thisObject = callData->argument(1);
ScopedValue v(scope);
ScopedValue result(scope);
@@ -834,10 +835,10 @@ ReturnedValue ArrayPrototype::method_some(const BuiltinFunction *b, CallData *ca
if (!exists)
continue;
- cData->args[0] = v;
- cData->args[1] = Primitive::fromDouble(k);
- cData->args[2] = instance;
- result = callback->call(cData);
+ jsCall->args[0] = v;
+ jsCall->args[1] = Primitive::fromDouble(k);
+ jsCall->args[2] = instance;
+ result = jsCall.call();
if (result->toBoolean())
return Encode(true);
}
@@ -857,8 +858,8 @@ ReturnedValue ArrayPrototype::method_forEach(const BuiltinFunction *b, CallData
if (!callback)
THROW_TYPE_ERROR();
- ScopedCallData cData(scope, 3);
- cData->thisObject = callData->argument(1);
+ JSCall jsCall(scope, callback, 3);
+ jsCall->thisObject = callData->argument(1);
ScopedValue v(scope);
for (uint k = 0; k < len; ++k) {
@@ -867,10 +868,10 @@ ReturnedValue ArrayPrototype::method_forEach(const BuiltinFunction *b, CallData
if (!exists)
continue;
- cData->args[0] = v;
- cData->args[1] = Primitive::fromDouble(k);
- cData->args[2] = instance;
- callback->call(cData);
+ jsCall->args[0] = v;
+ jsCall->args[1] = Primitive::fromDouble(k);
+ jsCall->args[2] = instance;
+ jsCall.call();
}
RETURN_UNDEFINED();
}
@@ -893,8 +894,8 @@ ReturnedValue ArrayPrototype::method_map(const BuiltinFunction *b, CallData *cal
a->setArrayLengthUnchecked(len);
ScopedValue mapped(scope);
- ScopedCallData cData(scope, 3);
- cData->thisObject = callData->argument(1);
+ JSCall jsCall(scope, callback, 3);
+ jsCall->thisObject = callData->argument(1);
ScopedValue v(scope);
for (uint k = 0; k < len; ++k) {
@@ -903,10 +904,10 @@ ReturnedValue ArrayPrototype::method_map(const BuiltinFunction *b, CallData *cal
if (!exists)
continue;
- cData->args[0] = v;
- cData->args[1] = Primitive::fromDouble(k);
- cData->args[2] = instance;
- mapped = callback->call(cData);
+ jsCall->args[0] = v;
+ jsCall->args[1] = Primitive::fromDouble(k);
+ jsCall->args[2] = instance;
+ mapped = jsCall.call();
a->arraySet(k, mapped);
}
return a.asReturnedValue();
@@ -930,8 +931,8 @@ ReturnedValue ArrayPrototype::method_filter(const BuiltinFunction *b, CallData *
ScopedValue selected(scope);
ScopedValue v(scope);
- ScopedCallData cData(scope, 3);
- cData->thisObject = callData->argument(1);
+ JSCall jsCall(scope, callback, 3);
+ jsCall->thisObject = callData->argument(1);
uint to = 0;
for (uint k = 0; k < len; ++k) {
@@ -940,10 +941,10 @@ ReturnedValue ArrayPrototype::method_filter(const BuiltinFunction *b, CallData *
if (!exists)
continue;
- cData->args[0] = v;
- cData->args[1] = Primitive::fromDouble(k);
- cData->args[2] = instance;
- selected = callback->call(cData);
+ jsCall->args[0] = v;
+ jsCall->args[1] = Primitive::fromDouble(k);
+ jsCall->args[2] = instance;
+ selected = jsCall.call();
if (selected->toBoolean()) {
a->arraySet(to, v);
++to;
@@ -983,18 +984,17 @@ ReturnedValue ArrayPrototype::method_reduce(const BuiltinFunction *b, CallData *
THROW_TYPE_ERROR();
}
- ScopedCallData cData(scope, 4);
- cData->thisObject = Primitive::undefinedValue();
+ JSCall jsCall(scope, callback, 4);
while (k < len) {
bool kPresent;
v = instance->getIndexed(k, &kPresent);
if (kPresent) {
- cData->args[0] = acc;
- cData->args[1] = v;
- cData->args[2] = Primitive::fromDouble(k);
- cData->args[3] = instance;
- acc = callback->call(cData);
+ jsCall->args[0] = acc;
+ jsCall->args[1] = v;
+ jsCall->args[2] = Primitive::fromDouble(k);
+ jsCall->args[3] = instance;
+ acc = jsCall.call();
}
++k;
}
@@ -1037,18 +1037,18 @@ ReturnedValue ArrayPrototype::method_reduceRight(const BuiltinFunction *b, CallD
THROW_TYPE_ERROR();
}
- ScopedCallData cData(scope, 4);
- cData->thisObject = Primitive::undefinedValue();
+ JSCall jsCall(scope, callback, 4);
+ jsCall->thisObject = Primitive::undefinedValue();
while (k > 0) {
bool kPresent;
v = instance->getIndexed(k - 1, &kPresent);
if (kPresent) {
- cData->args[0] = acc;
- cData->args[1] = v;
- cData->args[2] = Primitive::fromDouble(k - 1);
- cData->args[3] = instance;
- acc = callback->call(cData);
+ jsCall->args[0] = acc;
+ jsCall->args[1] = v;
+ jsCall->args[2] = Primitive::fromDouble(k - 1);
+ jsCall->args[3] = instance;
+ acc = jsCall.call();
}
--k;
}
diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp
index 5ac2a43b19..64aecfe352 100644
--- a/src/qml/jsruntime/qv4dateobject.cpp
+++ b/src/qml/jsruntime/qv4dateobject.cpp
@@ -1451,9 +1451,9 @@ ReturnedValue DatePrototype::method_toJSON(const BuiltinFunction *b, CallData *c
if (!toIso)
return v4->throwTypeError();
- ScopedCallData cData(scope);
- cData->thisObject = callData->thisObject;
- return toIso->call(cData);
+ JSCall jsCall(scope, toIso);
+ jsCall->thisObject = callData->thisObject;
+ return jsCall.call();
}
void DatePrototype::timezoneUpdated()
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index 4a6890c651..3f971fcca5 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -286,49 +286,48 @@ ReturnedValue FunctionPrototype::method_apply(const BuiltinFunction *b, CallData
len = arr->getLength();
}
- ScopedCallData cData(scope, len);
+ JSCall jsCall(scope, o, len);
if (len) {
if (ArgumentsObject::isNonStrictArgumentsObject(arr) && !arr->cast<ArgumentsObject>()->fullyCreated()) {
QV4::ArgumentsObject *a = arr->cast<ArgumentsObject>();
int l = qMin(len, (uint)a->d()->context->argc());
- memcpy(cData->args, a->d()->context->args(), l*sizeof(Value));
+ memcpy(jsCall->args, a->d()->context->args(), l*sizeof(Value));
for (quint32 i = l; i < len; ++i)
- cData->args[i] = Primitive::undefinedValue();
+ jsCall->args[i] = Primitive::undefinedValue();
} else if (arr->arrayType() == Heap::ArrayData::Simple && !arr->protoHasArray()) {
auto sad = static_cast<Heap::SimpleArrayData *>(arr->arrayData());
uint alen = sad ? sad->values.size : 0;
if (alen > len)
alen = len;
for (uint i = 0; i < alen; ++i)
- cData->args[i] = sad->data(i);
+ jsCall->args[i] = sad->data(i);
for (quint32 i = alen; i < len; ++i)
- cData->args[i] = Primitive::undefinedValue();
+ jsCall->args[i] = Primitive::undefinedValue();
} else {
for (quint32 i = 0; i < len; ++i)
- cData->args[i] = arr->getIndexed(i);
+ jsCall->args[i] = arr->getIndexed(i);
}
}
- cData->thisObject = callData->argument(0);
- return o->call(cData);
+ jsCall->thisObject = callData->argument(0);
+ return jsCall.call();
}
ReturnedValue FunctionPrototype::method_call(const BuiltinFunction *b, CallData *callData)
{
- QV4::Scope scope(b);
- FunctionObject *o = callData->thisObject.as<FunctionObject>();
- if (!o)
- return scope.engine->throwTypeError();
-
- ScopedCallData cData(scope, callData->argc ? callData->argc - 1 : 0);
+ if (!callData->thisObject.isFunctionObject()) {
+ ExecutionEngine *e = b->engine();
+ return e->throwTypeError();
+ }
+ callData->function = callData->thisObject;
+ callData->thisObject = callData->argc ? callData->args[0] : Primitive::undefinedValue();
if (callData->argc) {
- for (int i = 1; i < callData->argc; ++i)
- cData->args[i - 1] = callData->args[i];
+ --callData->argc;
+ for (int i = 0; i < callData->argc; ++i)
+ callData->args[i] = callData->args[i + 1];
}
- cData->thisObject = callData->argument(0);
-
- return o->call(cData);
+ return static_cast<FunctionObject &>(callData->function).call(callData);
}
ReturnedValue FunctionPrototype::method_bind(const BuiltinFunction *b, CallData *callData)
@@ -488,16 +487,15 @@ ReturnedValue BoundFunction::call(const Managed *that, CallData *dd)
return Encode::undefined();
Scoped<MemberData> boundArgs(scope, f->boundArgs());
- ScopedCallData callData(scope, (boundArgs ? boundArgs->size() : 0) + dd->argc);
- callData->thisObject = f->boundThis();
- Value *argp = callData->args;
+ JSCall jsCall(scope, f->target(), (boundArgs ? boundArgs->size() : 0) + dd->argc);
+ jsCall->thisObject = f->boundThis();
+ Value *argp = jsCall->args;
if (boundArgs) {
memcpy(argp, boundArgs->data(), boundArgs->size()*sizeof(Value));
argp += boundArgs->size();
}
memcpy(argp, dd->args, dd->argc*sizeof(Value));
- ScopedFunctionObject t(scope, f->target());
- return t->call(callData);
+ return jsCall.call();
}
ReturnedValue BoundFunction::construct(const Managed *that, CallData *dd)
@@ -509,13 +507,12 @@ ReturnedValue BoundFunction::construct(const Managed *that, CallData *dd)
return Encode::undefined();
Scoped<MemberData> boundArgs(scope, f->boundArgs());
- ScopedCallData callData(scope, (boundArgs ? boundArgs->size() : 0) + dd->argc);
- Value *argp = callData->args;
+ JSCall jsCall(scope, f->target(), (boundArgs ? boundArgs->size() : 0) + dd->argc);
+ Value *argp = jsCall->args;
if (boundArgs) {
memcpy(argp, boundArgs->data(), boundArgs->size()*sizeof(Value));
argp += boundArgs->size();
}
memcpy(argp, dd->args, dd->argc*sizeof(Value));
- ScopedFunctionObject t(scope, f->target());
- return t->construct(callData);
+ return jsCall.callAsConstructor();
}
diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp
index 74173f6a6a..11105dfdcb 100644
--- a/src/qml/jsruntime/qv4globalobject.cpp
+++ b/src/qml/jsruntime/qv4globalobject.cpp
@@ -374,12 +374,12 @@ ReturnedValue EvalFunction::evalCall(CallData *callData, bool directCall) const
if (function->isStrict() || (ctx->d()->v4Function->isStrict())) {
ScopedFunctionObject e(scope, FunctionObject::createScriptFunction(ctx, function));
- ScopedCallData callData(scope, 0);
+ JSCall jsCall(scope, e, 0);
if (directCall)
- callData->thisObject = scope.engine->currentStackFrame->thisObject();
+ jsCall->thisObject = scope.engine->currentStackFrame->thisObject();
else
- callData->thisObject = scope.engine->globalObject;
- return e->call(callData);
+ jsCall->thisObject = scope.engine->globalObject;
+ return jsCall.call();
}
ContextStateSaver stateSaver(scope, ctx);
@@ -387,10 +387,10 @@ ReturnedValue EvalFunction::evalCall(CallData *callData, bool directCall) const
// set the correct v4 function for the context
ctx->d()->v4Function = function;
- ScopedCallData cData(scope);
- cData->thisObject = scope.engine->currentStackFrame->thisObject();
- cData->context = *ctx;
- return function->call(cData);
+ JSCall jsCall(scope, nullptr);
+ jsCall->thisObject = scope.engine->currentStackFrame->thisObject();
+ jsCall->context = *ctx;
+ return function->call(jsCall);
}
diff --git a/src/qml/jsruntime/qv4include.cpp b/src/qml/jsruntime/qv4include.cpp
index 3c378bf398..8983bea1a8 100644
--- a/src/qml/jsruntime/qv4include.cpp
+++ b/src/qml/jsruntime/qv4include.cpp
@@ -119,10 +119,10 @@ void QV4Include::callback(const QV4::Value &callback, const QV4::Value &status)
if (!f)
return;
- QV4::ScopedCallData callData(scope, 1);
- callData->thisObject = v4->globalObject->asReturnedValue();
- callData->args[0] = status;
- f->call(callData);
+ QV4::JSCall jsCall(scope, f, 1);
+ jsCall->thisObject = v4->globalObject->asReturnedValue();
+ jsCall->args[0] = status;
+ jsCall.call();
if (scope.hasException())
scope.engine->catchException();
}
diff --git a/src/qml/jsruntime/qv4jscall_p.h b/src/qml/jsruntime/qv4jscall_p.h
index f871034789..c78337a89f 100644
--- a/src/qml/jsruntime/qv4jscall_p.h
+++ b/src/qml/jsruntime/qv4jscall_p.h
@@ -60,16 +60,15 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
-struct ScopedCallData {
- ScopedCallData(const Scope &scope, int argc = 0)
+struct JSCall {
+ JSCall(const Scope &scope, std::nullptr_t, int argc = 0)
{
int size = int(offsetof(QV4::CallData, args)/sizeof(QV4::Value)) + qMax(argc , int(QV4::Global::ReservedArgumentCount));
ptr = reinterpret_cast<CallData *>(scope.alloc(size));
ptr->tag = quint32(QV4::Value::ValueTypeInternal::Integer);
ptr->argc = argc;
}
-
- ScopedCallData(const Scope &scope, const FunctionObject *function, int argc = 0)
+ JSCall(const Scope &scope, const FunctionObject *function, int argc = 0)
{
int size = int(offsetof(QV4::CallData, args)/sizeof(QV4::Value)) + qMax(argc , int(QV4::Global::ReservedArgumentCount));
ptr = reinterpret_cast<CallData *>(scope.alloc(size));
@@ -77,6 +76,14 @@ struct ScopedCallData {
ptr->argc = argc;
ptr->function = *function;
}
+ JSCall(const Scope &scope, Heap::FunctionObject *function, int argc = 0)
+ {
+ int size = int(offsetof(QV4::CallData, args)/sizeof(QV4::Value)) + qMax(argc , int(QV4::Global::ReservedArgumentCount));
+ ptr = reinterpret_cast<CallData *>(scope.alloc(size));
+ ptr->tag = quint32(QV4::Value::ValueTypeInternal::Integer);
+ ptr->argc = argc;
+ ptr->function = function;
+ }
CallData *operator->() {
return ptr;
@@ -90,6 +97,10 @@ struct ScopedCallData {
return static_cast<FunctionObject &>(ptr->function).call(ptr);
}
+ ReturnedValue callAsConstructor() const {
+ return static_cast<FunctionObject &>(ptr->function).construct(ptr);
+ }
+
CallData *ptr;
};
diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp
index 88fc0d6b3c..83cfb434dc 100644
--- a/src/qml/jsruntime/qv4jsonobject.cpp
+++ b/src/qml/jsruntime/qv4jsonobject.cpp
@@ -697,21 +697,21 @@ QString Stringify::Str(const QString &key, const Value &v)
ScopedString s(scope, v4->newString(QStringLiteral("toJSON")));
ScopedFunctionObject toJSON(scope, o->get(s));
if (!!toJSON) {
- ScopedCallData callData(scope, 1);
- callData->thisObject = value;
- callData->args[0] = v4->newString(key);
- value = toJSON->call(callData);
+ JSCall jsCall(scope, toJSON, 1);
+ jsCall->thisObject = value;
+ jsCall->args[0] = v4->newString(key);
+ value = jsCall.call();
}
}
if (replacerFunction) {
ScopedObject holder(scope, v4->newObject());
holder->put(scope.engine->id_empty(), value);
- ScopedCallData callData(scope, 2);
- callData->args[0] = v4->newString(key);
- callData->args[1] = value;
- callData->thisObject = holder;
- value = replacerFunction->call(callData);
+ JSCall jsCall(scope, replacerFunction, 2);
+ jsCall->args[0] = v4->newString(key);
+ jsCall->args[1] = value;
+ jsCall->thisObject = holder;
+ value = jsCall.call();
}
o = value->asReturnedValue();
diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp
index 392ab565b0..c612e8450c 100644
--- a/src/qml/jsruntime/qv4lookup.cpp
+++ b/src/qml/jsruntime/qv4lookup.cpp
@@ -400,9 +400,9 @@ ReturnedValue Lookup::getterAccessor0(Lookup *l, ExecutionEngine *engine, const
if (!getter)
return Encode::undefined();
- ScopedCallData callData(scope, 0);
- callData->thisObject = object;
- return getter->call(callData);
+ JSCall jsCall(scope, getter, 0);
+ jsCall->thisObject = object;
+ return jsCall.call();
}
}
l->getter = getterFallback;
@@ -422,9 +422,9 @@ ReturnedValue Lookup::getterAccessor1(Lookup *l, ExecutionEngine *engine, const
if (!getter)
return Encode::undefined();
- ScopedCallData callData(scope, 0);
- callData->thisObject = object;
- return getter->call(callData);
+ JSCall jsCall(scope, getter, 0);
+ jsCall->thisObject = object;
+ return jsCall.call();
}
}
l->getter = getterFallback;
@@ -447,9 +447,9 @@ ReturnedValue Lookup::getterAccessor2(Lookup *l, ExecutionEngine *engine, const
if (!getter)
return Encode::undefined();
- ScopedCallData callData(scope, 0);
- callData->thisObject = object;
- return getter->call(callData);
+ JSCall jsCall(scope, getter, 0);
+ jsCall->thisObject = object;
+ return jsCall.call();
}
}
}
@@ -502,9 +502,9 @@ ReturnedValue Lookup::primitiveGetterAccessor0(Lookup *l, ExecutionEngine *engin
if (!getter)
return Encode::undefined();
- ScopedCallData callData(scope, 0);
- callData->thisObject = object;
- return getter->call(callData);
+ JSCall jsCall(scope, getter, 0);
+ jsCall->thisObject = object;
+ return jsCall.call();
}
}
l->getter = getterGeneric;
@@ -522,9 +522,9 @@ ReturnedValue Lookup::primitiveGetterAccessor1(Lookup *l, ExecutionEngine *engin
if (!getter)
return Encode::undefined();
- ScopedCallData callData(scope, 0);
- callData->thisObject = object;
- return getter->call(callData);
+ JSCall jsCall(scope, getter, 0);
+ jsCall->thisObject = object;
+ return jsCall.call();
}
}
l->getter = getterGeneric;
@@ -641,9 +641,8 @@ ReturnedValue Lookup::globalGetterAccessor0(Lookup *l, ExecutionEngine *engine)
if (!getter)
return Encode::undefined();
- ScopedCallData callData(scope, 0);
- callData->thisObject = Primitive::undefinedValue();
- return getter->call(callData);
+ JSCall jsCall(scope, getter, 0);
+ return jsCall.call();
}
l->globalGetter = globalGetterGeneric;
return globalGetterGeneric(l, engine);
@@ -659,9 +658,8 @@ ReturnedValue Lookup::globalGetterAccessor1(Lookup *l, ExecutionEngine *engine)
if (!getter)
return Encode::undefined();
- ScopedCallData callData(scope, 0);
- callData->thisObject = Primitive::undefinedValue();
- return getter->call(callData);
+ JSCall jsCall(scope, getter, 0);
+ return jsCall.call();
}
l->globalGetter = globalGetterGeneric;
return globalGetterGeneric(l, engine);
@@ -680,9 +678,8 @@ ReturnedValue Lookup::globalGetterAccessor2(Lookup *l, ExecutionEngine *engine)
if (!getter)
return Encode::undefined();
- ScopedCallData callData(scope, 0);
- callData->thisObject = Primitive::undefinedValue();
- return getter->call(callData);
+ JSCall jsCall(scope, getter, 0);
+ return jsCall.call();
}
}
}
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index b778a064be..d310c4b114 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -107,9 +107,9 @@ ReturnedValue Object::getValue(const Value &thisObject, const Value &v, Property
return Encode::undefined();
Scope scope(f->engine());
- ScopedCallData callData(scope);
- callData->thisObject = thisObject;
- return f->call(callData);
+ JSCall jsCall(scope, f);
+ jsCall->thisObject = thisObject;
+ return jsCall.call();
}
bool Object::putValue(uint memberIndex, const Value &value)
@@ -125,10 +125,10 @@ bool Object::putValue(uint memberIndex, const Value &value)
if (set) {
Scope scope(ic->engine);
ScopedFunctionObject setter(scope, set);
- ScopedCallData callData(scope, 1);
- callData->args[0] = value;
- callData->thisObject = this;
- setter->call(callData);
+ JSCall jsCall(scope, setter, 1);
+ jsCall->args[0] = value;
+ jsCall->thisObject = this;
+ jsCall.call();
return !ic->engine->hasException;
}
return false;
@@ -764,11 +764,11 @@ bool Object::internalPut(String *name, const Value &value)
Scope scope(engine);
ScopedFunctionObject setter(scope, *memberIndex);
- ScopedCallData callData(scope, 1);
- callData->args[0] = value;
- callData->thisObject = this;
- setter->call(callData);
- return !internalClass()->engine->hasException;
+ JSCall jsCall(scope, setter, 1);
+ jsCall->args[0] = value;
+ jsCall->thisObject = this;
+ jsCall.call();
+ return !engine->hasException;
}
insertMember(name, value);
@@ -829,11 +829,11 @@ bool Object::internalPutIndexed(uint index, const Value &value)
Scope scope(engine);
ScopedFunctionObject setter(scope, *arrayIndex);
- ScopedCallData callData(scope, 1);
- callData->args[0] = value;
- callData->thisObject = this;
- setter->call(callData);
- return !internalClass()->engine->hasException;
+ JSCall jsCall(scope, setter, 1);
+ jsCall->args[0] = value;
+ jsCall->thisObject = this;
+ jsCall.call();
+ return !engine->hasException;
}
arraySet(index, value);
diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp
index e7ef9d93cf..0f60881db1 100644
--- a/src/qml/jsruntime/qv4objectproto.cpp
+++ b/src/qml/jsruntime/qv4objectproto.cpp
@@ -479,9 +479,9 @@ ReturnedValue ObjectPrototype::method_toLocaleString(const BuiltinFunction *b, C
ScopedFunctionObject f(scope, o->get(scope.engine->id_toString()));
if (!f)
THROW_TYPE_ERROR();
- ScopedCallData cData(scope);
- cData->thisObject = o;
- return f->call(callData);
+ JSCall jsCall(scope, f);
+ jsCall->thisObject = o;
+ return jsCall.call();
}
ReturnedValue ObjectPrototype::method_valueOf(const BuiltinFunction *b, CallData *callData)
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index ddce96f9ca..40dfeefdcc 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -816,18 +816,18 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase
QV4::Scope scope(v4);
QV4::ScopedFunctionObject f(scope, This->function.value());
- QV4::ScopedCallData callData(scope, argCount);
- callData->thisObject = This->thisObject.isUndefined() ? v4->globalObject->asReturnedValue() : This->thisObject.value();
+ QV4::JSCall jsCall(scope, f, argCount);
+ jsCall->thisObject = This->thisObject.isUndefined() ? v4->globalObject->asReturnedValue() : This->thisObject.value();
for (int ii = 0; ii < argCount; ++ii) {
int type = argsTypes[ii + 1];
if (type == qMetaTypeId<QVariant>()) {
- callData->args[ii] = v4->fromVariant(*((QVariant *)metaArgs[ii + 1]));
+ jsCall->args[ii] = v4->fromVariant(*((QVariant *)metaArgs[ii + 1]));
} else {
- callData->args[ii] = v4->fromVariant(QVariant(type, metaArgs[ii + 1]));
+ jsCall->args[ii] = v4->fromVariant(QVariant(type, metaArgs[ii + 1]));
}
}
- f->call(callData);
+ jsCall.call();
if (scope.hasException()) {
QQmlError error = v4->catchExceptionAsQmlError();
if (error.description().isEmpty()) {
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index 4124188b59..db5551f99c 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -394,10 +394,10 @@ ReturnedValue RegExpPrototype::method_compile(const BuiltinFunction *b, CallData
if (!r)
return scope.engine->throwTypeError();
- ScopedCallData cData(scope, callData->argc);
- memcpy(cData->args, callData->args, callData->argc*sizeof(Value));
+ JSCall jsCall(scope, scope.engine->regExpCtor(), callData->argc);
+ memcpy(jsCall->args, callData->args, callData->argc*sizeof(Value));
- Scoped<RegExpObject> re(scope, scope.engine->regExpCtor()->as<FunctionObject>()->construct(cData));
+ Scoped<RegExpObject> re(scope, jsCall.callAsConstructor());
r->d()->value.set(scope.engine, re->value());
r->d()->global = re->global();
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 187cd7c313..f09d803d0b 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -424,12 +424,13 @@ ReturnedValue RuntimeHelpers::objectDefaultValue(const Object *object, int typeH
qSwap(meth1, meth2);
Scope scope(engine);
- ScopedCallData callData(scope, 0);
- callData->thisObject = *object;
+ JSCall jsCall(scope, nullptr, 0);
+ jsCall->thisObject = *object;
ScopedValue conv(scope, object->get(meth1));
if (FunctionObject *o = conv->as<FunctionObject>()) {
- ScopedValue r(scope, o->call(callData));
+ jsCall->function = o;
+ ScopedValue r(scope, jsCall.call());
if (r->isPrimitive())
return r->asReturnedValue();
}
@@ -439,7 +440,8 @@ ReturnedValue RuntimeHelpers::objectDefaultValue(const Object *object, int typeH
conv = object->get(meth2);
if (FunctionObject *o = conv->as<FunctionObject>()) {
- ScopedValue r(scope, o->call(callData));
+ jsCall->function = o;
+ ScopedValue r(scope, jsCall.call());
if (r->isPrimitive())
return r->asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp
index 598c12ffd4..c3200fbcea 100644
--- a/src/qml/jsruntime/qv4script.cpp
+++ b/src/qml/jsruntime/qv4script.cpp
@@ -152,16 +152,16 @@ ReturnedValue Script::run()
ContextStateSaver stateSaver(valueScope, scope);
scope->d()->v4Function = vmFunction;
- QV4::ScopedCallData cData(scope);
- cData->thisObject = engine->globalObject;
- cData->context = *scope;
- return vmFunction->call(cData);
+ QV4::JSCall jsCall(scope, nullptr);
+ jsCall->thisObject = engine->globalObject;
+ jsCall->context = *scope;
+ return vmFunction->call(jsCall);
} else {
Scoped<QmlContext> qml(valueScope, qmlContext.value());
- ScopedCallData callData(valueScope);
- callData->thisObject = Primitive::undefinedValue();
- callData->context = *qml;
- return vmFunction->call(callData);
+ JSCall jsCall(valueScope, nullptr);
+ jsCall->thisObject = Primitive::undefinedValue();
+ jsCall->context = *qml;
+ return vmFunction->call(jsCall);
}
}
diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp
index ed9f798cd7..28b20169d9 100644
--- a/src/qml/jsruntime/qv4sequenceobject.cpp
+++ b/src/qml/jsruntime/qv4sequenceobject.cpp
@@ -417,12 +417,14 @@ public:
bool operator()(typename Container::value_type lhs, typename Container::value_type rhs)
{
QV4::Scope scope(m_v4);
- ScopedObject compare(scope, m_compareFn);
- ScopedCallData callData(scope, 2);
- callData->args[0] = convertElementToValue(m_v4, lhs);
- callData->args[1] = convertElementToValue(m_v4, rhs);
- callData->thisObject = m_v4->globalObject;
- QV4::ScopedValue result(scope, compare->call(callData));
+ ScopedFunctionObject compare(scope, m_compareFn);
+ if (!compare)
+ return m_v4->throwTypeError();
+ JSCall jsCall(scope, compare, 2);
+ jsCall->args[0] = convertElementToValue(m_v4, lhs);
+ jsCall->args[1] = convertElementToValue(m_v4, rhs);
+ jsCall->thisObject = m_v4->globalObject;
+ QV4::ScopedValue result(scope, jsCall.call());
return result->toNumber() < 0;
}
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index 4964769b88..66ad5e79d2 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -411,9 +411,9 @@ ReturnedValue StringPrototype::method_match(const BuiltinFunction *b, CallData *
ScopedValue regexp(scope, callData->argument(0));
Scoped<RegExpObject> rx(scope, regexp);
if (!rx) {
- ScopedCallData callData(scope, 1);
- callData->args[0] = regexp;
- rx = scope.engine->regExpCtor()->construct(callData);
+ JSCall jsCall(scope, scope.engine->regExpCtor(), 1);
+ jsCall->args[0] = regexp;
+ rx = jsCall.callAsConstructor();
}
if (!rx)
@@ -426,11 +426,11 @@ ReturnedValue StringPrototype::method_match(const BuiltinFunction *b, CallData *
ScopedString execString(scope, scope.engine->newString(QStringLiteral("exec")));
ScopedFunctionObject exec(scope, scope.engine->regExpPrototype()->get(execString));
- ScopedCallData cData(scope, 1);
- cData->thisObject = rx;
- cData->args[0] = s;
+ JSCall jsCall(scope, exec, 1);
+ jsCall->thisObject = rx;
+ jsCall->args[0] = s;
if (!global)
- return exec->call(cData);
+ return jsCall.call();
ScopedString lastIndex(scope, scope.engine->newString(QStringLiteral("lastIndex")));
rx->put(lastIndex, ScopedValue(scope, Primitive::fromInt32(0)));
@@ -442,7 +442,7 @@ ReturnedValue StringPrototype::method_match(const BuiltinFunction *b, CallData *
ScopedValue index(scope);
ScopedValue result(scope);
while (1) {
- result = exec->call(cData);
+ result = jsCall.call();
if (result->isNull())
break;
assert(result->isObject());
@@ -590,8 +590,8 @@ ReturnedValue StringPrototype::method_replace(const BuiltinFunction *b, CallData
ScopedFunctionObject searchCallback(scope, replaceValue);
if (!!searchCallback) {
result.reserve(string.length() + 10*numStringMatches);
- ScopedCallData callData(scope, numCaptures + 2);
- callData->thisObject = Primitive::undefinedValue();
+ JSCall jsCall(scope, searchCallback, numCaptures + 2);
+ jsCall->thisObject = Primitive::undefinedValue();
int lastEnd = 0;
ScopedValue entry(scope);
for (int i = 0; i < numStringMatches; ++i) {
@@ -602,15 +602,15 @@ ReturnedValue StringPrototype::method_replace(const BuiltinFunction *b, CallData
entry = Primitive::undefinedValue();
if (start != JSC::Yarr::offsetNoMatch && end != JSC::Yarr::offsetNoMatch)
entry = scope.engine->newString(string.mid(start, end - start));
- callData->args[k] = entry;
+ jsCall->args[k] = entry;
}
uint matchStart = matchOffsets[i * numCaptures * 2];
Q_ASSERT(matchStart >= static_cast<uint>(lastEnd));
uint matchEnd = matchOffsets[i * numCaptures * 2 + 1];
- callData->args[numCaptures] = Primitive::fromUInt32(matchStart);
- callData->args[numCaptures + 1] = scope.engine->newString(string);
+ jsCall->args[numCaptures] = Primitive::fromUInt32(matchStart);
+ jsCall->args[numCaptures + 1] = scope.engine->newString(string);
- replacement = searchCallback->call(callData);
+ replacement = jsCall.call();
result += string.midRef(lastEnd, matchStart - lastEnd);
result += replacement->toQString();
lastEnd = matchEnd;
@@ -652,9 +652,9 @@ ReturnedValue StringPrototype::method_search(const BuiltinFunction *b, CallData
RegExpObject *regExp = regExpObj->as<RegExpObject>();
if (!regExp) {
- ScopedCallData callData(scope, 1);
- callData->args[0] = regExpObj;
- regExpObj = scope.engine->regExpCtor()->construct(callData);
+ JSCall jsCall(scope, scope.engine->regExpCtor(), 1);
+ jsCall->args[0] = regExpObj;
+ regExpObj = jsCall.callAsConstructor();
if (scope.engine->hasException)
return QV4::Encode::undefined();
diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp
index 3d0acb19b9..5bec5046fe 100644
--- a/src/qml/jsruntime/qv4typedarray.cpp
+++ b/src/qml/jsruntime/qv4typedarray.cpp
@@ -572,9 +572,9 @@ ReturnedValue TypedArrayPrototype::method_subarray(const BuiltinFunction *builti
if (!constructor)
return scope.engine->throwTypeError();
- ScopedCallData cData(scope, 3);
- cData->args[0] = buffer;
- cData->args[1] = Encode(a->d()->byteOffset + begin*a->d()->type->bytesPerElement);
- cData->args[2] = Encode(newLen);
- return constructor->construct(cData);
+ JSCall jsCall(scope, constructor, 3);
+ jsCall->args[0] = buffer;
+ jsCall->args[1] = Encode(a->d()->byteOffset + begin*a->d()->type->bytesPerElement);
+ jsCall->args[2] = Encode(newLen);
+ return jsCall.callAsConstructor();
}
diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp
index 20c84b34e6..ba2f37eb2d 100644
--- a/src/qml/qml/qqmlboundsignal.cpp
+++ b/src/qml/qml/qqmlboundsignal.cpp
@@ -193,35 +193,35 @@ void QQmlBoundSignalExpression::evaluate(void **a)
int *argsTypes = QQmlMetaObject(m_target).methodParameterTypes(methodIndex, &storage, 0);
int argCount = argsTypes ? *argsTypes : 0;
- QV4::ScopedCallData callData(scope, argCount);
+ QV4::JSCall jsCall(scope, nullptr, argCount);
for (int ii = 0; ii < argCount; ++ii) {
int type = argsTypes[ii + 1];
//### ideally we would use metaTypeToJS, however it currently gives different results
// for several cases (such as QVariant type and QObject-derived types)
//args[ii] = engine->metaTypeToJS(type, a[ii + 1]);
if (type == qMetaTypeId<QJSValue>()) {
- if (QV4::Value *v4Value = QJSValuePrivate::valueForData(reinterpret_cast<QJSValue *>(a[ii + 1]), &callData->args[ii]))
- callData->args[ii] = *v4Value;
+ if (QV4::Value *v4Value = QJSValuePrivate::valueForData(reinterpret_cast<QJSValue *>(a[ii + 1]), &jsCall->args[ii]))
+ jsCall->args[ii] = *v4Value;
else
- callData->args[ii] = QV4::Encode::undefined();
+ jsCall->args[ii] = QV4::Encode::undefined();
} else if (type == QMetaType::QVariant) {
- callData->args[ii] = scope.engine->fromVariant(*((QVariant *)a[ii + 1]));
+ jsCall->args[ii] = scope.engine->fromVariant(*((QVariant *)a[ii + 1]));
} else if (type == QMetaType::Int) {
//### optimization. Can go away if we switch to metaTypeToJS, or be expanded otherwise
- callData->args[ii] = QV4::Primitive::fromInt32(*reinterpret_cast<const int*>(a[ii + 1]));
+ jsCall->args[ii] = QV4::Primitive::fromInt32(*reinterpret_cast<const int*>(a[ii + 1]));
} else if (type == qMetaTypeId<QQmlV4Handle>()) {
- callData->args[ii] = *reinterpret_cast<QQmlV4Handle *>(a[ii + 1]);
+ jsCall->args[ii] = *reinterpret_cast<QQmlV4Handle *>(a[ii + 1]);
} else if (ep->isQObject(type)) {
if (!*reinterpret_cast<void* const *>(a[ii + 1]))
- callData->args[ii] = QV4::Primitive::nullValue();
+ jsCall->args[ii] = QV4::Primitive::nullValue();
else
- callData->args[ii] = QV4::QObjectWrapper::wrap(ep->v4engine(), *reinterpret_cast<QObject* const *>(a[ii + 1]));
+ jsCall->args[ii] = QV4::QObjectWrapper::wrap(ep->v4engine(), *reinterpret_cast<QObject* const *>(a[ii + 1]));
} else {
- callData->args[ii] = scope.engine->fromVariant(QVariant(type, a[ii + 1]));
+ jsCall->args[ii] = scope.engine->fromVariant(QVariant(type, a[ii + 1]));
}
}
- QQmlJavaScriptExpression::evaluate(callData, 0);
+ QQmlJavaScriptExpression::evaluate(jsCall, 0);
ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete.
}
@@ -238,12 +238,12 @@ void QQmlBoundSignalExpression::evaluate(const QList<QVariant> &args)
ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation.
- QV4::ScopedCallData callData(scope, args.count());
+ QV4::JSCall jsCall(scope, nullptr, args.count());
for (int ii = 0; ii < args.count(); ++ii) {
- callData->args[ii] = scope.engine->fromVariant(args[ii]);
+ jsCall->args[ii] = scope.engine->fromVariant(args[ii]);
}
- QQmlJavaScriptExpression::evaluate(callData, 0);
+ QQmlJavaScriptExpression::evaluate(jsCall, 0);
ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete.
}
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 4affc5a453..dd0d2096ce 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -1547,10 +1547,10 @@ void QV4::QmlIncubatorObject::statusChanged(QQmlIncubator::Status s)
QV4::ScopedFunctionObject f(scope, d()->statusChanged);
if (f) {
- QV4::ScopedCallData callData(scope, 1);
- callData->thisObject = this;
- callData->args[0] = QV4::Primitive::fromUInt32(s);
- f->call(callData);
+ QV4::JSCall jsCall(scope, f, 1);
+ jsCall->thisObject = this;
+ jsCall->args[0] = QV4::Primitive::fromUInt32(s);
+ jsCall.call();
if (scope.hasException()) {
QQmlError error = scope.engine->catchExceptionAsQmlError();
QQmlEnginePrivate::warning(QQmlEnginePrivate::get(scope.engine->qmlEngine()), error);
diff --git a/src/qml/qml/qqmldelayedcallqueue.cpp b/src/qml/qml/qqmldelayedcallqueue.cpp
index 87b6fac10e..1537657e0d 100644
--- a/src/qml/qml/qqmldelayedcallqueue.cpp
+++ b/src/qml/qml/qqmldelayedcallqueue.cpp
@@ -64,17 +64,17 @@ void QQmlDelayedCallQueue::DelayedFunctionCall::execute(QV4::ExecutionEngine *en
QV4::Scope scope(engine);
QV4::ArrayObject *array = m_args.as<QV4::ArrayObject>();
+ const QV4::FunctionObject *callback = m_function.as<QV4::FunctionObject>();
+ Q_ASSERT(callback);
const int argCount = array ? array->getLength() : 0;
- QV4::ScopedCallData callData(scope, argCount);
- callData->thisObject = QV4::Encode::undefined();
+ QV4::JSCall jsCall(scope, callback, argCount);
+ jsCall->thisObject = QV4::Encode::undefined();
for (int i = 0; i < argCount; i++) {
- callData->args[i] = array->getIndexed(i);
+ jsCall->args[i] = array->getIndexed(i);
}
- const QV4::FunctionObject *callback = m_function.as<QV4::FunctionObject>();
- Q_ASSERT(callback);
- callback->call(callData);
+ jsCall.call();
if (scope.engine->hasException) {
QQmlError error = scope.engine->catchExceptionAsQmlError();
diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp
index 36881f02ba..e40795283a 100644
--- a/src/qml/qml/qqmljavascriptexpression.cpp
+++ b/src/qml/qml/qqmljavascriptexpression.cpp
@@ -185,9 +185,9 @@ QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(bool *isUndefined)
{
QV4::ExecutionEngine *v4 = QV8Engine::getV4(m_context->engine);
QV4::Scope scope(v4);
- QV4::ScopedCallData callData(scope);
+ QV4::JSCall jsCall(scope, nullptr);
- return evaluate(callData, isUndefined);
+ return evaluate(jsCall, isUndefined);
}
QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, bool *isUndefined)
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index 3510367fd3..2b54819ad0 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -951,14 +951,13 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
}
const unsigned int parameterCount = function->formalParameterCount();
- QV4::ScopedCallData callData(scope, parameterCount);
- callData->thisObject = ep->v8engine()->global();
+ QV4::JSCall jsCall(scope, function, parameterCount);
+ jsCall->thisObject = ep->v8engine()->global();
for (uint ii = 0; ii < parameterCount; ++ii)
- callData->args[ii] = scope.engine->fromVariant(*(QVariant *)a[ii + 1]);
+ jsCall->args[ii] = scope.engine->fromVariant(*(QVariant *)a[ii + 1]);
- QV4::ScopedValue result(scope);
- result = function->call(callData);
+ QV4::ScopedValue result(scope, jsCall.call());
if (scope.hasException()) {
QQmlError error = scope.engine->catchExceptionAsQmlError();
if (error.isValid())
diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp
index a77c4c5678..21f1fb30b0 100644
--- a/src/qml/qml/qqmlxmlhttprequest.cpp
+++ b/src/qml/qml/qqmlxmlhttprequest.cpp
@@ -1576,9 +1576,7 @@ void QQmlXMLHttpRequest::dispatchCallback(Object *thisObj, QQmlContextData *cont
return;
}
- QV4::ScopedCallData callData(scope);
- callData->thisObject = Encode::undefined();
- callback->call(callData);
+ QV4::JSCall(scope, callback).call();
if (scope.engine->hasException) {
QQmlError error = scope.engine->catchExceptionAsQmlError();
diff --git a/src/qml/types/qquickworkerscript.cpp b/src/qml/types/qquickworkerscript.cpp
index a26bd81c8b..6df15c2513 100644
--- a/src/qml/types/qquickworkerscript.cpp
+++ b/src/qml/types/qquickworkerscript.cpp
@@ -248,10 +248,10 @@ void QQuickWorkerScriptEnginePrivate::WorkerEngine::init()
QV4::ScopedString name(scope, m_v4Engine->newString(QStringLiteral("sendMessage")));
QV4::ScopedValue function(scope, QV4::BuiltinFunction::create(globalContext, name,
QQuickWorkerScriptEnginePrivate::method_sendMessage));
- QV4::ScopedCallData callData(scope, 1);
- callData->args[0] = function;
- callData->thisObject = global();
- createsend.set(scope.engine, createsendconstructor->call(callData));
+ QV4::JSCall jsCall(scope, createsendconstructor, 1);
+ jsCall->args[0] = function;
+ jsCall->thisObject = global();
+ createsend.set(scope.engine, jsCall.call());
}
// Requires handle and context scope
@@ -265,10 +265,10 @@ QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::WorkerEngine::sendFunction(i
QV4::ScopedFunctionObject f(scope, createsend.value());
QV4::ScopedValue v(scope);
- QV4::ScopedCallData callData(scope, 1);
- callData->args[0] = QV4::Primitive::fromInt32(id);
- callData->thisObject = global();
- v = f->call(callData);
+ QV4::JSCall jsCall(scope, f, 1);
+ jsCall->args[0] = QV4::Primitive::fromInt32(id);
+ jsCall->thisObject = global();
+ v = jsCall.call();
if (scope.hasException())
v = scope.engine->catchException();
return v->asReturnedValue();
@@ -366,11 +366,11 @@ void QQuickWorkerScriptEnginePrivate::processMessage(int id, const QByteArray &d
QV4::Scoped<QV4::QmlContext> qmlContext(scope, script->qmlContext.value());
Q_ASSERT(!!qmlContext);
- QV4::ScopedCallData callData(scope, 2);
- callData->thisObject = workerEngine->global();
- callData->args[0] = qmlContext->d()->qml(); // ###
- callData->args[1] = value;
- f->call(callData);
+ QV4::JSCall jsCall(scope, f, 2);
+ jsCall->thisObject = workerEngine->global();
+ jsCall->args[0] = qmlContext->d()->qml(); // ###
+ jsCall->args[1] = value;
+ jsCall.call();
if (scope.hasException()) {
QQmlError error = scope.engine->catchExceptionAsQmlError();
reportScriptException(script, error);
diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp
index ddf34666a2..ff90a74c43 100644
--- a/src/quick/items/context2d/qquickcanvasitem.cpp
+++ b/src/quick/items/context2d/qquickcanvasitem.cpp
@@ -729,13 +729,13 @@ void QQuickCanvasItem::updatePolish()
QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(qmlEngine(this));
QV4::Scope scope(v4);
- QV4::ScopedCallData callData(scope, 1);
- callData->thisObject = QV4::QObjectWrapper::wrap(v4, this);
+ QV4::JSCall jsCall(scope, nullptr, 1);
+ jsCall->thisObject = QV4::QObjectWrapper::wrap(v4, this);
for (auto it = animationCallbacks.cbegin(), end = animationCallbacks.cend(); it != end; ++it) {
- QV4::ScopedFunctionObject f(scope, it.value().value());
- callData->args[0] = QV4::Primitive::fromUInt32(QDateTime::currentMSecsSinceEpoch() / 1000);
- f->call(callData);
+ jsCall->function = it.value().value();
+ jsCall->args[0] = QV4::Primitive::fromUInt32(QDateTime::currentMSecsSinceEpoch() / 1000);
+ jsCall.call();
}
}
else {