|
3 | 3 | #include <emscripten.h> // EM_JS, EM_JS_DEPS |
4 | 4 | #include <Python.h> |
5 | 5 |
|
6 | | -// We have to be careful to work correctly with memory snapshots. Even if we are |
7 | | -// loading a memory snapshot, we need to perform the JS initialization work. |
8 | | -// That means we can't call the initialization code from C. Instead, we export |
9 | | -// this function pointer to JS and then fill it in a preRun function which runs |
10 | | -// unconditionally. |
11 | | -/** |
12 | | - * Backwards compatible trampoline works with all JS runtimes |
13 | | - */ |
14 | 6 | EM_JS( |
15 | 7 | PyObject*, |
16 | 8 | _PyEM_TrampolineCall_inner, (int* success, |
17 | 9 | PyCFunctionWithKeywords func, |
18 | 10 | PyObject *arg1, |
19 | 11 | PyObject *arg2, |
20 | 12 | PyObject *arg3), { |
| 13 | + // JavaScript fallback trampoline |
21 | 14 | return wasmTable.get(func)(arg1, arg2, arg3); |
22 | 15 | } |
23 | | -try { |
24 | | - const trampolineModule = getWasmTrampolineModule(); |
25 | | - const trampolineInstance = new WebAssembly.Instance(trampolineModule, { |
26 | | - env: { __indirect_function_table: wasmTable, memory: wasmMemory }, |
27 | | - }); |
28 | | - _PyEM_TrampolineCall_inner = trampolineInstance.exports.trampoline_call; |
29 | | -} catch (e) {} |
| 16 | +// Try to replace the JS definition of _PyEM_TrampolineCall_inner with a wasm |
| 17 | +// version. |
| 18 | +(function () { |
| 19 | + // iOS ships broken wasm-gc, so feature detect and turn it off |
| 20 | + const isIOS = |
| 21 | + globalThis.navigator && |
| 22 | + (/iPad|iPhone|iPod/.test(navigator.userAgent) || |
| 23 | + // Starting with iPadOS 13, iPads might send a platform string that looks like a desktop Mac. |
| 24 | + // To differentiate, we check if the platform is 'MacIntel' (common for Macs and newer iPads) |
| 25 | + // AND if the device has multi-touch capabilities (navigator.maxTouchPoints > 1) |
| 26 | + (navigator.platform === "MacIntel" && |
| 27 | + typeof navigator.maxTouchPoints !== "undefined" && |
| 28 | + navigator.maxTouchPoints > 1)); |
| 29 | + if (isIOS) { |
| 30 | + return; |
| 31 | + } |
| 32 | + try { |
| 33 | + const trampolineModule = getWasmTrampolineModule(); |
| 34 | + const trampolineInstance = new WebAssembly.Instance(trampolineModule, { |
| 35 | + env: { __indirect_function_table: wasmTable, memory: wasmMemory }, |
| 36 | + }); |
| 37 | + _PyEM_TrampolineCall_inner = trampolineInstance.exports.trampoline_call; |
| 38 | + console.log("Assigned _PyEM_TrampolineCall_inner!"); |
| 39 | + } catch (e) { |
| 40 | + // Compilation error due to missing wasm-gc support, fall back to JS |
| 41 | + // trampoline |
| 42 | + } |
| 43 | +})(); |
30 | 44 | ); |
31 | 45 |
|
32 | 46 | PyObject* |
|
0 commit comments