wasm: Migrate WasmSuspendResume functions from EM_JS to C++

There is a problem with generating functions signature by Emscripten for
functions defined with EM_JS. This break dynamic linking when these
functions are imported from SIDE_MODULES.
This commit works around that issue by porting these functions to C++
which fixes their signature generation.

Task-number: QTBUG-136741
Change-Id: I3356d4dbe89b99e099d9d22327370471dc03c935
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
This commit is contained in:
Piotr Wiercinski 2025-05-12 17:41:18 +02:00
parent 427bd9a42c
commit 47e3a5b804

View File

@ -42,13 +42,15 @@ QWasmSuspendResumeControl *QWasmSuspendResumeControl::s_suspendResumeControl = n
// Setup/constructor function for Module.suspendResumeControl.
// FIXME if assigning to the Module object from C++ is/becomes possible
// then this does not need to be a separate JS function.
EM_JS(void, qtSuspendResumeControlClearJs, (), {
Module.qtSuspendResumeControl = {
resume: null,
eventHandlers: {},
pendingEvents: [],
};
});
void qtSuspendResumeControlClearJs() {
EM_ASM({
Module.qtSuspendResumeControl = ({
resume: null,
eventHandlers: {},
pendingEvents: [],
});
});
}
// Suspends the calling thread
EM_ASYNC_JS(void, qtSuspendJs, (), {
@ -60,23 +62,26 @@ EM_ASYNC_JS(void, qtSuspendJs, (), {
// Registers a JS event handler which when called registers its index
// as the "current" event handler, and then resumes the wasm instance.
// The wasm instance will then call the C++ event after it is resumed.
EM_JS(void, qtRegisterEventHandlerJs, (int index), {
let control = Module.qtSuspendResumeControl;
let handler = (arg) => {
control.pendingEvents.push({
index: index,
arg: arg
});
if (control.resume) {
const resume = control.resume;
control.resume = null;
resume();
} else {
Module.qtSendPendingEvents(); // not suspended, call the handler directly
}
};
control.eventHandlers[index] = handler;
});
void qtRegisterEventHandlerJs(int index) {
EM_ASM({
let index = $0;
let control = Module.qtSuspendResumeControl;
let handler = (arg) => {
control.pendingEvents.push({
index: index,
arg: arg
});
if (control.resume) {
const resume = control.resume;
control.resume = null;
resume();
} else {
Module.qtSendPendingEvents(); // not suspended, call the handler directly
}
};
control.eventHandlers[index] = handler;
}, index);
}
QWasmSuspendResumeControl::QWasmSuspendResumeControl()
{