mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	
		
			
	
	
		
			83 lines
		
	
	
	
		
			2.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			83 lines
		
	
	
	
		
			2.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								#if defined(PY_CALL_TRAMPOLINE)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <emscripten.h>             // EM_JS
							 | 
						||
| 
								 | 
							
								#include <Python.h>
							 | 
						||
| 
								 | 
							
								#include "pycore_runtime.h"         // _PyRuntime
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * This is the GoogleChromeLabs approved way to feature detect type-reflection:
							 | 
						||
| 
								 | 
							
								 * https://github.com/GoogleChromeLabs/wasm-feature-detect/blob/main/src/detectors/type-reflection/index.js
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								EM_JS(int, _PyEM_detect_type_reflection, (), {
							 | 
						||
| 
								 | 
							
								    return "Function" in WebAssembly;
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void
							 | 
						||
| 
								 | 
							
								_Py_EmscriptenTrampoline_Init(_PyRuntimeState *runtime)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    runtime->wasm_type_reflection_available = _PyEM_detect_type_reflection();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Backwards compatible trampoline works with all JS runtimes
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								EM_JS(PyObject*,
							 | 
						||
| 
								 | 
							
								_PyEM_TrampolineCall_JavaScript, (PyCFunctionWithKeywords func,
							 | 
						||
| 
								 | 
							
								                                  PyObject *arg1,
							 | 
						||
| 
								 | 
							
								                                  PyObject *arg2,
							 | 
						||
| 
								 | 
							
								                                  PyObject *arg3),
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return wasmTable.get(func)(arg1, arg2, arg3);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * In runtimes with WebAssembly type reflection, count the number of parameters
							 | 
						||
| 
								 | 
							
								 * and cast to the appropriate signature
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								EM_JS(int, _PyEM_CountFuncParams, (PyCFunctionWithKeywords func),
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    let n = _PyEM_CountFuncParams.cache.get(func);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (n !== undefined) {
							 | 
						||
| 
								 | 
							
								        return n;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    n = WebAssembly.Function.type(wasmTable.get(func)).parameters.length;
							 | 
						||
| 
								 | 
							
								    _PyEM_CountFuncParams.cache.set(func, n);
							 | 
						||
| 
								 | 
							
								    return n;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								_PyEM_CountFuncParams.cache = new Map();
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typedef PyObject* (*zero_arg)(void);
							 | 
						||
| 
								 | 
							
								typedef PyObject* (*one_arg)(PyObject*);
							 | 
						||
| 
								 | 
							
								typedef PyObject* (*two_arg)(PyObject*, PyObject*);
							 | 
						||
| 
								 | 
							
								typedef PyObject* (*three_arg)(PyObject*, PyObject*, PyObject*);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								PyObject*
							 | 
						||
| 
								 | 
							
								_PyEM_TrampolineCall_Reflection(PyCFunctionWithKeywords func,
							 | 
						||
| 
								 | 
							
								                                PyObject* self,
							 | 
						||
| 
								 | 
							
								                                PyObject* args,
							 | 
						||
| 
								 | 
							
								                                PyObject* kw)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    switch (_PyEM_CountFuncParams(func)) {
							 | 
						||
| 
								 | 
							
								        case 0:
							 | 
						||
| 
								 | 
							
								            return ((zero_arg)func)();
							 | 
						||
| 
								 | 
							
								        case 1:
							 | 
						||
| 
								 | 
							
								            return ((one_arg)func)(self);
							 | 
						||
| 
								 | 
							
								        case 2:
							 | 
						||
| 
								 | 
							
								            return ((two_arg)func)(self, args);
							 | 
						||
| 
								 | 
							
								        case 3:
							 | 
						||
| 
								 | 
							
								            return ((three_arg)func)(self, args, kw);
							 | 
						||
| 
								 | 
							
								        default:
							 | 
						||
| 
								 | 
							
								            PyErr_SetString(PyExc_SystemError,
							 | 
						||
| 
								 | 
							
								                            "Handler takes too many arguments");
							 | 
						||
| 
								 | 
							
								            return NULL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif
							 |