| 
									
										
										
										
											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
 |