mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	 2629ee4eb0
			
		
	
	
		2629ee4eb0
		
			
		
	
	
	
	
		
			
			With https://github.com/llvm/llvm-project/pull/150201 being merged, there is now a better way to generate the Emscripten trampoline, instead of including hand-generated binary WASM content. Requires Emscripten 4.0.12.
		
			
				
	
	
		
			59 lines
		
	
	
	
		
			2.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			59 lines
		
	
	
	
		
			2.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #if defined(PY_CALL_TRAMPOLINE)
 | |
| 
 | |
| #include <emscripten.h>             // EM_JS, EM_JS_DEPS
 | |
| #include <Python.h>
 | |
| 
 | |
| 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);
 | |
| }
 | |
| // Try to replace the JS definition of _PyEM_TrampolineCall_inner with a wasm
 | |
| // version.
 | |
| (function () {
 | |
|     // 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)
 | |
|     );
 | |
|     if (isIOS) {
 | |
|         return;
 | |
|     }
 | |
|     try {
 | |
|         const trampolineModule = getWasmTrampolineModule();
 | |
|         const trampolineInstance = new WebAssembly.Instance(trampolineModule, {
 | |
|             env: { __indirect_function_table: wasmTable, memory: wasmMemory },
 | |
|         });
 | |
|         _PyEM_TrampolineCall_inner = trampolineInstance.exports.trampoline_call;
 | |
|     } catch (e) {
 | |
|         // Compilation error due to missing wasm-gc support, fall back to JS
 | |
|         // trampoline
 | |
|     }
 | |
| })();
 | |
| );
 | |
| 
 | |
| PyObject*
 | |
| _PyEM_TrampolineCall(PyCFunctionWithKeywords func,
 | |
|                      PyObject* self,
 | |
|                      PyObject* args,
 | |
|                      PyObject* kw)
 | |
| {
 | |
|     int success = 1;
 | |
|     PyObject *result = _PyEM_TrampolineCall_inner(&success, func, self, args, kw);
 | |
|     if (!success) {
 | |
|         PyErr_SetString(PyExc_SystemError, "Handler takes too many arguments");
 | |
|     }
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| #endif
 |