mirror of
https://github.com/python/cpython.git
synced 2025-10-19 16:03:42 +00:00

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;
|
|
}
|