pyodide_webassembly_runtime_layer/lib.rs
1#![deny(clippy::complexity)]
2#![deny(clippy::correctness)]
3#![warn(clippy::nursery)]
4#![warn(clippy::pedantic)]
5#![deny(clippy::perf)]
6#![deny(clippy::style)]
7#![deny(clippy::suspicious)]
8#![warn(missing_docs)]
9
10//! [![CI Status]][workflow] [![MSRV]][repo] [![Latest Version]][crates.io]
11//! [![Rust Doc Crate]][docs.rs] [![Rust Doc Main]][docs]
12//!
13//! [CI Status]: https://img.shields.io/github/actions/workflow/status/juntyr/pyodide-webassembly-runtime-layer/ci.yml?branch=main
14//! [workflow]: https://github.com/juntyr/pyodide-webassembly-runtime-layer/actions/workflows/ci.yml?query=branch%3Amain
15//!
16//! [MSRV]: https://img.shields.io/badge/MSRV-1.76.0-blue
17//! [repo]: https://github.com/juntyr/pyodide-webassembly-runtime-layer
18//!
19//! [Latest Version]: https://img.shields.io/crates/v/pyodide-webassembly-runtime-layer
20//! [crates.io]: https://crates.io/crates/pyodide-webassembly-runtime-layer
21//!
22//! [Rust Doc Crate]: https://img.shields.io/docsrs/pyodide-webassembly-runtime-layer
23//! [docs.rs]: https://docs.rs/pyodide-webassembly-runtime-layer/
24//!
25//! [Rust Doc Main]: https://img.shields.io/badge/docs-main-blue
26//! [docs]: https://juntyr.github.io/pyodide-webassembly-runtime-layer/pyodide_webassembly_runtime_layer
27//!
28//! `pyodide-webassembly-runtime-layer` implements the [`wasm_runtime_layer`]
29//! backend API to provide access to the web browser's [`WebAssembly`] runtime
30//! using [`Pyodide`].
31//!
32//! The implementation of this crate is heavily inspired by the
33//! [`js_wasm_runtime_layer`] backend for the [`wasm_runtime_layer`]. Instead of
34//! relying on the [`js-sys`] and [`wasm-bindgen`] crates to generate
35//! JavaScript-based bindings to the [`WebAssembly`] JavaScript API, this crate
36//! uses [`Pyodide`]'s [`js`] FFI layer to interact with [`WebAssembly`] through
37//! Python running inside WASM. `pyodide-webassembly-runtime-layer` is therefore
38//! useful when developing a Python module in Rust, e.g. using [`PyO3`], which
39//! requires access to some WASM runtime using the [`wasm_runtime_layer`] API
40//! and may be deployed to the web itself using [`Pyodide`].
41//!
42//! ## Memory Management
43//!
44//! `pyodide-webassembly-runtime-layer` generally tries to keep memory
45//! management intuitive by relying primarily on Python's reference counting to
46//! drop objects once they are no longer needed by both the user-written Rust
47//! code and the [`WebAssembly`] runtime. As this crate coordinates interop
48//! across Rust, Python, and JavaScript, it takes extra care to avoid reference
49//! cycles across the different memory management strategies of the languages
50//! which would otherwise lead to memory leakage. If using this crate produces a
51//! memory leak that is avoided with a different [`wasm_runtime_layer`] backend,
52//! please [report it as a bug][new-issue].
53//!
54//! There is one exception to the intuitive memory management strategy:
55//!
56//! - [`Func::new`] creates a host function, which may capture arbitrary data.
57//! To avoid cross-language reference cycles, it is stored using [`wobbly`]
58//! references inside the [`Func`] and its associated [`Store`]. Even though
59//! the host function and its data are dropped once either the [`Store`] is
60//! dropped or references to the [`Func`] are dropped, additional bookkeeping
61//! data is required until both have been dropped.
62//!
63//! [`wasm_runtime_layer`]: https://docs.rs/wasm_runtime_layer/0.5/
64//! [`WebAssembly`]: https://developer.mozilla.org/en-US/docs/WebAssembly
65//! [`Pyodide`]: https://pyodide.org/en/stable/
66//! [`js_wasm_runtime_layer`]: https://docs.rs/js_wasm_runtime_layer/
67//! [`js-sys`]: https://docs.rs/js-sys/
68//! [`wasm-bindgen`]: https://docs.rs/wasm-bindgen/
69//! [`js`]: https://pyodide.org/en/stable/usage/api/python-api.html
70//! [`PyO3`]: https://docs.rs/pyo3/0.24/
71//! [new-issue]: https://github.com/juntyr/pyodide-webassembly-runtime-layer/issues/new
72//! [`Func::new`]: https://docs.rs/wasm_runtime_layer/0.5/wasm_runtime_layer/struct.Func.html#method.new
73//! [`wobbly`]: https://docs.rs/wobbly/0.1/
74//! [`Func`]: https://docs.rs/wasm_runtime_layer/0.5/wasm_runtime_layer/struct.Func.html
75//! [`Store`]: https://docs.rs/wasm_runtime_layer/0.5/wasm_runtime_layer/struct.Store.html
76
77use wasm_runtime_layer::backend::WasmEngine;
78
79mod conversion;
80mod externref;
81mod features;
82mod func;
83mod global;
84mod instance;
85mod memory;
86mod module;
87mod store;
88mod table;
89
90pub use externref::ExternRef;
91pub use func::Func;
92pub use global::Global;
93pub use instance::Instance;
94pub use memory::Memory;
95pub use module::Module;
96pub use store::{Store, StoreContext, StoreContextMut};
97pub use table::Table;
98
99#[derive(Default, Debug, Clone)]
100/// Runtime for [`WebAssembly`] web runtime.
101///
102/// [`WebAssembly`]: https://developer.mozilla.org/en-US/docs/WebAssembly
103pub struct Engine {
104 _private: (),
105}
106
107impl WasmEngine for Engine {
108 type ExternRef = ExternRef;
109 type Func = Func;
110 type Global = Global;
111 type Instance = Instance;
112 type Memory = Memory;
113 type Module = Module;
114 type Store<T> = Store<T>;
115 type StoreContext<'a, T: 'a> = StoreContext<'a, T>;
116 type StoreContextMut<'a, T: 'a> = StoreContextMut<'a, T>;
117 type Table = Table;
118}