gh-156780: Emscripten: support static linking · python/cpython@1b00df2 · GitHub
Skip to content

Commit 1b00df2

Browse files
clementperonclaude
andcommitted
gh-156780: Emscripten: support static linking
Export _PyRuntime's address from the call trampoline so it works without -sEXPORTED_FUNCTIONS, do not suspend in poll() when there is nothing to await, pass -sALLOW_TABLE_GROWTH when not linking with MAIN_MODULE, and wrap main() through the _main binding when there is no resolveGlobalSymbol. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 5a45a5d commit 1b00df2

6 files changed

Lines changed: 77 additions & 23 deletions

File tree

Programs/emscripten_beforemain.c

Lines changed: 41 additions & 20 deletions

Python/emscripten_syscalls.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,19 @@ EM_JS_MACROS(__externref_t, __maybe_poll_async, (intptr_t fds, int nfds, int tim
161161
if (!WebAssembly.promising) {
162162
return null;
163163
}
164+
// Suspending at all requires a promising stack, so do not if there is
165+
// nothing to await.
166+
var async = false;
167+
for (var i = 0; i < nfds; i++) {
168+
var s = FS.getStream(HEAP32[(fds + POLLFD_SIZE * i + POLLFD_FD)/4]);
169+
if (s && s.stream_ops.pollAsync) {
170+
async = true;
171+
break;
172+
}
173+
}
174+
if (!async) {
175+
return null;
176+
}
164177
return (async function() {
165178
try {
166179
var nonzero = 0;

Python/emscripten_trampoline.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ typedef PyObject* (*TrampolineFunc)(int* success,
4747
PyObject* args,
4848
PyObject* kw);
4949

50+
// The JS glue only binds _PyRuntime if it is exported, which an embedder
51+
// linking libpython does not do.
52+
EMSCRIPTEN_KEEPALIVE _PyRuntimeState *const _PyEM_runtime = &_PyRuntime;
53+
5054
/**
5155
* Backwards compatible trampoline works with all JS runtimes
5256
*/
@@ -90,7 +94,7 @@ function getPyEMTrampolinePtr() {
9094
addOnPreRun(function setEmscriptenTrampoline() {
9195
const ptr = getPyEMTrampolinePtr();
9296
const offset = HEAP32[__PyEM_EMSCRIPTEN_TRAMPOLINE_OFFSET / 4];
93-
HEAP32[(__PyRuntime + offset) / 4] = ptr;
97+
HEAP32[(HEAPU32[__PyEM_runtime / 4] + offset) / 4] = ptr;
9498
});
9599
);
96100

configure

Lines changed: 9 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

configure.ac

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2446,6 +2446,11 @@ AS_CASE([$ac_sys_system],
24462446
24472447
AS_VAR_IF([enable_wasm_dynamic_linking], [yes], [
24482448
AS_VAR_APPEND([LINKFORSHARED], [" -sMAIN_MODULE"])
2449+
AC_DEFINE([Py_EMSCRIPTEN_DYNAMIC_LINKING], [1],
2450+
[Define if the Emscripten build is linked with -sMAIN_MODULE.])
2451+
], [
2452+
dnl Implied by MAIN_MODULE; the call trampoline's addFunction() needs it.
2453+
AS_VAR_APPEND([LINKFORSHARED], [" -sALLOW_TABLE_GROWTH"])
24492454
])
24502455
24512456
AS_VAR_IF([enable_wasm_pthreads], [yes], [
@@ -5406,8 +5411,8 @@ PLATFORM_MAIN_OBJS=
54065411

54075412
AS_CASE([$ac_sys_system],
54085413
[Emscripten], [
5409-
AS_VAR_APPEND([PLATFORM_MAIN_OBJS], [' Programs/emscripten_beforemain.o'])
54105414
AS_VAR_APPEND([PLATFORM_OBJS], [' Python/emscripten_signal.o Python/emscripten_trampoline.o Python/emscripten_trampoline_wasm.o'])
5415+
AS_VAR_APPEND([PLATFORM_MAIN_OBJS], [' Programs/emscripten_beforemain.o'])
54115416
AS_VAR_IF([enable_emscripten_syscalls], [yes], [
54125417
AS_VAR_APPEND([PLATFORM_OBJS], [' Python/emscripten_syscalls.o'])
54135418
])

pyconfig.h.in

Lines changed: 3 additions & 0 deletions

0 commit comments

Comments
 (0)