mirror of
				https://github.com/python/cpython.git
				synced 2025-10-26 03:04:41 +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.
		
			
				
	
	
		
			38 lines
		
	
	
	
		
			1.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			38 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;
 | |
| }
 |