diff options
author | Ulf Hermann <[email protected]> | 2021-03-12 15:46:29 +0100 |
---|---|---|
committer | Ulf Hermann <[email protected]> | 2021-03-17 13:10:22 +0100 |
commit | 9caea013ceb221b5617c4940e7bb9ee9fecdd631 (patch) | |
tree | f4480e860a965f6515e516475baeced69b5d91fd | |
parent | b0e9c83f99aa7090c82b7c55894f5e264b74608a (diff) |
Clean up JSCallData setup
We either have pre-populated arguments and thisObject, then we can just
use them and keep them const. Or, we want to allocate and populate the
arguments and the thisObject. Then, do allocate them in a separate
object, and transform that into JSCallData afterwards if necessary.
Furthermore, avoid alloc(0) as that just returns the current stack top.
Writing to it will clobber other data. Rather, just use nullptr and
crash if it's written to.
Also, remove the useless operator-> from JSCallData. That one just
confuses the reader.
Change-Id: I8310911fcfe005b05a07b78fcb3791d991a0c2ce
Reviewed-by: Fabian Kosmale <[email protected]>
26 files changed, 216 insertions, 183 deletions
diff --git a/src/qml/jsapi/qjsmanagedvalue.cpp b/src/qml/jsapi/qjsmanagedvalue.cpp index 202c940785..ccd3cc0106 100644 --- a/src/qml/jsapi/qjsmanagedvalue.cpp +++ b/src/qml/jsapi/qjsmanagedvalue.cpp @@ -992,15 +992,15 @@ QJSValue QJSManagedValue::call(const QJSValueList &arguments) const QV4::ExecutionEngine *engine = f->engine(); QV4::Scope scope(engine); - QV4::JSCallData jsCallData(scope, arguments.length()); - *jsCallData->thisObject = engine->globalObject; + QV4::JSCallArguments jsCallData(scope, arguments.length()); + *jsCallData.thisObject = engine->globalObject; int i = 0; for (const QJSValue &arg : arguments) { if (Q_UNLIKELY(!QJSValuePrivate::checkEngine(engine, arg))) { qWarning("QJSManagedValue::call() failed: Argument was created in different engine."); return QJSValue(); } - jsCallData->args[i++] = QJSValuePrivate::convertToReturnedValue(engine, arg); + jsCallData.args[i++] = QJSValuePrivate::convertToReturnedValue(engine, arg); } return QJSValuePrivate::fromReturnedValue(f->call(jsCallData)); @@ -1031,8 +1031,8 @@ QJSValue QJSManagedValue::callWithInstance(const QJSValue &instance, } QV4::Scope scope(engine); - QV4::JSCallData jsCallData(scope, arguments.length()); - *jsCallData->thisObject = QJSValuePrivate::convertToReturnedValue(engine, instance); + QV4::JSCallArguments jsCallData(scope, arguments.length()); + *jsCallData.thisObject = QJSValuePrivate::convertToReturnedValue(engine, instance); int i = 0; for (const QJSValue &arg : arguments) { if (Q_UNLIKELY(!QJSValuePrivate::checkEngine(engine, arg))) { @@ -1040,7 +1040,7 @@ QJSValue QJSManagedValue::callWithInstance(const QJSValue &instance, "Argument was created in different engine."); return QJSValue(); } - jsCallData->args[i++] = QJSValuePrivate::convertToReturnedValue(engine, arg); + jsCallData.args[i++] = QJSValuePrivate::convertToReturnedValue(engine, arg); } return QJSValuePrivate::fromReturnedValue(f->call(jsCallData)); @@ -1064,7 +1064,7 @@ QJSValue QJSManagedValue::callAsConstructor(const QJSValueList &arguments) const QV4::ExecutionEngine *engine = f->engine(); QV4::Scope scope(engine); - QV4::JSCallData jsCallData(scope, arguments.length()); + QV4::JSCallArguments jsCallData(scope, arguments.length()); int i = 0; for (const QJSValue &arg : arguments) { if (Q_UNLIKELY(!QJSValuePrivate::checkEngine(engine, arg))) { @@ -1072,7 +1072,7 @@ QJSValue QJSManagedValue::callAsConstructor(const QJSValueList &arguments) const "Argument was created in different engine."); return QJSValue(); } - jsCallData->args[i++] = QJSValuePrivate::convertToReturnedValue(engine, arg); + jsCallData.args[i++] = QJSValuePrivate::convertToReturnedValue(engine, arg); } return QJSValuePrivate::fromReturnedValue(f->callAsConstructor(jsCallData)); diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp index c565f4c372..e6b310e86c 100644 --- a/src/qml/jsapi/qjsvalue.cpp +++ b/src/qml/jsapi/qjsvalue.cpp @@ -690,14 +690,14 @@ QJSValue QJSValue::call(const QJSValueList &args) const Q_ASSERT(engine); Scope scope(engine); - JSCallData jsCallData(scope, args.length()); - *jsCallData->thisObject = engine->globalObject; + JSCallArguments jsCallData(scope, args.length()); + *jsCallData.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(); } - jsCallData->args[i] = QJSValuePrivate::convertToReturnedValue(engine, args.at(i)); + jsCallData.args[i] = QJSValuePrivate::convertToReturnedValue(engine, args.at(i)); } ScopedValue result(scope, f->call(jsCallData)); @@ -744,14 +744,14 @@ QJSValue QJSValue::callWithInstance(const QJSValue &instance, const QJSValueList return QJSValue(); } - JSCallData jsCallData(scope, args.size()); - *jsCallData->thisObject = QJSValuePrivate::convertToReturnedValue(engine, instance); + JSCallArguments jsCallData(scope, args.size()); + *jsCallData.thisObject = QJSValuePrivate::convertToReturnedValue(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(); } - jsCallData->args[i] = QJSValuePrivate::convertToReturnedValue(engine, args.at(i)); + jsCallData.args[i] = QJSValuePrivate::convertToReturnedValue(engine, args.at(i)); } ScopedValue result(scope, f->call(jsCallData)); @@ -791,13 +791,13 @@ QJSValue QJSValue::callAsConstructor(const QJSValueList &args) const Q_ASSERT(engine); Scope scope(engine); - JSCallData jsCallData(scope, args.size()); + JSCallArguments jsCallData(scope, 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(); } - jsCallData->args[i] = QJSValuePrivate::convertToReturnedValue(engine, args.at(i)); + jsCallData.args[i] = QJSValuePrivate::convertToReturnedValue(engine, args.at(i)); } ScopedValue result(scope, f->callAsConstructor(jsCallData)); diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp index 0eea3345c5..577cc11cf4 100644 --- a/src/qml/jsruntime/qv4arraydata.cpp +++ b/src/qml/jsruntime/qv4arraydata.cpp @@ -650,9 +650,9 @@ bool ArrayElementLessThan::operator()(Value v1, Value v2) const if (o) { Scope scope(o->engine()); ScopedValue result(scope); - JSCallData jsCallData(scope, 2); - jsCallData->args[0] = v1; - jsCallData->args[1] = v2; + JSCallArguments jsCallData(scope, 2); + jsCallData.args[0] = v1; + jsCallData.args[1] = v2; result = o->call(jsCallData); if (scope.hasException()) return false; diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 7bbf6e9133..182e131c9e 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -2086,10 +2086,10 @@ ReturnedValue ExecutionEngine::callInContext(Function *function, QObject *self, return Encode::undefined(); // use JSCallData to pass arguments into the function call - QV4::JSCallData jsCall(scope, argc); + QV4::JSCallArguments jsCall(scope, argc); QV4::populateJSCallArguments(this, jsCall, argc, args, types); - QV4::CallData *callData = jsCall->callData(scope); + QV4::CallData *callData = jsCall.callData(scope); return function->call(selfValue, callData->argValues<QV4::Value>(), callData->argc(), qmlContext); } diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index 3f0a316af7..9701e0e9ca 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -722,9 +722,9 @@ ReturnedValue BoundFunction::virtualCall(const FunctionObject *fo, const Value * Scope scope(v4); Scoped<MemberData> boundArgs(scope, f->boundArgs()); ScopedFunctionObject target(scope, f->target()); - JSCallData jsCallData(scope, (boundArgs ? boundArgs->size() : 0) + argc); - *jsCallData->thisObject = f->boundThis(); - Value *argp = jsCallData->args; + JSCallArguments jsCallData(scope, (boundArgs ? boundArgs->size() : 0) + argc); + *jsCallData.thisObject = f->boundThis(); + Value *argp = jsCallData.args; if (boundArgs) { memcpy(argp, boundArgs->data(), boundArgs->size()*sizeof(Value)); argp += boundArgs->size(); @@ -743,8 +743,8 @@ ReturnedValue BoundFunction::virtualCallAsConstructor(const FunctionObject *fo, Scoped<MemberData> boundArgs(scope, f->boundArgs()); ScopedFunctionObject target(scope, f->target()); - JSCallData jsCallData(scope, (boundArgs ? boundArgs->size() : 0) + argc); - Value *argp = jsCallData->args; + JSCallArguments jsCallData(scope, (boundArgs ? boundArgs->size() : 0) + argc); + Value *argp = jsCallData.args; if (boundArgs) { memcpy(argp, boundArgs->data(), boundArgs->size()*sizeof(Value)); argp += boundArgs->size(); diff --git a/src/qml/jsruntime/qv4include.cpp b/src/qml/jsruntime/qv4include.cpp index c185894ab3..3e6417af57 100644 --- a/src/qml/jsruntime/qv4include.cpp +++ b/src/qml/jsruntime/qv4include.cpp @@ -127,9 +127,9 @@ void QV4Include::callback(const QV4::Value &callback, const QV4::Value &status) if (!f) return; - QV4::JSCallData jsCallData(scope, 1); - *jsCallData->thisObject = v4->globalObject->asReturnedValue(); - jsCallData->args[0] = status; + QV4::JSCallArguments jsCallData(scope, 1); + *jsCallData.thisObject = v4->globalObject->asReturnedValue(); + jsCallData.args[0] = status; f->call(jsCallData); if (scope.hasException()) scope.engine->catchException(); diff --git a/src/qml/jsruntime/qv4jscall.cpp b/src/qml/jsruntime/qv4jscall.cpp index 191436bd69..97314b8dad 100644 --- a/src/qml/jsruntime/qv4jscall.cpp +++ b/src/qml/jsruntime/qv4jscall.cpp @@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE Sets the arguments of JSCallData from type erased \a args based on type information provided by \a types */ -void QV4::populateJSCallArguments(ExecutionEngine *v4, JSCallData &jsCall, +void QV4::populateJSCallArguments(ExecutionEngine *v4, JSCallArguments &jsCall, int argc, void **args, const QMetaType *types) { for (int ii = 0; ii < argc; ++ii) { diff --git a/src/qml/jsruntime/qv4jscall_p.h b/src/qml/jsruntime/qv4jscall_p.h index 43dc0de727..15ede20be3 100644 --- a/src/qml/jsruntime/qv4jscall_p.h +++ b/src/qml/jsruntime/qv4jscall_p.h @@ -61,39 +61,61 @@ QT_BEGIN_NAMESPACE namespace QV4 { -struct JSCallData { - JSCallData(const Value *thisObject, const Value *argv, int argc) - : argc(argc), args(const_cast<Value *>(argv)), thisObject(const_cast<Value *>(thisObject)) +template<typename Args> +CallData *callDatafromJS(const Scope &scope, const Args *args, const FunctionObject *f = nullptr) +{ + int size = int(offsetof(QV4::CallData, args)/sizeof(QV4::Value)) + args->argc; + CallData *ptr = reinterpret_cast<CallData *>(scope.alloc<Scope::Uninitialized>(size)); + ptr->function = Encode::undefined(); + ptr->context = Encode::undefined(); + ptr->accumulator = Encode::undefined(); + ptr->thisObject = args->thisObject ? args->thisObject->asReturnedValue() : Encode::undefined(); + ptr->newTarget = Encode::undefined(); + ptr->setArgc(args->argc); + if (args->argc) + memcpy(ptr->args, args->args, args->argc*sizeof(Value)); + if (f) + ptr->function = f->asReturnedValue(); + return ptr; +} + +struct JSCallArguments +{ + JSCallArguments(const Scope &scope, int argc = 0) + : thisObject(scope.alloc()), args(scope.alloc(argc)), argc(argc) { } - JSCallData(const Scope &scope, int argc = 0) - : argc(argc), args(scope.alloc(argc)), thisObject(scope.alloc()) + CallData *callData(const Scope &scope, const FunctionObject *f = nullptr) const { + return callDatafromJS(scope, this, f); } - JSCallData *operator->() { - return this; + Value *thisObject; + Value *args; + const int argc; +}; + +struct JSCallData +{ + JSCallData(const Value *thisObject, const Value *argv, int argc) + : thisObject(thisObject), args(argv), argc(argc) + { } - CallData *callData(const Scope &scope, const FunctionObject *f = nullptr) const { - int size = int(offsetof(QV4::CallData, args)/sizeof(QV4::Value)) + argc; - CallData *ptr = reinterpret_cast<CallData *>(scope.alloc<Scope::Uninitialized>(size)); - ptr->function = Encode::undefined(); - ptr->context = Encode::undefined(); - ptr->accumulator = Encode::undefined(); - ptr->thisObject = thisObject ? thisObject->asReturnedValue() : Encode::undefined(); - ptr->newTarget = Encode::undefined(); - ptr->setArgc(argc); - if (argc) - memcpy(ptr->args, args, argc*sizeof(Value)); - if (f) - ptr->function = f->asReturnedValue(); - return ptr; + Q_IMPLICIT JSCallData(const JSCallArguments &args) + : thisObject(args.thisObject), args(args.args), argc(args.argc) + { } - int argc; - Value *args; - Value *thisObject; + + CallData *callData(const Scope &scope, const FunctionObject *f = nullptr) const + { + return callDatafromJS(scope, this, f); + } + + const Value *thisObject; + const Value *args; + const int argc; }; inline @@ -108,7 +130,7 @@ ReturnedValue FunctionObject::call(const JSCallData &data) const return call(data.thisObject, data.args, data.argc); } -void populateJSCallArguments(ExecutionEngine *v4, JSCallData &jsCall, int argc, +void populateJSCallArguments(ExecutionEngine *v4, JSCallArguments &jsCall, int argc, void **args, const QMetaType *types); struct ScopedStackFrame { diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp index c580fd2bf5..a3ffdb5431 100644 --- a/src/qml/jsruntime/qv4jsonobject.cpp +++ b/src/qml/jsruntime/qv4jsonobject.cpp @@ -700,9 +700,9 @@ QString Stringify::Str(const QString &key, const Value &v) ScopedString s(scope, v4->newString(QStringLiteral("toJSON"))); ScopedFunctionObject toJSON(scope, o->get(s)); if (!!toJSON) { - JSCallData jsCallData(scope, 1); - *jsCallData->thisObject = value; - jsCallData->args[0] = v4->newString(key); + JSCallArguments jsCallData(scope, 1); + *jsCallData.thisObject = value; + jsCallData.args[0] = v4->newString(key); value = toJSON->call(jsCallData); if (v4->hasException) return QString(); @@ -712,10 +712,10 @@ QString Stringify::Str(const QString &key, const Value &v) if (replacerFunction) { ScopedObject holder(scope, v4->newObject()); holder->put(scope.engine->id_empty(), value); - JSCallData jsCallData(scope, 2); - jsCallData->args[0] = v4->newString(key); - jsCallData->args[1] = value; - *jsCallData->thisObject = holder; + JSCallArguments jsCallData(scope, 2); + jsCallData.args[0] = v4->newString(key); + jsCallData.args[1] = value; + *jsCallData.thisObject = holder; value = replacerFunction->call(jsCallData); if (v4->hasException) return QString(); diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index bc145f958d..2ad1ecb6e3 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -102,9 +102,9 @@ ReturnedValue Object::getValueAccessor(const Value *thisObject, const Value &v, return Encode::undefined(); Scope scope(f->engine()); - JSCallData jsCallData(scope); + JSCallArguments jsCallData(scope); if (thisObject) - *jsCallData->thisObject = *thisObject; + *jsCallData.thisObject = *thisObject; return checkedResult(scope.engine, f->call(jsCallData)); } @@ -119,9 +119,9 @@ bool Object::putValue(uint memberIndex, PropertyAttributes attrs, const Value &v if (set) { Scope scope(ic->engine); ScopedFunctionObject setter(scope, set); - JSCallData jsCallData(scope, 1); - jsCallData->args[0] = value; - *jsCallData->thisObject = this; + JSCallArguments jsCallData(scope, 1); + jsCallData.args[0] = value; + *jsCallData.thisObject = this; setter->call(jsCallData); return !ic->engine->hasException; } @@ -519,9 +519,9 @@ bool Object::internalPut(PropertyKey id, const Value &value, Value *receiver) ScopedFunctionObject setter(scope, p->setter()); if (!setter) return false; - JSCallData jsCallData(scope, 1); - jsCallData->args[0] = value; - *jsCallData->thisObject = *receiver; + JSCallArguments jsCallData(scope, 1); + jsCallData.args[0] = value; + *jsCallData.thisObject = *receiver; setter->call(jsCallData); return !scope.engine->hasException; } diff --git a/src/qml/jsruntime/qv4promiseobject.cpp b/src/qml/jsruntime/qv4promiseobject.cpp index ecaff72b22..83bfba9b11 100644 --- a/src/qml/jsruntime/qv4promiseobject.cpp +++ b/src/qml/jsruntime/qv4promiseobject.cpp @@ -227,17 +227,17 @@ public: void ReactionHandler::executeResolveThenable(ResolveThenableEvent *event) { Scope scope(event->then.engine()); - JSCallData jsCallData(scope, 2); + JSCallArguments jsCallData(scope, 2); PromiseObject *promise = event->promise.as<PromiseObject>(); ScopedFunctionObject resolve {scope, FunctionBuilder::makeResolveFunction(scope.engine, promise->d())}; ScopedFunctionObject reject {scope, FunctionBuilder::makeRejectFunction(scope.engine, promise->d())}; - jsCallData->args[0] = resolve; + jsCallData.args[0] = resolve; jsCallData.args[1] = reject; - jsCallData->thisObject = event->thenable.as<QV4::Object>(); + jsCallData.thisObject = event->thenable.as<QV4::Object>(); event->then.as<const FunctionObject>()->call(jsCallData); if (scope.engine->hasException) { - JSCallData rejectCallData(scope, 1); - rejectCallData->args[0] = scope.engine->catchException(); + JSCallArguments rejectCallData(scope, 1); + rejectCallData.args[0] = scope.engine->catchException(); Scoped<RejectWrapper> reject {scope, scope.engine->memoryManager->allocate<QV4::RejectWrapper>()}; reject->call(rejectCallData); } @@ -440,16 +440,16 @@ ReturnedValue PromiseCtor::virtualCallAsConstructor(const FunctionObject *f, con ScopedFunctionObject resolve(scope, FunctionBuilder::makeResolveFunction(scope.engine, a->d())); ScopedFunctionObject reject(scope, FunctionBuilder::makeRejectFunction(scope.engine, a->d())); - JSCallData jsCallData(scope, 2); - jsCallData->args[0] = resolve; - jsCallData->args[1] = reject; - //jsCallData->thisObject = a; VERIFY corretness, but this should be undefined (see below) + JSCallArguments jsCallData(scope, 2); + jsCallData.args[0] = resolve; + jsCallData.args[1] = reject; + //jsCallData.thisObject = a; VERIFY corretness, but this should be undefined (see below) executor->call(jsCallData); // 9. Let completion be Call(executor, undefined, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »). if (scope.engine->hasException) { ScopedValue exception {scope, scope.engine->catchException()}; - JSCallData callData {scope, 1}; + JSCallArguments callData {scope, 1}; callData.args[0] = exception; reject->call(callData); } @@ -649,10 +649,10 @@ ReturnedValue PromiseCtor::method_all(const FunctionObject *f, const Value *this ScopedFunctionObject resolveElement(scope, FunctionBuilder::makeResolveElementFunction(e, index, executionState->d())); - JSCallData jsCallData(scope, 2); - jsCallData->args[0] = resolveElement; - jsCallData->args[1] = reject; - jsCallData->thisObject = nextPromise; + JSCallArguments jsCallData(scope, 2); + jsCallData.args[0] = resolveElement; + jsCallData.args[1] = reject; + jsCallData.thisObject = nextPromise; then->call(jsCallData); if (scope.hasException()) { @@ -793,10 +793,10 @@ ReturnedValue PromiseCtor::method_race(const FunctionObject *f, const Value *thi ScopedFunctionObject resolveOriginalPromise(scope, capability->d()->resolve); - JSCallData jsCallData(scope, 2); - jsCallData->args[0] = resolveOriginalPromise; - jsCallData->args[1] = reject; - jsCallData->thisObject = nextPromise; + JSCallArguments jsCallData(scope, 2); + jsCallData.args[0] = resolveOriginalPromise; + jsCallData.args[1] = reject; + jsCallData.thisObject = nextPromise; then->call(jsCallData); if (scope.hasException()) { @@ -927,10 +927,10 @@ ReturnedValue PromisePrototype::method_catch(const FunctionObject *f, const Valu onRejected = argv[0]; } - JSCallData jsCallData(scope, 2); - jsCallData->args[0] = Encode::undefined(); - jsCallData->args[1] = onRejected; - jsCallData->thisObject = promise; + JSCallArguments jsCallData(scope, 2); + jsCallData.args[0] = Encode::undefined(); + jsCallData.args[1] = onRejected; + jsCallData.thisObject = promise; ScopedString thenName(scope, scope.engine->newIdentifier(QStringLiteral("then"))); ScopedFunctionObject then(scope, promise->get(thenName)); @@ -1084,10 +1084,10 @@ ReturnedValue RejectWrapper::virtualCall(const FunctionObject *f, const Value *t ScopedString thenName(scope, scope.engine->newIdentifier(QStringLiteral("catch"))); ScopedFunctionObject then(scope, promise->get(thenName)); - JSCallData jsCallData(scope, 2); - jsCallData->args[0] = *f; - jsCallData->args[1] = Encode::undefined(); - jsCallData->thisObject = value; + JSCallArguments jsCallData(scope, 2); + jsCallData.args[0] = *f; + jsCallData.args[1] = Encode::undefined(); + jsCallData.thisObject = value; then->call(jsCallData); } diff --git a/src/qml/jsruntime/qv4proxy.cpp b/src/qml/jsruntime/qv4proxy.cpp index bc46f0ce58..b223e73f0f 100644 --- a/src/qml/jsruntime/qv4proxy.cpp +++ b/src/qml/jsruntime/qv4proxy.cpp @@ -90,10 +90,11 @@ ReturnedValue ProxyObject::virtualGet(const Managed *m, PropertyKey id, const Va if (hasProperty) *hasProperty = true; - JSCallData cdata(handler, scope.alloc(3), 3); - cdata.args[0] = target; - cdata.args[1] = id.toStringOrSymbol(scope.engine); - cdata.args[2] = *receiver; + Value *args = scope.alloc(3); + args[0] = target; + args[1] = id.toStringOrSymbol(scope.engine); + args[2] = *receiver; + JSCallData cdata(handler, args, 3); ScopedValue trapResult(scope, static_cast<const FunctionObject *>(trap.ptr)->call(cdata)); if (scope.engine->hasException) @@ -131,11 +132,12 @@ bool ProxyObject::virtualPut(Managed *m, PropertyKey id, const Value &value, Val if (!trap->isFunctionObject()) return scope.engine->throwTypeError(); - JSCallData cdata(handler, scope.alloc(4), 4); - cdata.args[0] = target; - cdata.args[1] = id.toStringOrSymbol(scope.engine); - cdata.args[2] = value; - cdata.args[3] = *receiver; + Value *args = scope.alloc(4); + args[0] = target; + args[1] = id.toStringOrSymbol(scope.engine); + args[2] = value; + args[3] = *receiver; + JSCallData cdata(handler, args, 4); ScopedValue trapResult(scope, static_cast<const FunctionObject *>(trap.ptr)->call(cdata)); if (scope.engine->hasException || !trapResult->toBoolean()) @@ -172,10 +174,11 @@ bool ProxyObject::virtualDeleteProperty(Managed *m, PropertyKey id) if (!trap->isFunctionObject()) return scope.engine->throwTypeError(); - JSCallData cdata(handler, scope.alloc(3), 3); - cdata.args[0] = target; - cdata.args[1] = id.toStringOrSymbol(scope.engine); - cdata.args[2] = o->d(); // ### fix receiver handling + Value *args = scope.alloc(3); + args[0] = target; + args[1] = id.toStringOrSymbol(scope.engine); + args[2] = o->d(); // ### fix receiver handling + JSCallData cdata(handler, args, 3); ScopedValue trapResult(scope, static_cast<const FunctionObject *>(trap.ptr)->call(cdata)); if (scope.engine->hasException || !trapResult->toBoolean()) @@ -208,9 +211,10 @@ bool ProxyObject::virtualHasProperty(const Managed *m, PropertyKey id) if (!trap->isFunctionObject()) return scope.engine->throwTypeError(); - JSCallData cdata(handler, scope.alloc(2), 2); - cdata.args[0] = target; - cdata.args[1] = id.isArrayIndex() ? Value::fromUInt32(id.asArrayIndex()).toString(scope.engine) : id.asStringOrSymbol(); + Value *args = scope.alloc(2); + args[0] = target; + args[1] = id.isArrayIndex() ? Value::fromUInt32(id.asArrayIndex()).toString(scope.engine) : id.asStringOrSymbol(); + JSCallData cdata(handler, args, 2); ScopedValue trapResult(scope, static_cast<const FunctionObject *>(trap.ptr)->call(cdata)); if (scope.engine->hasException) @@ -250,9 +254,10 @@ PropertyAttributes ProxyObject::virtualGetOwnProperty(const Managed *m, Property return Attr_Invalid; } - JSCallData cdata(handler, scope.alloc(2), 2); - cdata.args[0] = target; - cdata.args[1] = id.isArrayIndex() ? Value::fromUInt32(id.asArrayIndex()).toString(scope.engine) : id.asStringOrSymbol(); + Value *args = scope.alloc(2); + args[0] = target; + args[1] = id.isArrayIndex() ? Value::fromUInt32(id.asArrayIndex()).toString(scope.engine) : id.asStringOrSymbol(); + JSCallData cdata(handler, args, 2); ScopedValue trapResult(scope, static_cast<const FunctionObject *>(trap.ptr)->call(cdata)); if (scope.engine->hasException) @@ -325,10 +330,11 @@ bool ProxyObject::virtualDefineOwnProperty(Managed *m, PropertyKey id, const Pro return false; } - JSCallData cdata(handler, scope.alloc(3), 3); - cdata.args[0] = target; - cdata.args[1] = id.isArrayIndex() ? Value::fromUInt32(id.asArrayIndex()).toString(scope.engine) : id.asStringOrSymbol(); - cdata.args[2] = ObjectPrototype::fromPropertyDescriptor(scope.engine, p, attrs); + Value *args = scope.alloc(3); + args[0] = target; + args[1] = id.isArrayIndex() ? Value::fromUInt32(id.asArrayIndex()).toString(scope.engine) : id.asStringOrSymbol(); + args[2] = ObjectPrototype::fromPropertyDescriptor(scope.engine, p, attrs); + JSCallData cdata(handler, args, 3); ScopedValue trapResult(scope, static_cast<const FunctionObject *>(trap.ptr)->call(cdata)); bool result = !scope.engine->hasException && trapResult->toBoolean(); @@ -377,8 +383,9 @@ bool ProxyObject::virtualIsExtensible(const Managed *m) if (!trap->isFunctionObject()) return scope.engine->throwTypeError(); - JSCallData cdata(handler, scope.alloc(1), 1); - cdata.args[0] = target; + Value *args = scope.alloc(1); + args[0] = target; + JSCallData cdata(handler, args, 1); ScopedValue trapResult(scope, static_cast<const FunctionObject *>(trap.ptr)->call(cdata)); if (scope.engine->hasException) @@ -410,8 +417,9 @@ bool ProxyObject::virtualPreventExtensions(Managed *m) if (!trap->isFunctionObject()) return scope.engine->throwTypeError(); - JSCallData cdata(handler, scope.alloc(1), 1); - cdata.args[0] = target; + Value *args = scope.alloc(1); + args[0] = target; + JSCallData cdata(handler, args, 1); ScopedValue trapResult(scope, static_cast<const FunctionObject *>(trap.ptr)->call(cdata)); if (scope.engine->hasException) @@ -447,8 +455,9 @@ Heap::Object *ProxyObject::virtualGetPrototypeOf(const Managed *m) return nullptr; } - JSCallData cdata(handler, scope.alloc(1), 1); - cdata.args[0] = target; + Value *args = scope.alloc(1); + args[0] = target; + JSCallData cdata(handler, args, 1); ScopedValue trapResult(scope, static_cast<const FunctionObject *>(trap.ptr)->call(cdata)); if (scope.engine->hasException) @@ -491,9 +500,10 @@ bool ProxyObject::virtualSetPrototypeOf(Managed *m, const Object *p) return false; } - JSCallData cdata(handler, scope.alloc(2), 2); - cdata.args[0] = target; - cdata.args[1] = p ? p->asReturnedValue() : Encode::null(); + Value *args = scope.alloc(2); + args[0] = target; + args[1] = p ? p->asReturnedValue() : Encode::null(); + JSCallData cdata(handler, args, 2); ScopedValue trapResult(scope, static_cast<const FunctionObject *>(trap.ptr)->call(cdata)); bool result = !scope.engine->hasException && trapResult->toBoolean(); @@ -584,8 +594,9 @@ OwnPropertyKeyIterator *ProxyObject::virtualOwnPropertyKeys(const Object *m, Val return nullptr; } - JSCallData cdata(handler, scope.alloc(1), 1); - cdata.args[0] = target; + Value *args = scope.alloc(1); + args[0] = target; + JSCallData cdata(handler, args, 1); ScopedObject trapResult(scope, static_cast<const FunctionObject *>(trap.ptr)->call(cdata)); if (scope.engine->hasException) return nullptr; diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index f8268849ff..c43a4bfe25 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -1006,14 +1006,14 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase QV4::Scope scope(v4); QV4::ScopedFunctionObject f(scope, This->function.value()); - QV4::JSCallData jsCallData(scope, argCount); - *jsCallData->thisObject = This->thisObject.isUndefined() ? v4->globalObject->asReturnedValue() : This->thisObject.value(); + QV4::JSCallArguments jsCallData(scope, argCount); + *jsCallData.thisObject = This->thisObject.isUndefined() ? v4->globalObject->asReturnedValue() : This->thisObject.value(); for (int ii = 0; ii < argCount; ++ii) { QMetaType type = storage[ii]; if (type == QMetaType::fromType<QVariant>()) { - jsCallData->args[ii] = v4->fromVariant(*((QVariant *)metaArgs[ii + 1])); + jsCallData.args[ii] = v4->fromVariant(*((QVariant *)metaArgs[ii + 1])); } else { - jsCallData->args[ii] = v4->fromVariant(QVariant(type, metaArgs[ii + 1])); + jsCallData.args[ii] = v4->fromVariant(QVariant(type, metaArgs[ii + 1])); } } @@ -2307,7 +2307,7 @@ ReturnedValue QMetaObjectWrapper::constructInternal(const Value *argv, int argc) Scope scope(v4); Scoped<QObjectWrapper> object(scope); - JSCallData cData(scope.alloc(), argv, argc); + JSCallData cData(nullptr, argv, argc); CallData *callData = cData.callData(scope); const QQmlObjectOrGadget objectOrGadget(mo); diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp index 16b9295ab7..fdc595b2a4 100644 --- a/src/qml/jsruntime/qv4regexpobject.cpp +++ b/src/qml/jsruntime/qv4regexpobject.cpp @@ -704,18 +704,18 @@ ReturnedValue RegExpPrototype::method_replace(const FunctionObject *f, const Val int n = 1; Scope innerScope(scope.engine); - JSCallData cData(scope, nCaptures + 3); + JSCallArguments cData(scope, nCaptures + 3); while (n <= nCaptures) { v = resultObject->get(PropertyKey::fromArrayIndex(n)); if (!v->isUndefined()) - cData->args[n] = v->toString(scope.engine); + cData.args[n] = v->toString(scope.engine); ++n; } QString replacement; if (functionalReplace) { - cData->args[0] = matchString; - cData->args[nCaptures + 1] = Encode(position); - cData->args[nCaptures + 2] = s; + cData.args[0] = matchString; + cData.args[nCaptures + 1] = Encode(position); + cData.args[nCaptures + 2] = s; ScopedValue replValue(scope, replaceFunction->call(cData)); if (scope.hasException()) return Encode::undefined(); diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index 2ea54a3512..46c6ce4854 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -802,7 +802,7 @@ ReturnedValue Runtime::GetIterator::call(ExecutionEngine *engine, const Value &i ScopedFunctionObject f(scope, o->get(engine->symbol_iterator())); if (!f) return engine->throwTypeError(); - JSCallData cData(o, scope.alloc(0), 0); + JSCallData cData(o, nullptr, 0); ScopedObject it(scope, f->call(cData)); if (engine->hasException) return Encode::undefined(); @@ -825,7 +825,7 @@ ReturnedValue Runtime::IteratorNext::call(ExecutionEngine *engine, const Value & engine->throwTypeError(); return Encode(true); } - JSCallData cData(&iterator, scope.alloc(0), 0); + JSCallData cData(&iterator, nullptr, 0); ScopedObject o(scope, f->call(cData)); if (scope.hasException()) return Encode(true); diff --git a/src/qml/jsruntime/qv4urlobject.cpp b/src/qml/jsruntime/qv4urlobject.cpp index 937cd6e3a2..a49f840365 100644 --- a/src/qml/jsruntime/qv4urlobject.cpp +++ b/src/qml/jsruntime/qv4urlobject.cpp @@ -1376,10 +1376,10 @@ ReturnedValue UrlSearchParamsPrototype::method_forEach(const FunctionObject *b, Scoped<String> name(scope, o->nameAtRaw(i)); Scoped<String> value(scope, o->valueAtRaw(i)); - QV4::JSCallData calldata(scope, 2); + QV4::JSCallArguments calldata(scope, 2); - calldata->args[0] = value; - calldata->args[1] = name; + calldata.args[0] = value; + calldata.args[1] = name; func->call(calldata); } diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp index 8a641970e7..ee8fbe94e0 100644 --- a/src/qml/qml/qqmlboundsignal.cpp +++ b/src/qml/qml/qqmlboundsignal.cpp @@ -193,7 +193,7 @@ void QQmlBoundSignalExpression::evaluate(void **a) bool ok = QQmlMetaObject(m_target).methodParameterTypes(methodIndex, &storage, nullptr); const int argCount = ok ? storage.size() : 0; - QV4::JSCallData jsCall(scope, argCount); + QV4::JSCallArguments jsCall(scope, argCount); populateJSCallArguments(v4, jsCall, argCount, a, storage.constData()); QQmlJavaScriptExpression::evaluate(jsCall.callData(scope), nullptr); @@ -214,9 +214,9 @@ void QQmlBoundSignalExpression::evaluate(const QList<QVariant> &args) ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation. - QV4::JSCallData jsCall(scope, args.count()); + QV4::JSCallArguments jsCall(scope, args.count()); for (int ii = 0; ii < args.count(); ++ii) { - jsCall->args[ii] = scope.engine->fromVariant(args[ii]); + jsCall.args[ii] = scope.engine->fromVariant(args[ii]); } QQmlJavaScriptExpression::evaluate(jsCall.callData(scope), nullptr); diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index 7d9261604e..bfbbcd2d73 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -1753,9 +1753,9 @@ void QV4::QmlIncubatorObject::statusChanged(QQmlIncubator::Status s) QV4::ScopedFunctionObject f(scope, d()->statusChanged); if (f) { - QV4::JSCallData jsCallData(scope, 1); - *jsCallData->thisObject = this; - jsCallData->args[0] = QV4::Value::fromUInt32(s); + QV4::JSCallArguments jsCallData(scope, 1); + *jsCallData.thisObject = this; + jsCallData.args[0] = QV4::Value::fromUInt32(s); f->call(jsCallData); if (scope.hasException()) { QQmlError error = scope.engine->catchExceptionAsQmlError(); diff --git a/src/qml/qml/qqmldelayedcallqueue.cpp b/src/qml/qml/qqmldelayedcallqueue.cpp index 141c55c0ec..598de8d3a0 100644 --- a/src/qml/qml/qqmldelayedcallqueue.cpp +++ b/src/qml/qml/qqmldelayedcallqueue.cpp @@ -67,11 +67,11 @@ void QQmlDelayedCallQueue::DelayedFunctionCall::execute(QV4::ExecutionEngine *en const QV4::FunctionObject *callback = m_function.as<QV4::FunctionObject>(); Q_ASSERT(callback); const int argCount = array ? array->getLength() : 0; - QV4::JSCallData jsCallData(scope, argCount); - *jsCallData->thisObject = QV4::Encode::undefined(); + QV4::JSCallArguments jsCallData(scope, argCount); + *jsCallData.thisObject = QV4::Encode::undefined(); for (int i = 0; i < argCount; i++) { - jsCallData->args[i] = array->get(i); + jsCallData.args[i] = array->get(i); } callback->call(jsCallData); diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp index ba792cbd8f..260ac79c25 100644 --- a/src/qml/qml/qqmljavascriptexpression.cpp +++ b/src/qml/qml/qqmljavascriptexpression.cpp @@ -185,7 +185,7 @@ QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(bool *isUndefined) { QV4::ExecutionEngine *v4 = m_context->engine()->handle(); QV4::Scope scope(v4); - QV4::JSCallData jsCall(scope); + QV4::JSCallArguments jsCall(scope); return evaluate(jsCall.callData(scope), isUndefined); } diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index 417ac6b3b7..f6681b77c8 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -1000,11 +1000,11 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void * const unsigned int parameterCount = (arguments && arguments->names) ? arguments->names->count() : 0; Q_ASSERT(parameterCount == function->formalParameterCount()); - QV4::JSCallData jsCallData(scope, parameterCount); - *jsCallData->thisObject = v4->global(); + QV4::JSCallArguments jsCallData(scope, parameterCount); + *jsCallData.thisObject = v4->global(); for (uint ii = 0; ii < parameterCount; ++ii) { - jsCallData->args[ii] = scope.engine->metaTypeToJS(QMetaType(arguments->arguments[ii + 1]), a[ii + 1]); + jsCallData.args[ii] = scope.engine->metaTypeToJS(QMetaType(arguments->arguments[ii + 1]), a[ii + 1]); } const QMetaType returnType = methodData->propType(); diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index a1f9377d79..67a26e4806 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -1591,7 +1591,7 @@ void QQmlXMLHttpRequest::dispatchCallbackNow(Object *thisObj, bool done, bool er if (!callback) return; - QV4::JSCallData jsCallData(scope); + QV4::JSCallArguments jsCallData(scope); callback->call(jsCallData); if (scope.engine->hasException) { diff --git a/src/qmllocalstorage/qqmllocalstorage.cpp b/src/qmllocalstorage/qqmllocalstorage.cpp index 8ab7c75ef7..8d8c4f4392 100644 --- a/src/qmllocalstorage/qqmllocalstorage.cpp +++ b/src/qmllocalstorage/qqmllocalstorage.cpp @@ -412,9 +412,9 @@ static ReturnedValue qmlsqldatabase_changeVersion(const FunctionObject *b, const ok = false; db.transaction(); - JSCallData jsCall(scope, 1); - *jsCall->thisObject = scope.engine->globalObject; - jsCall->args[0] = query; + JSCallArguments jsCall(scope, 1); + *jsCall.thisObject = scope.engine->globalObject; + jsCall.args[0] = query; TransactionRollback rollbackOnException(&db, &query->d()->inTransaction); callback->call(jsCall); @@ -468,9 +468,9 @@ static ReturnedValue qmlsqldatabase_transaction_shared(const FunctionObject *b, db.transaction(); if (callback) { - JSCallData jsCall(scope, 1); - *jsCall->thisObject = scope.engine->globalObject; - jsCall->args[0] = w; + JSCallArguments jsCall(scope, 1); + *jsCall.thisObject = scope.engine->globalObject; + jsCall.args[0] = w; TransactionRollback rollbackOnException(&db, &w->d()->inTransaction); callback->call(jsCall); rollbackOnException.clear(); @@ -781,9 +781,9 @@ void QQmlLocalStorage::openDatabaseSync(QQmlV4Function *args) *db->d()->version = version; if (created && dbcreationCallback) { - JSCallData jsCall(scope, 1); - *jsCall->thisObject = scope.engine->globalObject; - jsCall->args[0] = db; + JSCallArguments jsCall(scope, 1); + *jsCall.thisObject = scope.engine->globalObject; + jsCall.args[0] = db; dbcreationCallback->call(jsCall); } diff --git a/src/qmlworkerscript/qquickworkerscript.cpp b/src/qmlworkerscript/qquickworkerscript.cpp index a5d2fe6e87..c5e14acbfe 100644 --- a/src/qmlworkerscript/qquickworkerscript.cpp +++ b/src/qmlworkerscript/qquickworkerscript.cpp @@ -240,9 +240,9 @@ void QQuickWorkerScriptEnginePrivate::processMessage(int id, const QByteArray &d QV4::ScopedValue value(scope, QV4::Serialize::deserialize(data, engine)); - QV4::JSCallData jsCallData(scope, 1); - *jsCallData->thisObject = engine->global(); - jsCallData->args[0] = value; + QV4::JSCallArguments jsCallData(scope, 1); + *jsCallData.thisObject = engine->global(); + jsCallData.args[0] = value; onmessage->call(jsCallData); if (scope.hasException()) { QQmlError error = scope.engine->catchExceptionAsQmlError(); diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp index a5888203cd..110877da45 100644 --- a/src/quick/items/context2d/qquickcanvasitem.cpp +++ b/src/quick/items/context2d/qquickcanvasitem.cpp @@ -713,12 +713,12 @@ void QQuickCanvasItem::updatePolish() QV4::ExecutionEngine *v4 = qmlEngine(this)->handle(); QV4::Scope scope(v4); QV4::ScopedFunctionObject function(scope); - QV4::JSCallData jsCall(scope, 1); - *jsCall->thisObject = QV4::QObjectWrapper::wrap(v4, this); + QV4::JSCallArguments jsCall(scope, 1); + *jsCall.thisObject = QV4::QObjectWrapper::wrap(v4, this); for (auto it = animationCallbacks.cbegin(), end = animationCallbacks.cend(); it != end; ++it) { function = it.value().value(); - jsCall->args[0] = QV4::Value::fromUInt32(QDateTime::currentMSecsSinceEpoch()); + jsCall.args[0] = QV4::Value::fromUInt32(QDateTime::currentMSecsSinceEpoch()); function->call(jsCall); } } diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 43fb3fc1eb..c2b577c274 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -2675,9 +2675,9 @@ static inline bool evaluate_error(QV4::ExecutionEngine *v4, const QV4::Value &o, scope.engine->catchException(); return true; } - QV4::JSCallData jsCallData(scope, 1); - jsCallData->args[0] = o; - *jsCallData->thisObject = v4->global(); + QV4::JSCallArguments jsCallData(scope, 1); + jsCallData.args[0] = o; + *jsCallData.thisObject = v4->global(); function->call(jsCallData); if (scope.engine->hasException) { scope.engine->catchException(); @@ -2705,9 +2705,9 @@ static inline bool evaluate_value(QV4::ExecutionEngine *v4, const QV4::Value &o, return false; QV4::ScopedValue value(scope); - QV4::JSCallData jsCallData(scope, 1); - jsCallData->args[0] = o; - *jsCallData->thisObject = v4->global(); + QV4::JSCallArguments jsCallData(scope, 1); + jsCallData.args[0] = o; + *jsCallData.thisObject = v4->global(); value = function->call(jsCallData); if (scope.engine->hasException) { scope.engine->catchException(); @@ -2734,9 +2734,9 @@ static inline QV4::ReturnedValue evaluate(QV4::ExecutionEngine *v4, const QV4::V } if (!function) return QV4::Encode::undefined(); - QV4::JSCallData jsCallData(scope, 1); - jsCallData->args[0] = o; - *jsCallData->thisObject = v4->global(); + QV4::JSCallArguments jsCallData(scope, 1); + jsCallData.args[0] = o; + *jsCallData.thisObject = v4->global(); QV4::ScopedValue result(scope, function->call(jsCallData)); if (scope.engine->hasException) { scope.engine->catchException(); |