Skip to content

Commit bfbb818

Browse files
hoodmaneAA-Turner
andauthored
Apply AA-Turner's edits
Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com>
1 parent c912ad1 commit bfbb818

File tree

1 file changed

+39
-35
lines changed

1 file changed

+39
-35
lines changed

peps/pep-0776.rst

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ Abstract
1414
========
1515

1616
`Emscripten <https://emscripten.org/>`__ is a complete open source compiler
17-
toolchain which compiles C/C++ code into WebAssembly/JavaScript executables that
18-
run in JavaScript runtimes including browsers and Node.js.
17+
toolchain. It compiles C/C++ code into WebAssembly/JavaScript executables,
18+
for use in JavaScript runtimes, including browsers and Node.js.
1919

2020
This PEP formalizes the addition of Tier 3 for Emscripten support in Python 3.14
21-
which `was approved by the steering council on October 25, 2024
21+
which `was approved by the Steering Council on October 25, 2024
2222
<https://github.com/python/steering-council/issues/256>`__. The goal is to allow
2323
Pyodide wheels to be uploaded to PyPI.
2424

@@ -65,7 +65,7 @@ Packaging Goals
6565
1. To describe Pyodide's packaging tooling
6666
2. To describe Pyodide's wheel abi to a similar level of detail as the manylinux
6767
PEPs
68-
3. To request that Pyodide wheels be allowed for upload to PyPI
68+
3. For Pyodide wheels to be allowed for upload to PyPI
6969

7070

7171
Emscripten Platform Information
@@ -79,11 +79,11 @@ Background on Emscripten
7979
consists of a C and C++ compiler and linker based on LLVM, together with a
8080
runtime based on a mildly patched musl libc.
8181

82-
Emscripten is a POSIX-based platform. It uses the WebAssembly binary format,
83-
specified here:
82+
Emscripten is a POSIX-based platform. It uses the `WebAssembly binary format`_,
83+
and the `WebAssembly dynamic linking section`_.
8484

85-
* https://webassembly.github.io/spec/core/binary/index.html
86-
* https://github.com/WebAssembly/tool-conventions/blob/main/DynamicLinking.md
85+
.. _WebAssembly binary format: https://webassembly.github.io/spec/core/binary/index.html
86+
.. _WebAssembly dynamic linking section: https://github.com/WebAssembly/tool-conventions/blob/main/DynamicLinking.md
8787

8888
The ``emcc`` compiler is a wrapper around ``clang``. The ``emcc`` linker is a
8989
wrapper around ``wasm-ld`` (also part of the LLVM toolchain).
@@ -106,18 +106,20 @@ Emscripten executables can be linked with threading support, but it comes
106106
with several limitations:
107107

108108
* Enabling threading requires websites to be served with special security headers
109-
that indicate acceptance of the possibility of `Spectre <https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)>`__-style information
109+
that indicate acceptance of the possibility of Spectre_-style information
110110
leakage. These headers are a usability hazard for users who are not intimately
111111
familiar with the web platform.
112112

113+
.. _Spectre: https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)
114+
113115
* If an executable is linked with both threading and a dynamic loader, Emscripten
114116
prints a warning that using dynamic loading and pthreads together is
115117
experimental. It may cause performance problems or crashes. These problems may
116118
require WebAssembly standards work to resolve.
117119

118120
Because of these limitations, Pyodide standardizes a no-pthreads build of
119-
Python. We will start with support for no-pthreads builds. If there is
120-
sufficient demand, a pthreads build with no dynamic loader could be added later.
121+
Python. If there is sufficient demand, a pthreads build with no dynamic loader
122+
could be added later.
121123

122124
Emscripten ABI Compatibility
123125
----------------------------
@@ -141,20 +143,20 @@ ABI for each feature release of Python.
141143
The Pyodide team also coordinates the ABI flags that Pyodide uses with the
142144
Emscripten ABI that Rust supports in order to ensure that we have support for
143145
the many popular Rust packages. Historically, most of the work for this has
144-
been related to unwinding ABIs. See for instance `this Rust Major change
145-
proposal <https://github.com/rust-lang/compiler-team/issues/801>`__.
146+
been related to unwinding ABIs. See for instance `this Rust Major Change
147+
Proposal <https://github.com/rust-lang/compiler-team/issues/801>`__.
146148

