-
Task
-
Resolution: Unresolved
-
P1: Critical
-
None
-
6.8, 6.9, 6.10
-
None
Currently you can transfer ownership of a QObject to the JavaScript engine without actually notifying any particular JavaScript engine. The QJSEngine::setObjectOwnership() method is static, after all. The transfer of ownership only takes effect if you expose the QObject to the engine in a way that creates a heap object to track it. There are many ways of passing QObjects around that don't create a heap object. Creating a heap object is expensive and we try to avoid it where we can. Therefore, you never really know whether the JavaScript engine has actually assumed ownership of the object or not.
On top of this, our documentation states that object ownership is automatically transferred if you return a QObject from a Q_INVOKABLE method. It does not state, however, whether this also holds for lists of objects, and how the method is supposed to be invoked. The behavior regarding lists has changed between Qt 6.5 and 6.8. Furthermore, the ownership is currently not transferred if the method is called from generated C++ code.
In general, the current API is confusing and error-prone. We should re-design it. One way to do so is taking inspiration from NodeJS's "escape" value scopes. An escaping scope basically places its value's on the caller's stack. This is quite adequate for returning a value.
We could have a pair of new methods in QJSEngine that handle the cases of transferring ownership to the current C++ scope or the current JavaScript scope:
QJSManagedValue scopedObject(QObject *); QObject *returnedObject(QObject *);
It can be debated whether the return value of returnedObject() should be a special type ReturnedObject<T> to mark the object as actually returned.
Once this API is in place we can deprecate the previous mechanisms of transferring ownership. We'd produce a warning every time setObjectOwnership() or returning from Q_INVOKABLEs is used to effectively transfer ownership to JavaScript.
In addition we'd still need a way to track single objects returned from invokables to generated C++ code.