diff options
| author | Ulf Hermann <ulf.hermann@qt.io> | 2024-05-06 17:18:09 +0200 |
|---|---|---|
| committer | Ulf Hermann <ulf.hermann@qt.io> | 2024-05-14 14:17:02 +0200 |
| commit | 1f13344e500e837e296212eaf3525e57e14cd055 (patch) | |
| tree | cda35827cc5227793078f4620aad8e0593ed627d /src/qml/jsruntime/qv4functionobject.cpp | |
| parent | 8b6a9403bf2e04d34b9b07d2780186029fab99d0 (diff) | |
V4: Move FunctionObject flags into VTable
These are really rather generic type traits that shouldn't be stored in
individual objects. Moving them away slims down FunctionObject even
more.
FunctionObject doesn't add any extra overhead on top of Object anymore.
You also cannot easily cast an object that doesn't implement any call
methods to FunctionObject anymore. Therefore, we can derive from
FunctionObject even if we only need to implement call methods in a
further derived class.
The fact that ProxyObject is not a FunctionObject but its derivatives
are is already tested as part of the ecmascript test suite.
Task-number: QTBUG-124662
Change-Id: I5632de8c54ac1d6a4b15c4926c655b87b475db49
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4functionobject.cpp')
| -rw-r--r-- | src/qml/jsruntime/qv4functionobject.cpp | 35 |
1 files changed, 15 insertions, 20 deletions
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index 153e8964e8..7240500012 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -37,8 +37,6 @@ void Heap::FunctionObject::init(QV4::ExecutionEngine *engine, QV4::String *name) ScopedFunctionObject f(s, this); if (name) f->setName(name); - - isConstructor = (vtable()->callAsConstructor != QV4::FunctionObject::virtualCallAsConstructor); } void Heap::FunctionObject::init(QV4::ExecutionEngine *engine, const QString &name) @@ -100,22 +98,14 @@ ReturnedValue FunctionObject::name() const return get(engine()->id_name()); } -ReturnedValue FunctionObject::virtualCall( - const FunctionObject *f, const Value *, const Value *, int) -{ - return f->engine()->throwTypeError(QStringLiteral("Function can only be called with |new|.")); -} - -void FunctionObject::virtualCallWithMetaTypes( - const FunctionObject *f, QObject *, void **, const QMetaType *, int) +ReturnedValue FunctionObject::failCall() const { - f->engine()->throwTypeError(QStringLiteral("Function can only be called with |new|.")); + return engine()->throwTypeError(QStringLiteral("Function can only be called with |new|.")); } -ReturnedValue FunctionObject::virtualCallAsConstructor( - const FunctionObject *f, const Value *, int, const Value *) +ReturnedValue FunctionObject::failCallAsConstructor() const { - return f->engine()->throwTypeError(QStringLiteral("Function is not a constructor.")); + return engine()->throwTypeError(QStringLiteral("Function is not a constructor.")); } void FunctionObject::virtualConvertAndCall( @@ -431,7 +421,13 @@ ReturnedValue FunctionPrototype::method_bind(const FunctionObject *b, const Valu boundArgs->set(scope.engine, i, argv[i + 1]); } - return BoundFunction::create(target, boundThis, boundArgs)->asReturnedValue(); + if (target->isConstructor()) { + return scope.engine->memoryManager->allocate<BoundConstructor>(target, boundThis, boundArgs) + ->asReturnedValue(); + } + + return scope.engine->memoryManager->allocate<BoundFunction>(target, boundThis, boundArgs) + ->asReturnedValue(); } ReturnedValue FunctionPrototype::method_hasInstance(const FunctionObject *, const Value *thisObject, const Value *argv, int argc) @@ -569,7 +565,6 @@ void Heap::ArrowFunction::init(QV4::ExecutionContext *scope, Function *function, Scope s(scope); Q_ASSERT(internalClass && internalClass->verifyIndex(s.engine->id_length()->propertyKey(), Index_Length)); setProperty(s.engine, Index_Length, Value::fromInt32(int(function->compiledFunction->length))); - canBeTailCalled = true; } void Heap::ScriptFunction::init(QV4::ExecutionContext *scope, Function *function) @@ -725,9 +720,6 @@ void Heap::BoundFunction::init( this->boundArgs.set(s.engine, boundArgs ? boundArgs->d() : nullptr); this->boundThis.set(s.engine, boundThis); - if (!target->isConstructor()) - isConstructor = false; - ScopedObject f(s, this); ScopedValue l(s, target->get(engine->id_length())); @@ -766,7 +758,10 @@ ReturnedValue BoundFunction::virtualCall(const FunctionObject *fo, const Value * return checkedResult(v4, target->call(jsCallData)); } -ReturnedValue BoundFunction::virtualCallAsConstructor(const FunctionObject *fo, const Value *argv, int argc, const Value *) +DEFINE_OBJECT_VTABLE(BoundConstructor); + +ReturnedValue BoundConstructor::virtualCallAsConstructor( + const FunctionObject *fo, const Value *argv, int argc, const Value *) { const BoundFunction *f = static_cast<const BoundFunction *>(fo); Scope scope(f->engine()); |
