Discussion:
[Development] QtScript vs Qml/QJsEngine ?
Stephen Kelly
2012-05-26 10:51:23 UTC
Permalink
Hi,

There is a discussion on a kde list touching on whether there is a replacement
for QtScript in Qt 5.

http://thread.gmane.org/gmane.comp.kde.devel.kwrite/32993/focus=75079

Is the QJSEngine the start of public API providing a replacement for QtScript?

Thanks,
--
Stephen Kelly <***@kdab.com> | Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
www.kdab.com || Germany +49-30-521325470 || Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-Independent Software Solutions
Kent Hansen
2012-05-30 10:05:04 UTC
Permalink
Hi Stephen,
Post by Stephen Kelly
Hi,
There is a discussion on a kde list touching on whether there is a replacement
for QtScript in Qt 5.
http://thread.gmane.org/gmane.comp.kde.devel.kwrite/32993/focus=75079
Is the QJSEngine the start of public API providing a replacement for QtScript?
Yes, QJS will be a public API in Qt5.

It's not a full-fledged replacement for QtScript, though. QJS currently
provides a subset of QtScript API/features. We've been careful to avoid
introducing API that leaks back-end-specific details. While QJSEngine
can be used alone, the primary use case of QJS is QML integration (i.e.,
using QJSValue to bridge between C++ and JS).

There's no plan to update QtScript to use a newer version or
JavaScriptCore, or to use V8 as the back-end (because of the
aforementioned implementation leaks in the API, which made it too
costly/risky to maintain). The module is Done(tm).

Best regards,
Kent
Olivier Goffart
2012-05-30 13:11:18 UTC
Permalink
Post by Stephen Kelly
Hi,
There is a discussion on a kde list touching on whether there is a
replacement for QtScript in Qt 5.
http://thread.gmane.org/gmane.comp.kde.devel.kwrite/32993/focus=75079
Is the QJSEngine the start of public API providing a replacement for QtScript?
Thanks,
To summarize the problem with QtScript:

QtScript was originally developed using its own JavaScript engine.
While good, it was year behind the state of the art JS engine. It was much
much slower (did not have JIT) and the new ECMAScript feature were not
implemented yet. (the old engine is still available in the QtScript Classic
solution [1])

So we switched the internal engine to use JavaScriptCore.
JavaScriptCore is the WebKit main JavaScript engine. It is developed only for
use within WebKit. It does not have a real public API[2] so QtScript hooks
into the JavaScriptCore internals.
Also, patches to JavaScriptCore were required to add some feature and make
sure we can have all of the QtScript old API. One of the problem is that
QtScript was exposing some implementation details in its API. Some of the
function (for example in QScriptContext) are not even implemented at all in
the JavaScriptCore port because it did not match the way JavaScriptCore is
working. But still, most of the API of QtScript just works like before so
there is not that much behaviour changes.

The problem is that JavaScriptCore is changing a lot. And the upstream do not
care about QtScript use case, they only care about the use within WebKit.
Which means they do not want to include out patches. And they are not really
open to have a stable API to do what is possible with QtScript.

Updating QtScript from upstream is a lot of work. Not only our patches need to
be re-applied, but the whole QtScript code need to be re-adjusted to the new
internals and changes in the private API. That can easily be one week of work
for a couple of developers.

This is the reason why we wanted to change again the backend to V8. That
engine has a stable API. And it is not tight to a html engine, their developer
care about the QtScript use case (embedding a script engine into an
application).
We started the work to port the QtScript API to V8 (our work is still on
gitorious [3])
We made good progress, but run into the problem that V8 has different
internals, and some concept of the QtScript API are really difficult to map to
V8. Nothing is impossible of course, but another problem is that this mapping
has a cost performance wise, and the QML team were not ok with that cost.
When Qt5 was decided, we decided to give up on the QtScript API that comes
from the old backend, and write a smaller API that maps better the V8 API.
(Also, QtScript was no more an important module since QML team had decided to
use V8 directly for performance reasons)

So in your case, the situation is indeed quite bad. The QtScript is not
really maintained anymore.

One possible solution in Qt 4.x would be to use the V8 API directly. Its API
is probably good enough for what you need to achieve. The only problem is
that the V8 API is not really Qt-ish. It has its own way to manage memory you
need to get used to. And you won't have nice automatic QObject bindings with
signals/slots. (you just need to write your own V8 wrappers)


[1] http://doc.qt.nokia.com/solutions/4/qtscriptclassic/index.html
[2] The available C public API is very limited does not let you do more than
executing scripts. There is no way to bind objects properly or do what is
required for most of QtScript usage.
[3] http://qt.gitorious.org/+qt-developers/qt/qt-script-ng/commits/master-v8
--
Olivier

