2023-09-15 15:04:21 -07:00
|
|
|
#if defined(PY_CALL_TRAMPOLINE)
|
|
|
|
|
2025-01-13 00:09:39 +01:00
|
|
|
#include <emscripten.h> // EM_JS, EM_JS_DEPS
|
2023-09-15 15:04:21 -07:00
|
|
|
#include <Python.h>
|
|
|
|
|
2025-09-17 18:21:01 +02:00
|
|
|
EM_JS(
|
|
|
|
PyObject*,
|
|
|
|
_PyEM_TrampolineCall_inner, (int* success,
|
|
|
|
PyCFunctionWithKeywords func,
|
|
|
|
PyObject *arg1,
|
|
|
|
PyObject *arg2,
|
|
|
|
PyObject *arg3), {
|
|
|
|
// JavaScript fallback trampoline
|
|
|
|
return wasmTable.get(func)(arg1, arg2, arg3);
|
2025-01-13 00:09:39 +01:00
|
|
|
}
|
2025-09-17 18:21:01 +02:00
|
|
|
// Try to replace the JS definition of _PyEM_TrampolineCall_inner with a wasm
|
|
|
|
// version.
|
|
|
|
(function () {
|
2025-06-12 06:28:47 +02:00
|
|
|
// Starting with iOS 18.3.1, WebKit on iOS has an issue with the garbage
|
|
|
|
// collector that breaks the call trampoline. See #130418 and
|
|
|
|
// https://bugs.webkit.org/show_bug.cgi?id=293113 for details.
|
|
|
|
let isIOS = globalThis.navigator && (
|
|
|
|
/iPad|iPhone|iPod/.test(navigator.userAgent) ||
|
|
|
|
// Starting with iPadOS 13, iPads might send a platform string that looks like a desktop Mac.
|
|
|
|
// To differentiate, we check if the platform is 'MacIntel' (common for Macs and newer iPads)
|
|
|
|
// AND if the device has multi-touch capabilities (navigator.maxTouchPoints > 1)
|
|
|
|
(navigator.platform === 'MacIntel' && typeof navigator.maxTouchPoints !== 'undefined' && navigator.maxTouchPoints > 1)
|
2025-06-17 01:41:46 +02:00
|
|
|
);
|
2025-02-24 00:26:04 +01:00
|
|
|
if (isIOS) {
|
2025-09-17 18:21:01 +02:00
|
|
|
return;
|
2025-02-24 00:26:04 +01:00
|
|
|
}
|
2025-01-13 00:09:39 +01:00
|
|
|
try {
|
2025-09-17 18:21:01 +02:00
|
|
|
const trampolineModule = getWasmTrampolineModule();
|
|
|
|
const trampolineInstance = new WebAssembly.Instance(trampolineModule, {
|
|
|
|
env: { __indirect_function_table: wasmTable, memory: wasmMemory },
|
|
|
|
});
|
|
|
|
_PyEM_TrampolineCall_inner = trampolineInstance.exports.trampoline_call;
|
2025-01-23 00:02:04 +00:00
|
|
|
} catch (e) {
|
2025-09-17 18:21:01 +02:00
|
|
|
// Compilation error due to missing wasm-gc support, fall back to JS
|
|
|
|
// trampoline
|
2024-07-14 11:25:09 +02:00
|
|
|
}
|
2025-09-17 18:21:01 +02:00
|
|
|
})();
|
2025-01-13 00:09:39 +01:00
|
|
|
);
|
2023-09-15 15:04:21 -07:00
|
|
|
|
|
|
|
PyObject*
|
2025-01-13 00:09:39 +01:00
|
|
|
_PyEM_TrampolineCall(PyCFunctionWithKeywords func,
|
|
|
|
PyObject* self,
|
|
|
|
PyObject* args,
|
|
|
|
PyObject* kw)
|
2023-09-15 15:04:21 -07:00
|
|
|
{
|
2025-09-17 18:21:01 +02:00
|
|
|
int success = 1;
|
|
|
|
PyObject *result = _PyEM_TrampolineCall_inner(&success, func, self, args, kw);
|
|
|
|
if (!success) {
|
|
|
|
PyErr_SetString(PyExc_SystemError, "Handler takes too many arguments");
|
2023-09-15 15:04:21 -07:00
|
|
|
}
|
2025-09-17 18:21:01 +02:00
|
|
|
return result;
|
2023-09-15 15:04:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|