aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4functionobject.cpp
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-04-18 01:00:05 +0200
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-04-18 01:00:06 +0200
commitf0f01cc37910a6b1ca454a4374138d76cd09901a (patch)
tree1b112993e5b84f58541c7216d1fcc738271f0ab3 /src/qml/jsruntime/qv4functionobject.cpp
parent7c3dad14d38aea0239e5e66c9018acdc0e6c0b55 (diff)
parent6069cc1cd1a6309cdffeb8bdd9c4035f33742228 (diff)
Merge remote-tracking branch 'origin/5.11' into dev
Diffstat (limited to 'src/qml/jsruntime/qv4functionobject.cpp')
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp47
1 files changed, 32 insertions, 15 deletions
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index bc28dd2f6c..73a8eb1193 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -75,7 +75,6 @@ void Heap::FunctionObject::init(QV4::ExecutionContext *scope, QV4::String *name,
jsConstruct = QV4::FunctionObject::callAsConstructor;
Object::init();
- function = nullptr;
this->scope.set(scope->engine(), scope->d());
Scope s(scope->engine());
ScopedFunctionObject f(s, this);
@@ -88,7 +87,6 @@ void Heap::FunctionObject::init(QV4::ExecutionContext *scope, QV4::String *name,
jsConstruct = reinterpret_cast<const ObjectVTable *>(vtable())->callAsConstructor;
Object::init();
- function = nullptr;
this->scope.set(scope->engine(), scope->d());
Scope s(scope->engine());
ScopedFunctionObject f(s, this);
@@ -101,8 +99,7 @@ void Heap::FunctionObject::init(QV4::ExecutionContext *scope, Function *function
jsConstruct = reinterpret_cast<const ObjectVTable *>(vtable())->callAsConstructor;
Object::init();
- this->function = function;
- function->compilationUnit->addref();
+ setFunction(function);
this->scope.set(scope->engine(), scope->d());
Scope s(scope->engine());
ScopedString name(s, function->name());
@@ -123,13 +120,18 @@ void Heap::FunctionObject::init()
jsConstruct = reinterpret_cast<const ObjectVTable *>(vtable())->callAsConstructor;
Object::init();
- function = nullptr;
this->scope.set(internalClass->engine, internalClass->engine->rootContext()->d());
Q_ASSERT(internalClass && internalClass->find(internalClass->engine->id_prototype()) == Index_Prototype);
setProperty(internalClass->engine, Index_Prototype, Primitive::undefinedValue());
}
-
+void Heap::FunctionObject::setFunction(Function *f)
+{
+ if (f) {
+ function = f;
+ function->compilationUnit->addref();
+ }
+}
void Heap::FunctionObject::destroy()
{
if (function)
@@ -347,20 +349,36 @@ ReturnedValue FunctionPrototype::method_bind(const FunctionObject *b, const Valu
{
QV4::Scope scope(b);
ScopedFunctionObject target(scope, thisObject);
- if (!target)
+ if (!target || target->isBinding())
return scope.engine->throwTypeError();
ScopedValue boundThis(scope, argc ? argv[0] : Primitive::undefinedValue());
Scoped<MemberData> boundArgs(scope, (Heap::MemberData *)nullptr);
- if (argc > 1) {
- boundArgs = MemberData::allocate(scope.engine, argc - 1);
- boundArgs->d()->values.size = argc - 1;
- for (uint i = 0, ei = static_cast<uint>(argc - 1); i < ei; ++i)
+
+ int nArgs = (argc - 1 >= 0) ? argc - 1 : 0;
+ if (target->isBoundFunction()) {
+ BoundFunction *bound = static_cast<BoundFunction *>(target.getPointer());
+ Scoped<MemberData> oldArgs(scope, bound->boundArgs());
+ boundThis = bound->boundThis();
+ int oldSize = oldArgs->size();
+ boundArgs = MemberData::allocate(scope.engine, oldSize + nArgs);
+ boundArgs->d()->values.size = oldSize + nArgs;
+ for (uint i = 0; i < static_cast<uint>(oldSize); ++i)
+ boundArgs->set(scope.engine, i, oldArgs->data()[i]);
+ for (uint i = 0; i < static_cast<uint>(nArgs); ++i)
+ boundArgs->set(scope.engine, oldSize + i, argv[i + 1]);
+ target = bound->target();
+ } else if (nArgs) {
+ boundArgs = MemberData::allocate(scope.engine, nArgs);
+ boundArgs->d()->values.size = nArgs;
+ for (uint i = 0, ei = static_cast<uint>(nArgs); i < ei; ++i)
boundArgs->set(scope.engine, i, argv[i + 1]);
}
- ExecutionContext *global = scope.engine->rootContext();
- return BoundFunction::create(global, target, boundThis, boundArgs)->asReturnedValue();
+ ScopedContext ctx(scope, target->scope());
+ Heap::BoundFunction *bound = BoundFunction::create(ctx, target, boundThis, boundArgs);
+ bound->setFunction(target->function());
+ return bound->asReturnedValue();
}
DEFINE_OBJECT_VTABLE(ScriptFunction);
@@ -392,8 +410,7 @@ void Heap::ScriptFunction::init(QV4::ExecutionContext *scope, Function *function
FunctionObject::init();
this->scope.set(scope->engine(), scope->d());
- this->function = function;
- function->compilationUnit->addref();
+ setFunction(function);
Q_ASSERT(function);
Q_ASSERT(function->code);