Woboq - Qt services and support - http://woboq.com
Diego Iastrubni
2012-05-30 13:23:49 UTC
Permalink
Post by Stephen Kelly
Hi,
There is a discussion on a kde list touching on whether there is a
replacement for QtScript in Qt 5.
http://thread.gmane.org/gmane.comp.kde.devel.kwrite/32993/focus=75079
Is the QJSEngine the start of public API providing a replacement for QtScript?
So as an application developer, which wants to add JS scripting
capabilities to JavaScript code (so user can extend my application). What
are my options?

How can I load JS files, and call some specific functions defined
internally in those JS? I will also need to expose some API of mine to
those JS files.

(Note: I am not talking about QML at all)
Jedrzej Nowacki
2012-05-30 14:12:01 UTC
Permalink
Post by Diego Iastrubni
Post by Stephen Kelly
Hi,
There is a discussion on a kde list touching on whether there is a
replacement for QtScript in Qt 5.
http://thread.gmane.org/gmane.comp.kde.devel.kwrite/32993/focus=75079
Is the QJSEngine the start of public API providing a replacement for QtScript?
So as an application developer, which wants to add JS scripting
capabilities to JavaScript code (so user can extend my application). What
are my options?
How can I load JS files, and call some specific functions defined
internally in those JS? I will also need to expose some API of mine to
those JS files.
(Note: I am not talking about QML at all)
Hi,
You have two options:
- depend on QtScript module which works fine but is done and will not be
updated with new features.
- depend on QJS api which is smaller definitely less powerful, but well
integrated with QML
Cheers,
Jędrek
Kent Hansen
2012-05-31 06:41:29 UTC
Permalink
Hi,
Post by Stephen Kelly
Post by Stephen Kelly
Hi,
There is a discussion on a kde list touching on whether there is a
replacement for QtScript in Qt 5.
http://thread.gmane.org/gmane.comp.kde.devel.kwrite/32993/focus=75079
Post by Stephen Kelly
Is the QJSEngine the start of public API providing a replacement for QtScript?
So as an application developer, which wants to add JS scripting
capabilities to JavaScript code (so user can extend my application).
What are my options?
How can I load JS files, and call some specific functions defined
internally in those JS? I will also need to expose some API of mine to
those JS files.
(Note: I am not talking about QML at all)
The QJSEngine/Value API already supports that use case. The code would
be 99% the same as with QtScript, if you're familiar with that.

QJSEngine engine;
engine.evaluate("function add(a, b) { return a+ b; }"); // contents of
some file
QJSValue addFun = engine.globalObject().property("add"); // get the
function from the script
qDebug() << addFun.call(QJSValueList() << 1 << 2).toNumber();

Exposing a QObject is also similar to QtScript:

MyQObject *obj = ...;
engine.globalObject().setProperty("myQObject", engine.newQObject(obj));
engine.evaluate("myQObject.someSlot()");

What's missing is the more low-level API, like QScriptContext that
Olivier mentioned. There's currently no API for exposing a "plain C
callback" with QJS; everything has to go through the QObject binding.
You can provide individual functions to JS by only exposing a particular
QObject wrapper function, e.g.:

engine.globalObject().setProperty("myGlobalFunction",
engine.newQObject(obj).property("someSlot"));

There's currently no API for dealing with exceptions. QtScript had
uncaughtExceptionBacktrace() and friends; in QJS there is only
QJSValue::isError() as of yet. You can get error messages, stack trace
etc. by querying properties of error objects.

QJS has no debugging API or tools. V8 provides a public debugging API,
but we'd have to be very careful if QJS were to wrap that (again, to
avoid leaking back-end details).

Also worth mentioning is the quirky
QScriptEngine::setProcessEventsInterval(), which was annoying to support
with both JSC and V8 (and didn't ever work reliably even with the
original back-end, because the engine could potentially call into a
long-running C++ function, which invalidated the promise of respecting
the user-specified interval). If you need to execute potentially
long-running JavaScript, you'll need to do it from a separate thread
with QJS.

Best regards,
Kent

Thiago Macieira
2012-05-30 14:57:07 UTC
Permalink
Post by Olivier Goffart
QtScript was originally developed using its own JavaScript engine.
Add here, because Olivier's description skipped one or two years in history
between the sentences.

When it was originally developed, the QtScript engine was state-of-the-art and
was faster than almost any JavaScript implementation that we could get our
hands on, specifically Mozilla's SpiderMonkey and KDE / WebKit's KJS (they
hadn't diverged much yet). IIRC, the only areas where Roberto didn't manage to
get better performance was where Qt compatibility was required, for example in
the use of QString.
Post by Olivier Goffart
While good, it was year behind the state of the art JS engine. It was much
much slower (did not have JIT) and the new ECMAScript feature were not
implemented yet. (the old engine is still available in the QtScript
Classic solution [1])
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Intel Sweden AB - Registration Number: 556189-6027
Knarrarnäsgatan 15, 164 40 Kista, Stockholm, Sweden
Loading...