mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	
		
			
	
	
		
			39 lines
		
	
	
	
		
			1.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			39 lines
		
	
	
	
		
			1.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|   | // This file must be compiled with -mgc to enable the extra wasm-gc
 | ||
|  | // instructions. It has to be compiled separately because not enough JS runtimes
 | ||
|  | // support wasm-gc yet. If the JS runtime does not support wasm-gc (or has buggy
 | ||
|  | // support like iOS), we will use the JS trampoline fallback.
 | ||
|  | 
 | ||
|  | // We can't import Python.h here because it is compiled/linked with -nostdlib.
 | ||
|  | // We don't need to know what's inside PyObject* anyways. We could just call it
 | ||
|  | // void* everywhere. There are two reasons to do this:
 | ||
|  | // 1. to improve readability
 | ||
|  | // 2. eventually when we are comfortable requiring wasm-gc, we can merge this
 | ||
|  | //    into emscripten_trampoline.c without worrying about it.
 | ||
|  | typedef void PyObject; | ||
|  | 
 | ||
|  | typedef PyObject* (*three_arg)(PyObject*, PyObject*, PyObject*); | ||
|  | typedef PyObject* (*two_arg)(PyObject*, PyObject*); | ||
|  | typedef PyObject* (*one_arg)(PyObject*); | ||
|  | typedef PyObject* (*zero_arg)(void); | ||
|  | 
 | ||
|  | #define TRY_RETURN_CALL(ty, args...) \
 | ||
|  |   if (__builtin_wasm_test_function_pointer_signature((ty)func)) { \ | ||
|  |     return ((ty)func)(args); \ | ||
|  |   } | ||
|  | 
 | ||
|  | __attribute__((export_name("trampoline_call"))) PyObject* | ||
|  | trampoline_call(int* success, | ||
|  |                 void* func, | ||
|  |                 PyObject* self, | ||
|  |                 PyObject* args, | ||
|  |                 PyObject* kw) | ||
|  | { | ||
|  |   *success = 1; | ||
|  |   TRY_RETURN_CALL(three_arg, self, args, kw); | ||
|  |   TRY_RETURN_CALL(two_arg, self, args); | ||
|  |   TRY_RETURN_CALL(one_arg, self); | ||
|  |   TRY_RETURN_CALL(zero_arg); | ||
|  |   *success = 0; | ||
|  |   return 0; | ||
|  | } |