147149
Development Tools
148150
-----------------
149151

150152
Emscripten development tools are equally well supported on Linux, Windows, and
151-
macOS. Upstream tools:
153+
macOS. The upstream tools include:
152154

153-
* The Emscripten Software Developer Kit (emsdk) which can be used to install the
154-
Emscripten compiler toolchain (emcc).
155-
* emcc is a C and C++ compiler, linker, and a sysroot with headers for the
156-
system libraries. The system libraries themselves are generated on the fly
157-
based on the ABI requested.
155+
* The Emscripten Software Developer Kit (:program:`emsdk`) which can be used to
156+
install the Emscripten compiler toolchain (:program:`emcc`).
157+
* :program:`emcc` is a C and C++ compiler, linker, and a sysroot with headers
158+
for the system libraries. The system libraries themselves are generated on
159+
the fly based on the ABI requested.
158160
* Node.js can be used as an "emulator" to run Emscripten programs from the
159161
command line. This emulation behaves best on Linux with macOS as a runner up.
160162
Node.js is the most convenient way to test Emscripten programs.
@@ -170,7 +172,9 @@ Pyodide's tools:
170172
* ``pyodide venv`` can make a virtual environment that runs in Pyodide.
171173
* ``pytest-pyodide`` can test Python code against various JavaScript runtimes.
172174

173-
cibuildwheel supports building wheels to target Emscripten using ``pyodide build``.
175+
cibuildwheel__ supports building wheels to target Emscripten using ``pyodide build``.
176+
177+
__ https://cibuildwheel.pypa.io/
174178

175179
In the short term, Pyodide's packaging tooling will stay in the Pyodide
176180
repository. It is an open question where Pyodide's packaging tooling should live
@@ -189,13 +193,13 @@ shut down the runtime on exit. It also includes an implementation for all of the
189193
system calls, including the file system, the dynamic loader, and any logic to
190194
expose additional functionality from the JavaScript runtime to C code.
191195

192-
The ``.mjs`` file exports a single ``bootstrapEmscriptenExecutable()``
196+
The ``.mjs`` file exports a single :js:func:`bootstrapEmscriptenExecutable()`
193197
JavaScript function that bootstraps the runtime, calls the ``main()`` function,
194198
and returns an API object that can be used to call C functions. Each time it is
195199
called produces a complete and independent copy of the runtime with its own
196200
separate address space.
197201

198-
The ``bootstrapEmscriptenExecutable()`` takes a large number of runtime
202+
The :js:func:`bootstrapEmscriptenExecutable()` takes a large number of runtime
199203
settings. `The full list is described in the Emscripten documentation here.
200204
<https://emscripten.org/docs/api_reference/module.html#id3>`__ The most
201205
important of these are as follows:
@@ -242,8 +246,8 @@ Emscripten file system. There are several possible approaches to this:
242246
uncompressed zip file allows the web server and client to apply better
243247
compression to the standard library itself. It also uses the more efficient
244248
native decompression algorithms of the browser rather than less efficient
245-
WebAssembly decompression. The disadvantage of this is a higher memory
246-
footprint and it breaks :py:mod:`inspect` and various tests that do not expect the
249+
WebAssembly decompression. The disadvantages of this are a higher memory
250+
footprint and breaking :py:mod:`inspect` & various tests that do not expect the
247251
standard library to be packaged in this way.
248252

249253
* Put the standard library into an uncompressed tar archive and mount it into a
@@ -256,30 +260,30 @@ Pyodide uses the ``ZipImporter`` approach in every runtime. Python uses the
256260
NODEFS approach when run with node and the ``ZipImporter`` approach for the web
257261
example. We will continue with this approach.
258262

