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