aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4functionobject.cpp
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/qml/jsruntime/qv4functionobject.cpp
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/qml/jsruntime/qv4functionobject.cpp')
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp53
1 files changed, 25 insertions, 28 deletions
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();
}