259-
The ``ZipImporter`` provides a clean resolution for a bootstrapping problem: The
263+
The ``ZipImporter`` provides a clean resolution for a bootstrapping problem: the
260264
Python runtime is capable of unpacking a wide variety of archive formats, but
261265
the Python runtime is not ready to use until the standard library is already
262266
available. Since ``zipimport.py`` is a frozen module, it avoids these problems.
263267
All of the other approaches solve the bootstrapping problem by setting up the
264268
standard library using JavaScript.
265269

266-
Packages
267-
~~~~~~~~
270+
Third-party packages
271+
~~~~~~~~~~~~~~~~~~~~
268272

269273
It is also necessary to make any needed packages available in the Emscripten
270-
file system. Currently Emscripten cpython has no support for packages. Pyodide
274+
file system. Currently Emscripten CPython has no support for packages. Pyodide
271275
uses two different approaches for packages:
272276

273277
* In the browser, Pyodide downloads and unpacks wheels into the MEMFS
274278
site-packages directory. It then preloads all dynamic libraries in the wheel.
275279
The work of downloading and installing all the packages is redone every time
276280
the runtime starts.
277281

278-
* The Pyodide ``python`` cli entrypoint mounts all of the host file system as
282+
* The Pyodide ``python`` CLI entrypoint mounts all of the host file system as
279283
NODEFS directories before it bootstraps Python. This allows the normal virtual
280284
environment mechanism to work. Pyodide virtual environments contain a patched
281285
copy of pip and a custom ``pip.conf`` so that pip will install Pyodide wheels.
282-
On startup the Pyodide ``python`` cli will preload all Emscripten dynamic
286+
On startup the Pyodide ``python`` CLI will preload all Emscripten dynamic
283287
libraries that are in the site-packages directory.
284288

285289

@@ -288,7 +292,7 @@ Console and Interactive Usage
288292

289293
``stdin`` defaults to always returning ``EOF``, while ``stdout`` and ``stderr``
290294
default to calling ``console.log`` and ``console.error`` respectively. It is
291-
possible to pass handlers to ``bootstrapEmscriptenExecutable()`` to configure
295+
possible to pass handlers to :js:func:`bootstrapEmscriptenExecutable()` to configure
292296
the standard streams, but no matter what the I/O devices have undesirable line
293297
buffering behavior that forces a new line when flushed. To implement a well
294298
behaved TTY in-browser, it is necessary to remove the default I/O devices and
@@ -394,7 +398,7 @@ exceptions. This ensures that any recoverable JavaScript error is caught before
394398
it unwinds through any WebAssembly frames. All entrypoints to WebAssembly are
395399
also wrapped with JavaScript try/catch blocks. Any exceptions caught there have
396400
unwound WebAssembly frames and are thus considered to be fatal errors (though
397-
there is a special case to handle ``exit()``). This requires foundational
401+
there is a special case to handle :func:`~sys.exit()`). This requires foundational
398402
integration with the Python/JavaScript foreign function interface.
399403

400404
When the Pyodide runtime catches a fatal exception, it introspects the error to
@@ -413,7 +417,7 @@ traceback.
413417

414418
Because Emscripten Python currently has no JavaScript API and no foreign function
415419
interface, the situation is much simpler. The Python Node.js runner wraps the call
416-
to ``bootstrapEmscriptenExecutable()`` in a try/catch block. If an exception is
420+
to :js:func:`bootstrapEmscriptenExecutable()` in a try/catch block. If an exception is
417421
caught, it displays the JavaScript exception and calls ``_Py_DumpTraceback()``.
418422
It then exits with code 1. We will stick with this approach until we add either
419423
a JavaScript API or foreign function interface, which is out of scope for this PEP.
@@ -714,8 +718,8 @@ code duplication.
714718
Eventually, we would like to upstream Pyodide's bootstrapping API. In the short
715719
term, to keep things simple we will support no JavaScript API.
716720

717-
FFI
718-
~~~
721+
JavaScript foreign function interface (FFI)
722+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
719723

720724
Because Emscripten supports POSIX, a significant number of tasks can be achieved
721725
using the ``os`` module. However, many fundamental operations in JavaScript

0 commit comments

Comments
 (0)