diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-09-01 11:48:15 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2017-09-02 07:12:17 +0000 |
commit | 74c8fe86755af485f8d0a47799d6d50f00070f05 (patch) | |
tree | 9e3d8c51d46d9f0fa2555cc77d184d6b3ee1be7d /src/qml/jsruntime/qv4functionobject.cpp | |
parent | a91383545c6f487cff61f401d11f1e85939222e9 (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.cpp | 53 |
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(); } |