[Development] Wasm: Support for Emscripten JSPI

Stephan Bergmann sberg.fun at gmail.com
Tue Dec 10 15:55:58 CET 2024


Hi again,

Another thing I'm looking into is the emerging support for JSPI in 
browsers, Emscripten, and Qt.  And I wonder whether, in my below 
experiments, I'm holding anything fundamentally wrong (which might 
easily be the case):

I have a minimal qmake-based project that just shows a window with a 
button, and when the button gets clicked it opens a dialog:

> $ cat dialog.pro
> CONFIG += debug
> HEADERS += window.h
> QT += widgets
> SOURCES += main.cc

> $ cat window.h
> #ifndef INCLUDED_window_h
> #define INCLUDED_window_h
> 
> #include "QtWidgets/QPushButton"
> #include "QtWidgets/QWidget"
> 
> class Window: public QWidget {
>     Q_OBJECT
> public:
>     Window();
> 
> private slots:
>     void showDialog();
> 
> private:
>     QPushButton * button_;
> };
> 
> #endif

> $ cat main.cc
> #include "QtWidgets/QApplication"
> #include "QtWidgets/QDialog"
> #include "QtWidgets/QPushButton"
> 
> #include "window.h"
> 
> Window::Window() {
>     button_ = new QPushButton("dialog", this);
>     connect(button_, SIGNAL(clicked()), this, SLOT(showDialog()));
> }
> 
> void Window::showDialog() {
>     QDialog dialog(this);
>     dialog.exec();
> }
> 
> int main(int argc, char ** argv) {
>     QApplication app(argc, argv);
>     Window window;
>     window.show();
>     return app.exec();
> }

When building this for Wasm and running it in a browser, opening the 
dialog would give the expected

> Warning: exec() is not supported on Qt for WebAssembly in this configuration. Please build with asyncify support, or use an asynchronous API like QDialog::open()
> Uncaught Please compile your program with async support in order to use asynchronous operations like emscripten_sleep

But when I build recent Qt dev branch configured with 
`-feature-wasm-jspi`, and add `QMAKE_LFLAGS += -sJSPI` to dialog.pro, my 
understanding is that opening the dialog should then work.  However, at 
least when I build against recent emsdk 3.1.73, and run in recent Chrome 
131 with JSPI enabled in <chrome://flags>, opening the dialog causes an

> Uncaught RuntimeError: attempting to suspend without a WebAssembly.promising export

Am I doing anything wrong?

(And a minor observation regarding the need to explicitly set 
`QMAKE_LFLAGS += -sJSPI` as described at 
<https://code.qt.io/cgit/qt/qtdoc.git/commit/?id=7516b4e74feb55a34c4d1409854ad291cafd7b3e> 
"wasm: document asyncify JSPI":  My naive understanding is that that 
should no longer be necessary thanks to 
<https://code.qt.io/cgit/qt/qtbase.git/commit/?id=7a21ba15ed0385878ba9bf9741b8df9b61ebe3cc> 
"wasm: support enabling JSPI via QT_EMSCRIPTEN_ASYNCIFY=2", but only 
actually works when configuring Qt with the old `-device-option 
QT_EMSCRIPTEN_ASYNCIFY=2`, but not with the new `-feature-wasm-jspi` 
alternative introduced in 
<https://code.qt.io/cgit/qt/qtbase.git/commit/?id=92ad0f1f014909a792d157dca680fca5cff01605> 
"wasm: add configure option for asyncify JSPI".  The latter presumably 
forgot to adapt mkspecs/common/wasm/wasm.conf?)


More information about the Development mailing list