mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 07:31:38 +00:00 
			
		
		
		
	gh-128627: Use __builtin_wasm_test_function_pointer_signature for Emscripten trampoline (GH-137470)
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.
(cherry picked from commit 2629ee4eb0)
Co-authored-by: Hood Chatham <roberthoodchatham@gmail.com>
		
	
			
		
			
				
	
	
		
			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
 |